diff options
Diffstat (limited to 'boost/type_erasure/any.hpp')
-rw-r--r-- | boost/type_erasure/any.hpp | 2208 |
1 files changed, 2208 insertions, 0 deletions
diff --git a/boost/type_erasure/any.hpp b/boost/type_erasure/any.hpp new file mode 100644 index 0000000000..3ed0243498 --- /dev/null +++ b/boost/type_erasure/any.hpp @@ -0,0 +1,2208 @@ +// 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 <algorithm> +#include <boost/config.hpp> +#include <boost/utility/enable_if.hpp> +#include <boost/utility/addressof.hpp> +#include <boost/utility/declval.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/mpl/or.hpp> +#include <boost/mpl/pair.hpp> +#include <boost/mpl/map.hpp> +#include <boost/mpl/fold.hpp> +#include <boost/type_traits/remove_reference.hpp> +#include <boost/type_traits/remove_const.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/type_traits/is_const.hpp> +#include <boost/preprocessor/cat.hpp> +#include <boost/preprocessor/iteration/iterate.hpp> +#include <boost/preprocessor/repetition/enum_params.hpp> +#include <boost/preprocessor/repetition/enum_binary_params.hpp> +#include <boost/preprocessor/repetition/enum_trailing_params.hpp> +#include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp> +#include <boost/type_erasure/detail/access.hpp> +#include <boost/type_erasure/detail/any_base.hpp> +#include <boost/type_erasure/detail/normalize.hpp> +#include <boost/type_erasure/detail/storage.hpp> +#include <boost/type_erasure/detail/instantiate.hpp> +#include <boost/type_erasure/config.hpp> +#include <boost/type_erasure/binding.hpp> +#include <boost/type_erasure/static_binding.hpp> +#include <boost/type_erasure/concept_interface.hpp> +#include <boost/type_erasure/call.hpp> +#include <boost/type_erasure/relaxed.hpp> +#include <boost/type_erasure/param.hpp> + +namespace boost { +namespace type_erasure { + +template<class Sig> +struct constructible; + +template<class T> +struct destructible; + +template<class T, class U> +struct assignable; + +namespace detail { + +template<class Derived, class Concept, class T> +struct compute_bases +{ + typedef typename ::boost::mpl::fold< + typename ::boost::type_erasure::detail::collect_concepts< + Concept + >::type, + ::boost::type_erasure::any_base<Derived>, + ::boost::type_erasure::concept_interface< + ::boost::mpl::_2, + ::boost::mpl::_1, + T + > + >::type type; +}; + +template<class T> +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<class Op> +yes check_overload(const Op*); +no check_overload(const void*); + +struct fallback {}; + +template<class T> +fallback make_fallback(const T&, boost::mpl::false_) +{ + return fallback(); +} + +template<class T> +const T& make_fallback(const T& arg, boost::mpl::true_) +{ + return arg; +} + +template<class T> +struct is_any : ::boost::mpl::false_ {}; + +template<class Concept, class T> +struct is_any<any<Concept, T> > : ::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 Concept, class T = _self> +class any : + public ::boost::type_erasure::detail::compute_bases< + ::boost::type_erasure::any<Concept, T>, + Concept, + T + >::type +{ + typedef ::boost::type_erasure::binding<Concept> 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<Concept>)); + data.data = 0; + } + +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + + template<class U> + any(const U& data_arg) + : table(( + BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, U), + ::boost::type_erasure::make_binding< + ::boost::mpl::map< ::boost::mpl::pair<T, U> > + >() + )), + data(data_arg) + {} + template<class U, class Map> + any(const U& data_arg, const static_binding<Map>& binding_arg) + : table(( + BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map), + binding_arg + )), + data(data_arg) + { + BOOST_MPL_ASSERT((::boost::is_same< + typename ::boost::mpl::at<Map, T>::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<class U> + any(U&& data_arg) + : table(( + BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, typename ::boost::remove_cv<typename ::boost::remove_reference<U>::type>::type), + ::boost::type_erasure::make_binding< + ::boost::mpl::map< ::boost::mpl::pair<T, typename ::boost::remove_cv<typename ::boost::remove_reference<U>::type>::type> > + >() + )), + data(std::forward<U>(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<class U, class Map> + any(U&& data_arg, const static_binding<Map>& binding_arg) + : table(( + BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map), + binding_arg + )), + data(std::forward<U>(data_arg)) + { + BOOST_MPL_ASSERT((::boost::is_same< + typename ::boost::mpl::at<Map, T>::type, typename ::boost::remove_cv<typename ::boost::remove_reference<U>::type>::type>)); + } + +#endif + + // Handle array/function-to-pointer decay + /** INTERNAL ONLY */ + template<class U> + any(U* data_arg) + : table(( + BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, U*), + ::boost::type_erasure::make_binding< + ::boost::mpl::map< ::boost::mpl::pair<T, U*> > + >() + )), + data(data_arg) + {} + /** INTERNAL ONLY */ + template<class U, class Map> + any(U* data_arg, const static_binding<Map>& binding_arg) + : table(( + BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map), + binding_arg + )), + data(data_arg) + { + BOOST_MPL_ASSERT((::boost::is_same< + typename ::boost::mpl::at<Map, T>::type, U*>)); + } + /** + * Copies an @ref any. + * + * \param other The object to make a copy of. + * + * \pre @c Concept must contain @ref constructible "constructible<T(const T&)>". + * (This is included in @ref copy_constructible "copy_constructible<T>") + * + * \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<T(const T&)>(), 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<T(const T&)>. + * \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<class Concept2, class Tag2> + any(const any<Concept2, Tag2>& other) + : table( + ::boost::type_erasure::detail::access::table(other), + ::boost::mpl::map< + ::boost::mpl::pair< + T, + typename ::boost::remove_const< + typename ::boost::remove_reference<Tag2>::type + >::type + > + >() + ), + data(::boost::type_erasure::call( + constructible< + typename ::boost::remove_const< + typename boost::remove_reference<Tag2>::type + >::type(const typename boost::remove_reference<Tag2>::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<T(const T&)>. + * \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<class Concept2, class Tag2, class Map> + any(const any<Concept2, Tag2>& other, const static_binding<Map>& 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<Tag2>::type + >::type(const typename boost::remove_reference<Tag2>::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<T(const T&)>. + * \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<class Concept2, class Tag2> + any(const any<Concept2, Tag2>& other, const binding<Concept>& binding_arg) + : table(binding_arg), + data(::boost::type_erasure::call( + constructible< + typename ::boost::remove_const< + typename boost::remove_reference<Tag2>::type + >::type(const typename boost::remove_reference<Tag2>::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<class... U> + 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<class... U> + explicit any(const binding<Concept>& 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<class Concept2, class Tag2> + any(any<Concept2, Tag2>& other) + : table( + ::boost::type_erasure::detail::access::table(other), + ::boost::mpl::map< + ::boost::mpl::pair< + T, + typename ::boost::remove_const< + typename ::boost::remove_reference<Tag2>::type + >::type + > + >() + ), + data(::boost::type_erasure::call( + ::boost::type_erasure::detail::make( + false? other._boost_type_erasure_deduce_constructor(other) : 0 + ), other) + ) + {} + template<class Concept2, class Tag2> + any(any<Concept2, Tag2>&& other) + : table( + ::boost::type_erasure::detail::access::table(other), + ::boost::mpl::map< + ::boost::mpl::pair< + T, + typename ::boost::remove_const< + typename ::boost::remove_reference<Tag2>::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<Concept, T&>& 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<Concept, T&>& 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<Concept, T&>&& 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<Concept, const T&>& 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<Concept, const T&>& 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<Concept, const T&>&& 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<class U, class Map> + any(U* data_arg, static_binding<Map>& binding_arg) + : table(( + BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map), + binding_arg + )), + data(data_arg) + { + BOOST_MPL_ASSERT((::boost::is_same< + typename ::boost::mpl::at<Map, T>::type, U*>)); + } +#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES + template<class U, class Map> + any(U& data_arg, static_binding<Map>& binding_arg) + : table(( + BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map), + binding_arg + )), + data(data_arg) + { + BOOST_MPL_ASSERT((::boost::is_same< + typename ::boost::mpl::at<Map, T>::type, U>)); + } + template<class U, class Map> + any(const U& data_arg, static_binding<Map>& binding_arg) + : table(( + BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map), + binding_arg + )), + data(data_arg) + { + BOOST_MPL_ASSERT((::boost::is_same< + typename ::boost::mpl::at<Map, T>::type, U>)); + } + template<class U, class Map> + any(U& data_arg, const static_binding<Map>& binding_arg) + : table(( + BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map), + binding_arg + )), + data(data_arg) + { + BOOST_MPL_ASSERT((::boost::is_same< + typename ::boost::mpl::at<Map, T>::type, U>)); + } +#endif +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template<class U, class Map> + any(U* data_arg, static_binding<Map>&& binding_arg) + : table(( + BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map), + binding_arg + )), + data(data_arg) + { + BOOST_MPL_ASSERT((::boost::is_same< + typename ::boost::mpl::at<Map, T>::type, U*>)); + } + template<class U, class Map> + any(U&& data_arg, static_binding<Map>& binding_arg) + : table(( + BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map), + binding_arg + )), + data(data_arg) + { + BOOST_MPL_ASSERT((::boost::is_same< + typename ::boost::mpl::at<Map, T>::type, typename ::boost::remove_cv<typename ::boost::remove_reference<U>::type>::type>)); + } + template<class U, class Map> + any(U&& data_arg, static_binding<Map>&& binding_arg) + : table(( + BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map), + binding_arg + )), + data(data_arg) + { + BOOST_MPL_ASSERT((::boost::is_same< + typename ::boost::mpl::at<Map, T>::type, typename ::boost::remove_cv<typename ::boost::remove_reference<U>::type>::type>)); + } +#endif + template<class Concept2, class Tag2, class Map> + any(any<Concept2, Tag2>& other, static_binding<Map>& 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<Tag2>::type + >::type(const typename boost::remove_reference<Tag2>::type&) + >(), other) + ) + {} + template<class Concept2, class Tag2, class Map> + any(any<Concept2, Tag2>& other, const static_binding<Map>& 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<Tag2>::type + >::type(const typename boost::remove_reference<Tag2>::type&) + >(), other) + ) + {} + template<class Concept2, class Tag2, class Map> + any(const any<Concept2, Tag2>& other, static_binding<Map>& 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<Tag2>::type + >::type(const typename boost::remove_reference<Tag2>::type&) + >(), other) + ) + {} + template<class Concept2, class Tag2> + any(any<Concept2, Tag2>& other, binding<Concept>& binding_arg) + : table(binding_arg), + data(::boost::type_erasure::call( + constructible< + typename ::boost::remove_const< + typename boost::remove_reference<Tag2>::type + >::type(const typename boost::remove_reference<Tag2>::type&) + >(), other) + ) + {} + template<class Concept2, class Tag2> + any(any<Concept2, Tag2>& other, const binding<Concept>& binding_arg) + : table(binding_arg), + data(::boost::type_erasure::call( + constructible< + typename ::boost::remove_const< + typename boost::remove_reference<Tag2>::type + >::type(const typename boost::remove_reference<Tag2>::type&) + >(), other) + ) + {} + template<class Concept2, class Tag2> + any(const any<Concept2, Tag2>& other, binding<Concept>& binding_arg) + : table(binding_arg), + data(::boost::type_erasure::call( + constructible< + typename ::boost::remove_const< + typename boost::remove_reference<Tag2>::type + >::type(const typename boost::remove_reference<Tag2>::type&) + >(), other) + ) + {} + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template<class Concept2, class Tag2, class Map> + any(any<Concept2, Tag2>& other, static_binding<Map>&& 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<Tag2>::type + >::type(const typename boost::remove_reference<Tag2>::type&) + >(), other) + ) + {} + template<class Concept2, class Tag2, class Map> + any(const any<Concept2, Tag2>& other, static_binding<Map>&& 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<Tag2>::type + >::type(const typename boost::remove_reference<Tag2>::type&) + >(), other) + ) + {} + template<class Concept2, class Tag2, class Map> + any(any<Concept2, Tag2>&& other, static_binding<Map>&& 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<Tag2>::type + >::type(const typename boost::remove_reference<Tag2>::type&) + >(), std::move(other)) + ) + {} + template<class Concept2, class Tag2, class Map> + any(any<Concept2, Tag2>&& other, static_binding<Map>& 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<Tag2>::type + >::type(const typename boost::remove_reference<Tag2>::type&) + >(), std::move(other)) + ) + {} + template<class Concept2, class Tag2, class Map> + any(any<Concept2, Tag2>&& other, const static_binding<Map>& 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<Tag2>::type + >::type(const typename boost::remove_reference<Tag2>::type&) + >(), std::move(other)) + ) + {} + template<class Concept2, class Tag2> + any(any<Concept2, Tag2>& other, binding<Concept>&& binding_arg) + : table(binding_arg), + data(::boost::type_erasure::call( + constructible< + typename ::boost::remove_const< + typename boost::remove_reference<Tag2>::type + >::type(const typename boost::remove_reference<Tag2>::type&) + >(), other) + ) + {} + template<class Concept2, class Tag2> + any(const any<Concept2, Tag2>& other, binding<Concept>&& binding_arg) + : table(binding_arg), + data(::boost::type_erasure::call( + constructible< + typename ::boost::remove_const< + typename boost::remove_reference<Tag2>::type + >::type(const typename boost::remove_reference<Tag2>::type&) + >(), other) + ) + {} + template<class Concept2, class Tag2> + any(any<Concept2, Tag2>&& other, binding<Concept>&& binding_arg) + : table(binding_arg), + data(::boost::type_erasure::call( + constructible< + typename ::boost::remove_const< + typename boost::remove_reference<Tag2>::type + >::type(const typename boost::remove_reference<Tag2>::type&) + >(), std::move(other)) + ) + {} + template<class Concept2, class Tag2> + any(any<Concept2, Tag2>&& other, binding<Concept>& binding_arg) + : table(binding_arg), + data(::boost::type_erasure::call( + constructible< + typename ::boost::remove_const< + typename boost::remove_reference<Tag2>::type + >::type(const typename boost::remove_reference<Tag2>::type&) + >(), std::move(other)) + ) + {} + template<class Concept2, class Tag2> + any(any<Concept2, Tag2>&& other, const binding<Concept>& binding_arg) + : table(binding_arg), + data(::boost::type_erasure::call( + constructible< + typename ::boost::remove_const< + typename boost::remove_reference<Tag2>::type + >::type(const typename boost::remove_reference<Tag2>::type&) + >(), std::move(other)) + ) + {} +#endif + + // One argument is a special case. The argument must be an any + // and the constructor must be explicit. + template<class Tag2> + explicit any(const any<Concept, Tag2>& 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<class Tag2> + explicit any(any<Concept, Tag2>& 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<class Tag2> + explicit any(any<Concept, Tag2>&& 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<Concept>& binding_arg) + : table(binding_arg), + data( + ::boost::type_erasure::call( + binding_arg, + ::boost::type_erasure::constructible<T()>() + ) + ) + {} + explicit any(binding<Concept>& binding_arg) + : table(binding_arg), + data( + ::boost::type_erasure::call( + binding_arg, + ::boost::type_erasure::constructible<T()>() + ) + ) + {} + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + + explicit any(binding<Concept>&& binding_arg) + : table(binding_arg), + data( + ::boost::type_erasure::call( + binding_arg, + ::boost::type_erasure::constructible<T()>() + ) + ) + {} + +#endif + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + + template<class R, class... A, class... U> + const table_type& _boost_type_erasure_extract_table( + ::boost::type_erasure::constructible<R(A...)>*, + U&&... u) + { + return *::boost::type_erasure::detail::extract_table(static_cast<void(*)(A...)>(0), u...); + } + + template<class U0, class U1, class... U> + any(U0&& u0, U1&& u1, U&&... u) + : table( + _boost_type_erasure_extract_table( + false? this->_boost_type_erasure_deduce_constructor(std::forward<U0>(u0), std::forward<U1>(u1), std::forward<U>(u)...) : 0, + std::forward<U0>(u0), std::forward<U1>(u1), std::forward<U>(u)... + ) + ), + data( + ::boost::type_erasure::call( + ::boost::type_erasure::detail::make( + false? this->_boost_type_erasure_deduce_constructor(std::forward<U0>(u0), std::forward<U1>(u1), std::forward<U>(u)...) : 0 + ), + std::forward<U0>(u0), std::forward<U1>(u1), std::forward<U>(u)... + ) + ) + {} + + template<class U0, class... U> + any(const binding<Concept>& 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>(u0), std::forward<U>(u)...) : 0 + ), + std::forward<U0>(u0), std::forward<U>(u)... + ) + ) + {} + + // disambiguate + template<class U0, class... U> + any(binding<Concept>& 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>(u0), std::forward<U>(u)...) : 0 + ), + std::forward<U0>(u0), std::forward<U>(u)... + ) + ) + {} + template<class U0, class... U> + any(binding<Concept>&& 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>(u0), std::forward<U>(u)...) : 0 + ), + std::forward<U0>(u0), std::forward<U>(u)... + ) + ) + {} + +#else + +#include <boost/type_erasure/detail/construct.hpp> + +#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<class U> + any& operator=(const U& other) + { + _boost_type_erasure_resolve_assign(other); + return *this; + } + /** + * \pre @c Concept includes @ref destructible "destructible<T>". + */ + ~any() + { + table.template find<destructible<T> >()(data); + } + +#ifndef BOOST_NO_FUNCTION_REFERENCE_QUALIFIERS + /** INTERNAL ONLY */ + operator param<Concept, T&>() & { return param<Concept, T&>(data, table); } + /** INTERNAL ONLY */ + operator param<Concept, T&&>() && { return param<Concept, T&&>(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<class Other> + 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<any&>(). + _boost_type_erasure_deduce_assign(other) + ) + ) == sizeof(::boost::type_erasure::detail::yes) + >() + ) + ) : 0, + ::boost::type_erasure::is_relaxed<Concept>() + ); + } + /** INTERNAL ONLY */ + template<class Other, class U> + void _boost_type_erasure_assign_impl( + const Other& other, + const assignable<T, U>*, + ::boost::mpl::false_) + { + ::boost::type_erasure::call(assignable<T, U>(), *this, other); + } + /** INTERNAL ONLY */ + template<class Other, class U> + void _boost_type_erasure_assign_impl( + const Other& other, + const assignable<T, U>*, + ::boost::mpl::true_) + { + ::boost::type_erasure::call(assignable<T, U>(), *this, other); + } + /** INTERNAL ONLY */ + template<class Other> + 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<class Concept2, class Tag2> + void _boost_type_erasure_resolve_assign(const any<Concept2, Tag2>& 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<any&>(). + _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<any&>(). + _boost_type_erasure_deduce_constructor(other) + ) + ) == sizeof(::boost::type_erasure::detail::yes) + >() + ) + ) : 0, + ::boost::type_erasure::is_relaxed<Concept>() + ); + } + /** INTERNAL ONLY */ + template<class Other, class U> + void _boost_type_erasure_assign_impl( + const Other& other, + const assignable<T, U>*, + const void*, + ::boost::mpl::false_) + { + ::boost::type_erasure::call(assignable<T, U>(), *this, other); + } + /** INTERNAL ONLY */ + template<class Other, class U> + void _boost_type_erasure_assign_impl( + const Other& other, + const assignable<T, U>*, + const void*, + ::boost::mpl::true_) + { + ::boost::type_erasure::call(assignable<T, U>(), *this, other); + } + /** INTERNAL ONLY */ + template<class Other, class Sig> + void _boost_type_erasure_assign_impl( + const Other& other, + const void*, + const constructible<Sig>*, + ::boost::mpl::true_) + { + any temp(other); + _boost_type_erasure_swap(temp); + } + /** INTERNAL ONLY */ + template<class Other, class U, class Sig> + void _boost_type_erasure_assign_impl( + const Other& other, + const assignable<T, U>*, + const constructible<Sig>*, + ::boost::mpl::true_) + { + if(::boost::type_erasure::check_match(assignable<T, U>(), *this, other)) + { + ::boost::type_erasure::unchecked_call(assignable<T, U>(), *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 Concept, class T> +class any<Concept, T&> : + public ::boost::type_erasure::detail::compute_bases< + ::boost::type_erasure::any<Concept, T&>, + Concept, + T + >::type +{ + typedef ::boost::type_erasure::binding<Concept> 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<class U> + any(U& arg +#ifndef BOOST_TYPE_ERASURE_DOXYGEN + , typename ::boost::disable_if< + ::boost::mpl::or_< + ::boost::is_const<U>, + ::boost::type_erasure::detail::is_any<U> + > + >::type* = 0 +#endif + ) + : table(( + BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, U), + ::boost::type_erasure::make_binding< + ::boost::mpl::map< ::boost::mpl::pair<T, U> > + >() + )) + { + 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<class U, class Map> + any(U& arg, const static_binding<Map>& binding_arg) + : table(( + BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map), + binding_arg + )) + { + BOOST_MPL_ASSERT((::boost::is_same< + typename ::boost::mpl::at<Map, T>::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<Concept, T>& 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<class Concept2, class Tag2> + any(const any<Concept2, Tag2&>& other +#ifndef BOOST_TYPE_ERASURE_DOXYGEN + , typename ::boost::disable_if< + ::boost::mpl::or_< + ::boost::is_same<Concept, Concept2>, + ::boost::is_const<Tag2> + > + >::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<class Concept2, class Tag2> + any(any<Concept2, Tag2>& other +#ifndef BOOST_TYPE_ERASURE_DOXYGEN + , typename ::boost::disable_if< + ::boost::mpl::or_< + ::boost::is_same<Concept, Concept2>, + ::boost::is_const<typename ::boost::remove_reference<Tag2>::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<Tag2>::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<class Concept2, class Tag2, class Map> + any(const any<Concept2, Tag2&>& other, const static_binding<Map>& binding_arg +#ifndef BOOST_TYPE_ERASURE_DOXYGEN + , typename ::boost::disable_if< ::boost::is_const<Tag2> >::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<class Concept2, class Tag2, class Map> + any(any<Concept2, Tag2>& other, const static_binding<Map>& binding_arg +#ifndef BOOST_TYPE_ERASURE_DOXYGEN + , typename ::boost::disable_if< + ::boost::is_const<typename ::boost::remove_reference<Tag2>::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<class Concept2, class Tag2> + any(const any<Concept2, Tag2&>& other, const binding<Concept>& binding_arg +#ifndef BOOST_TYPE_ERASURE_DOXYGEN + , typename ::boost::disable_if< + ::boost::is_const<Tag2> + >::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<class Concept2, class Tag2> + any(any<Concept2, Tag2>& other, const binding<Concept>& binding_arg +#ifndef BOOST_TYPE_ERASURE_DOXYGEN + , typename ::boost::disable_if< + ::boost::is_const<typename ::boost::remove_reference<Tag2>::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<class U> + 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<class U> + any& operator=(const U& other) + { + _boost_type_erasure_resolve_assign(other); + return *this; + } + +#ifndef BOOST_NO_FUNCTION_REFERENCE_QUALIFIERS + /** INTERNAL ONLY */ + operator param<Concept, T&>() const { return param<Concept, T&>(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<class Other> + 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<any&>(). + _boost_type_erasure_deduce_assign(other) + ) + ) == sizeof(::boost::type_erasure::detail::yes) + >() + ) + ) : 0, + ::boost::type_erasure::is_relaxed<Concept>() + ); + } + /** INTERNAL ONLY */ + template<class Other, class U> + void _boost_type_erasure_assign_impl( + Other& other, + const assignable<T, U>*, + ::boost::mpl::false_) + { + ::boost::type_erasure::call(assignable<T, U>(), *this, other); + } + /** INTERNAL ONLY */ + template<class Other, class U> + void _boost_type_erasure_assign_impl( + Other& other, + const assignable<T, U>*, + ::boost::mpl::true_) + { + if(::boost::type_erasure::check_match(assignable<T, U>(), *this, other)) { + ::boost::type_erasure::unchecked_call(assignable<T, U>(), *this, other); + } else { + any temp(other); + _boost_type_erasure_swap(temp); + } + } + /** INTERNAL ONLY */ + template<class Other> + 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 Concept, class T> +class any<Concept, const T&> : + public ::boost::type_erasure::detail::compute_bases< + ::boost::type_erasure::any<Concept, const T&>, + Concept, + T + >::type +{ + typedef ::boost::type_erasure::binding<Concept> 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<class U> + any(const U& arg) + : table(( + BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, U), + ::boost::type_erasure::make_binding< + ::boost::mpl::map< ::boost::mpl::pair<T, U> > + >() + )) + { + data.data = const_cast<void*>(static_cast<const void*>(::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<class U, class Map> + any(const U& arg, const static_binding<Map>& binding_arg) + : table(( + BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map), + binding_arg + )) + { + BOOST_MPL_ASSERT((::boost::is_same< + typename ::boost::mpl::at<Map, T>::type, U>)); + data.data = const_cast<void*>(static_cast<const void*>(::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<Concept, T&>& 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<Concept, T>& 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<Concept, T&&>& 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<class Concept2, class Tag2> + any(const any<Concept2, Tag2>& other +#ifndef BOOST_TYPE_ERASURE_DOXYGEN + , typename ::boost::disable_if< ::boost::is_same<Concept, Concept2> >::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<Tag2>::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<class Concept2, class Tag2, class Map> + any(const any<Concept2, Tag2>& other, const static_binding<Map>& 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<class Concept2, class Tag2> + any(const any<Concept2, Tag2>& other, const binding<Concept>& 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<Concept>)); + 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<class U> + any& operator=(const U& other) + { + BOOST_MPL_ASSERT((::boost::type_erasure::is_relaxed<Concept>)); + any temp(other); + _boost_type_erasure_swap(temp); + return *this; + } + +#ifndef BOOST_NO_FUNCTION_REFERENCE_QUALIFIERS + /** INTERNAL ONLY */ + operator param<Concept, const T&>() const { return param<Concept, const T&>(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 Concept, class T> +class any<Concept, T&&> : + public ::boost::type_erasure::detail::compute_bases< + ::boost::type_erasure::any<Concept, T&&>, + Concept, + T + >::type +{ + typedef ::boost::type_erasure::binding<Concept> 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<class U> + any(U&& arg +#ifndef BOOST_TYPE_ERASURE_DOXYGEN + , typename ::boost::disable_if< + ::boost::mpl::or_< + ::boost::is_reference<U>, + ::boost::is_const<U>, + ::boost::type_erasure::detail::is_any<U> + > + >::type* = 0 +#endif + ) + : table(( + BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, U), + ::boost::type_erasure::make_binding< + ::boost::mpl::map< ::boost::mpl::pair<T, U> > + >() + )) + { + 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<class U, class Map> + any(U&& arg, const static_binding<Map>& binding_arg) + : table(( + BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map), + binding_arg + )) + { + BOOST_MPL_ASSERT((::boost::is_same< + typename ::boost::mpl::at<Map, T>::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<Concept, T>&& 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<class Concept2, class Tag2> + any(any<Concept2, Tag2&&>&& other +#ifndef BOOST_TYPE_ERASURE_DOXYGEN + , typename ::boost::disable_if< + ::boost::mpl::or_< + ::boost::is_reference<Tag2>, + ::boost::is_same<Concept, Concept2>, + ::boost::is_const<Tag2> + > + >::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<class Concept2, class Tag2> + any(any<Concept2, Tag2>&& other +#ifndef BOOST_TYPE_ERASURE_DOXYGEN + , typename ::boost::disable_if< + ::boost::mpl::or_< + ::boost::is_same<Concept, Concept2>, + ::boost::is_const<typename ::boost::remove_reference<Tag2>::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<Tag2>::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<class Concept2, class Tag2, class Map> + any(const any<Concept2, Tag2&&>& other, const static_binding<Map>& binding_arg +#ifndef BOOST_TYPE_ERASURE_DOXYGEN + , typename ::boost::disable_if< ::boost::is_const<Tag2> >::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<class Concept2, class Tag2, class Map> + any(any<Concept2, Tag2>&& other, const static_binding<Map>& binding_arg +#ifndef BOOST_TYPE_ERASURE_DOXYGEN + , typename ::boost::disable_if< + ::boost::is_const<typename ::boost::remove_reference<Tag2>::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<class Concept2, class Tag2> + any(const any<Concept2, Tag2&&>& other, const binding<Concept>& binding_arg +#ifndef BOOST_TYPE_ERASURE_DOXYGEN + , typename ::boost::disable_if< + ::boost::is_const<Tag2> + >::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<class Concept2, class Tag2> + any(any<Concept2, Tag2>&& other, const binding<Concept>& binding_arg +#ifndef BOOST_TYPE_ERASURE_DOXYGEN + , typename ::boost::disable_if< + ::boost::is_const<typename ::boost::remove_reference<Tag2>::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<class U> + 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<class U> + any& operator=(const U& other) + { + _boost_type_erasure_resolve_assign(other); + return *this; + } + +#ifndef BOOST_NO_FUNCTION_REFERENCE_QUALIFIERS + /** INTERNAL ONLY */ + operator param<Concept, T&&>() const { return param<Concept, T&&>(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<class Other> + 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<any&>(). + _boost_type_erasure_deduce_assign(other) + ) + ) == sizeof(::boost::type_erasure::detail::yes) + >() + ) + ) : 0, + ::boost::type_erasure::is_relaxed<Concept>() + ); + } + /** INTERNAL ONLY */ + template<class Other, class U> + void _boost_type_erasure_assign_impl( + Other& other, + const assignable<T, U>*, + ::boost::mpl::false_) + { + ::boost::type_erasure::call(assignable<T, U>(), *this, other); + } + /** INTERNAL ONLY */ + template<class Other, class U> + void _boost_type_erasure_assign_impl( + Other& other, + const assignable<T, U>*, + ::boost::mpl::true_) + { + if(::boost::type_erasure::check_match(assignable<T, U>(), *this, other)) { + ::boost::type_erasure::unchecked_call(assignable<T, U>(), *this, other); + } else { + any temp(other); + _boost_type_erasure_swap(temp); + } + } + /** INTERNAL ONLY */ + template<class Other> + 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 |