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 - May 2013
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>
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)
101 any(rhs).swap(*this);
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)
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>
169 class holder : public placeholder
173 holder(const ValueType & value)
178 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
179 holder(ValueType&& value)
180 : held(static_cast< ValueType&& >(value))
186 virtual const boost::typeindex::type_info& type() const BOOST_NOEXCEPT
188 return boost::typeindex::type_id<ValueType>().type_info();
191 virtual placeholder * clone() const
193 return new holder(held);
196 public: // representation
200 private: // intentionally left unimplemented
201 holder & operator=(const holder &);
204 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
206 private: // representation
208 template<typename ValueType>
209 friend ValueType * any_cast(any *) BOOST_NOEXCEPT;
211 template<typename ValueType>
212 friend ValueType * unsafe_any_cast(any *) BOOST_NOEXCEPT;
216 public: // representation (public so any_cast can be non-friend)
220 placeholder * content;
224 inline void swap(any & lhs, any & rhs) BOOST_NOEXCEPT
229 class BOOST_SYMBOL_VISIBLE bad_any_cast :
230 #ifndef BOOST_NO_RTTI
233 public std::exception
237 virtual const char * what() const BOOST_NOEXCEPT_OR_NOTHROW
239 return "boost::bad_any_cast: "
240 "failed conversion using boost::any_cast";
244 template<typename ValueType>
245 ValueType * any_cast(any * operand) BOOST_NOEXCEPT
247 return operand && operand->type() == boost::typeindex::type_id<ValueType>()
249 static_cast<any::holder<BOOST_DEDUCED_TYPENAME remove_cv<ValueType>::type> *>(operand->content)->held
254 template<typename ValueType>
255 inline const ValueType * any_cast(const any * operand) BOOST_NOEXCEPT
257 return any_cast<ValueType>(const_cast<any *>(operand));
260 template<typename ValueType>
261 ValueType any_cast(any & operand)
263 typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
266 nonref * result = any_cast<nonref>(boost::addressof(operand));
268 boost::throw_exception(bad_any_cast());
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>,
277 BOOST_DEDUCED_TYPENAME boost::add_reference<ValueType>::type
281 # pragma warning(push)
282 # pragma warning(disable: 4172) // "returning address of local variable or temporary" but *result is not local!
284 return static_cast<ref_type>(*result);
286 # pragma warning(pop)
290 template<typename ValueType>
291 inline ValueType any_cast(const any & operand)
293 typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
294 return any_cast<const nonref &>(const_cast<any &>(operand));
297 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
298 template<typename ValueType>
299 inline ValueType any_cast(any&& operand)
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"
306 return any_cast<ValueType>(operand);
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
319 return boost::addressof(
320 static_cast<any::holder<ValueType> *>(operand->content)->held
324 template<typename ValueType>
325 inline const ValueType * unsafe_any_cast(const any * operand) BOOST_NOEXCEPT
327 return unsafe_any_cast<ValueType>(const_cast<any *>(operand));
331 // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
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)