2209 lines
73 KiB
C++
2209 lines
73 KiB
C++
// 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: any.hpp 83393 2013-03-10 03:48:33Z steven_watanabe $
|
|
|
|
#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_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_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
|