Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:02:16

0001 //  Copyright (c) 2001-2011 Hartmut Kaiser
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_LEX_POSITION_TOKEN_MAY_13_2011_0846PM)
0007 #define BOOST_SPIRIT_LEX_POSITION_TOKEN_MAY_13_2011_0846PM
0008 
0009 #if defined(_MSC_VER)
0010 #pragma once
0011 #endif
0012 
0013 #include <boost/config.hpp>
0014 #include <boost/detail/workaround.hpp>
0015 #include <boost/spirit/home/qi/detail/assign_to.hpp>
0016 #include <boost/spirit/home/support/attributes.hpp>
0017 #include <boost/spirit/home/support/argument.hpp>
0018 #include <boost/spirit/home/support/detail/lexer/generator.hpp>
0019 #include <boost/spirit/home/support/detail/lexer/rules.hpp>
0020 #include <boost/spirit/home/support/detail/lexer/consts.hpp>
0021 #include <boost/spirit/home/support/utree/utree_traits_fwd.hpp>
0022 #include <boost/spirit/home/lex/lexer/terminals.hpp>
0023 #include <boost/fusion/include/vector.hpp>
0024 #include <boost/fusion/include/at.hpp>
0025 #include <boost/fusion/include/value_at.hpp>
0026 #include <boost/variant.hpp>
0027 #include <boost/mpl/vector.hpp>
0028 #include <boost/mpl/bool.hpp>
0029 #include <boost/mpl/is_sequence.hpp>
0030 #include <boost/mpl/begin.hpp>
0031 #include <boost/mpl/insert.hpp>
0032 #include <boost/mpl/vector.hpp>
0033 #include <boost/mpl/if.hpp>
0034 #include <boost/mpl/or.hpp>
0035 #include <boost/type_traits/is_same.hpp>
0036 #include <boost/range/iterator_range_core.hpp>
0037 #include <boost/static_assert.hpp>
0038 
0039 #if defined(BOOST_SPIRIT_DEBUG)
0040 #include <iosfwd>
0041 #endif
0042 
0043 namespace boost { namespace spirit { namespace lex { namespace lexertl
0044 { 
0045     ///////////////////////////////////////////////////////////////////////////
0046     //
0047     //  The position_token is the type of the objects returned by the 
0048     //  iterator if it has been specified while instantiating the lexer object.
0049     //
0050     //    template parameters:
0051     //        Iterator        The type of the iterator used to access the
0052     //                        underlying character stream.
0053     //        AttributeTypes  A mpl sequence containing the types of all 
0054     //                        required different token values to be supported 
0055     //                        by this token type.
0056     //        HasState        A mpl::bool_ indicating, whether this token type
0057     //                        should support lexer states.
0058     //        Idtype          The type to use for the token id (defaults to 
0059     //                        std::size_t).
0060     //
0061     //  It is possible to use other token types with the spirit::lex 
0062     //  framework as well. If you plan to use a different type as your token 
0063     //  type, you'll need to expose the following things from your token type 
0064     //  to make it compatible with spirit::lex:
0065     //
0066     //    typedefs
0067     //        iterator_type   The type of the iterator used to access the
0068     //                        underlying character stream.
0069     //
0070     //        id_type         The type of the token id used.
0071     //
0072     //    methods
0073     //        default constructor
0074     //                        This should initialize the token as an end of 
0075     //                        input token.
0076     //        constructors    The prototype of the other required 
0077     //                        constructors should be:
0078     //
0079     //              token(int)
0080     //                        This constructor should initialize the token as 
0081     //                        an invalid token (not carrying any specific 
0082     //                        values)
0083     //
0084     //              where:  the int is used as a tag only and its value is 
0085     //                      ignored
0086     //
0087     //                        and:
0088     //
0089     //              token(Idtype id, std::size_t state, 
0090     //                    iterator_type first, iterator_type last);
0091     //
0092     //              where:  id:           token id
0093     //                      state:        lexer state this token was matched in
0094     //                      first, last:  pair of iterators marking the matched 
0095     //                                    range in the underlying input stream 
0096     //
0097     //        accessors
0098     //              id()      return the token id of the matched input sequence
0099     //              id(newid) set the token id of the token instance
0100     //
0101     //              state()   return the lexer state this token was matched in
0102     //
0103     //              value()   return the token value
0104     //
0105     //  Additionally, you will have to implement a couple of helper functions
0106     //  in the same namespace as the token type: a comparison operator==() to 
0107     //  compare your token instances, a token_is_valid() function and different 
0108     //  specializations of the Spirit customization point 
0109     //  assign_to_attribute_from_value as shown below.
0110     //
0111     ///////////////////////////////////////////////////////////////////////////
0112     template <typename Iterator = char const*
0113       , typename AttributeTypes = mpl::vector0<>
0114       , typename HasState = mpl::true_
0115       , typename Idtype = std::size_t> 
0116     struct position_token;
0117 
0118     ///////////////////////////////////////////////////////////////////////////
0119     //  This specialization of the token type doesn't contain any item data and
0120     //  doesn't support working with lexer states. Although, like all other
0121     //  variants of position_token, it carries a pair of iterators marking the
0122     //  begin and the end of the matched character sequence.
0123     ///////////////////////////////////////////////////////////////////////////
0124     template <typename Iterator, typename Idtype>
0125     struct position_token<Iterator, lex::omit, mpl::false_, Idtype>
0126     {
0127         typedef Iterator iterator_type;
0128         typedef iterator_range<iterator_type> iterpair_type;
0129         typedef mpl::false_ has_state;
0130         typedef Idtype id_type;
0131         typedef unused_type token_value_type;
0132 
0133         //  default constructed tokens correspond to EOI tokens
0134         position_token() 
0135           : id_(id_type(boost::lexer::npos)) {}
0136 
0137         //  construct an invalid token
0138         explicit position_token(int) 
0139           : id_(id_type(0)) {}
0140 
0141         position_token(id_type id, std::size_t) 
0142           : id_(id) {}
0143 
0144         position_token(id_type id, std::size_t, token_value_type)
0145           : id_(id) {}
0146 
0147         position_token(id_type id, std::size_t, Iterator const& first
0148               , Iterator const& last)
0149           : id_(id), matched_(first, last) {}
0150 
0151         //  this default conversion operator is needed to allow the direct 
0152         //  usage of tokens in conjunction with the primitive parsers defined 
0153         //  in Qi
0154         operator id_type() const { return id_; }
0155 
0156         //  Retrieve or set the token id of this token instance. 
0157         id_type id() const { return id_; }
0158         void id(id_type newid) { id_ = newid; }
0159 
0160         std::size_t state() const { return 0; }   // always '0' (INITIAL state)
0161 
0162         bool is_valid() const 
0163         { 
0164             return 0 != id_ && id_type(boost::lexer::npos) != id_; 
0165         }
0166 
0167         // access the stored iterator range of the matched input sequence
0168         iterator_type begin() const { return matched_.begin(); }
0169         iterator_type end() const { return matched_.end(); }
0170 
0171         iterpair_type& matched() { return matched_; }
0172         iterpair_type const& matched() const { return matched_; }
0173 
0174         token_value_type& value() { static token_value_type u; return u; }
0175         token_value_type const& value() const { return unused; }
0176 
0177 #if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
0178         // workaround for MSVC10 which has problems copying a default 
0179         // constructed iterator_range
0180         position_token& operator= (position_token const& rhs)
0181         {
0182             if (this != &rhs) 
0183             {
0184                 id_ = rhs.id_;
0185                 if (is_valid()) 
0186                     matched_ = rhs.matched_;
0187             }
0188             return *this;
0189         }
0190 #endif
0191 
0192     protected:
0193         id_type id_;              // token id, 0 if nothing has been matched
0194         iterpair_type matched_;   // matched input sequence
0195     };
0196 
0197 #if defined(BOOST_SPIRIT_DEBUG)
0198     template <typename Char, typename Traits, typename Iterator
0199       , typename AttributeTypes, typename HasState, typename Idtype> 
0200     inline std::basic_ostream<Char, Traits>& 
0201     operator<< (std::basic_ostream<Char, Traits>& os
0202       , position_token<Iterator, AttributeTypes, HasState, Idtype> const& t)
0203     {
0204         if (t.is_valid()) {
0205             Iterator end = t.end();
0206             for (Iterator it = t.begin(); it != end; ++it)
0207                 os << *it;
0208         }
0209         else {
0210             os << "<invalid token>";
0211         }
0212         return os;
0213     }
0214 #endif
0215 
0216     ///////////////////////////////////////////////////////////////////////////
0217     //  This specialization of the token type doesn't contain any item data but
0218     //  supports working with lexer states.
0219     ///////////////////////////////////////////////////////////////////////////
0220     template <typename Iterator, typename Idtype>
0221     struct position_token<Iterator, lex::omit, mpl::true_, Idtype>
0222       : position_token<Iterator, lex::omit, mpl::false_, Idtype>
0223     {
0224     private:
0225         typedef position_token<Iterator, lex::omit, mpl::false_, Idtype> 
0226             base_type;
0227 
0228     public:
0229         typedef typename base_type::id_type id_type;
0230         typedef Iterator iterator_type;
0231         typedef mpl::true_ has_state;
0232         typedef unused_type token_value_type;
0233 
0234         //  default constructed tokens correspond to EOI tokens
0235         position_token() : state_(boost::lexer::npos) {}
0236 
0237         //  construct an invalid token
0238         explicit position_token(int) 
0239           : base_type(0), state_(boost::lexer::npos) {}
0240 
0241         position_token(id_type id, std::size_t state)
0242           : base_type(id, boost::lexer::npos), state_(state) {}
0243 
0244         position_token(id_type id, std::size_t state, token_value_type)
0245           : base_type(id, boost::lexer::npos, unused)
0246           , state_(state) {}
0247 
0248         position_token(id_type id, std::size_t state
0249               , Iterator const& first, Iterator const& last)
0250           : base_type(id, boost::lexer::npos, first, last)
0251           , state_(state) {}
0252 
0253         std::size_t state() const { return state_; }
0254 
0255 #if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
0256         // workaround for MSVC10 which has problems copying a default 
0257         // constructed iterator_range
0258         position_token& operator= (position_token const& rhs)
0259         {
0260             if (this != &rhs) 
0261             {
0262                 this->base_type::operator=(static_cast<base_type const&>(rhs));
0263                 state_ = rhs.state_;
0264             }
0265             return *this;
0266         }
0267 #endif
0268 
0269     protected:
0270         std::size_t state_;      // lexer state this token was matched in
0271     };
0272 
0273     ///////////////////////////////////////////////////////////////////////////
0274     // These specializations for an empty attribute list cause all token 
0275     // instances to expose as it attribute the iterator_range pointing to the
0276     // matched input sequence.
0277     ///////////////////////////////////////////////////////////////////////////
0278     template <typename Iterator, typename HasState, typename Idtype>
0279     struct position_token<Iterator, mpl::vector<>, HasState, Idtype>
0280       : position_token<Iterator, lex::omit, HasState, Idtype>
0281     {
0282     private:
0283         typedef position_token<Iterator, lex::omit, HasState, Idtype> base_type;
0284 
0285     public:
0286         typedef typename base_type::id_type id_type;
0287         typedef typename base_type::iterator_type iterator_type;
0288         typedef typename base_type::iterpair_type iterpair_type;
0289         typedef HasState has_state;
0290         typedef iterpair_type token_value_type;
0291 
0292         //  default constructed tokens correspond to EOI tokens
0293         position_token() {}
0294 
0295         //  construct an invalid token
0296         explicit position_token(int) 
0297           : base_type(0) {}
0298 
0299         position_token(id_type id, std::size_t state)
0300           : base_type(id, state) {}
0301 
0302         position_token(id_type id, std::size_t state, token_value_type)
0303           : base_type(id, state, unused) {}
0304 
0305         position_token(id_type id, std::size_t state
0306               , Iterator const& first, Iterator const& last)
0307           : base_type(id, state, first, last) {}
0308 
0309         token_value_type& value() { return this->base_type::matched(); }
0310         token_value_type const& value() const { return this->base_type::matched(); }
0311     };
0312 
0313     template <typename Iterator, typename HasState, typename Idtype>
0314     struct position_token<Iterator, mpl::vector0<>, HasState, Idtype>
0315       : position_token<Iterator, lex::omit, HasState, Idtype>
0316     {
0317     private:
0318         typedef position_token<Iterator, lex::omit, HasState, Idtype> base_type;
0319 
0320     public:
0321         typedef typename base_type::id_type id_type;
0322         typedef typename base_type::iterator_type iterator_type;
0323         typedef typename base_type::iterpair_type iterpair_type;
0324         typedef HasState has_state;
0325         typedef iterpair_type token_value_type;
0326 
0327         //  default constructed tokens correspond to EOI tokens
0328         position_token() {}
0329 
0330         //  construct an invalid token
0331         explicit position_token(int) 
0332           : base_type(0) {}
0333 
0334         position_token(id_type id, std::size_t state)
0335           : base_type(id, state) {}
0336 
0337         position_token(id_type id, std::size_t state, token_value_type)
0338           : base_type(id, state, unused) {}
0339 
0340         position_token(id_type id, std::size_t state
0341               , Iterator const& first, Iterator const& last)
0342           : base_type(id, state, first, last) {}
0343 
0344         token_value_type& value() { return this->base_type::matched(); }
0345         token_value_type const& value() const { return this->base_type::matched(); }
0346     };
0347 
0348     ///////////////////////////////////////////////////////////////////////////
0349     // These specializations for an attribute list of length one cause all token 
0350     // instances to expose the specified type as its attribute.
0351     ///////////////////////////////////////////////////////////////////////////
0352     template <typename Iterator, typename Attribute, typename HasState
0353       , typename Idtype>
0354     struct position_token<Iterator, mpl::vector<Attribute>, HasState, Idtype>
0355       : position_token<Iterator, lex::omit, HasState, Idtype>
0356     {
0357     private:
0358         typedef position_token<Iterator, lex::omit, HasState, Idtype> base_type;
0359 
0360     public:
0361         typedef typename base_type::id_type id_type;
0362         typedef typename base_type::iterator_type iterator_type;
0363         typedef typename base_type::iterpair_type iterpair_type;
0364         typedef HasState has_state;
0365         typedef boost::optional<Attribute> token_value_type;
0366 
0367         //  default constructed tokens correspond to EOI tokens
0368         position_token() {}
0369 
0370         //  construct an invalid token
0371         explicit position_token(int) 
0372           : base_type(0) {}
0373 
0374         position_token(id_type id, std::size_t state)
0375           : base_type(id, state) {}
0376 
0377         position_token(id_type id, std::size_t state, token_value_type const& v)
0378           : base_type(id, state, unused), value_(v) {}
0379 
0380         position_token(id_type id, std::size_t state
0381               , Iterator const& first, Iterator const& last)
0382           : base_type(id, state, first, last) {}
0383 
0384         token_value_type& value() { return value_; }
0385         token_value_type const& value() const { return value_; }
0386 
0387         bool has_value() const { return !!value_; }
0388 
0389 #if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
0390         // workaround for MSVC10 which has problems copying a default 
0391         // constructed iterator_range
0392         position_token& operator= (position_token const& rhs)
0393         {
0394             if (this != &rhs) 
0395             {
0396                 this->base_type::operator=(static_cast<base_type const&>(rhs));
0397                 if (this->is_valid()) 
0398                     value_ = rhs.value_;
0399             }
0400             return *this;
0401         }
0402 #endif
0403 
0404     protected:
0405         token_value_type value_; // token value
0406     };
0407 
0408     template <typename Iterator, typename Attribute, typename HasState
0409       , typename Idtype>
0410     struct position_token<Iterator, mpl::vector1<Attribute>, HasState, Idtype>
0411       : position_token<Iterator, lex::omit, HasState, Idtype>
0412     {
0413     private:
0414         typedef position_token<Iterator, lex::omit, HasState, Idtype> base_type;
0415 
0416     public:
0417         typedef typename base_type::id_type id_type;
0418         typedef typename base_type::iterator_type iterator_type;
0419         typedef typename base_type::iterpair_type iterpair_type;
0420         typedef HasState has_state;
0421         typedef boost::optional<Attribute> token_value_type;
0422 
0423         //  default constructed tokens correspond to EOI tokens
0424         position_token() {}
0425 
0426         //  construct an invalid token
0427         explicit position_token(int) 
0428           : base_type(0) {}
0429 
0430         position_token(id_type id, std::size_t state)
0431           : base_type(id, state) {}
0432 
0433         position_token(id_type id, std::size_t state, token_value_type const& v)
0434           : base_type(id, state, unused), value_(v) {}
0435 
0436         position_token(id_type id, std::size_t state
0437               , Iterator const& first, Iterator const& last)
0438           : base_type(id, state, first, last) {}
0439 
0440         token_value_type& value() { return value_; }
0441         token_value_type const& value() const { return value_; }
0442 
0443         bool has_value() const { return value_; }
0444 
0445 #if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
0446         // workaround for MSVC10 which has problems copying a default 
0447         // constructed iterator_range
0448         position_token& operator= (position_token const& rhs)
0449         {
0450             if (this != &rhs) 
0451             {
0452                 this->base_type::operator=(static_cast<base_type const&>(rhs));
0453                 if (this->is_valid()) 
0454                     value_ = rhs.value_;
0455             }
0456             return *this;
0457         }
0458 #endif
0459 
0460     protected:
0461         token_value_type value_; // token value
0462     };
0463 
0464     ///////////////////////////////////////////////////////////////////////////
0465     //  The generic version of the position_token type derives from the 
0466     //  specialization above and adds a single data member holding the item 
0467     //  data carried by the token instance.
0468     ///////////////////////////////////////////////////////////////////////////
0469     namespace detail
0470     {
0471         ///////////////////////////////////////////////////////////////////////
0472         //  Meta-function to calculate the type of the variant data item to be 
0473         //  stored with each token instance.
0474         //
0475         //  Note: The iterator pair needs to be the first type in the list of 
0476         //        types supported by the generated variant type (this is being 
0477         //        used to identify whether the stored data item in a particular 
0478         //        token instance needs to be converted from the pair of 
0479         //        iterators (see the first of the assign_to_attribute_from_value 
0480         //        specializations below).
0481         ///////////////////////////////////////////////////////////////////////
0482         template <typename IteratorPair, typename AttributeTypes>
0483         struct position_token_value_typesequence
0484         {
0485             typedef typename mpl::insert<
0486                 AttributeTypes
0487               , typename mpl::begin<AttributeTypes>::type
0488               , IteratorPair
0489             >::type sequence_type;
0490             typedef typename make_variant_over<sequence_type>::type type;
0491         };
0492 
0493         ///////////////////////////////////////////////////////////////////////
0494         //  The type of the data item stored with a token instance is defined 
0495         //  by the template parameter 'AttributeTypes' and may be:
0496         //  
0497         //     lex::omit:         no data item is stored with the token 
0498         //                        instance (this is handled by the 
0499         //                        specializations of the token class
0500         //                        below)
0501         //     mpl::vector0<>:    each token instance stores a pair of 
0502         //                        iterators pointing to the matched input 
0503         //                        sequence
0504         //     mpl::vector<...>:  each token instance stores a variant being 
0505         //                        able to store the pair of iterators pointing 
0506         //                        to the matched input sequence, or any of the 
0507         //                        types a specified in the mpl::vector<>
0508         //
0509         //  All this is done to ensure the token type is as small (in terms 
0510         //  of its byte-size) as possible.
0511         ///////////////////////////////////////////////////////////////////////
0512         template <typename IteratorPair, typename AttributeTypes>
0513         struct position_token_value
0514           : mpl::eval_if<
0515                 mpl::or_<
0516                     is_same<AttributeTypes, mpl::vector0<> >
0517                   , is_same<AttributeTypes, mpl::vector<> > >
0518               , mpl::identity<IteratorPair>
0519               , position_token_value_typesequence<IteratorPair, AttributeTypes> >
0520         {};
0521     }
0522 
0523     template <typename Iterator, typename AttributeTypes, typename HasState
0524       , typename Idtype>
0525     struct position_token 
0526       : position_token<Iterator, lex::omit, HasState, Idtype>
0527     {
0528     private: // precondition assertions
0529         BOOST_STATIC_ASSERT((mpl::is_sequence<AttributeTypes>::value || 
0530                             is_same<AttributeTypes, lex::omit>::value));
0531         typedef position_token<Iterator, lex::omit, HasState, Idtype> 
0532             base_type;
0533 
0534     protected: 
0535         //  If no additional token value types are given, the token will 
0536         //  hold no token value at all as the base class already has the 
0537         //  iterator pair of the matched range in the underlying input sequence. 
0538         //  Otherwise the token value is stored as a variant and will 
0539         //  initially hold an unused_type but is able to hold any of 
0540         //  the given data types as well. The conversion from the iterator pair 
0541         //  to the required data type is done when it is accessed for the first 
0542         //  time.
0543         typedef iterator_range<Iterator> iterpair_type;
0544 
0545     public:
0546         typedef typename base_type::id_type id_type;
0547         typedef typename detail::position_token_value<
0548             iterpair_type, AttributeTypes>::type token_value_type;
0549 
0550         typedef Iterator iterator_type;
0551 
0552         //  default constructed tokens correspond to EOI tokens
0553         position_token() {}
0554 
0555         //  construct an invalid token
0556         explicit position_token(int)
0557           : base_type(0) {}
0558 
0559         position_token(id_type id, std::size_t state, token_value_type const& value)
0560           : base_type(id, state, value), value_(value) {}
0561 
0562         position_token(id_type id, std::size_t state, Iterator const& first
0563               , Iterator const& last)
0564           : base_type(id, state, first, last)
0565           , value_(iterpair_type(first, last)) 
0566         {}
0567 
0568         token_value_type& value() { return value_; }
0569         token_value_type const& value() const { return value_; }
0570 
0571 #if BOOST_WORKAROUND(BOOST_MSVC, == 1600)
0572         // workaround for MSVC10 which has problems copying a default 
0573         // constructed iterator_range
0574         position_token& operator= (position_token const& rhs)
0575         {
0576             if (this != &rhs) 
0577             {
0578                 this->base_type::operator=(static_cast<base_type const&>(rhs));
0579                 if (this->is_valid()) 
0580                     value_ = rhs.value_;
0581             }
0582             return *this;
0583         }
0584 #endif
0585 
0586     protected:
0587         token_value_type value_; // token value, by default a pair of iterators
0588     };
0589 
0590     ///////////////////////////////////////////////////////////////////////////
0591     //  tokens are considered equal, if their id's match (these are unique)
0592     template <typename Iterator, typename AttributeTypes, typename HasState
0593       , typename Idtype>
0594     inline bool 
0595     operator== (position_token<Iterator, AttributeTypes, HasState, Idtype> const& lhs, 
0596                 position_token<Iterator, AttributeTypes, HasState, Idtype> const& rhs)
0597     {
0598         return lhs.id() == rhs.id();
0599     }
0600 
0601     ///////////////////////////////////////////////////////////////////////////
0602     //  This overload is needed by the multi_pass/functor_input_policy to 
0603     //  validate a token instance. It has to be defined in the same namespace 
0604     //  as the token class itself to allow ADL to find it.
0605     ///////////////////////////////////////////////////////////////////////////
0606     template <typename Iterator, typename AttributeTypes, typename HasState
0607       , typename Idtype>
0608     inline bool 
0609     token_is_valid(position_token<Iterator, AttributeTypes, HasState, Idtype> const& t)
0610     {
0611         return t.is_valid();
0612     }
0613 }}}}
0614 
0615 namespace boost { namespace spirit { namespace traits
0616 {
0617     ///////////////////////////////////////////////////////////////////////////
0618     //  We have to provide specializations for the customization point
0619     //  assign_to_attribute_from_value allowing to extract the needed value 
0620     //  from the token. 
0621     ///////////////////////////////////////////////////////////////////////////
0622 
0623     //  This is called from the parse function of token_def if the token_def
0624     //  has been defined to carry a special attribute type
0625     template <typename Attribute, typename Iterator, typename AttributeTypes
0626       , typename HasState, typename Idtype>
0627     struct assign_to_attribute_from_value<Attribute
0628       , lex::lexertl::position_token<Iterator, AttributeTypes, HasState, Idtype> >
0629     {
0630         static void 
0631         call(lex::lexertl::position_token<
0632                 Iterator, AttributeTypes, HasState, Idtype> const& t
0633           , Attribute& attr)
0634         {
0635         //  The goal of this function is to avoid the conversion of the pair of
0636         //  iterators (to the matched character sequence) into the token value 
0637         //  of the required type being done more than once. For this purpose it 
0638         //  checks whether the stored value type is still the default one (pair 
0639         //  of iterators) and if yes, replaces the pair of iterators with the 
0640         //  converted value to be returned from subsequent calls.
0641 
0642             if (0 == t.value().which()) {
0643             //  first access to the token value
0644                 typedef iterator_range<Iterator> iterpair_type;
0645                 iterpair_type const& ip = t.matched();
0646 
0647             // Interestingly enough we use the assign_to() framework defined in 
0648             // Spirit.Qi allowing to convert the pair of iterators to almost any 
0649             // required type (assign_to(), if available, uses the standard Spirit 
0650             // parsers to do the conversion).
0651                 spirit::traits::assign_to(ip.begin(), ip.end(), attr);
0652 
0653             //  If you get an error during the compilation of the following 
0654             //  assignment expression, you probably forgot to list one or more 
0655             //  types used as token value types (in your token_def<...> 
0656             //  definitions) in your definition of the token class. I.e. any token 
0657             //  value type used for a token_def<...> definition has to be listed 
0658             //  during the declaration of the token type to use. For instance let's 
0659             //  assume we have two token_def's:
0660             //
0661             //      token_def<int> number; number = "...";
0662             //      token_def<std::string> identifier; identifier = "...";
0663             //
0664             //  Then you'll have to use the following token type definition 
0665             //  (assuming you are using the token class):
0666             //
0667             //      typedef mpl::vector<int, std::string> token_values;
0668             //      typedef token<base_iter_type, token_values> token_type;
0669             //
0670             //  where: base_iter_type is the iterator type used to expose the 
0671             //         underlying input stream.
0672             //
0673             //  This token_type has to be used as the second template parameter 
0674             //  to the lexer class:
0675             //
0676             //      typedef lexer<base_iter_type, token_type> lexer_type;
0677             //
0678             //  again, assuming you're using the lexer<> template for your 
0679             //  tokenization.
0680 
0681                 typedef lex::lexertl::position_token<
0682                     Iterator, AttributeTypes, HasState, Idtype> token_type;
0683                 spirit::traits::assign_to(
0684                     attr, const_cast<token_type&>(t).value());   // re-assign value
0685             }
0686             else {
0687             // reuse the already assigned value
0688                 spirit::traits::assign_to(get<Attribute>(t.value()), attr);
0689             }
0690         }
0691     };
0692 
0693     template <typename Attribute, typename Iterator, typename AttributeTypes
0694       , typename HasState, typename Idtype>
0695     struct assign_to_container_from_value<Attribute
0696           , lex::lexertl::position_token<Iterator, AttributeTypes, HasState, Idtype> >
0697       : assign_to_attribute_from_value<Attribute
0698           , lex::lexertl::position_token<Iterator, AttributeTypes, HasState, Idtype> >
0699     {};
0700 
0701     ///////////////////////////////////////////////////////////////////////////
0702     //  These are called from the parse function of token_def if the token type
0703     //  has no special attribute type assigned 
0704     template <typename Attribute, typename Iterator, typename HasState
0705       , typename Idtype>
0706     struct assign_to_attribute_from_value<Attribute
0707       , lex::lexertl::position_token<Iterator, mpl::vector0<>, HasState, Idtype> >
0708     {
0709         static void 
0710         call(lex::lexertl::position_token<
0711                 Iterator, mpl::vector0<>, HasState, Idtype> const& t
0712           , Attribute& attr)
0713         {
0714             //  The default type returned by the token_def parser component (if 
0715             //  it has no token value type assigned) is the pair of iterators 
0716             //  to the matched character sequence.
0717             spirit::traits::assign_to(t.begin(), t.end(), attr);
0718         }
0719     };
0720 
0721 //     template <typename Attribute, typename Iterator, typename HasState
0722 //       , typename Idtype>
0723 //     struct assign_to_container_from_value<Attribute
0724 //           , lex::lexertl::position_token<Iterator, mpl::vector0<>, HasState, Idtype> >
0725 //       : assign_to_attribute_from_value<Attribute
0726 //           , lex::lexertl::position_token<Iterator, mpl::vector0<>, HasState, Idtype> >
0727 //     {};
0728 
0729     // same as above but using mpl::vector<> instead of mpl::vector0<>
0730     template <typename Attribute, typename Iterator, typename HasState
0731       , typename Idtype>
0732     struct assign_to_attribute_from_value<Attribute
0733       , lex::lexertl::position_token<Iterator, mpl::vector<>, HasState, Idtype> >
0734     {
0735         static void 
0736         call(lex::lexertl::position_token<
0737                 Iterator, mpl::vector<>, HasState, Idtype> const& t
0738           , Attribute& attr)
0739         {
0740             //  The default type returned by the token_def parser component (if 
0741             //  it has no token value type assigned) is the pair of iterators 
0742             //  to the matched character sequence.
0743             spirit::traits::assign_to(t.begin(), t.end(), attr);
0744         }
0745     };
0746 
0747 //     template <typename Attribute, typename Iterator, typename HasState
0748 //       , typename Idtype>
0749 //     struct assign_to_container_from_value<Attribute
0750 //           , lex::lexertl::position_token<Iterator, mpl::vector<>, HasState, Idtype> >
0751 //       : assign_to_attribute_from_value<Attribute
0752 //           , lex::lexertl::position_token<Iterator, mpl::vector<>, HasState, Idtype> >
0753 //     {};
0754 
0755     ///////////////////////////////////////////////////////////////////////////
0756     //  These are called from the parse function of token_def if the token type
0757     //  has no special attribute type assigned 
0758     template <typename Attribute, typename Iterator, typename Attr
0759       , typename HasState, typename Idtype>
0760     struct assign_to_attribute_from_value<Attribute
0761       , lex::lexertl::position_token<Iterator, mpl::vector1<Attr>, HasState, Idtype> >
0762     {
0763         static void 
0764         call(lex::lexertl::position_token<
0765                 Iterator, mpl::vector1<Attr>, HasState, Idtype> const& t
0766           , Attribute& attr)
0767         {
0768         //  The goal of this function is to avoid the conversion of the pair of
0769         //  iterators (to the matched character sequence) into the token value 
0770         //  of the required type being done more than once.
0771 
0772             if (!t.has_value()) {
0773             //  first access to the token value
0774                 typedef iterator_range<Iterator> iterpair_type;
0775                 iterpair_type const& ip = t.matched();
0776 
0777             // Interestingly enough we use the assign_to() framework defined in 
0778             // Spirit.Qi allowing to convert the pair of iterators to almost any 
0779             // required type (assign_to(), if available, uses the standard Spirit 
0780             // parsers to do the conversion).
0781                 spirit::traits::assign_to(ip.begin(), ip.end(), attr);
0782 
0783             // Re-assign the attribute to the stored value
0784                 typedef lex::lexertl::position_token<
0785                     Iterator, mpl::vector1<Attr>, HasState, Idtype> token_type;
0786                 spirit::traits::assign_to(
0787                     attr, const_cast<token_type&>(t).value());
0788             }
0789             else {
0790             // reuse the already assigned value
0791                 spirit::traits::assign_to(t.value(), attr);
0792             }
0793         }
0794     };
0795 
0796 //     template <typename Attribute, typename Iterator, typename Attr
0797 //       , typename HasState, typename Idtype>
0798 //     struct assign_to_container_from_value<Attribute
0799 //           , lex::lexertl::position_token<Iterator, mpl::vector1<Attr>, HasState, Idtype> >
0800 //       : assign_to_attribute_from_value<Attribute
0801 //           , lex::lexertl::position_token<Iterator, mpl::vector1<Attr>, HasState, Idtype> >
0802 //     {};
0803 
0804     // same as above but using mpl::vector<Attr> instead of mpl::vector1<Attr>
0805     template <typename Attribute, typename Iterator, typename Attr
0806       , typename HasState, typename Idtype>
0807     struct assign_to_attribute_from_value<Attribute
0808       , lex::lexertl::position_token<Iterator, mpl::vector<Attr>, HasState, Idtype> >
0809     {
0810         static void 
0811         call(lex::lexertl::position_token<
0812                 Iterator, mpl::vector<Attr>, HasState, Idtype> const& t
0813           , Attribute& attr)
0814         {
0815         //  The goal of this function is to avoid the conversion of the pair of
0816         //  iterators (to the matched character sequence) into the token value 
0817         //  of the required type being done more than once.
0818 
0819             if (!t.has_value()) {
0820             //  first access to the token value
0821                 typedef iterator_range<Iterator> iterpair_type;
0822                 iterpair_type const& ip = t.matched();
0823 
0824             // Interestingly enough we use the assign_to() framework defined in 
0825             // Spirit.Qi allowing to convert the pair of iterators to almost any 
0826             // required type (assign_to(), if available, uses the standard Spirit 
0827             // parsers to do the conversion).
0828                 spirit::traits::assign_to(ip.begin(), ip.end(), attr);
0829 
0830             // Re-assign the attribute to the stored value
0831                 typedef lex::lexertl::position_token<
0832                     Iterator, mpl::vector<Attr>, HasState, Idtype> token_type;
0833                 spirit::traits::assign_to(
0834                     attr, const_cast<token_type&>(t).value());
0835             }
0836             else {
0837             // reuse the already assigned value
0838                 spirit::traits::assign_to(t.value(), attr);
0839             }
0840         }
0841     };
0842 
0843 //     template <typename Attribute, typename Iterator, typename Attr
0844 //       , typename HasState, typename Idtype>
0845 //     struct assign_to_container_from_value<Attribute
0846 //           , lex::lexertl::position_token<Iterator, mpl::vector<Attr>, HasState, Idtype> >
0847 //       : assign_to_attribute_from_value<Attribute
0848 //           , lex::lexertl::position_token<Iterator, mpl::vector<Attr>, HasState, Idtype> >
0849 //     {};
0850 
0851     //  This is called from the parse function of token_def if the token type
0852     //  has been explicitly omitted (i.e. no attribute value is used), which
0853     //  essentially means that every attribute gets initialized using default 
0854     //  constructed values.
0855     template <typename Attribute, typename Iterator, typename HasState
0856       , typename Idtype>
0857     struct assign_to_attribute_from_value<Attribute
0858       , lex::lexertl::position_token<Iterator, lex::omit, HasState, Idtype> >
0859     {
0860         static void 
0861         call(lex::lexertl::position_token<Iterator, lex::omit, HasState, Idtype> const&
0862           , Attribute&)
0863         {
0864             // do nothing
0865         }
0866     };
0867 
0868     template <typename Attribute, typename Iterator, typename HasState
0869       , typename Idtype>
0870     struct assign_to_container_from_value<Attribute
0871           , lex::lexertl::position_token<Iterator, lex::omit, HasState, Idtype> >
0872       : assign_to_attribute_from_value<Attribute
0873           , lex::lexertl::position_token<Iterator, lex::omit, HasState, Idtype> >
0874     {};
0875 
0876     //  This is called from the parse function of lexer_def_
0877     template <typename Iterator, typename AttributeTypes, typename HasState
0878       , typename Idtype_, typename Idtype>
0879     struct assign_to_attribute_from_value<
0880         fusion::vector2<Idtype_, iterator_range<Iterator> >
0881       , lex::lexertl::position_token<Iterator, AttributeTypes, HasState, Idtype> >
0882     {
0883         static void 
0884         call(lex::lexertl::position_token<Iterator, AttributeTypes, HasState, Idtype> const& t
0885           , fusion::vector2<Idtype_, iterator_range<Iterator> >& attr)
0886         {
0887             //  The type returned by the lexer_def_ parser components is a 
0888             //  fusion::vector containing the token id of the matched token 
0889             //  and the pair of iterators to the matched character sequence.
0890             typedef iterator_range<Iterator> iterpair_type;
0891             typedef fusion::vector2<Idtype_, iterator_range<Iterator> > 
0892                 attribute_type;
0893 
0894             iterpair_type const& ip = t.matched();
0895             attr = attribute_type(t.id(), ip);
0896         }
0897     };
0898 
0899     template <typename Iterator, typename AttributeTypes, typename HasState
0900       , typename Idtype_, typename Idtype>
0901     struct assign_to_container_from_value<
0902             fusion::vector2<Idtype_, iterator_range<Iterator> >
0903           , lex::lexertl::position_token<Iterator, AttributeTypes, HasState, Idtype> >
0904       : assign_to_attribute_from_value<
0905             fusion::vector2<Idtype_, iterator_range<Iterator> >
0906           , lex::lexertl::position_token<Iterator, AttributeTypes, HasState, Idtype> >
0907     {};
0908 
0909     ///////////////////////////////////////////////////////////////////////////
0910     // Overload debug output for a single token, this integrates lexer tokens 
0911     // with Qi's simple_trace debug facilities
0912     template <typename Iterator, typename Attribute, typename HasState
0913       , typename Idtype>
0914     struct token_printer_debug<
0915         lex::lexertl::position_token<Iterator, Attribute, HasState, Idtype> >
0916     {
0917         typedef lex::lexertl::position_token<Iterator, Attribute, HasState, Idtype> token_type;
0918 
0919         template <typename Out>
0920         static void print(Out& out, token_type const& val) 
0921         {
0922             out << '[';
0923             spirit::traits::print_token(out, val.value());
0924             out << ']';
0925         }
0926     };
0927 }}}
0928 
0929 #endif