]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/include/boost/spirit/home/x3/support/ast/variant.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / spirit / include / boost / spirit / home / x3 / support / ast / variant.hpp
1 /*=============================================================================
2 Copyright (c) 2001-2014 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_X3_VARIANT_AUGUST_6_2011_0859AM)
8 #define BOOST_SPIRIT_X3_VARIANT_AUGUST_6_2011_0859AM
9
10 #include <boost/variant.hpp>
11 #include <boost/mpl/list.hpp>
12 #include <boost/type_traits/is_base_of.hpp>
13 #include <type_traits>
14
15 ///////////////////////////////////////////////////////////////////////////////
16 namespace boost { namespace spirit { namespace x3
17 {
18 template <typename T>
19 class forward_ast
20 {
21 public:
22
23 typedef T type;
24
25 public:
26
27 forward_ast() : p_(new T) {}
28
29 forward_ast(forward_ast const& operand)
30 : p_(new T(operand.get())) {}
31
32 forward_ast(forward_ast&& operand)
33 : p_(operand.p_)
34 {
35 operand.p_ = 0;
36 }
37
38 forward_ast(T const& operand)
39 : p_(new T(operand)) {}
40
41 forward_ast(T&& operand)
42 : p_(new T(std::move(operand))) {}
43
44 ~forward_ast()
45 {
46 boost::checked_delete(p_);
47 }
48
49 forward_ast& operator=(forward_ast const& rhs)
50 {
51 assign(rhs.get());
52 return *this;
53 }
54
55 void swap(forward_ast& operand) BOOST_NOEXCEPT
56 {
57 T* temp = operand.p_;
58 operand.p_ = p_;
59 p_ = temp;
60 }
61
62 forward_ast& operator=(T const& rhs)
63 {
64 assign(rhs);
65 return *this;
66 }
67
68 forward_ast& operator=(forward_ast&& rhs) BOOST_NOEXCEPT
69 {
70 swap(rhs);
71 return *this;
72 }
73
74 forward_ast& operator=(T&& rhs)
75 {
76 get() = std::move(rhs);
77 return *this;
78 }
79
80 T& get() { return *get_pointer(); }
81 const T& get() const { return *get_pointer(); }
82
83 T* get_pointer() { return p_; }
84 const T* get_pointer() const { return p_; }
85
86 operator T const&() const { return this->get(); }
87 operator T&() { return this->get(); }
88
89 private:
90
91 void assign(const T& rhs)
92 {
93 this->get() = rhs;
94 }
95
96 T* p_;
97 };
98
99 // function template swap
100 //
101 // Swaps two forward_ast<T> objects of the same type T.
102 //
103 template <typename T>
104 inline void swap(forward_ast<T>& lhs, forward_ast<T>& rhs) BOOST_NOEXCEPT
105 {
106 lhs.swap(rhs);
107 }
108
109 namespace detail
110 {
111 template <typename T>
112 struct remove_forward : mpl::identity<T>
113 {};
114
115 template <typename T>
116 struct remove_forward<forward_ast<T>> : mpl::identity<T>
117 {};
118 }
119
120 template <typename ...Types>
121 struct variant
122 {
123 // tell spirit that this is an adapted variant
124 struct adapted_variant_tag;
125
126 using variant_type = boost::variant<Types...>;
127 using types = mpl::list<typename detail::remove_forward<Types>::type...>;
128 using base_type = variant; // The current instantiation
129
130 template<typename T>
131 using non_self_t // used only for SFINAE checks below
132 = std::enable_if_t<!(std::is_base_of<base_type
133 ,std::remove_reference_t<T>
134 >
135 ::value)
136 >;
137
138 variant() : var() {}
139
140 template <typename T, class = non_self_t<T>>
141 explicit variant(T const& rhs)
142 : var(rhs) {}
143
144 template <typename T, class = non_self_t<T>>
145 explicit variant(T&& rhs)
146 : var(std::forward<T>(rhs)) {}
147
148 variant(variant const& rhs)
149 : var(rhs.var) {}
150
151 variant(variant& rhs)
152 : var(rhs.var) {}
153
154 variant(variant&& rhs)
155 : var(std::forward<variant_type>(rhs.var)) {}
156
157 variant& operator=(variant const& rhs)
158 {
159 var = rhs.get();
160 return *this;
161 }
162
163 variant& operator=(variant&& rhs)
164 {
165 var = std::forward<variant_type>(rhs.get());
166 return *this;
167 }
168
169 template <typename T, class = non_self_t<T>>
170 variant& operator=(T const& rhs)
171 {
172 var = rhs;
173 return *this;
174 }
175
176 template <typename T, class = non_self_t<T>>
177 variant& operator=(T&& rhs)
178 {
179 var = std::forward<T>(rhs);
180 return *this;
181 }
182
183 template <typename F>
184 typename F::result_type apply_visitor(F const& v)
185 {
186 return var.apply_visitor(v);
187 }
188
189 template <typename F>
190 typename F::result_type apply_visitor(F const& v) const
191 {
192 return var.apply_visitor(v);
193 }
194
195 template <typename F>
196 typename F::result_type apply_visitor(F& v)
197 {
198 return var.apply_visitor(v);
199 }
200
201 template <typename F>
202 typename F::result_type apply_visitor(F& v) const
203 {
204 return var.apply_visitor(v);
205 }
206
207 variant_type const& get() const
208 {
209 return var;
210 }
211
212 variant_type& get()
213 {
214 return var;
215 }
216
217 void swap(variant& rhs) BOOST_NOEXCEPT
218 {
219 var.swap(rhs.var);
220 }
221
222 variant_type var;
223 };
224 }}}
225
226 namespace boost
227 {
228 template <typename T, typename ...Types>
229 inline T const&
230 get(boost::spirit::x3::variant<Types...> const& x)
231 {
232 return boost::get<T>(x.get());
233 }
234
235 template <typename T, typename ...Types>
236 inline T&
237 get(boost::spirit::x3::variant<Types...>& x)
238 {
239 return boost::get<T>(x.get());
240 }
241
242 template <typename T, typename ...Types>
243 inline T const*
244 get(boost::spirit::x3::variant<Types...> const* x)
245 {
246 return boost::get<T>(&x->get());
247 }
248
249 template <typename T, typename ...Types>
250 inline T*
251 get(boost::spirit::x3::variant<Types...>* x)
252 {
253 return boost::get<T>(&x->get());
254 }
255 }
256
257 #endif