1 //  Copyright (c) 2001-2011 Hartmut Kaiser
2 //  Copyright (c) 2001-2011 Joel de Guzman
3 //
4 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
5 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 
7 #if !defined(BOOST_SPIRIT_LEX_REFERENCE_APR_20_2009_0827AM)
8 #define BOOST_SPIRIT_LEX_REFERENCE_APR_20_2009_0827AM
9 
10 #if defined(_MSC_VER)
11 #pragma once
12 #endif
13 
14 #include <boost/spirit/home/lex/meta_compiler.hpp>
15 #include <boost/spirit/home/lex/lexer_type.hpp>
16 #include <boost/spirit/home/qi/reference.hpp>
17 #include <boost/spirit/home/support/info.hpp>
18 #include <boost/spirit/home/support/handles_container.hpp>
19 #include <boost/ref.hpp>
20 
21 namespace boost { namespace spirit { namespace lex
22 {
23     ///////////////////////////////////////////////////////////////////////////
24     // reference is a lexer that references another lexer (its Subject)
25     // all lexer components are at the same time
26     ///////////////////////////////////////////////////////////////////////////
27     template <typename Subject, typename IdType = unused_type>
28     struct reference;
29 
30     template <typename Subject>
31     struct reference<Subject, unused_type>
32       : qi::reference<Subject>
33       , lexer_type<reference<Subject> >
34     {
referenceboost::spirit::lex::reference35         reference(Subject& subject)
36           : qi::reference<Subject>(subject) {}
37 
38         template <typename LexerDef, typename String>
collectboost::spirit::lex::reference39         void collect(LexerDef& lexdef, String const& state
40           , String const& targetstate) const
41         {
42             this->ref.get().collect(lexdef, state, targetstate);
43         }
44 
45         template <typename LexerDef>
add_actionsboost::spirit::lex::reference46         void add_actions(LexerDef& lexdef) const
47         {
48             this->ref.get().add_actions(lexdef);
49         }
50     };
51 
52     template <typename Subject, typename IdType>
53     struct reference : reference<Subject>
54     {
referenceboost::spirit::lex::reference55         reference(Subject& subject)
56           : reference<Subject>(subject) {}
57 
idboost::spirit::lex::reference58         IdType id() const
59         {
60             return this->ref.get().id();
61         }
unique_idboost::spirit::lex::reference62         std::size_t unique_id() const
63         {
64             return this->ref.get().unique_id();
65         }
stateboost::spirit::lex::reference66         std::size_t state() const
67         {
68             return this->ref.get().state();
69         }
70     };
71 }}}
72 
73 namespace boost { namespace spirit { namespace traits
74 {
75     ///////////////////////////////////////////////////////////////////////////
76     template <typename Subject, typename IdType
77       , typename Attribute, typename Context, typename Iterator>
78     struct handles_container<lex::reference<Subject, IdType>
79           , Attribute, Context, Iterator>
80       : handles_container<
81             typename remove_const<Subject>::type, Attribute, Context, Iterator>
82     {};
83 }}}
84 
85 #endif
86