Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:52:30

0001 //  Copyright (c) 2011 Aaron Graham
0002 //
0003 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 #if !defined(BOOST_SPIRIT_REPOSITORY_QI_ADVANCE_JAN_23_2011_1203PM)
0007 #define BOOST_SPIRIT_REPOSITORY_QI_ADVANCE_JAN_23_2011_1203PM
0008 
0009 #include <boost/spirit/home/support/terminal.hpp>
0010 #include <boost/spirit/include/qi_parse.hpp>
0011 
0012 ///////////////////////////////////////////////////////////////////////////////
0013 // definition the place holder
0014 namespace boost { namespace spirit { namespace repository { namespace qi
0015 {
0016     BOOST_SPIRIT_TERMINAL_EX(advance)
0017 }}}}
0018 
0019 ///////////////////////////////////////////////////////////////////////////////
0020 // implementation the enabler
0021 namespace boost { namespace spirit
0022 {
0023     template <typename A0>
0024     struct use_terminal<qi::domain
0025       , terminal_ex<repository::qi::tag::advance, fusion::vector1<A0> > >
0026       : mpl::or_<is_integral<A0>, is_enum<A0> >
0027     {};
0028 
0029     template <>
0030     struct use_lazy_terminal<qi::domain, repository::qi::tag::advance, 1>
0031       : mpl::true_
0032     {};
0033 }}
0034 
0035 ///////////////////////////////////////////////////////////////////////////////
0036 // implementation of the parser
0037 namespace boost { namespace spirit { namespace repository { namespace qi
0038 {
0039     template <typename Int>
0040     struct advance_parser
0041       : boost::spirit::qi::primitive_parser< advance_parser<Int> >
0042     {
0043         // Define the attribute type exposed by this parser component
0044         template <typename Context, typename Iterator>
0045         struct attribute
0046         {
0047             typedef boost::spirit::unused_type type;
0048         };
0049 
0050         advance_parser(Int dist)
0051           : dist(dist)
0052         {}
0053 
0054         // This function is called during the actual parsing process
0055         template <typename Iterator, typename Context
0056             , typename Skipper, typename Attribute>
0057         bool parse(Iterator& first, Iterator const& last
0058             , Context&, Skipper&, Attribute&) const
0059         {
0060             // This series of checks is designed to fail parsing on negative
0061             // values, without generating a "expression always evaluates true"
0062             // warning on unsigned types.
0063             if (dist == Int(0)) return true;
0064             if (dist < Int(1)) return false;
0065 
0066             typedef typename std::iterator_traits<Iterator>::iterator_category
0067                 iterator_category;
0068             return advance(first, last, iterator_category());
0069         }
0070 
0071         // This function is called during error handling to create
0072         // a human readable string for the error context.
0073         template <typename Context>
0074         boost::spirit::info what(Context&) const
0075         {
0076             return boost::spirit::info("advance");
0077         }
0078 
0079     private:
0080         // this is the general implementation used by most iterator categories
0081         template <typename Iterator, typename IteratorCategory>
0082         bool advance(Iterator& first, Iterator const& last
0083             , IteratorCategory) const
0084         {
0085             Int n = dist;
0086             Iterator i = first;
0087             while (n)
0088             {
0089                 if (i == last) return false;
0090                 ++i;
0091                 --n;
0092             }
0093             first = i;
0094             return true;
0095         }
0096 
0097         // this is a specialization for random access iterators
0098         template <typename Iterator>
0099         bool advance(Iterator& first, Iterator const& last
0100             , std::random_access_iterator_tag) const
0101         {
0102             Iterator const it = first + dist;
0103             if (it > last) return false;
0104             first = it;
0105             return true;
0106         }
0107 
0108         Int const dist;
0109     };
0110 }}}}
0111 
0112 ///////////////////////////////////////////////////////////////////////////////
0113 // instantiation of the parser
0114 namespace boost { namespace spirit { namespace qi
0115 {
0116     template <typename Modifiers, typename A0>
0117     struct make_primitive<
0118           terminal_ex<repository::qi::tag::advance, fusion::vector1<A0> >
0119         , Modifiers>
0120     {
0121         typedef repository::qi::advance_parser<A0> result_type;
0122 
0123         template <typename Terminal>
0124         result_type operator()(Terminal const& term, unused_type) const
0125         {
0126             return result_type(fusion::at_c<0>(term.args));
0127         }
0128     };
0129 }}}
0130 
0131 #endif