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 - 2020
16
17#include <boost/config.hpp>
18#include <boost/type_index.hpp>
19#include <boost/type_traits/remove_reference.hpp>
20#include <boost/type_traits/decay.hpp>
21#include <boost/type_traits/remove_cv.hpp>
22#include <boost/type_traits/add_reference.hpp>
23#include <boost/type_traits/is_reference.hpp>
24#include <boost/type_traits/is_const.hpp>
25#include <boost/throw_exception.hpp>
26#include <boost/static_assert.hpp>
27#include <boost/utility/enable_if.hpp>
28#include <boost/core/addressof.hpp>
29#include <boost/type_traits/is_same.hpp>
30#include <boost/type_traits/is_const.hpp>
31#include <boost/type_traits/conditional.hpp>
32
33namespace boost
34{
35 class any
36 {
37 public: // structors
38
39 BOOST_CONSTEXPR any() BOOST_NOEXCEPT
40 : content(0)
41 {
42 }
43
44 template<typename ValueType>
45 any(const ValueType & value)
46 : content(new holder<
47 BOOST_DEDUCED_TYPENAME remove_cv<BOOST_DEDUCED_TYPENAME decay<const ValueType>::type>::type
48 >(value))
49 {
50 }
51
52 any(const any & other)
53 : content(other.content ? other.content->clone() : 0)
54 {
55 }
56
57#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
58 // Move constructor
59 any(any&& other) BOOST_NOEXCEPT
60 : content(other.content)
61 {
62 other.content = 0;
63 }
64
65 // Perfect forwarding of ValueType
66 template<typename ValueType>
67 any(ValueType&& value
68 , typename boost::disable_if<boost::is_same<any&, ValueType> >::type* = 0 // disable if value has type `any&`
69 , typename boost::disable_if<boost::is_const<ValueType> >::type* = 0) // disable if value has type `const ValueType&&`
70 : content(new holder< typename decay<ValueType>::type >(static_cast<ValueType&&>(value)))
71 {
72 }
73#endif
74
75 ~any() BOOST_NOEXCEPT
76 {
77 delete content;
78 }
79
80 public: // modifiers
81
82 any & swap(any & rhs) BOOST_NOEXCEPT
83 {
84 placeholder* tmp = content;
85 content = rhs.content;
86 rhs.content = tmp;
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 rhs.swap(*this);
102 return *this;
103 }
104
105#else
106 any & operator=(const any& rhs)
107 {
108 any(rhs).swap(rhs&: *this);
109 return *this;
110 }
111
112 // move assignment
113 any & operator=(any&& rhs) BOOST_NOEXCEPT
114 {
115 rhs.swap(rhs&: *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(rhs&: *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(rhs&: *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 BOOST_SYMBOL_VISIBLE 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
170#ifndef BOOST_NO_CXX11_FINAL
171 final
172#endif
173 : public placeholder
174 {
175 public: // structors
176
177 holder(const ValueType & value)
178 : held(value)
179 {
180 }
181
182#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
183 holder(ValueType&& value)
184 : held(static_cast< ValueType&& >(value))
185 {
186 }
187#endif
188 public: // queries
189
190 const boost::typeindex::type_info& type() const BOOST_NOEXCEPT BOOST_OVERRIDE
191 {
192 return boost::typeindex::type_id<ValueType>().type_info();
193 }
194
195 placeholder * clone() const BOOST_OVERRIDE
196 {
197 return new holder(held);
198 }
199
200 public: // representation
201
202 ValueType held;
203
204 private: // intentionally left unimplemented
205 holder & operator=(const holder &);
206 };
207
208#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
209
210 private: // representation
211
212 template<typename ValueType>
213 friend ValueType * any_cast(any *) BOOST_NOEXCEPT;
214
215 template<typename ValueType>
216 friend ValueType * unsafe_any_cast(any *) BOOST_NOEXCEPT;
217
218#else
219
220 public: // representation (public so any_cast can be non-friend)
221
222#endif
223
224 placeholder * content;
225
226 };
227
228 inline void swap(any & lhs, any & rhs) BOOST_NOEXCEPT
229 {
230 lhs.swap(rhs);
231 }
232
233 class BOOST_SYMBOL_VISIBLE bad_any_cast :
234#ifndef BOOST_NO_RTTI
235 public std::bad_cast
236#else
237 public std::exception
238#endif
239 {
240 public:
241 const char * what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE
242 {
243 return "boost::bad_any_cast: "
244 "failed conversion using boost::any_cast";
245 }
246 };
247
248 template<typename ValueType>
249 ValueType * any_cast(any * operand) BOOST_NOEXCEPT
250 {
251 return operand && operand->type() == boost::typeindex::type_id<ValueType>()
252 ? boost::addressof(
253 static_cast<any::holder<BOOST_DEDUCED_TYPENAME remove_cv<ValueType>::type> *>(operand->content)->held
254 )
255 : 0;
256 }
257
258 template<typename ValueType>
259 inline const ValueType * any_cast(const any * operand) BOOST_NOEXCEPT
260 {
261 return any_cast<ValueType>(const_cast<any *>(operand));
262 }
263
264 template<typename ValueType>
265 ValueType any_cast(any & operand)
266 {
267 typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
268
269
270 nonref * result = any_cast<nonref>(boost::addressof(o&: operand));
271 if(!result)
272 boost::throw_exception(e: bad_any_cast());
273
274 // Attempt to avoid construction of a temporary object in cases when
275 // `ValueType` is not a reference. Example:
276 // `static_cast<std::string>(*result);`
277 // which is equal to `std::string(*result);`
278 typedef BOOST_DEDUCED_TYPENAME boost::conditional<
279 boost::is_reference<ValueType>::value,
280 ValueType,
281 BOOST_DEDUCED_TYPENAME boost::add_reference<ValueType>::type
282 >::type ref_type;
283
284#ifdef BOOST_MSVC
285# pragma warning(push)
286# pragma warning(disable: 4172) // "returning address of local variable or temporary" but *result is not local!
287#endif
288 return static_cast<ref_type>(*result);
289#ifdef BOOST_MSVC
290# pragma warning(pop)
291#endif
292 }
293
294 template<typename ValueType>
295 inline ValueType any_cast(const any & operand)
296 {
297 typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
298 return any_cast<const nonref &>(const_cast<any &>(operand));
299 }
300
301#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
302 template<typename ValueType>
303 inline ValueType any_cast(any&& operand)
304 {
305 BOOST_STATIC_ASSERT_MSG(
306 boost::is_rvalue_reference<ValueType&&>::value /*true if ValueType is rvalue or just a value*/
307 || boost::is_const< typename boost::remove_reference<ValueType>::type >::value,
308 "boost::any_cast shall not be used for getting nonconst references to temporary objects"
309 );
310 return any_cast<ValueType>(operand);
311 }
312#endif
313
314
315 // Note: The "unsafe" versions of any_cast are not part of the
316 // public interface and may be removed at any time. They are
317 // required where we know what type is stored in the any and can't
318 // use typeid() comparison, e.g., when our types may travel across
319 // different shared libraries.
320 template<typename ValueType>
321 inline ValueType * unsafe_any_cast(any * operand) BOOST_NOEXCEPT
322 {
323 return boost::addressof(
324 static_cast<any::holder<ValueType> *>(operand->content)->held
325 );
326 }
327
328 template<typename ValueType>
329 inline const ValueType * unsafe_any_cast(const any * operand) BOOST_NOEXCEPT
330 {
331 return unsafe_any_cast<ValueType>(const_cast<any *>(operand));
332 }
333}
334
335// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
336// Copyright Antony Polukhin, 2013-2020.
337//
338// Distributed under the Boost Software License, Version 1.0. (See
339// accompanying file LICENSE_1_0.txt or copy at
340// http://www.boost.org/LICENSE_1_0.txt)
341
342#endif
343

source code of include/boost/any.hpp