1 // See http://www.boost.org/libs/any for Documentation.
3 #ifndef BOOST_ANY_INCLUDED
4 #define BOOST_ANY_INCLUDED
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 - 2019
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/type_traits/conditional.hpp>
41 BOOST_CONSTEXPR any() BOOST_NOEXCEPT
46 template<typename ValueType>
47 any(const ValueType & value)
49 BOOST_DEDUCED_TYPENAME remove_cv<BOOST_DEDUCED_TYPENAME decay<const ValueType>::type>::type
54 any(const any & other)
55 : content(other.content ? other.content->clone() : 0)
59 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
61 any(any&& other) BOOST_NOEXCEPT
62 : content(other.content)
67 // Perfect forwarding of ValueType
68 template<typename ValueType>
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)))
84 any & swap(any & rhs) BOOST_NOEXCEPT
86 std::swap(content, rhs.content);
91 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
92 template<typename ValueType>
93 any & operator=(const ValueType & rhs)
99 any & operator=(any rhs)
106 any & operator=(const any& rhs)
108 any(rhs).swap(*this);
113 any & operator=(any&& rhs) BOOST_NOEXCEPT
120 // Perfect forwarding of ValueType
121 template <class ValueType>
122 any & operator=(ValueType&& rhs)
124 any(static_cast<ValueType&&>(rhs)).swap(*this);
131 bool empty() const BOOST_NOEXCEPT
136 void clear() BOOST_NOEXCEPT
141 const boost::typeindex::type_info& type() const BOOST_NOEXCEPT
143 return content ? content->type() : boost::typeindex::type_id<void>().type_info();
146 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
149 public: // types (public so any_cast can be non-friend)
152 class BOOST_SYMBOL_VISIBLE placeholder
156 virtual ~placeholder()
162 virtual const boost::typeindex::type_info& type() const BOOST_NOEXCEPT = 0;
164 virtual placeholder * clone() const = 0;
168 template<typename ValueType>
170 #ifndef BOOST_NO_CXX11_FINAL
177 holder(const ValueType & value)
182 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
183 holder(ValueType&& value)
184 : held(static_cast< ValueType&& >(value))
190 virtual const boost::typeindex::type_info& type() const BOOST_NOEXCEPT
192 return boost::typeindex::type_id<ValueType>().type_info();
195 virtual placeholder * clone() const
197 return new holder(held);
200 public: // representation
204 private: // intentionally left unimplemented
205 holder & operator=(const holder &);
208 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
210 private: // representation
212 template<typename ValueType>
213 friend ValueType * any_cast(any *) BOOST_NOEXCEPT;
215 template<typename ValueType>
216 friend ValueType * unsafe_any_cast(any *) BOOST_NOEXCEPT;
220 public: // representation (public so any_cast can be non-friend)
224 placeholder * content;
228 inline void swap(any & lhs, any & rhs) BOOST_NOEXCEPT
233 class BOOST_SYMBOL_VISIBLE bad_any_cast :
234 #ifndef BOOST_NO_RTTI
237 public std::exception
241 virtual const char * what() const BOOST_NOEXCEPT_OR_NOTHROW
243 return "boost::bad_any_cast: "
244 "failed conversion using boost::any_cast";
248 template<typename ValueType>
249 ValueType * any_cast(any * operand) BOOST_NOEXCEPT
251 return operand && operand->type() == boost::typeindex::type_id<ValueType>()
253 static_cast<any::holder<BOOST_DEDUCED_TYPENAME remove_cv<ValueType>::type> *>(operand->content)->held
258 template<typename ValueType>
259 inline const ValueType * any_cast(const any * operand) BOOST_NOEXCEPT
261 return any_cast<ValueType>(const_cast<any *>(operand));
264 template<typename ValueType>
265 ValueType any_cast(any & operand)
267 typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
270 nonref * result = any_cast<nonref>(boost::addressof(operand));
272 boost::throw_exception(bad_any_cast());
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,
281 BOOST_DEDUCED_TYPENAME boost::add_reference<ValueType>::type
285 # pragma warning(push)
286 # pragma warning(disable: 4172) // "returning address of local variable or temporary" but *result is not local!
288 return static_cast<ref_type>(*result);
290 # pragma warning(pop)
294 template<typename ValueType>
295 inline ValueType any_cast(const any & operand)
297 typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
298 return any_cast<const nonref &>(const_cast<any &>(operand));
301 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
302 template<typename ValueType>
303 inline ValueType any_cast(any&& operand)
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"
310 return any_cast<ValueType>(operand);
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
323 return boost::addressof(
324 static_cast<any::holder<ValueType> *>(operand->content)->held
328 template<typename ValueType>
329 inline const ValueType * unsafe_any_cast(const any * operand) BOOST_NOEXCEPT
331 return unsafe_any_cast<ValueType>(const_cast<any *>(operand));
335 // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
336 // Copyright Antony Polukhin, 2013-2019.
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)