]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/variant/get.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / variant / get.hpp
1 //-----------------------------------------------------------------------------
2 // boost variant/get.hpp header file
3 // See http://www.boost.org for updates, documentation, and revision history.
4 //-----------------------------------------------------------------------------
5 //
6 // Copyright (c) 2003 Eric Friedman, Itay Maman
7 // Copyright (c) 2014-2022 Antony Polukhin
8 //
9 // Distributed under the Boost Software License, Version 1.0. (See
10 // accompanying file LICENSE_1_0.txt or copy at
11 // http://www.boost.org/LICENSE_1_0.txt)
12
13 #ifndef BOOST_VARIANT_GET_HPP
14 #define BOOST_VARIANT_GET_HPP
15
16 #include <exception>
17
18 #include <boost/config.hpp>
19 #include <boost/detail/workaround.hpp>
20 #include <boost/static_assert.hpp>
21 #include <boost/throw_exception.hpp>
22 #include <boost/utility/addressof.hpp>
23 #include <boost/variant/variant_fwd.hpp>
24 #include <boost/variant/detail/element_index.hpp>
25 #include <boost/variant/detail/move.hpp>
26
27 #include <boost/type_traits/add_reference.hpp>
28 #include <boost/type_traits/add_pointer.hpp>
29 #include <boost/type_traits/is_lvalue_reference.hpp>
30
31 namespace boost {
32
33 #if defined(BOOST_CLANG)
34 # pragma clang diagnostic push
35 # pragma clang diagnostic ignored "-Wweak-vtables"
36 #endif
37 //////////////////////////////////////////////////////////////////////////
38 // class bad_get
39 //
40 // The exception thrown in the event of a failed get of a value.
41 //
42 class BOOST_SYMBOL_VISIBLE bad_get
43 : public std::exception
44 {
45 public: // std::exception implementation
46
47 const char * what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE
48 {
49 return "boost::bad_get: "
50 "failed value get using boost::get";
51 }
52
53 };
54 #if defined(BOOST_CLANG)
55 # pragma clang diagnostic pop
56 #endif
57
58
59 //////////////////////////////////////////////////////////////////////////
60 // function template get<T>
61 //
62 // Retrieves content of given variant object if content is of type T.
63 // Otherwise: pointer ver. returns 0; reference ver. throws bad_get.
64 //
65
66 namespace detail { namespace variant {
67
68 // (detail) class template get_visitor
69 //
70 // Generic static visitor that: if the value is of the specified type,
71 // returns a pointer to the value it visits; else a null pointer.
72 //
73 template <typename T>
74 struct get_visitor
75 {
76 private: // private typedefs
77
78 typedef typename add_pointer<T>::type pointer;
79 typedef typename add_reference<T>::type reference;
80
81 public: // visitor typedefs
82
83 typedef pointer result_type;
84
85 public: // visitor interfaces
86
87 pointer operator()(reference operand) const BOOST_NOEXCEPT
88 {
89 return boost::addressof(operand);
90 }
91
92 template <typename U>
93 pointer operator()(const U&) const BOOST_NOEXCEPT
94 {
95 return static_cast<pointer>(0);
96 }
97 };
98
99 }} // namespace detail::variant
100
101 #ifndef BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE
102 # if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x0551))
103 # define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t)
104 # else
105 # if defined(BOOST_NO_CXX11_NULLPTR)
106 # define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \
107 , t* = 0
108 # else
109 # define BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(t) \
110 , t* = nullptr
111 # endif
112 # endif
113 #endif
114
115 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
116 // relaxed_get<U>(variant) methods
117 //
118 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
119 inline
120 typename add_pointer<U>::type
121 relaxed_get(
122 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
123 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
124 ) BOOST_NOEXCEPT
125 {
126 typedef typename add_pointer<U>::type U_ptr;
127 if (!operand) return static_cast<U_ptr>(0);
128
129 detail::variant::get_visitor<U> v;
130 return operand->apply_visitor(v);
131 }
132
133 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
134 inline
135 typename add_pointer<const U>::type
136 relaxed_get(
137 const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
138 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
139 ) BOOST_NOEXCEPT
140 {
141 typedef typename add_pointer<const U>::type U_ptr;
142 if (!operand) return static_cast<U_ptr>(0);
143
144 detail::variant::get_visitor<const U> v;
145 return operand->apply_visitor(v);
146 }
147
148 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
149 inline
150 typename add_reference<U>::type
151 relaxed_get(
152 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
153 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
154 )
155 {
156 typedef typename add_pointer<U>::type U_ptr;
157 U_ptr result = relaxed_get<U>(boost::addressof(operand));
158
159 if (!result)
160 boost::throw_exception(bad_get());
161 return *result;
162 }
163
164 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
165 inline
166 typename add_reference<const U>::type
167 relaxed_get(
168 const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
169 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
170 )
171 {
172 typedef typename add_pointer<const U>::type U_ptr;
173 U_ptr result = relaxed_get<const U>(boost::addressof(operand));
174
175 if (!result)
176 boost::throw_exception(bad_get());
177 return *result;
178 }
179
180 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
181
182 #if defined(BOOST_MSVC) && (_MSC_VER < 1900) // MSVC-2014 has fixed the incorrect diagnostics.
183 # pragma warning(push)
184 # pragma warning(disable: 4172) // returning address of local variable or temporary
185 #endif
186
187 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
188 inline
189 U&&
190 relaxed_get(
191 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >&& operand
192 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
193 )
194 {
195 typedef typename add_pointer<U>::type U_ptr;
196 U_ptr result = relaxed_get<U>(boost::addressof(operand));
197
198 if (!result)
199 boost::throw_exception(bad_get());
200 return static_cast<U&&>(*result);
201 }
202
203 #if defined(BOOST_MSVC) && (_MSC_VER < 1900)
204 # pragma warning(pop)
205 #endif
206
207 #endif
208
209 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
210 // strict_get<U>(variant) methods
211 //
212 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
213 inline
214 typename add_pointer<U>::type
215 strict_get(
216 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
217 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
218 ) BOOST_NOEXCEPT
219 {
220 BOOST_STATIC_ASSERT_MSG(
221 (boost::detail::variant::holds_element<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, U >::value),
222 "boost::variant does not contain specified type U, "
223 "call to boost::get<U>(boost::variant<T...>*) will always return NULL"
224 );
225
226 return relaxed_get<U>(operand);
227 }
228
229 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
230 inline
231 typename add_pointer<const U>::type
232 strict_get(
233 const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
234 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
235 ) BOOST_NOEXCEPT
236 {
237 BOOST_STATIC_ASSERT_MSG(
238 (boost::detail::variant::holds_element<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, const U >::value),
239 "boost::variant does not contain specified type U, "
240 "call to boost::get<U>(const boost::variant<T...>*) will always return NULL"
241 );
242
243 return relaxed_get<U>(operand);
244 }
245
246 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
247 inline
248 typename add_reference<U>::type
249 strict_get(
250 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
251 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
252 )
253 {
254 BOOST_STATIC_ASSERT_MSG(
255 (boost::detail::variant::holds_element<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, U >::value),
256 "boost::variant does not contain specified type U, "
257 "call to boost::get<U>(boost::variant<T...>&) will always throw boost::bad_get exception"
258 );
259
260 return relaxed_get<U>(operand);
261 }
262
263 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
264 inline
265 typename add_reference<const U>::type
266 strict_get(
267 const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
268 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
269 )
270 {
271 BOOST_STATIC_ASSERT_MSG(
272 (boost::detail::variant::holds_element<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, const U >::value),
273 "boost::variant does not contain specified type U, "
274 "call to boost::get<U>(const boost::variant<T...>&) will always throw boost::bad_get exception"
275 );
276
277 return relaxed_get<U>(operand);
278 }
279
280 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
281 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
282 inline
283 U&&
284 strict_get(
285 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >&& operand
286 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
287 )
288 {
289 BOOST_STATIC_ASSERT_MSG(
290 (!boost::is_lvalue_reference<U>::value),
291 "remove ampersand '&' from template type U in boost::get<U>(boost::variant<T...>&&) "
292 );
293
294 BOOST_STATIC_ASSERT_MSG(
295 (boost::detail::variant::holds_element<boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >, U >::value),
296 "boost::variant does not contain specified type U, "
297 "call to boost::get<U>(const boost::variant<T...>&) will always throw boost::bad_get exception"
298 );
299
300 return relaxed_get<U>(detail::variant::move(operand));
301 }
302 #endif
303
304 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
305 // get<U>(variant) methods
306 //
307
308 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
309 inline
310 typename add_pointer<U>::type
311 get(
312 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
313 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
314 ) BOOST_NOEXCEPT
315 {
316 #ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
317 return relaxed_get<U>(operand);
318 #else
319 return strict_get<U>(operand);
320 #endif
321
322 }
323
324 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
325 inline
326 typename add_pointer<const U>::type
327 get(
328 const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >* operand
329 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
330 ) BOOST_NOEXCEPT
331 {
332 #ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
333 return relaxed_get<U>(operand);
334 #else
335 return strict_get<U>(operand);
336 #endif
337 }
338
339 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
340 inline
341 typename add_reference<U>::type
342 get(
343 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
344 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
345 )
346 {
347 #ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
348 return relaxed_get<U>(operand);
349 #else
350 return strict_get<U>(operand);
351 #endif
352 }
353
354 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
355 inline
356 typename add_reference<const U>::type
357 get(
358 const boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >& operand
359 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
360 )
361 {
362 #ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
363 return relaxed_get<U>(operand);
364 #else
365 return strict_get<U>(operand);
366 #endif
367 }
368
369 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
370 template <typename U, BOOST_VARIANT_ENUM_PARAMS(typename T) >
371 inline
372 U&&
373 get(
374 boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) >&& operand
375 BOOST_VARIANT_AUX_GET_EXPLICIT_TEMPLATE_TYPE(U)
376 )
377 {
378 #ifdef BOOST_VARIANT_USE_RELAXED_GET_BY_DEFAULT
379 return relaxed_get<U>(detail::variant::move(operand));
380 #else
381 return strict_get<U>(detail::variant::move(operand));
382 #endif
383 }
384 #endif
385
386 } // namespace boost
387
388 #endif // BOOST_VARIANT_GET_HPP