/*============================================================================= Copyright (c) 2001-2011 Joel de Guzman Copyright (c) 2001-2011 Hartmut Kaiser Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ #if !defined(SPIRIT_SEQUENCE_BASE_APRIL_22_2006_0811AM) #define SPIRIT_SEQUENCE_BASE_APRIL_22_2006_0811AM #if defined(_MSC_VER) #pragma once #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace spirit { namespace qi { template struct sequence_base // this class is shared by sequence and expect : nary_parser { typedef Elements elements_type; struct sequence_base_id; template struct attribute { // Put all the element attributes in a tuple typedef typename traits::build_attribute_sequence< Elements, Context, traits::sequence_attribute_transform , Iterator, qi::domain >::type all_attributes; // Now, build a fusion vector over the attributes. Note // that build_fusion_vector 1) removes all unused attributes // and 2) may return unused_type if all elements have // unused_type(s). typedef typename traits::build_fusion_vector::type type_; // Finally, strip single element vectors into its // naked form: vector1 --> T typedef typename traits::strip_single_element_vector::type type; }; sequence_base(Elements const& elements_) : elements(elements_) {} // standard case. Attribute is a fusion tuple template bool parse_impl(Iterator& first, Iterator const& last , Context& context, Skipper const& skipper , Attribute& attr_, mpl::false_) const { Iterator iter = first; typedef traits::attribute_not_unused predicate; // wrap the attribute in a tuple if it is not a tuple or if the // attribute of this sequence is a single element tuple typedef typename attribute::type_ attr_type_; typename traits::wrap_if_not_tuple , mpl::not_ > >::type >::type attr_local(attr_); // return false if *any* of the parsers fail if (spirit::any_if(elements, attr_local , Derived::fail_function(iter, last, context, skipper), predicate())) return false; first = iter; return true; } // Special case when Attribute is an stl container template bool parse_impl(Iterator& first, Iterator const& last , Context& context, Skipper const& skipper , Attribute& attr_, mpl::true_) const { // ensure the attribute is actually a container type traits::make_container(attr_); Iterator iter = first; // return false if *any* of the parsers fail if (fusion::any(elements , detail::make_sequence_pass_container( Derived::fail_function(iter, last, context, skipper), attr_)) ) return false; first = iter; return true; } // main parse function. Dispatches to parse_impl depending // on the Attribute type. template bool parse(Iterator& first, Iterator const& last , Context& context, Skipper const& skipper , Attribute& attr_) const { return parse_impl(first, last, context, skipper, attr_ , traits::is_container()); } template info what(Context& context) const { info result(this->derived().id()); fusion::for_each(elements, spirit::detail::what_function(result, context)); return result; } Elements elements; }; }}} #endif