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     Copyright (c) 2001-2011 Hartmut Kaiser
0004 
0005     Distributed under the Boost Software License, Version 1.0. (See accompanying
0006     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 =============================================================================*/
0008 #ifndef BOOST_SPIRIT_QI_OPERATOR_LIST_HPP
0009 #define BOOST_SPIRIT_QI_OPERATOR_LIST_HPP
0010 
0011 #if defined(_MSC_VER)
0012 #pragma once
0013 #endif
0014 
0015 #include <boost/spirit/home/qi/meta_compiler.hpp>
0016 #include <boost/spirit/home/qi/parser.hpp>
0017 #include <boost/spirit/home/support/container.hpp>
0018 #include <boost/spirit/home/qi/detail/attributes.hpp>
0019 #include <boost/spirit/home/qi/detail/fail_function.hpp>
0020 #include <boost/spirit/home/qi/detail/pass_container.hpp>
0021 #include <boost/spirit/home/support/has_semantic_action.hpp>
0022 #include <boost/spirit/home/support/handles_container.hpp>
0023 #include <boost/spirit/home/support/info.hpp>
0024 #include <boost/proto/operators.hpp>
0025 #include <boost/proto/tags.hpp>
0026 #include <vector>
0027 
0028 namespace boost { namespace spirit
0029 {
0030     ///////////////////////////////////////////////////////////////////////////
0031     // Enablers
0032     ///////////////////////////////////////////////////////////////////////////
0033     template <>
0034     struct use_operator<qi::domain, proto::tag::modulus> // enables p % d
0035       : mpl::true_ {};
0036 }}
0037 
0038 namespace boost { namespace spirit { namespace qi
0039 {
0040     template <typename Left, typename Right>
0041     struct list : binary_parser<list<Left, Right> >
0042     {
0043         typedef Left left_type;
0044         typedef Right right_type;
0045 
0046         template <typename Context, typename Iterator>
0047         struct attribute
0048         {
0049             // Build a std::vector from the LHS's attribute. Note
0050             // that build_std_vector may return unused_type if the
0051             // subject's attribute is an unused_type.
0052             typedef typename
0053                 traits::build_std_vector<
0054                     typename traits::
0055                         attribute_of<Left, Context, Iterator>::type
0056                 >::type
0057             type;
0058         };
0059 
0060         list(Left const& left_, Right const& right_)
0061           : left(left_), right(right_) {}
0062 
0063         template <typename F>
0064         bool parse_container(F f) const
0065         {
0066             // in order to succeed we need to match at least one element 
0067             if (f (left))
0068                 return false;
0069 
0070             typename F::iterator_type save = f.f.first;
0071             while (right.parse(f.f.first, f.f.last, f.f.context, f.f.skipper, unused)
0072               && !f (left))
0073             {
0074                 save = f.f.first;
0075             }
0076 
0077             f.f.first = save;
0078             return true;
0079         }
0080 
0081         template <typename Iterator, typename Context
0082           , typename Skipper, typename Attribute>
0083         bool parse(Iterator& first, Iterator const& last
0084           , Context& context, Skipper const& skipper
0085           , Attribute& attr_) const
0086         {
0087             typedef detail::fail_function<Iterator, Context, Skipper>
0088                 fail_function;
0089 
0090             // ensure the attribute is actually a container type
0091             traits::make_container(attr_);
0092 
0093             Iterator iter = first;
0094             fail_function f(iter, last, context, skipper);
0095             if (!parse_container(detail::make_pass_container(f, attr_)))
0096                 return false;
0097 
0098             first = f.first;
0099             return true;
0100         }
0101 
0102         template <typename Context>
0103         info what(Context& context) const
0104         {
0105             return info("list",
0106                 std::make_pair(left.what(context), right.what(context)));
0107         }
0108 
0109         Left left;
0110         Right right;
0111     };
0112 
0113     ///////////////////////////////////////////////////////////////////////////
0114     // Parser generators: make_xxx function (objects)
0115     ///////////////////////////////////////////////////////////////////////////
0116     template <typename Elements, typename Modifiers>
0117     struct make_composite<proto::tag::modulus, Elements, Modifiers>
0118       : make_binary_composite<Elements, list>
0119     {};
0120 }}}
0121 
0122 namespace boost { namespace spirit { namespace traits
0123 {
0124     ///////////////////////////////////////////////////////////////////////////
0125     template <typename Left, typename Right>
0126     struct has_semantic_action<qi::list<Left, Right> >
0127       : binary_has_semantic_action<Left, Right> {};
0128 
0129     ///////////////////////////////////////////////////////////////////////////
0130     template <typename Left, typename Right, typename Attribute
0131       , typename Context, typename Iterator>
0132     struct handles_container<qi::list<Left, Right>, Attribute, Context
0133           , Iterator> 
0134       : mpl::true_ {};
0135 }}}
0136 
0137 #endif