1 /*=============================================================================
2     Copyright (c) 2001-2014 Joel de Guzman
3     http://spirit.sourceforge.net/
4 
5     Distributed under the Boost Software License, Version 1.0. (See accompanying
6     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 =============================================================================*/
8 #if !defined(BOOST_SPIRIT_X3_CONTEXT_JAN_4_2012_1215PM)
9 #define BOOST_SPIRIT_X3_CONTEXT_JAN_4_2012_1215PM
10 
11 #include <boost/spirit/home/x3/support/unused.hpp>
12 #include <boost/mpl/identity.hpp>
13 
14 namespace boost { namespace spirit { namespace x3
15 {
16     template <typename ID, typename T, typename Next = unused_type>
17     struct context
18     {
contextboost::spirit::x3::context19         context(T& val, Next const& next)
20             : val(val), next(next) {}
21 
getboost::spirit::x3::context22         T& get(mpl::identity<ID>) const
23         {
24             return val;
25         }
26 
27         template <typename ID_>
getboost::spirit::x3::context28         decltype(auto) get(ID_ id) const
29         {
30             return next.get(id);
31         }
32 
33         T& val;
34         Next const& next;
35     };
36 
37     template <typename ID, typename T>
38     struct context<ID, T, unused_type>
39     {
contextboost::spirit::x3::context40         context(T& val)
41             : val(val) {}
42 
contextboost::spirit::x3::context43         context(T& val, unused_type)
44             : val(val) {}
45 
getboost::spirit::x3::context46         T& get(mpl::identity<ID>) const
47         {
48             return val;
49         }
50 
51         template <typename ID_>
getboost::spirit::x3::context52         unused_type get(ID_) const
53         {
54             return {};
55         }
56 
57         T& val;
58     };
59 
60     template <typename Tag, typename Context>
get(Context const & context)61     inline decltype(auto) get(Context const& context)
62     {
63         return context.get(mpl::identity<Tag>());
64     }
65 
66     template <typename ID, typename T, typename Next>
make_context(T & val,Next const & next)67     inline context<ID, T, Next> make_context(T& val, Next const& next)
68     {
69         return { val, next };
70     }
71 
72     template <typename ID, typename T>
make_context(T & val)73     inline context<ID, T> make_context(T& val)
74     {
75         return { val };
76     }
77 
78     namespace detail
79     {
80         template <typename ID, typename T, typename Next, typename FoundVal>
81         inline Next const&
make_unique_context(T & val,Next const & next,FoundVal &)82         make_unique_context(T& val, Next const& next, FoundVal&)
83         {
84             return next;
85         }
86 
87         template <typename ID, typename T, typename Next>
88         inline context<ID, T, Next>
make_unique_context(T & val,Next const & next,unused_type)89         make_unique_context(T& val, Next const& next, unused_type)
90         {
91             return { val, next };
92         }
93     }
94 
95     template <typename ID, typename T, typename Next>
96     inline auto
make_unique_context(T & val,Next const & next)97     make_unique_context(T& val, Next const& next)
98     {
99         return detail::make_unique_context<ID>(val, next, x3::get<ID>(next));
100     }
101 }}}
102 
103 #endif
104