1 /*=============================================================================
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_REFERENCE_OCTOBER_31_2008_1218AM)
8 #define BOOST_SPIRIT_REFERENCE_OCTOBER_31_2008_1218AM
9 
10 #if defined(_MSC_VER)
11 #pragma once
12 #endif
13 
14 #include <boost/spirit/home/qi/meta_compiler.hpp>
15 #include <boost/spirit/home/qi/parser.hpp>
16 #include <boost/spirit/home/support/info.hpp>
17 #include <boost/spirit/home/support/handles_container.hpp>
18 #include <boost/type_traits/remove_const.hpp>
19 #include <boost/ref.hpp>
20 
21 namespace boost { namespace spirit { namespace qi
22 {
23     ///////////////////////////////////////////////////////////////////////////
24     // reference is a parser that references another parser (its Subject)
25     ///////////////////////////////////////////////////////////////////////////
26     template <typename Subject>
27     struct reference : parser<reference<Subject> >
28     {
29         typedef Subject subject_type;
30 
referenceboost::spirit::qi::reference31         reference(Subject& subject)
32           : ref(subject) {}
33 
34         template <typename Context, typename Iterator>
35         struct attribute : Subject::template attribute<Context, Iterator> {};
36 
37         template <typename Iterator, typename Context
38           , typename Skipper, typename Attribute>
parseboost::spirit::qi::reference39         bool parse(Iterator& first, Iterator const& last
40           , Context& context, Skipper const& skipper
41           , Attribute& attr_) const
42         {
43             return ref.get().parse(first, last, context, skipper, attr_);
44         }
45 
46         template <typename Context>
whatboost::spirit::qi::reference47         info what(Context& context) const
48         {
49             // the reference is transparent (does not add any info)
50             return ref.get().what(context);
51         }
52 
53         boost::reference_wrapper<Subject> ref;
54     };
55 }}}
56 
57 namespace boost { namespace spirit { namespace traits
58 {
59     ///////////////////////////////////////////////////////////////////////////
60     template <typename Subject, typename Attribute, typename Context
61       , typename Iterator>
62     struct handles_container<qi::reference<Subject>, Attribute, Context
63       , Iterator>
64       : handles_container<typename remove_const<Subject>::type
65         , Attribute, Context, Iterator>
66     {};
67 }}}
68 
69 #endif
70