]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/any.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / any.hpp
1 // See http://www.boost.org/libs/any for Documentation.
2
3 #ifndef BOOST_ANY_INCLUDED
4 #define BOOST_ANY_INCLUDED
5
6 #if defined(_MSC_VER)
7 # pragma once
8 #endif
9
10 // what: variant type boost::any
11 // who: contributed by Kevlin Henney,
12 // with features contributed and bugs found by
13 // Antony Polukhin, Ed Brey, Mark Rodgers,
14 // Peter Dimov, and James Curran
15 // when: July 2001, April 2013 - May 2013
16
17 #include <algorithm>
18
19 #include <boost/config.hpp>
20 #include <boost/type_index.hpp>
21 #include <boost/type_traits/remove_reference.hpp>
22 #include <boost/type_traits/decay.hpp>
23 #include <boost/type_traits/remove_cv.hpp>
24 #include <boost/type_traits/add_reference.hpp>
25 #include <boost/type_traits/is_reference.hpp>
26 #include <boost/type_traits/is_const.hpp>
27 #include <boost/throw_exception.hpp>
28 #include <boost/static_assert.hpp>
29 #include <boost/utility/enable_if.hpp>
30 #include <boost/core/addressof.hpp>
31 #include <boost/type_traits/is_same.hpp>
32 #include <boost/type_traits/is_const.hpp>
33 #include <boost/mpl/if.hpp>
34
35 namespace boost
36 {
37 class any
38 {
39 public: // structors
40
41 any() BOOST_NOEXCEPT
42 : content(0)
43 {
44 }
45
46 template<typename ValueType>
47 any(const ValueType & value)
48 : content(new holder<
49 BOOST_DEDUCED_TYPENAME remove_cv<BOOST_DEDUCED_TYPENAME decay<const ValueType>::type>::type
50 >(value))
51 {
52 }
53
54 any(const any & other)
55 : content(other.content ? other.content->clone() : 0)
56 {
57 }
58
59 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
60 // Move constructor
61 any(any&& other) BOOST_NOEXCEPT
62 : content(other.content)
63 {
64 other.content = 0;
65 }
66
67 // Perfect forwarding of ValueType
68 template<typename ValueType>
69 any(ValueType&& value
70 , typename boost::disable_if<boost::is_same<any&, ValueType> >::type* = 0 // disable if value has type `any&`
71 , typename boost::disable_if<boost::is_const<ValueType> >::type* = 0) // disable if value has type `const ValueType&&`
72 : content(new holder< typename decay<ValueType>::type >(static_cast<ValueType&&>(value)))
73 {
74 }
75 #endif
76
77 ~any() BOOST_NOEXCEPT
78 {
79 delete content;
80 }
81
82 public: // modifiers
83
84 any & swap(any & rhs) BOOST_NOEXCEPT
85 {
86 std::swap(content, rhs.content);
87 return *this;
88 }
89
90
91 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
92 template<typename ValueType>
93 any & operator=(const ValueType & rhs)
94 {
95 any(rhs).swap(*this);
96 return *this;
97 }
98
99 any & operator=(any rhs)
100 {
101 any(rhs).swap(*this);
102 return *this;
103 }
104
105 #else
106 any & operator=(const any& rhs)
107 {
108 any(rhs).swap(*this);
109 return *this;
110 }
111
112 // move assignement
113 any & operator=(any&& rhs) BOOST_NOEXCEPT
114 {
115 rhs.swap(*this);
116 any().swap(rhs);
117 return *this;
118 }
119
120 // Perfect forwarding of ValueType
121 template <class ValueType>
122 any & operator=(ValueType&& rhs)
123 {
124 any(static_cast<ValueType&&>(rhs)).swap(*this);
125 return *this;
126 }
127 #endif
128
129 public: // queries
130
131 bool empty() const BOOST_NOEXCEPT
132 {
133 return !content;
134 }
135
136 void clear() BOOST_NOEXCEPT
137 {
138 any().swap(*this);
139 }
140
141 const boost::typeindex::type_info& type() const BOOST_NOEXCEPT
142 {
143 return content ? content->type() : boost::typeindex::type_id<void>().type_info();
144 }
145
146 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
147 private: // types
148 #else
149 public: // types (public so any_cast can be non-friend)
150 #endif
151
152 class placeholder
153 {
154 public: // structors
155
156 virtual ~placeholder()
157 {
158 }
159
160 public: // queries
161
162 virtual const boost::typeindex::type_info& type() const BOOST_NOEXCEPT = 0;
163
164 virtual placeholder * clone() const = 0;
165
166 };
167
168 template<typename ValueType>
169 class holder : public placeholder
170 {
171 public: // structors
172
173 holder(const ValueType & value)
174 : held(value)
175 {
176 }
177
178 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
179 holder(ValueType&& value)
180 : held(static_cast< ValueType&& >(value))
181 {
182 }
183 #endif
184 public: // queries
185
186 virtual const boost::typeindex::type_info& type() const BOOST_NOEXCEPT
187 {
188 return boost::typeindex::type_id<ValueType>().type_info();
189 }
190
191 virtual placeholder * clone() const
192 {
193 return new holder(held);
194 }
195
196 public: // representation
197
198 ValueType held;
199
200 private: // intentionally left unimplemented
201 holder & operator=(const holder &);
202 };
203
204 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
205
206 private: // representation
207
208 template<typename ValueType>
209 friend ValueType * any_cast(any *) BOOST_NOEXCEPT;
210
211 template<typename ValueType>
212 friend ValueType * unsafe_any_cast(any *) BOOST_NOEXCEPT;
213
214 #else
215
216 public: // representation (public so any_cast can be non-friend)
217
218 #endif
219
220 placeholder * content;
221
222 };
223
224 inline void swap(any & lhs, any & rhs) BOOST_NOEXCEPT
225 {
226 lhs.swap(rhs);
227 }
228
229 class BOOST_SYMBOL_VISIBLE bad_any_cast :
230 #ifndef BOOST_NO_RTTI
231 public std::bad_cast
232 #else
233 public std::exception
234 #endif
235 {
236 public:
237 virtual const char * what() const BOOST_NOEXCEPT_OR_NOTHROW
238 {
239 return "boost::bad_any_cast: "
240 "failed conversion using boost::any_cast";
241 }
242 };
243
244 template<typename ValueType>
245 ValueType * any_cast(any * operand) BOOST_NOEXCEPT
246 {
247 return operand && operand->type() == boost::typeindex::type_id<ValueType>()
248 ? boost::addressof(
249 static_cast<any::holder<BOOST_DEDUCED_TYPENAME remove_cv<ValueType>::type> *>(operand->content)->held
250 )
251 : 0;
252 }
253
254 template<typename ValueType>
255 inline const ValueType * any_cast(const any * operand) BOOST_NOEXCEPT
256 {
257 return any_cast<ValueType>(const_cast<any *>(operand));
258 }
259
260 template<typename ValueType>
261 ValueType any_cast(any & operand)
262 {
263 typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
264
265
266 nonref * result = any_cast<nonref>(boost::addressof(operand));
267 if(!result)
268 boost::throw_exception(bad_any_cast());
269
270 // Attempt to avoid construction of a temporary object in cases when
271 // `ValueType` is not a reference. Example:
272 // `static_cast<std::string>(*result);`
273 // which is equal to `std::string(*result);`
274 typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_<
275 boost::is_reference<ValueType>,
276 ValueType,
277 BOOST_DEDUCED_TYPENAME boost::add_reference<ValueType>::type
278 >::type ref_type;
279
280 #ifdef BOOST_MSVC
281 # pragma warning(push)
282 # pragma warning(disable: 4172) // "returning address of local variable or temporary" but *result is not local!
283 #endif
284 return static_cast<ref_type>(*result);
285 #ifdef BOOST_MSVC
286 # pragma warning(pop)
287 #endif
288 }
289
290 template<typename ValueType>
291 inline ValueType any_cast(const any & operand)
292 {
293 typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
294 return any_cast<const nonref &>(const_cast<any &>(operand));
295 }
296
297 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
298 template<typename ValueType>
299 inline ValueType any_cast(any&& operand)
300 {
301 BOOST_STATIC_ASSERT_MSG(
302 boost::is_rvalue_reference<ValueType&&>::value /*true if ValueType is rvalue or just a value*/
303 || boost::is_const< typename boost::remove_reference<ValueType>::type >::value,
304 "boost::any_cast shall not be used for getting nonconst references to temporary objects"
305 );
306 return any_cast<ValueType>(operand);
307 }
308 #endif
309
310
311 // Note: The "unsafe" versions of any_cast are not part of the
312 // public interface and may be removed at any time. They are
313 // required where we know what type is stored in the any and can't
314 // use typeid() comparison, e.g., when our types may travel across
315 // different shared libraries.
316 template<typename ValueType>
317 inline ValueType * unsafe_any_cast(any * operand) BOOST_NOEXCEPT
318 {
319 return boost::addressof(
320 static_cast<any::holder<ValueType> *>(operand->content)->held
321 );
322 }
323
324 template<typename ValueType>
325 inline const ValueType * unsafe_any_cast(const any * operand) BOOST_NOEXCEPT
326 {
327 return unsafe_any_cast<ValueType>(const_cast<any *>(operand));
328 }
329 }
330
331 // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
332 //
333 // Distributed under the Boost Software License, Version 1.0. (See
334 // accompanying file LICENSE_1_0.txt or copy at
335 // http://www.boost.org/LICENSE_1_0.txt)
336
337 #endif