Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-19 09:47:46

0001 /*=============================================================================
0002     Copyright (c) 2001-2011 Joel de Guzman
0003 
0004     Distributed under the Boost Software License, Version 1.0. (See accompanying
0005     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 =============================================================================*/
0007 #ifndef BOOST_SPIRIT_QI_OPERATOR_SEQUENTIAL_OR_HPP
0008 #define BOOST_SPIRIT_QI_OPERATOR_SEQUENTIAL_OR_HPP
0009 
0010 #if defined(_MSC_VER)
0011 #pragma once
0012 #endif
0013 
0014 #include <boost/spirit/home/qi/meta_compiler.hpp>
0015 #include <boost/spirit/home/qi/detail/pass_function.hpp>
0016 #include <boost/spirit/home/qi/detail/attributes.hpp>
0017 #include <boost/spirit/home/support/detail/what_function.hpp>
0018 #include <boost/spirit/home/support/algorithm/any_if_ns_so.hpp>
0019 #include <boost/spirit/home/support/handles_container.hpp>
0020 #include <boost/fusion/include/as_vector.hpp>
0021 #include <boost/fusion/include/for_each.hpp>
0022 #include <boost/proto/operators.hpp>
0023 #include <boost/proto/tags.hpp>
0024 
0025 namespace boost { namespace spirit
0026 {
0027     ///////////////////////////////////////////////////////////////////////////
0028     // Enablers
0029     ///////////////////////////////////////////////////////////////////////////
0030     template <>
0031     struct use_operator<qi::domain, proto::tag::logical_or> // enables ||
0032       : mpl::true_ {};
0033 
0034     template <>
0035     struct flatten_tree<qi::domain, proto::tag::logical_or> // flattens ||
0036       : mpl::true_ {};
0037 }}
0038 
0039 namespace boost { namespace spirit { namespace qi
0040 {
0041     template <typename Elements>
0042     struct sequential_or : nary_parser<sequential_or<Elements> >
0043     {
0044         template <typename Context, typename Iterator>
0045         struct attribute
0046         {
0047             // Put all the element attributes in a tuple,
0048             // wrapping each element in a boost::optional
0049             typedef typename traits::build_attribute_sequence<
0050                 Elements, Context, traits::sequential_or_attribute_transform
0051               , Iterator, qi::domain
0052             >::type all_attributes;
0053 
0054             // Now, build a fusion vector over the attributes. Note
0055             // that build_fusion_vector 1) removes all unused attributes
0056             // and 2) may return unused_type if all elements have
0057             // unused_type(s).
0058             typedef typename
0059                 traits::build_fusion_vector<all_attributes>::type
0060             type;
0061         };
0062 
0063         sequential_or(Elements const& elements_)
0064           : elements(elements_) {}
0065 
0066         template <typename Iterator, typename Context
0067           , typename Skipper, typename Attribute>
0068         bool parse(Iterator& first, Iterator const& last
0069           , Context& context, Skipper const& skipper
0070           , Attribute& attr_) const
0071         {
0072             typedef traits::attribute_not_unused<Context, Iterator> predicate;
0073             detail::pass_function<Iterator, Context, Skipper>
0074                 f(first, last, context, skipper);
0075 
0076             // wrap the attribute in a tuple if it is not a tuple
0077             typename traits::wrap_if_not_tuple<Attribute>::type attr_local(attr_);
0078 
0079             // return true if *any* of the parsers succeed
0080             // (we use the non-short-circuiting and strict order version:
0081             // any_if_ns_so to force all the elements to be tested and
0082             // in the defined order: first is first, last is last)
0083             return spirit::any_if_ns_so(elements, attr_local, f, predicate());
0084         }
0085 
0086         template <typename Context>
0087         info what(Context& context) const
0088         {
0089             info result("sequential-or");
0090             fusion::for_each(elements,
0091                 spirit::detail::what_function<Context>(result, context));
0092             return result;
0093         }
0094 
0095         Elements elements;
0096     };
0097 
0098     ///////////////////////////////////////////////////////////////////////////
0099     // Parser generators: make_xxx function (objects)
0100     ///////////////////////////////////////////////////////////////////////////
0101     template <typename Elements, typename Modifiers>
0102     struct make_composite<proto::tag::logical_or, Elements, Modifiers>
0103       : make_nary_composite<Elements, sequential_or>
0104     {};
0105 }}}
0106 
0107 namespace boost { namespace spirit { namespace traits
0108 {
0109     ///////////////////////////////////////////////////////////////////////////
0110     // We specialize this for sequential_or (see support/attributes.hpp).
0111     // For sequential_or, we only wrap the attribute in a tuple IFF
0112     // it is not already a fusion tuple.
0113     template <typename Elements, typename Attribute>
0114     struct pass_attribute<qi::sequential_or<Elements>, Attribute>
0115       : wrap_if_not_tuple<Attribute> {};
0116 
0117     ///////////////////////////////////////////////////////////////////////////
0118     template <typename Elements>
0119     struct has_semantic_action<qi::sequential_or<Elements> >
0120       : nary_has_semantic_action<Elements> {};
0121 
0122     ///////////////////////////////////////////////////////////////////////////
0123     template <typename Elements, typename Attribute, typename Context
0124       , typename Iterator>
0125     struct handles_container<qi::sequential_or<Elements>, Attribute, Context
0126       , Iterator>
0127       : nary_handles_container<Elements, Attribute, Context, Iterator> {};
0128 }}}
0129 
0130 #endif