Chris@16
|
1 //-----------------------------------------------------------------------------
|
Chris@16
|
2 // boost variant/get.hpp header file
|
Chris@16
|
3 // See http://www.boost.org for updates, documentation, and revision history.
|
Chris@16
|
4 //-----------------------------------------------------------------------------
|
Chris@16
|
5 //
|
Chris@101
|
6 // Copyright (c) 2003 Eric Friedman, Itay Maman
|
Chris@101
|
7 // Copyright (c) 2014 Antony Polukhin
|
Chris@16
|
8 //
|
Chris@16
|
9 // Distributed under the Boost Software License, Version 1.0. (See
|
Chris@16
|
10 // accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
11 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
12
|
Chris@16
|
13 #ifndef BOOST_VARIANT_GET_HPP
|
Chris@16
|
14 #define BOOST_VARIANT_GET_HPP
|
Chris@16
|
15
|
Chris@16
|
16 #include <exception>
|
Chris@16
|
17
|
Chris@16
|
18 #include "boost/config.hpp"
|
Chris@16
|
19 #include "boost/detail/workaround.hpp"
|
Chris@101
|
20 #include "boost/static_assert.hpp"
|
Chris@16
|
21 #include "boost/throw_exception.hpp"
|
Chris@16
|
22 #include "boost/utility/addressof.hpp"
|
Chris@16
|
23 #include "boost/variant/variant_fwd.hpp"
|
Chris@101
|
24 #include "boost/variant/detail/element_index.hpp"
|
Chris@16
|
25
|
Chris@16
|
26 #include "boost/type_traits/add_reference.hpp"
|
Chris@16
|
27 #include "boost/type_traits/add_pointer.hpp"
|
Chris@16
|
28
|
Chris@16
|
29 namespace boost {
|
Chris@16
|
30
|
Chris@16
|
31 //////////////////////////////////////////////////////////////////////////
|
Chris@16
|
32 // class bad_get
|
Chris@16
|
33 //
|
Chris@16
|
34 // The exception thrown in the event of a failed get of a value.
|
Chris@16
|
35 //
|
Chris@101
|
36 class BOOST_SYMBOL_VISIBLE bad_get
|
Chris@16
|
37 : public std::exception
|
Chris@16
|
38 {
|
Chris@16
|
39 public: // std::exception implementation
|
Chris@16
|
40
|
Chris@16
|
41 virtual const char * what() const BOOST_NOEXCEPT_OR_NOTHROW
|
Chris@16
|
42 {
|
Chris@16
|
43 return "boost::bad_get: "
|
Chris@16
|
44 "failed value get using boost::get";
|
Chris@16
|
45 }
|
Chris@16
|
46
|
Chris@16
|
47 };
|
Chris@16
|
48
|
Chris@16
|
49 //////////////////////////////////////////////////////////////////////////
|
Chris@16
|
50 // function template get<T>
|
Chris@16
|
51 //
|
Chris@16
|
52 // Retrieves content of given variant object if content is of type T.
|
Chris@16
|
53 // Otherwise: pointer ver. returns 0; reference ver. throws bad_get.
|
Chris@16
|
54 //
|
Chris@16
|
55
|
Chris@16
|
56 namespace detail { namespace variant {
|
Chris@16
|
57
|
Chris@16
|
58 // (detail) class template get_visitor
|
Chris@16
|
59 //
|
Chris@16
|
60 // Generic static visitor that: if the value is of the specified type,
|
Chris@16
|
61 // returns a pointer to the value it visits; else a null pointer.
|
Chris@16
|
62 //
|
Chris@16
|
63 template <typename T>
|
Chris@16
|
64 struct get_visitor
|
Chris@16
|
65 {
|
Chris@16
|
66 private: // private typedefs
|
Chris@16
|
67
|
Chris@16
|
68 typedef typename add_pointer<T>::type pointer;
|
Chris@16
|
69 typedef typename add_reference<T>::type reference;
|
Chris@16
|
70
|
Chris@16
|
71 public: // visitor typedefs
|
Chris@16
|
72
|
Chris@16
|
73 typedef pointer result_type;
|
Chris@16
|
74
|
Chris@16
|
75 public: // visitor interfaces
|
Chris@16
|
76
|
Chris@101
|
77 pointer operator()(reference operand) const BOOST_NOEXCEPT
|
Chris@16
|
78 {
|
Chris@16
|
79 return boost::addressof(operand);
|
Chris@16
|
80 }
|
Chris@16
|
81
|
Chris@16
|
82 template <typename U>
|
Chris@101
|
83 pointer operator()(const U&) const BOOST_NOEXCEPT
|
Chris@16
|
84 {
|
Chris@16
|
85 return static_cast<pointer>(0);
|
Chris@16
|
86 }
|
Chris@16
|
87 };
|
Chris@16
|
88
|
Chris@16
|
89 }} // namespace detail::variant
|
Chris@16
|
90
|
Chris@101
|
91 #ifndef BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE
|
Chris@101
|
92 # if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551))
|
Chris@101
|
93 # define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t)
|
Chris@101
|
94 # else
|
Chris@101
|
95 # define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \
|
Chris@101
|
96 , t* = 0
|
Chris@101
|
97 # endif
|
Chris@16
|
98 #endif
|
Chris@16
|
99
|
Chris@101
|
100 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
Chris@101
|
101 // relaxed_get<U>(variant) methods
|
Chris@101
|
102 //
|
Chris@16
|
103 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
Chris@16
|
104 inline
|
Chris@16
|
105 typename add_pointer<U>::type
|
Chris@101
|
106 relaxed_get(
|
Chris@16
|
107 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
|
Chris@16
|
108 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
Chris@101
|
109 ) BOOST_NOEXCEPT
|
Chris@16
|
110 {
|
Chris@16
|
111 typedef typename add_pointer<U>::type U_ptr;
|
Chris@16
|
112 if (!operand) return static_cast<U_ptr>(0);
|
Chris@16
|
113
|
Chris@16
|
114 detail::variant::get_visitor<U> v;
|
Chris@16
|
115 return operand->apply_visitor(v);
|
Chris@16
|
116 }
|
Chris@16
|
117
|
Chris@16
|
118 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
Chris@16
|
119 inline
|
Chris@16
|
120 typename add_pointer<const U>::type
|
Chris@101
|
121 relaxed_get(
|
Chris@16
|
122 const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
|
Chris@16
|
123 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
Chris@101
|
124 ) BOOST_NOEXCEPT
|
Chris@16
|
125 {
|
Chris@16
|
126 typedef typename add_pointer<const U>::type U_ptr;
|
Chris@16
|
127 if (!operand) return static_cast<U_ptr>(0);
|
Chris@16
|
128
|
Chris@16
|
129 detail::variant::get_visitor<const U> v;
|
Chris@16
|
130 return operand->apply_visitor(v);
|
Chris@16
|
131 }
|
Chris@16
|
132
|
Chris@16
|
133 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
Chris@16
|
134 inline
|
Chris@16
|
135 typename add_reference<U>::type
|
Chris@101
|
136 relaxed_get(
|
Chris@101
|
137 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
|
Chris@101
|
138 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
Chris@101
|
139 )
|
Chris@101
|
140 {
|
Chris@101
|
141 typedef typename add_pointer<U>::type U_ptr;
|
Chris@101
|
142 U_ptr result = relaxed_get<U>(&operand);
|
Chris@101
|
143
|
Chris@101
|
144 if (!result)
|
Chris@101
|
145 boost::throw_exception(bad_get());
|
Chris@101
|
146 return *result;
|
Chris@101
|
147 }
|
Chris@101
|
148
|
Chris@101
|
149 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
Chris@101
|
150 inline
|
Chris@101
|
151 typename add_reference<const U>::type
|
Chris@101
|
152 relaxed_get(
|
Chris@101
|
153 const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
|
Chris@101
|
154 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
Chris@101
|
155 )
|
Chris@101
|
156 {
|
Chris@101
|
157 typedef typename add_pointer<const U>::type U_ptr;
|
Chris@101
|
158 U_ptr result = relaxed_get<const U>(&operand);
|
Chris@101
|
159
|
Chris@101
|
160 if (!result)
|
Chris@101
|
161 boost::throw_exception(bad_get());
|
Chris@101
|
162 return *result;
|
Chris@101
|
163 }
|
Chris@101
|
164
|
Chris@101
|
165
|
Chris@101
|
166
|
Chris@101
|
167 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
Chris@101
|
168 // strict_get<U>(variant) methods
|
Chris@101
|
169 //
|
Chris@101
|
170 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
Chris@101
|
171 inline
|
Chris@101
|
172 typename add_pointer<U>::type
|
Chris@101
|
173 strict_get(
|
Chris@101
|
174 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
|
Chris@101
|
175 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
Chris@101
|
176 ) BOOST_NOEXCEPT
|
Chris@101
|
177 {
|
Chris@101
|
178 BOOST_STATIC_ASSERT_MSG(
|
Chris@101
|
179 (boost::detail::variant::holds_element<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, U >::value),
|
Chris@101
|
180 "boost::variant does not contain specified type U, "
|
Chris@101
|
181 "call to boost::get<U>(boost::variant<T...>*) will always return NULL"
|
Chris@101
|
182 );
|
Chris@101
|
183
|
Chris@101
|
184 return relaxed_get<U>(operand);
|
Chris@101
|
185 }
|
Chris@101
|
186
|
Chris@101
|
187 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
Chris@101
|
188 inline
|
Chris@101
|
189 typename add_pointer<const U>::type
|
Chris@101
|
190 strict_get(
|
Chris@101
|
191 const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
|
Chris@101
|
192 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
Chris@101
|
193 ) BOOST_NOEXCEPT
|
Chris@101
|
194 {
|
Chris@101
|
195 BOOST_STATIC_ASSERT_MSG(
|
Chris@101
|
196 (boost::detail::variant::holds_element<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, const U >::value),
|
Chris@101
|
197 "boost::variant does not contain specified type U, "
|
Chris@101
|
198 "call to boost::get<U>(const boost::variant<T...>*) will always return NULL"
|
Chris@101
|
199 );
|
Chris@101
|
200
|
Chris@101
|
201 return relaxed_get<U>(operand);
|
Chris@101
|
202 }
|
Chris@101
|
203
|
Chris@101
|
204 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
Chris@101
|
205 inline
|
Chris@101
|
206 typename add_reference<U>::type
|
Chris@101
|
207 strict_get(
|
Chris@101
|
208 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
|
Chris@101
|
209 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
Chris@101
|
210 )
|
Chris@101
|
211 {
|
Chris@101
|
212 BOOST_STATIC_ASSERT_MSG(
|
Chris@101
|
213 (boost::detail::variant::holds_element<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, U >::value),
|
Chris@101
|
214 "boost::variant does not contain specified type U, "
|
Chris@101
|
215 "call to boost::get<U>(boost::variant<T...>&) will always throw boost::bad_get exception"
|
Chris@101
|
216 );
|
Chris@101
|
217
|
Chris@101
|
218 return relaxed_get<U>(operand);
|
Chris@101
|
219 }
|
Chris@101
|
220
|
Chris@101
|
221 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
Chris@101
|
222 inline
|
Chris@101
|
223 typename add_reference<const U>::type
|
Chris@101
|
224 strict_get(
|
Chris@101
|
225 const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
|
Chris@101
|
226 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
Chris@101
|
227 )
|
Chris@101
|
228 {
|
Chris@101
|
229 BOOST_STATIC_ASSERT_MSG(
|
Chris@101
|
230 (boost::detail::variant::holds_element<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, const U >::value),
|
Chris@101
|
231 "boost::variant does not contain specified type U, "
|
Chris@101
|
232 "call to boost::get<U>(const boost::variant<T...>&) will always throw boost::bad_get exception"
|
Chris@101
|
233 );
|
Chris@101
|
234
|
Chris@101
|
235 return relaxed_get<U>(operand);
|
Chris@101
|
236 }
|
Chris@101
|
237
|
Chris@101
|
238 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
Chris@101
|
239 // get<U>(variant) methods
|
Chris@101
|
240 //
|
Chris@101
|
241
|
Chris@101
|
242 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
Chris@101
|
243 inline
|
Chris@101
|
244 typename add_pointer<U>::type
|
Chris@101
|
245 get(
|
Chris@101
|
246 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
|
Chris@101
|
247 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
Chris@101
|
248 ) BOOST_NOEXCEPT
|
Chris@101
|
249 {
|
Chris@101
|
250 #ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
|
Chris@101
|
251 return relaxed_get<U>(operand);
|
Chris@101
|
252 #else
|
Chris@101
|
253 return strict_get<U>(operand);
|
Chris@101
|
254 #endif
|
Chris@101
|
255
|
Chris@101
|
256 }
|
Chris@101
|
257
|
Chris@101
|
258 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
Chris@101
|
259 inline
|
Chris@101
|
260 typename add_pointer<const U>::type
|
Chris@101
|
261 get(
|
Chris@101
|
262 const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
|
Chris@101
|
263 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
Chris@101
|
264 ) BOOST_NOEXCEPT
|
Chris@101
|
265 {
|
Chris@101
|
266 #ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
|
Chris@101
|
267 return relaxed_get<U>(operand);
|
Chris@101
|
268 #else
|
Chris@101
|
269 return strict_get<U>(operand);
|
Chris@101
|
270 #endif
|
Chris@101
|
271 }
|
Chris@101
|
272
|
Chris@101
|
273 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
Chris@101
|
274 inline
|
Chris@101
|
275 typename add_reference<U>::type
|
Chris@16
|
276 get(
|
Chris@16
|
277 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
|
Chris@16
|
278 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
Chris@16
|
279 )
|
Chris@16
|
280 {
|
Chris@101
|
281 #ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
|
Chris@101
|
282 return relaxed_get<U>(operand);
|
Chris@101
|
283 #else
|
Chris@101
|
284 return strict_get<U>(operand);
|
Chris@101
|
285 #endif
|
Chris@16
|
286 }
|
Chris@16
|
287
|
Chris@16
|
288 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
|
Chris@16
|
289 inline
|
Chris@16
|
290 typename add_reference<const U>::type
|
Chris@16
|
291 get(
|
Chris@16
|
292 const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
|
Chris@16
|
293 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
|
Chris@16
|
294 )
|
Chris@16
|
295 {
|
Chris@101
|
296 #ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
|
Chris@101
|
297 return relaxed_get<U>(operand);
|
Chris@101
|
298 #else
|
Chris@101
|
299 return strict_get<U>(operand);
|
Chris@101
|
300 #endif
|
Chris@16
|
301 }
|
Chris@16
|
302
|
Chris@16
|
303 } // namespace boost
|
Chris@16
|
304
|
Chris@16
|
305 #endif // BOOST_VARIANT_GET_HPP
|