// Boost.TypeErasure library // // Copyright 2011 Steven Watanabe // // Distributed under the Boost Software License Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // $Id$ #ifndef BOOST_TYPE_ERASURE_ANY_HPP_INCLUDED #define BOOST_TYPE_ERASURE_ANY_HPP_INCLUDED #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace type_erasure { template struct constructible; template struct destructible; template struct assignable; namespace detail { template struct compute_bases { typedef typename ::boost::mpl::fold< typename ::boost::type_erasure::detail::collect_concepts< Concept >::type, ::boost::type_erasure::any_base, ::boost::type_erasure::concept_interface< ::boost::mpl::_2, ::boost::mpl::_1, T > >::type type; }; template T make(T*) { return T(); } // This dance is necessary to avoid errors calling // an ellipsis function with a non-trivially-copyable // argument. typedef char no; struct yes { no dummy[2]; }; template yes check_overload(const Op*); no check_overload(const void*); struct fallback {}; template fallback make_fallback(const T&, boost::mpl::false_) { return fallback(); } template const T& make_fallback(const T& arg, boost::mpl::true_) { return arg; } template struct is_any : ::boost::mpl::false_ {}; template struct is_any > : ::boost::mpl::true_ {}; } #ifdef BOOST_MSVC #pragma warning(push) #pragma warning(disable:4355) #pragma warning(disable:4521) #endif /** * The class template @ref any can store any object that * models a specific \Concept. It dispatches all * the functions defined by the \Concept to the contained type * at runtime. * * \tparam Concept The \Concept that the stored type should model. * \tparam T A @ref placeholder specifying which type this is. * * \see concept_of, placeholder_of, \any_cast, \is_empty, \binding_of, \typeid_of */ template class any : public ::boost::type_erasure::detail::compute_bases< ::boost::type_erasure::any, Concept, T >::type { typedef ::boost::type_erasure::binding table_type; public: /** INTERNAL ONLY */ typedef Concept _boost_type_erasure_concept_type; /** INTERNAL ONLY */ any(const ::boost::type_erasure::detail::storage& data_arg, const table_type& table_arg) : table(table_arg), data(data_arg) {} #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES /** INTERNAL ONLY */ any(::boost::type_erasure::detail::storage&& data_arg, const table_type& table_arg) : table(table_arg), data(data_arg) {} #endif /** * Constructs an empty @ref any. * * Except as otherwise noted, all operations on an * empty @ref any result in a @ref bad_function_call exception. * The copy-constructor of an empty @ref any creates another * null @ref any. The destructor of an empty @ref any is a no-op. * Comparison operators treat all empty @ref any "anys" as equal. * \typeid_of applied to an empty @ref any returns @c typeid(void). * * An @ref any which does not include @ref relaxed in its * \Concept can never be null. * * \pre @ref relaxed must be in @c Concept. * * \throws Nothing. * * @see \is_empty */ any() { BOOST_MPL_ASSERT((::boost::type_erasure::is_relaxed)); data.data = 0; } #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) template any(const U& data_arg) : table(( BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, U), ::boost::type_erasure::make_binding< ::boost::mpl::map< ::boost::mpl::pair > >() )), data(data_arg) {} template any(const U& data_arg, const static_binding& binding_arg) : table(( BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map), binding_arg )), data(data_arg) { BOOST_MPL_ASSERT((::boost::is_same< typename ::boost::mpl::at::type, U>)); } #else /** * Constructs an @ref any to hold a copy of @c data. * The @c Concept will be instantiated with the * placeholder @c T bound to U. * * \param data The object to store in the @ref any. * * \pre @c U is a model of @c Concept. * \pre @c U must be \CopyConstructible. * \pre @c Concept must not refer to any non-deduced placeholder besides @c T. * * \throws std::bad_alloc or whatever that the copy * constructor of @c U throws. * * \note This constructor never matches if the argument is * an @ref any, @ref binding, or @ref static_binding. */ template any(U&& data_arg) : table(( BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, typename ::boost::remove_cv::type>::type), ::boost::type_erasure::make_binding< ::boost::mpl::map< ::boost::mpl::pair::type>::type> > >() )), data(std::forward(data_arg)) {} /** * Constructs an @ref any to hold a copy of @c data * with explicitly specified placeholder bindings. * * \param data The object to store in the @ref any. * \param binding Specifies the types that * all the placeholders should bind to. * * \pre @c U is a model of @c Concept. * \pre @c U must be \CopyConstructible. * \pre @c Map is an MPL map with an entry for every * non-deduced placeholder referred to by @c Concept. * \pre @c @c T must map to @c U in @c Map. * * \throws std::bad_alloc or whatever that the copy * constructor of @c U throws. * * \note This constructor never matches if the argument is an @ref any. */ template any(U&& data_arg, const static_binding& binding_arg) : table(( BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map), binding_arg )), data(std::forward(data_arg)) { BOOST_MPL_ASSERT((::boost::is_same< typename ::boost::mpl::at::type, typename ::boost::remove_cv::type>::type>)); } #endif // Handle array/function-to-pointer decay /** INTERNAL ONLY */ template any(U* data_arg) : table(( BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, U*), ::boost::type_erasure::make_binding< ::boost::mpl::map< ::boost::mpl::pair > >() )), data(data_arg) {} /** INTERNAL ONLY */ template any(U* data_arg, const static_binding& binding_arg) : table(( BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map), binding_arg )), data(data_arg) { BOOST_MPL_ASSERT((::boost::is_same< typename ::boost::mpl::at::type, U*>)); } /** * Copies an @ref any. * * \param other The object to make a copy of. * * \pre @c Concept must contain @ref constructible "constructible". * (This is included in @ref copy_constructible "copy_constructible") * * \throws std::bad_alloc or whatever that the copy * constructor of the contained type throws. */ any(const any& other) : table(other.table), data(::boost::type_erasure::call(constructible(), other)) {} /** * Upcasts from an @ref any with stricter requirements to * an @ref any with weaker requirements. * * \param other The object to make a copy of. * * \pre @c Concept must contain @ref constructible. * \pre @c Concept must not refer to any non-deduced placeholder besides @c T. * \pre After substituting @c T for @c Tag2, the requirements of * @c Concept2 must be a superset of the requirements of * @c Concept. * * \throws std::bad_alloc or whatever that the copy * constructor of the contained type throws. */ template any(const any& other) : table( ::boost::type_erasure::detail::access::table(other), ::boost::mpl::map< ::boost::mpl::pair< T, typename ::boost::remove_const< typename ::boost::remove_reference::type >::type > >() ), data(::boost::type_erasure::call( constructible< typename ::boost::remove_const< typename boost::remove_reference::type >::type(const typename boost::remove_reference::type&) >(), other) ) {} /** * Constructs an @ref any from another @ref any. * * \param other The object to make a copy of. * \param binding Specifies the mapping between the placeholders * used by the two concepts. * * \pre @c Concept must contain @ref constructible. * \pre @c Map must be an MPL map with keys for all the non-deduced * placeholders used by @c Concept and values for the corresponding * placeholders in @c Concept2. * \pre After substituting placeholders according to @c Map, the * requirements of @c Concept2 must be a superset of the * requirements of @c Concept. * * \throws std::bad_alloc or whatever that the copy * constructor of the contained type throws. */ template any(const any& other, const static_binding& binding_arg) : table(::boost::type_erasure::detail::access::table(other), binding_arg), data(::boost::type_erasure::call( constructible< typename ::boost::remove_const< typename boost::remove_reference::type >::type(const typename boost::remove_reference::type&) >(), other) ) {} /** * Constructs an @ref any from another @ref any. * * \param other The object to make a copy of. * \param binding Specifies the bindings of placeholders to actual types. * * \pre @c Concept must contain @ref constructible. * \pre The type stored in @c other must match the type expected by * @c binding. * * \post binding_of(*this) == @c binding * * \throws std::bad_alloc or whatever that the copy * constructor of the contained type throws. * * \warning This constructor is potentially dangerous, as it cannot * check at compile time whether the arguments match. */ template any(const any& other, const binding& binding_arg) : table(binding_arg), data(::boost::type_erasure::call( constructible< typename ::boost::remove_const< typename boost::remove_reference::type >::type(const typename boost::remove_reference::type&) >(), other) ) {} #ifdef BOOST_TYPE_ERASURE_DOXYGEN /** * Calls a constructor of the contained type. The bindings * will be deduced from the arguments. * * \param arg The arguments to be passed to the underlying constructor. * * \pre @c Concept must contain an instance of @ref constructible which * can be called with these arguments. * \pre At least one of the arguments must by an @ref any with the * same @c Concept as this. * \pre The bindings of all the arguments that are @ref any's, must * be the same. * * \throws std::bad_alloc or whatever that the * constructor of the contained type throws. * * \note This constructor is never chosen if any other constructor * can be called instead. */ template explicit any(U&&... arg); /** * Calls a constructor of the contained type. * * \param binding Specifies the bindings of placeholders to actual types. * \param arg The arguments to be passed to the underlying constructor. * * \pre @c Concept must contain a matching instance of @ref constructible. * \pre The contained type of every argument that is an @ref any, must * be the same as that specified by @c binding. * * \post binding_of(*this) == @c binding * * \throws std::bad_alloc or whatever that the * constructor of the contained type throws. */ template explicit any(const binding& binding_arg, U&&... arg) : table(binding_arg), data( ::boost::type_erasure::detail::make( false? this->_boost_type_erasure_deduce_constructor(arg...) : 0 )(arg...) ) {} #else #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES any(any&& other) : table(::boost::type_erasure::detail::access::table(other)), data(::boost::type_erasure::call( ::boost::type_erasure::detail::make( false? this->_boost_type_erasure_deduce_constructor(std::move(other)) : 0 ), std::move(other)) ) {} any(any& other) : table(::boost::type_erasure::detail::access::table(other)), data(::boost::type_erasure::call( ::boost::type_erasure::detail::make( false? this->_boost_type_erasure_deduce_constructor(other) : 0 ), other) ) {} template any(any& other) : table( ::boost::type_erasure::detail::access::table(other), ::boost::mpl::map< ::boost::mpl::pair< T, typename ::boost::remove_const< typename ::boost::remove_reference::type >::type > >() ), data(::boost::type_erasure::call( ::boost::type_erasure::detail::make( false? other._boost_type_erasure_deduce_constructor(other) : 0 ), other) ) {} template any(any&& other) : table( ::boost::type_erasure::detail::access::table(other), ::boost::mpl::map< ::boost::mpl::pair< T, typename ::boost::remove_const< typename ::boost::remove_reference::type >::type > >() ), data(::boost::type_erasure::call( ::boost::type_erasure::detail::make( false? other._boost_type_erasure_deduce_constructor(std::move(other)) : 0 ), std::move(other)) ) {} #endif // construction from a reference any(const any& other) : table(::boost::type_erasure::detail::access::table(other)), data(::boost::type_erasure::call( ::boost::type_erasure::detail::make( false? this->_boost_type_erasure_deduce_constructor(other) : 0 ), other) ) {} any(any& other) : table(::boost::type_erasure::detail::access::table(other)), data(::boost::type_erasure::call( ::boost::type_erasure::detail::make( false? this->_boost_type_erasure_deduce_constructor(other) : 0 ), other) ) {} #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES any(any&& other) : table(::boost::type_erasure::detail::access::table(other)), data(::boost::type_erasure::call( ::boost::type_erasure::detail::make( false? this->_boost_type_erasure_deduce_constructor(other) : 0 ), other) ) {} #endif any(const any& other) : table(::boost::type_erasure::detail::access::table(other)), data(::boost::type_erasure::call( ::boost::type_erasure::detail::make( false? this->_boost_type_erasure_deduce_constructor(other) : 0 ), other) ) {} any(any& other) : table(::boost::type_erasure::detail::access::table(other)), data(::boost::type_erasure::call( ::boost::type_erasure::detail::make( false? this->_boost_type_erasure_deduce_constructor(other) : 0 ), other) ) {} #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES any(any&& other) : table(::boost::type_erasure::detail::access::table(other)), data(::boost::type_erasure::call( ::boost::type_erasure::detail::make( false? this->_boost_type_erasure_deduce_constructor(other) : 0 ), other) ) {} #endif // disambiguating overloads template any(U* data_arg, static_binding& binding_arg) : table(( BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map), binding_arg )), data(data_arg) { BOOST_MPL_ASSERT((::boost::is_same< typename ::boost::mpl::at::type, U*>)); } #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES template any(U& data_arg, static_binding& binding_arg) : table(( BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map), binding_arg )), data(data_arg) { BOOST_MPL_ASSERT((::boost::is_same< typename ::boost::mpl::at::type, U>)); } template any(const U& data_arg, static_binding& binding_arg) : table(( BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map), binding_arg )), data(data_arg) { BOOST_MPL_ASSERT((::boost::is_same< typename ::boost::mpl::at::type, U>)); } template any(U& data_arg, const static_binding& binding_arg) : table(( BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map), binding_arg )), data(data_arg) { BOOST_MPL_ASSERT((::boost::is_same< typename ::boost::mpl::at::type, U>)); } #endif #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES template any(U* data_arg, static_binding&& binding_arg) : table(( BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map), binding_arg )), data(data_arg) { BOOST_MPL_ASSERT((::boost::is_same< typename ::boost::mpl::at::type, U*>)); } template any(U&& data_arg, static_binding& binding_arg) : table(( BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map), binding_arg )), data(data_arg) { BOOST_MPL_ASSERT((::boost::is_same< typename ::boost::mpl::at::type, typename ::boost::remove_cv::type>::type>)); } template any(U&& data_arg, static_binding&& binding_arg) : table(( BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map), binding_arg )), data(data_arg) { BOOST_MPL_ASSERT((::boost::is_same< typename ::boost::mpl::at::type, typename ::boost::remove_cv::type>::type>)); } #endif template any(any& other, static_binding& binding_arg) : table(::boost::type_erasure::detail::access::table(other), binding_arg), data(::boost::type_erasure::call( constructible< typename ::boost::remove_const< typename boost::remove_reference::type >::type(const typename boost::remove_reference::type&) >(), other) ) {} template any(any& other, const static_binding& binding_arg) : table(::boost::type_erasure::detail::access::table(other), binding_arg), data(::boost::type_erasure::call( constructible< typename ::boost::remove_const< typename boost::remove_reference::type >::type(const typename boost::remove_reference::type&) >(), other) ) {} template any(const any& other, static_binding& binding_arg) : table(::boost::type_erasure::detail::access::table(other), binding_arg), data(::boost::type_erasure::call( constructible< typename ::boost::remove_const< typename boost::remove_reference::type >::type(const typename boost::remove_reference::type&) >(), other) ) {} template any(any& other, binding& binding_arg) : table(binding_arg), data(::boost::type_erasure::call( constructible< typename ::boost::remove_const< typename boost::remove_reference::type >::type(const typename boost::remove_reference::type&) >(), other) ) {} template any(any& other, const binding& binding_arg) : table(binding_arg), data(::boost::type_erasure::call( constructible< typename ::boost::remove_const< typename boost::remove_reference::type >::type(const typename boost::remove_reference::type&) >(), other) ) {} template any(const any& other, binding& binding_arg) : table(binding_arg), data(::boost::type_erasure::call( constructible< typename ::boost::remove_const< typename boost::remove_reference::type >::type(const typename boost::remove_reference::type&) >(), other) ) {} #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES template any(any& other, static_binding&& binding_arg) : table(::boost::type_erasure::detail::access::table(other), binding_arg), data(::boost::type_erasure::call( constructible< typename ::boost::remove_const< typename boost::remove_reference::type >::type(const typename boost::remove_reference::type&) >(), other) ) {} template any(const any& other, static_binding&& binding_arg) : table(::boost::type_erasure::detail::access::table(other), binding_arg), data(::boost::type_erasure::call( constructible< typename ::boost::remove_const< typename boost::remove_reference::type >::type(const typename boost::remove_reference::type&) >(), other) ) {} template any(any&& other, static_binding&& binding_arg) : table(::boost::type_erasure::detail::access::table(other), binding_arg), data(::boost::type_erasure::call( constructible< typename ::boost::remove_const< typename boost::remove_reference::type >::type(const typename boost::remove_reference::type&) >(), std::move(other)) ) {} template any(any&& other, static_binding& binding_arg) : table(::boost::type_erasure::detail::access::table(other), binding_arg), data(::boost::type_erasure::call( constructible< typename ::boost::remove_const< typename boost::remove_reference::type >::type(const typename boost::remove_reference::type&) >(), std::move(other)) ) {} template any(any&& other, const static_binding& binding_arg) : table(::boost::type_erasure::detail::access::table(other), binding_arg), data(::boost::type_erasure::call( constructible< typename ::boost::remove_const< typename boost::remove_reference::type >::type(const typename boost::remove_reference::type&) >(), std::move(other)) ) {} template any(any& other, binding&& binding_arg) : table(binding_arg), data(::boost::type_erasure::call( constructible< typename ::boost::remove_const< typename boost::remove_reference::type >::type(const typename boost::remove_reference::type&) >(), other) ) {} template any(const any& other, binding&& binding_arg) : table(binding_arg), data(::boost::type_erasure::call( constructible< typename ::boost::remove_const< typename boost::remove_reference::type >::type(const typename boost::remove_reference::type&) >(), other) ) {} template any(any&& other, binding&& binding_arg) : table(binding_arg), data(::boost::type_erasure::call( constructible< typename ::boost::remove_const< typename boost::remove_reference::type >::type(const typename boost::remove_reference::type&) >(), std::move(other)) ) {} template any(any&& other, binding& binding_arg) : table(binding_arg), data(::boost::type_erasure::call( constructible< typename ::boost::remove_const< typename boost::remove_reference::type >::type(const typename boost::remove_reference::type&) >(), std::move(other)) ) {} template any(any&& other, const binding& binding_arg) : table(binding_arg), data(::boost::type_erasure::call( constructible< typename ::boost::remove_const< typename boost::remove_reference::type >::type(const typename boost::remove_reference::type&) >(), std::move(other)) ) {} #endif // One argument is a special case. The argument must be an any // and the constructor must be explicit. template explicit any(const any& other) : table(::boost::type_erasure::detail::access::table(other)), data(::boost::type_erasure::call( ::boost::type_erasure::detail::make( false? this->_boost_type_erasure_deduce_constructor(other) : 0 ), other) ) {} template explicit any(any& other) : table(::boost::type_erasure::detail::access::table(other)), data(::boost::type_erasure::call( ::boost::type_erasure::detail::make( false? this->_boost_type_erasure_deduce_constructor(other) : 0 ), other) ) {} #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES template explicit any(any&& other) : table(::boost::type_erasure::detail::access::table(other)), data(::boost::type_erasure::call( ::boost::type_erasure::detail::make( false? this->_boost_type_erasure_deduce_constructor(std::move(other)) : 0 ), std::move(other)) ) {} #endif explicit any(const binding& binding_arg) : table(binding_arg), data( ::boost::type_erasure::call( binding_arg, ::boost::type_erasure::constructible() ) ) {} explicit any(binding& binding_arg) : table(binding_arg), data( ::boost::type_erasure::call( binding_arg, ::boost::type_erasure::constructible() ) ) {} #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES explicit any(binding&& binding_arg) : table(binding_arg), data( ::boost::type_erasure::call( binding_arg, ::boost::type_erasure::constructible() ) ) {} #endif #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) template const table_type& _boost_type_erasure_extract_table( ::boost::type_erasure::constructible*, U&&... u) { return *::boost::type_erasure::detail::extract_table(static_cast(0), u...); } template any(U0&& u0, U1&& u1, U&&... u) : table( _boost_type_erasure_extract_table( false? this->_boost_type_erasure_deduce_constructor(std::forward(u0), std::forward(u1), std::forward(u)...) : 0, std::forward(u0), std::forward(u1), std::forward(u)... ) ), data( ::boost::type_erasure::call( ::boost::type_erasure::detail::make( false? this->_boost_type_erasure_deduce_constructor(std::forward(u0), std::forward(u1), std::forward(u)...) : 0 ), std::forward(u0), std::forward(u1), std::forward(u)... ) ) {} template any(const binding& binding_arg, U0&& u0, U&&... u) : table(binding_arg), data( ::boost::type_erasure::call( binding_arg, ::boost::type_erasure::detail::make( false? this->_boost_type_erasure_deduce_constructor(std::forward(u0), std::forward(u)...) : 0 ), std::forward(u0), std::forward(u)... ) ) {} // disambiguate template any(binding& binding_arg, U0&& u0, U&&... u) : table(binding_arg), data( ::boost::type_erasure::call( binding_arg, ::boost::type_erasure::detail::make( false? this->_boost_type_erasure_deduce_constructor(std::forward(u0), std::forward(u)...) : 0 ), std::forward(u0), std::forward(u)... ) ) {} template any(binding&& binding_arg, U0&& u0, U&&... u) : table(binding_arg), data( ::boost::type_erasure::call( binding_arg, ::boost::type_erasure::detail::make( false? this->_boost_type_erasure_deduce_constructor(std::forward(u0), std::forward(u)...) : 0 ), std::forward(u0), std::forward(u)... ) ) {} #else #include #endif #endif /** * Assigns to an @ref any. * * If an appropriate overload of @ref assignable is not available * and @ref relaxed is in @c Concept, falls back on * constructing from @c other. * * \throws Whatever the assignment operator of the contained * type throws. When falling back on construction, * throws @c std::bad_alloc or whatever the copy * constructor of the contained type throws. In * this case assignment provides the strong exception * guarantee. When calling the assignment operator * of the contained type, the exception guarantee is * whatever the contained type provides. */ any& operator=(const any& other) { _boost_type_erasure_resolve_assign(other); return *this; } /** * Assigns to an @ref any. * * If an appropriate overload of @ref assignable is not available * and @ref relaxed is in @c Concept, falls back on * constructing from @c other. * * \throws Whatever the assignment operator of the contained * type throws. When falling back on construction, * throws @c std::bad_alloc or whatever the copy * constructor of the contained type throws. In * this case assignment provides the strong exception * guarantee. When calling an assignment operator * of the contained type, the exception guarantee is * whatever the contained type provides. */ template any& operator=(const U& other) { _boost_type_erasure_resolve_assign(other); return *this; } /** * \pre @c Concept includes @ref destructible "destructible". */ ~any() { table.template find >()(data); } #ifndef BOOST_NO_FUNCTION_REFERENCE_QUALIFIERS /** INTERNAL ONLY */ operator param() & { return param(data, table); } /** INTERNAL ONLY */ operator param() && { return param(data, table); } #endif private: /** INTERNAL ONLY */ void _boost_type_erasure_swap(any& other) { ::std::swap(data, other.data); ::std::swap(table, other.table); } /** INTERNAL ONLY */ template void _boost_type_erasure_resolve_assign(const Other& other) { _boost_type_erasure_assign_impl( other, false? this->_boost_type_erasure_deduce_assign( ::boost::type_erasure::detail::make_fallback( other, ::boost::mpl::bool_< sizeof( ::boost::type_erasure::detail::check_overload( ::boost::declval(). _boost_type_erasure_deduce_assign(other) ) ) == sizeof(::boost::type_erasure::detail::yes) >() ) ) : 0, ::boost::type_erasure::is_relaxed() ); } /** INTERNAL ONLY */ template void _boost_type_erasure_assign_impl( const Other& other, const assignable*, ::boost::mpl::false_) { ::boost::type_erasure::call(assignable(), *this, other); } /** INTERNAL ONLY */ template void _boost_type_erasure_assign_impl( const Other& other, const assignable*, ::boost::mpl::true_) { ::boost::type_erasure::call(assignable(), *this, other); } /** INTERNAL ONLY */ template void _boost_type_erasure_assign_impl( const Other& other, const void*, ::boost::mpl::true_) { any temp(other); _boost_type_erasure_swap(temp); } /** INTERNAL ONLY */ template void _boost_type_erasure_resolve_assign(const any& other) { _boost_type_erasure_assign_impl( other, false? this->_boost_type_erasure_deduce_assign( ::boost::type_erasure::detail::make_fallback( other, ::boost::mpl::bool_< sizeof( ::boost::type_erasure::detail::check_overload( ::boost::declval(). _boost_type_erasure_deduce_assign(other) ) ) == sizeof(::boost::type_erasure::detail::yes) >() ) ) : 0, false? this->_boost_type_erasure_deduce_constructor( ::boost::type_erasure::detail::make_fallback( other, ::boost::mpl::bool_< sizeof( ::boost::type_erasure::detail::check_overload( ::boost::declval(). _boost_type_erasure_deduce_constructor(other) ) ) == sizeof(::boost::type_erasure::detail::yes) >() ) ) : 0, ::boost::type_erasure::is_relaxed() ); } /** INTERNAL ONLY */ template void _boost_type_erasure_assign_impl( const Other& other, const assignable*, const void*, ::boost::mpl::false_) { ::boost::type_erasure::call(assignable(), *this, other); } /** INTERNAL ONLY */ template void _boost_type_erasure_assign_impl( const Other& other, const assignable*, const void*, ::boost::mpl::true_) { ::boost::type_erasure::call(assignable(), *this, other); } /** INTERNAL ONLY */ template void _boost_type_erasure_assign_impl( const Other& other, const void*, const constructible*, ::boost::mpl::true_) { any temp(other); _boost_type_erasure_swap(temp); } /** INTERNAL ONLY */ template void _boost_type_erasure_assign_impl( const Other& other, const assignable*, const constructible*, ::boost::mpl::true_) { if(::boost::type_erasure::check_match(assignable(), *this, other)) { ::boost::type_erasure::unchecked_call(assignable(), *this, other); } else { any temp(other); _boost_type_erasure_swap(temp); } } friend struct ::boost::type_erasure::detail::access; // The table has to be initialized first for exception // safety in some constructors. table_type table; ::boost::type_erasure::detail::storage data; }; template class any : public ::boost::type_erasure::detail::compute_bases< ::boost::type_erasure::any, Concept, T >::type { typedef ::boost::type_erasure::binding table_type; public: /** INTERNAL ONLY */ typedef Concept _boost_type_erasure_concept_type; /** INTERNAL ONLY */ any(const ::boost::type_erasure::detail::storage& data_arg, const table_type& table_arg) : data(data_arg), table(table_arg) {} /** * Constructs an @ref any from a reference. * * \param arg The object to bind the reference to. * * \pre @c U is a model of @c Concept. * \pre @c Concept must not refer to any non-deduced placeholder besides @c T. * * \throws Nothing. */ template any(U& arg #ifndef BOOST_TYPE_ERASURE_DOXYGEN , typename ::boost::disable_if< ::boost::mpl::or_< ::boost::is_const, ::boost::type_erasure::detail::is_any > >::type* = 0 #endif ) : table(( BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, U), ::boost::type_erasure::make_binding< ::boost::mpl::map< ::boost::mpl::pair > >() )) { data.data = ::boost::addressof(arg); } /** * Constructs an @ref any from a reference. * * \param arg The object to bind the reference to. * \param binding Specifies the actual types that * all the placeholders should bind to. * * \pre @c U is a model of @c Concept. * \pre @c Map is an MPL map with an entry for every * non-deduced placeholder referred to by @c Concept. * * \throws Nothing. */ template any(U& arg, const static_binding& binding_arg) : table(( BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map), binding_arg )) { BOOST_MPL_ASSERT((::boost::is_same< typename ::boost::mpl::at::type, U>)); data.data = ::boost::addressof(arg); } /** * Constructs an @ref any from another reference. * * \param other The reference to copy. * * \throws Nothing. */ any(const any& other) : data(other.data), table(other.table) {} #ifndef BOOST_TYPE_ERASURE_DOXYGEN any(any& other) : data(other.data), table(other.table) {} #endif /** * Constructs an @ref any from another @ref any. * * \param other The object to bind the reference to. * * \throws Nothing. */ any(any& other) : data(::boost::type_erasure::detail::access::data(other)), table(::boost::type_erasure::detail::access::table(other)) {} /** * Constructs an @ref any from another reference. * * \param other The reference to copy. * * \pre @c Concept must not refer to any non-deduced placeholder besides @c T. * \pre After substituting @c T for @c Tag2, the requirements of * @c Concept2 must be a superset of the requirements of * @c Concept. * * \throws std::bad_alloc */ template any(const any& other #ifndef BOOST_TYPE_ERASURE_DOXYGEN , typename ::boost::disable_if< ::boost::mpl::or_< ::boost::is_same, ::boost::is_const > >::type* = 0 #endif ) : data(::boost::type_erasure::detail::access::data(other)), table( ::boost::type_erasure::detail::access::table(other), ::boost::mpl::map< ::boost::mpl::pair< T, Tag2 > >()) {} /** * Constructs an @ref any from another @ref any. * * \param other The object to bind the reference to. * * \pre @c Concept must not refer to any non-deduced placeholder besides @c T. * \pre After substituting @c T for @c Tag2, the requirements of * @c Concept2 must be a superset of the requirements of * @c Concept. * * \throws std::bad_alloc */ template any(any& other #ifndef BOOST_TYPE_ERASURE_DOXYGEN , typename ::boost::disable_if< ::boost::mpl::or_< ::boost::is_same, ::boost::is_const::type> > >::type* = 0 #endif ) : data(::boost::type_erasure::detail::access::data(other)), table( ::boost::type_erasure::detail::access::table(other), ::boost::mpl::map< ::boost::mpl::pair< T, typename ::boost::remove_reference::type > >()) {} /** * Constructs an @ref any from another reference. * * \param other The reference to copy. * \param binding Specifies the mapping between the two concepts. * * \pre @c Map must be an MPL map with keys for all the non-deduced * placeholders used by @c Concept and values for the corresponding * placeholders in @c Concept2. * \pre After substituting placeholders according to @c Map, the * requirements of @c Concept2 must be a superset of the * requirements of @c Concept. * * \throws std::bad_alloc */ template any(const any& other, const static_binding& binding_arg #ifndef BOOST_TYPE_ERASURE_DOXYGEN , typename ::boost::disable_if< ::boost::is_const >::type* = 0 #endif ) : data(::boost::type_erasure::detail::access::data(other)), table(::boost::type_erasure::detail::access::table(other), binding_arg) {} /** * Constructs an @ref any from another @ref any. * * \param other The object to bind the reference to. * \param binding Specifies the mapping between the two concepts. * * \pre @c Map must be an MPL map with keys for all the non-deduced * placeholders used by @c Concept and values for the corresponding * placeholders in @c Concept2. * \pre After substituting placeholders according to @c Map, the * requirements of @c Concept2 must be a superset of the * requirements of @c Concept. * * \throws std::bad_alloc */ template any(any& other, const static_binding& binding_arg #ifndef BOOST_TYPE_ERASURE_DOXYGEN , typename ::boost::disable_if< ::boost::is_const::type> >::type* = 0 #endif ) : data(::boost::type_erasure::detail::access::data(other)), table(::boost::type_erasure::detail::access::table(other), binding_arg) {} /** * Constructs an @ref any from another reference. * * \param other The reference to copy. * \param binding Specifies the bindings of placeholders to actual types. * * \pre The type stored in @c other must match the type expected by * @c binding. * * \post binding_of(*this) == @c binding * * \throws Nothing. */ template any(const any& other, const binding& binding_arg #ifndef BOOST_TYPE_ERASURE_DOXYGEN , typename ::boost::disable_if< ::boost::is_const >::type* = 0 #endif ) : data(::boost::type_erasure::detail::access::data(other)), table(binding_arg) {} /** * Constructs an @ref any from another @ref any. * * \param other The object to bind the reference to. * \param binding Specifies the bindings of placeholders to actual types. * * \pre The type stored in @c other must match the type expected by * @c binding. * * \post binding_of(*this) == @c binding * * \throws Nothing. */ template any(any& other, const binding& binding_arg #ifndef BOOST_TYPE_ERASURE_DOXYGEN , typename ::boost::disable_if< ::boost::is_const::type> >::type* = 0 #endif ) : data(::boost::type_erasure::detail::access::data(other)), table(binding_arg) {} /** * Assigns to an @ref any. * * If an appropriate overload of @ref assignable is not available * and @ref relaxed is in @c Concept, falls back on * constructing from @c other. * * \throws Whatever the assignment operator of the contained * type throws. When falling back on construction, * throws @c std::bad_alloc. In this case assignment * provides the strong exception guarantee. When * calling the assignment operator of the contained type, * the exception guarantee is whatever the contained type provides. */ any& operator=(const any& other) { _boost_type_erasure_resolve_assign(other); return *this; } /** * Assigns to an @ref any. * * If an appropriate overload of @ref assignable is not available * and @ref relaxed is in @c Concept, falls back on * constructing from @c other. * * \throws Whatever the assignment operator of the contained * type throws. When falling back on construction, * throws @c std::bad_alloc. In this case assignment * provides the strong exception guarantee. When * calling the assignment operator of the contained type, * the exception guarantee is whatever the contained type provides. */ template any& operator=(U& other) { _boost_type_erasure_resolve_assign(other); return *this; } /** * Assigns to an @ref any. * * If an appropriate overload of @ref assignable is not available * and @ref relaxed is in @c Concept, falls back on * constructing from @c other. * * \throws Whatever the assignment operator of the contained * type throws. When falling back on construction, * throws @c std::bad_alloc. In this case assignment * provides the strong exception guarantee. When * calling the assignment operator of the contained type, * the exception guarantee is whatever the contained type provides. */ template any& operator=(const U& other) { _boost_type_erasure_resolve_assign(other); return *this; } #ifndef BOOST_NO_FUNCTION_REFERENCE_QUALIFIERS /** INTERNAL ONLY */ operator param() const { return param(data, table); } #endif private: /** INTERNAL ONLY */ void _boost_type_erasure_swap(any& other) { ::std::swap(data, other.data); ::std::swap(table, other.table); } /** INTERNAL ONLY */ template void _boost_type_erasure_resolve_assign(Other& other) { _boost_type_erasure_assign_impl( other, false? this->_boost_type_erasure_deduce_assign( ::boost::type_erasure::detail::make_fallback( other, ::boost::mpl::bool_< sizeof( ::boost::type_erasure::detail::check_overload( ::boost::declval(). _boost_type_erasure_deduce_assign(other) ) ) == sizeof(::boost::type_erasure::detail::yes) >() ) ) : 0, ::boost::type_erasure::is_relaxed() ); } /** INTERNAL ONLY */ template void _boost_type_erasure_assign_impl( Other& other, const assignable*, ::boost::mpl::false_) { ::boost::type_erasure::call(assignable(), *this, other); } /** INTERNAL ONLY */ template void _boost_type_erasure_assign_impl( Other& other, const assignable*, ::boost::mpl::true_) { if(::boost::type_erasure::check_match(assignable(), *this, other)) { ::boost::type_erasure::unchecked_call(assignable(), *this, other); } else { any temp(other); _boost_type_erasure_swap(temp); } } /** INTERNAL ONLY */ template void _boost_type_erasure_assign_impl( Other& other, const void*, ::boost::mpl::true_) { any temp(other); _boost_type_erasure_swap(temp); } friend struct ::boost::type_erasure::detail::access; ::boost::type_erasure::detail::storage data; table_type table; }; #ifdef BOOST_MSVC #pragma warning(pop) #endif template class any : public ::boost::type_erasure::detail::compute_bases< ::boost::type_erasure::any, Concept, T >::type { typedef ::boost::type_erasure::binding table_type; public: /** INTERNAL ONLY */ typedef Concept _boost_type_erasure_concept_type; /** INTERNAL ONLY */ any(const ::boost::type_erasure::detail::storage& data_arg, const table_type& table_arg) : data(data_arg), table(table_arg) {} /** * Constructs an @ref any from a reference. * * \param arg The object to bind the reference to. * * \pre @c U is a model of @c Concept. * \pre @c Concept must not refer to any non-deduced placeholder besides @c T. * * \throws Nothing. */ template any(const U& arg) : table(( BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, U), ::boost::type_erasure::make_binding< ::boost::mpl::map< ::boost::mpl::pair > >() )) { data.data = const_cast(static_cast(::boost::addressof(arg))); } /** * Constructs an @ref any from a reference. * * \param arg The object to bind the reference to. * \param binding Specifies the actual types that * all the placeholders should bind to. * * \pre @c U is a model of @c Concept. * \pre @c Map is an MPL map with an entry for every * non-deduced placeholder referred to by @c Concept. * * \throws Nothing. */ template any(const U& arg, const static_binding& binding_arg) : table(( BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map), binding_arg )) { BOOST_MPL_ASSERT((::boost::is_same< typename ::boost::mpl::at::type, U>)); data.data = const_cast(static_cast(::boost::addressof(arg))); } /** * Constructs an @ref any from another @ref any. * * \param other The reference to copy. * * \throws Nothing. */ any(const any& other) : data(other.data), table(other.table) {} /** * Constructs an @ref any from another @ref any. * * \param other The reference to copy. * * \throws Nothing. */ any(const any& other) : data(::boost::type_erasure::detail::access::data(other)), table(::boost::type_erasure::detail::access::table(other)) {} /** * Constructs an @ref any from another @ref any. * * \param other The object to bind the reference to. * * \throws Nothing. */ any(const any& other) : data(::boost::type_erasure::detail::access::data(other)), table(::boost::type_erasure::detail::access::table(other)) {} #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES /** * Constructs an @ref any from another @ref any. * * \param other The object to bind the reference to. * * \throws Nothing. */ any(const any& other) : data(::boost::type_erasure::detail::access::data(other)), table(::boost::type_erasure::detail::access::table(other)) {} #endif /** * Constructs an @ref any from another @ref any. * * \param other The object to bind the reference to. * * \pre @c Concept must not refer to any non-deduced placeholder besides @c T. * \pre After substituting @c T for @c Tag2, the requirements of * @c Concept2 must be a superset of the requirements of * @c Concept. * * \throws std::bad_alloc */ template any(const any& other #ifndef BOOST_TYPE_ERASURE_DOXYGEN , typename ::boost::disable_if< ::boost::is_same >::type* = 0 #endif ) : data(::boost::type_erasure::detail::access::data(other)), table( ::boost::type_erasure::detail::access::table(other), ::boost::mpl::map< ::boost::mpl::pair< T, typename ::boost::remove_const< typename ::boost::remove_reference::type >::type > >()) {} /** * Constructs an @ref any from another @ref any. * * \param other The object to bind the reference to. * \param binding Specifies the mapping between the two concepts. * * \pre @c Map must be an MPL map with keys for all the non-deduced * placeholders used by @c Concept and values for the corresponding * placeholders in @c Concept2. * \pre After substituting placeholders according to @c Map, the * requirements of @c Concept2 must be a superset of the * requirements of @c Concept. * * \throws std::bad_alloc */ template any(const any& other, const static_binding& binding_arg) : data(::boost::type_erasure::detail::access::data(other)), table(::boost::type_erasure::detail::access::table(other), binding_arg) {} /** * Constructs an @ref any from another @ref any. * * \param other The object to bind the reference to. * \param binding Specifies the bindings of placeholders to actual types. * * \pre The type stored in @c other must match the type expected by * @c binding. * * \post binding_of(*this) == @c binding * * \throws Nothing. */ template any(const any& other, const binding& binding_arg) : data(::boost::type_erasure::detail::access::data(other)), table(binding_arg) {} /** * Assigns to an @ref any. * * \pre @ref relaxed is in @c Concept. * * \throws Nothing. */ any& operator=(const any& other) { BOOST_MPL_ASSERT((::boost::type_erasure::is_relaxed)); any temp(other); _boost_type_erasure_swap(temp); return *this; } /** * Assigns to an @ref any. * * \pre @ref relaxed is in @c Concept. * * \throws std::bad_alloc. Provides the strong exception guarantee. */ template any& operator=(const U& other) { BOOST_MPL_ASSERT((::boost::type_erasure::is_relaxed)); any temp(other); _boost_type_erasure_swap(temp); return *this; } #ifndef BOOST_NO_FUNCTION_REFERENCE_QUALIFIERS /** INTERNAL ONLY */ operator param() const { return param(data, table); } #endif private: /** INTERNAL ONLY */ void _boost_type_erasure_swap(any& other) { ::std::swap(data, other.data); ::std::swap(table, other.table); } friend struct ::boost::type_erasure::detail::access; ::boost::type_erasure::detail::storage data; table_type table; }; #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES template class any : public ::boost::type_erasure::detail::compute_bases< ::boost::type_erasure::any, Concept, T >::type { typedef ::boost::type_erasure::binding table_type; public: /** INTERNAL ONLY */ typedef Concept _boost_type_erasure_concept_type; /** INTERNAL ONLY */ any(const ::boost::type_erasure::detail::storage& data_arg, const table_type& table_arg) : data(data_arg), table(table_arg) {} /** * Constructs an @ref any from a reference. * * \param arg The object to bind the reference to. * * \pre @c U is a model of @c Concept. * \pre @c Concept must not refer to any non-deduced placeholder besides @c T. * * \throws Nothing. */ template any(U&& arg #ifndef BOOST_TYPE_ERASURE_DOXYGEN , typename ::boost::disable_if< ::boost::mpl::or_< ::boost::is_reference, ::boost::is_const, ::boost::type_erasure::detail::is_any > >::type* = 0 #endif ) : table(( BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, U), ::boost::type_erasure::make_binding< ::boost::mpl::map< ::boost::mpl::pair > >() )) { data.data = ::boost::addressof(arg); } /** * Constructs an @ref any from a reference. * * \param arg The object to bind the reference to. * \param binding Specifies the actual types that * all the placeholders should bind to. * * \pre @c U is a model of @c Concept. * \pre @c Map is an MPL map with an entry for every * non-deduced placeholder referred to by @c Concept. * * \throws Nothing. */ template any(U&& arg, const static_binding& binding_arg) : table(( BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map), binding_arg )) { BOOST_MPL_ASSERT((::boost::is_same< typename ::boost::mpl::at::type, U>)); data.data = ::boost::addressof(arg); } /** * Constructs an @ref any from another rvalue reference. * * \param other The reference to copy. * * \throws Nothing. */ #ifndef BOOST_TYPE_ERASURE_DOXYGEN any(any&& other) : data(other.data), table(std::move(other.table)) {} any(const any& other) : data(other.data), table(other.table) {} #endif /** * Constructs an @ref any from another @ref any. * * \param other The object to bind the reference to. * * \throws Nothing. */ any(any&& other) : data(::boost::type_erasure::detail::access::data(other)), table(std::move(::boost::type_erasure::detail::access::table(other))) {} /** * Constructs an @ref any from another rvalue reference. * * \param other The reference to copy. * * \pre @c Concept must not refer to any non-deduced placeholder besides @c T. * \pre After substituting @c T for @c Tag2, the requirements of * @c Concept2 must be a superset of the requirements of * @c Concept. * * \throws std::bad_alloc */ template any(any&& other #ifndef BOOST_TYPE_ERASURE_DOXYGEN , typename ::boost::disable_if< ::boost::mpl::or_< ::boost::is_reference, ::boost::is_same, ::boost::is_const > >::type* = 0 #endif ) : data(::boost::type_erasure::detail::access::data(other)), table( std::move(::boost::type_erasure::detail::access::table(other)), ::boost::mpl::map< ::boost::mpl::pair< T, Tag2 > >()) {} /** * Constructs an @ref any from another @ref any. * * \param other The object to bind the reference to. * * \pre @c Concept must not refer to any non-deduced placeholder besides @c T. * \pre After substituting @c T for @c Tag2, the requirements of * @c Concept2 must be a superset of the requirements of * @c Concept. * * \throws std::bad_alloc */ template any(any&& other #ifndef BOOST_TYPE_ERASURE_DOXYGEN , typename ::boost::disable_if< ::boost::mpl::or_< ::boost::is_same, ::boost::is_const::type> > >::type* = 0 #endif ) : data(::boost::type_erasure::detail::access::data(other)), table( std::move(::boost::type_erasure::detail::access::table(other)), ::boost::mpl::map< ::boost::mpl::pair< T, typename ::boost::remove_reference::type > >()) {} /** * Constructs an @ref any from another reference. * * \param other The reference to copy. * \param binding Specifies the mapping between the two concepts. * * \pre @c Map must be an MPL map with keys for all the non-deduced * placeholders used by @c Concept and values for the corresponding * placeholders in @c Concept2. * \pre After substituting placeholders according to @c Map, the * requirements of @c Concept2 must be a superset of the * requirements of @c Concept. * * \throws std::bad_alloc */ template any(const any& other, const static_binding& binding_arg #ifndef BOOST_TYPE_ERASURE_DOXYGEN , typename ::boost::disable_if< ::boost::is_const >::type* = 0 #endif ) : data(::boost::type_erasure::detail::access::data(other)), table(std::move(::boost::type_erasure::detail::access::table(other)), binding_arg) {} /** * Constructs an @ref any from another @ref any. * * \param other The object to bind the reference to. * \param binding Specifies the mapping between the two concepts. * * \pre @c Map must be an MPL map with keys for all the non-deduced * placeholders used by @c Concept and values for the corresponding * placeholders in @c Concept2. * \pre After substituting placeholders according to @c Map, the * requirements of @c Concept2 must be a superset of the * requirements of @c Concept. * * \throws std::bad_alloc */ template any(any&& other, const static_binding& binding_arg #ifndef BOOST_TYPE_ERASURE_DOXYGEN , typename ::boost::disable_if< ::boost::is_const::type> >::type* = 0 #endif ) : data(::boost::type_erasure::detail::access::data(other)), table(::boost::type_erasure::detail::access::table(other), binding_arg) {} /** * Constructs an @ref any from another rvalue reference. * * \param other The reference to copy. * \param binding Specifies the bindings of placeholders to actual types. * * \pre The type stored in @c other must match the type expected by * @c binding. * * \post binding_of(*this) == @c binding * * \throws Nothing. */ template any(const any& other, const binding& binding_arg #ifndef BOOST_TYPE_ERASURE_DOXYGEN , typename ::boost::disable_if< ::boost::is_const >::type* = 0 #endif ) : data(::boost::type_erasure::detail::access::data(other)), table(binding_arg) {} /** * Constructs an @ref any from another @ref any. * * \param other The object to bind the reference to. * \param binding Specifies the bindings of placeholders to actual types. * * \pre The type stored in @c other must match the type expected by * @c binding. * * \post binding_of(*this) == @c binding * * \throws Nothing. */ template any(any&& other, const binding& binding_arg #ifndef BOOST_TYPE_ERASURE_DOXYGEN , typename ::boost::disable_if< ::boost::is_const::type> >::type* = 0 #endif ) : data(::boost::type_erasure::detail::access::data(other)), table(binding_arg) {} /** * Assigns to an @ref any. * * If an appropriate overload of @ref assignable is not available * and @ref relaxed is in @c Concept, falls back on * constructing from @c other. * * \throws Whatever the assignment operator of the contained * type throws. When falling back on construction, * throws @c std::bad_alloc. In this case assignment * provides the strong exception guarantee. When * calling the assignment operator of the contained type, * the exception guarantee is whatever the contained type provides. */ any& operator=(const any& other) { _boost_type_erasure_resolve_assign(other); return *this; } /** * Assigns to an @ref any. * * If an appropriate overload of @ref assignable is not available * and @ref relaxed is in @c Concept, falls back on * constructing from @c other. * * \throws Whatever the assignment operator of the contained * type throws. When falling back on construction, * throws @c std::bad_alloc. In this case assignment * provides the strong exception guarantee. When * calling the assignment operator of the contained type, * the exception guarantee is whatever the contained type provides. */ template any& operator=(U& other) { _boost_type_erasure_resolve_assign(other); return *this; } /** * Assigns to an @ref any. * * If an appropriate overload of @ref assignable is not available * and @ref relaxed is in @c Concept, falls back on * constructing from @c other. * * \throws Whatever the assignment operator of the contained * type throws. When falling back on construction, * throws @c std::bad_alloc. In this case assignment * provides the strong exception guarantee. When * calling the assignment operator of the contained type, * the exception guarantee is whatever the contained type provides. */ template any& operator=(const U& other) { _boost_type_erasure_resolve_assign(other); return *this; } #ifndef BOOST_NO_FUNCTION_REFERENCE_QUALIFIERS /** INTERNAL ONLY */ operator param() const { return param(data, table); } #endif private: /** INTERNAL ONLY */ void _boost_type_erasure_swap(any& other) { ::std::swap(data, other.data); ::std::swap(table, other.table); } /** INTERNAL ONLY */ template void _boost_type_erasure_resolve_assign(Other& other) { _boost_type_erasure_assign_impl( other, false? this->_boost_type_erasure_deduce_assign( ::boost::type_erasure::detail::make_fallback( other, ::boost::mpl::bool_< sizeof( ::boost::type_erasure::detail::check_overload( ::boost::declval(). _boost_type_erasure_deduce_assign(other) ) ) == sizeof(::boost::type_erasure::detail::yes) >() ) ) : 0, ::boost::type_erasure::is_relaxed() ); } /** INTERNAL ONLY */ template void _boost_type_erasure_assign_impl( Other& other, const assignable*, ::boost::mpl::false_) { ::boost::type_erasure::call(assignable(), *this, other); } /** INTERNAL ONLY */ template void _boost_type_erasure_assign_impl( Other& other, const assignable*, ::boost::mpl::true_) { if(::boost::type_erasure::check_match(assignable(), *this, other)) { ::boost::type_erasure::unchecked_call(assignable(), *this, other); } else { any temp(other); _boost_type_erasure_swap(temp); } } /** INTERNAL ONLY */ template void _boost_type_erasure_assign_impl( Other& other, const void*, ::boost::mpl::true_) { any temp(other); _boost_type_erasure_swap(temp); } friend struct ::boost::type_erasure::detail::access; ::boost::type_erasure::detail::storage data; table_type table; }; #endif } } #endif