Chris@102
|
1 /*=============================================================================
|
Chris@102
|
2 Copyright (c) 2001-2014 Joel de Guzman
|
Chris@102
|
3 http://spirit.sourceforge.net/
|
Chris@102
|
4
|
Chris@102
|
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@102
|
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@102
|
7 =============================================================================*/
|
Chris@102
|
8 #if !defined(BOOST_SPIRIT_X3_CONTEXT_JAN_4_2012_1215PM)
|
Chris@102
|
9 #define BOOST_SPIRIT_X3_CONTEXT_JAN_4_2012_1215PM
|
Chris@102
|
10
|
Chris@102
|
11 #if defined(_MSC_VER)
|
Chris@102
|
12 #pragma once
|
Chris@102
|
13 #endif
|
Chris@102
|
14
|
Chris@102
|
15 #include <boost/spirit/home/x3/support/unused.hpp>
|
Chris@102
|
16 #include <boost/mpl/identity.hpp>
|
Chris@102
|
17
|
Chris@102
|
18 namespace boost { namespace spirit { namespace x3
|
Chris@102
|
19 {
|
Chris@102
|
20 template <typename ID, typename T, typename Next = unused_type>
|
Chris@102
|
21 struct context
|
Chris@102
|
22 {
|
Chris@102
|
23 context(T& val, Next const& next)
|
Chris@102
|
24 : val(val), next(next) {}
|
Chris@102
|
25
|
Chris@102
|
26 template <typename ID_, typename Unused = void>
|
Chris@102
|
27 struct get_result
|
Chris@102
|
28 {
|
Chris@102
|
29 typedef typename Next::template get_result<ID_>::type type;
|
Chris@102
|
30 };
|
Chris@102
|
31
|
Chris@102
|
32 template <typename Unused>
|
Chris@102
|
33 struct get_result<mpl::identity<ID>, Unused>
|
Chris@102
|
34 {
|
Chris@102
|
35 typedef T& type;
|
Chris@102
|
36 };
|
Chris@102
|
37
|
Chris@102
|
38 T& get(mpl::identity<ID>) const
|
Chris@102
|
39 {
|
Chris@102
|
40 return val;
|
Chris@102
|
41 }
|
Chris@102
|
42
|
Chris@102
|
43 template <typename ID_>
|
Chris@102
|
44 typename Next::template get_result<ID_>::type
|
Chris@102
|
45 get(ID_ id) const
|
Chris@102
|
46 {
|
Chris@102
|
47 return next.get(id);
|
Chris@102
|
48 }
|
Chris@102
|
49
|
Chris@102
|
50 T& val;
|
Chris@102
|
51 Next const& next;
|
Chris@102
|
52 };
|
Chris@102
|
53
|
Chris@102
|
54 template <typename ID, typename T>
|
Chris@102
|
55 struct context<ID, T, unused_type>
|
Chris@102
|
56 {
|
Chris@102
|
57 context(T& val)
|
Chris@102
|
58 : val(val) {}
|
Chris@102
|
59
|
Chris@102
|
60 context(T& val, unused_type)
|
Chris@102
|
61 : val(val) {}
|
Chris@102
|
62
|
Chris@102
|
63 template <typename ID_, typename Unused = void>
|
Chris@102
|
64 struct get_result
|
Chris@102
|
65 {
|
Chris@102
|
66 typedef unused_type type;
|
Chris@102
|
67 };
|
Chris@102
|
68
|
Chris@102
|
69 template <typename Unused>
|
Chris@102
|
70 struct get_result<mpl::identity<ID>, Unused>
|
Chris@102
|
71 {
|
Chris@102
|
72 typedef T& type;
|
Chris@102
|
73 };
|
Chris@102
|
74
|
Chris@102
|
75 T& get(mpl::identity<ID>) const
|
Chris@102
|
76 {
|
Chris@102
|
77 return val;
|
Chris@102
|
78 }
|
Chris@102
|
79
|
Chris@102
|
80 template <typename ID_>
|
Chris@102
|
81 unused_type
|
Chris@102
|
82 get(ID_) const
|
Chris@102
|
83 {
|
Chris@102
|
84 return unused;
|
Chris@102
|
85 }
|
Chris@102
|
86
|
Chris@102
|
87 T& val;
|
Chris@102
|
88 };
|
Chris@102
|
89
|
Chris@102
|
90 template <typename Tag, typename Context>
|
Chris@102
|
91 inline auto
|
Chris@102
|
92 get(Context const& context)
|
Chris@102
|
93 -> decltype(context.get(mpl::identity<Tag>()))
|
Chris@102
|
94 {
|
Chris@102
|
95 return context.get(mpl::identity<Tag>());
|
Chris@102
|
96 }
|
Chris@102
|
97
|
Chris@102
|
98 template <typename ID, typename T, typename Next>
|
Chris@102
|
99 inline context<ID, T, Next> make_context(T& val, Next const& next)
|
Chris@102
|
100 {
|
Chris@102
|
101 return context<ID, T, Next>(val, next);
|
Chris@102
|
102 }
|
Chris@102
|
103
|
Chris@102
|
104 template <typename ID, typename T>
|
Chris@102
|
105 inline context<ID, T> make_context(T& val)
|
Chris@102
|
106 {
|
Chris@102
|
107 return context<ID, T>(val);
|
Chris@102
|
108 }
|
Chris@102
|
109
|
Chris@102
|
110 namespace detail
|
Chris@102
|
111 {
|
Chris@102
|
112 template <typename ID, typename T, typename Next, typename FoundVal>
|
Chris@102
|
113 inline Next const&
|
Chris@102
|
114 make_unique_context(T& val, Next const& next, FoundVal&)
|
Chris@102
|
115 {
|
Chris@102
|
116 return next;
|
Chris@102
|
117 }
|
Chris@102
|
118
|
Chris@102
|
119 template <typename ID, typename T, typename Next>
|
Chris@102
|
120 inline context<ID, T, Next>
|
Chris@102
|
121 make_unique_context(T& val, Next const& next, unused_type)
|
Chris@102
|
122 {
|
Chris@102
|
123 return context<ID, T, Next>(val, next);
|
Chris@102
|
124 }
|
Chris@102
|
125 }
|
Chris@102
|
126
|
Chris@102
|
127 template <typename ID, typename T, typename Next>
|
Chris@102
|
128 inline auto
|
Chris@102
|
129 make_unique_context(T& val, Next const& next)
|
Chris@102
|
130 {
|
Chris@102
|
131 return detail::make_unique_context<ID>(val, next, x3::get<ID>(next));
|
Chris@102
|
132 }
|
Chris@102
|
133 }}}
|
Chris@102
|
134
|
Chris@102
|
135 #endif
|