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