summaryrefslogtreecommitdiff
path: root/boost/type_erasure/any.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/type_erasure/any.hpp')
-rw-r--r--boost/type_erasure/any.hpp1108
1 files changed, 961 insertions, 147 deletions
diff --git a/boost/type_erasure/any.hpp b/boost/type_erasure/any.hpp
index 3ed0243498..2505c96908 100644
--- a/boost/type_erasure/any.hpp
+++ b/boost/type_erasure/any.hpp
@@ -12,6 +12,9 @@
#define BOOST_TYPE_ERASURE_ANY_HPP_INCLUDED
#include <algorithm>
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+# include <utility> // std::forward, std::move
+#endif
#include <boost/config.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/utility/addressof.hpp>
@@ -20,7 +23,8 @@
#include <boost/mpl/or.hpp>
#include <boost/mpl/pair.hpp>
#include <boost/mpl/map.hpp>
-#include <boost/mpl/fold.hpp>
+#include <boost/mpl/reverse_fold.hpp>
+#include <boost/type_traits/decay.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/is_same.hpp>
@@ -44,9 +48,18 @@
#include <boost/type_erasure/relaxed.hpp>
#include <boost/type_erasure/param.hpp>
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4355)
+#pragma warning(disable:4521)
+#pragma warning(disable:4522) // multiple assignment operators specified
+#endif
+
namespace boost {
namespace type_erasure {
+#ifndef BOOST_TYPE_ERASURE_DOXYGEN
+
template<class Sig>
struct constructible;
@@ -56,17 +69,48 @@ struct destructible;
template<class T, class U>
struct assignable;
+#endif
+
namespace detail {
+#if defined(BOOST_NO_CXX11_DECLTYPE) || defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
+
+template<class Concept, class Base, class ID>
+struct choose_concept_interface
+{
+ typedef ::boost::type_erasure::concept_interface<Concept, Base, ID> type;
+};
+
+#else
+
+struct default_concept_interface
+{
+ template<class Concept, class Base, class ID>
+ using apply = ::boost::type_erasure::concept_interface<Concept, Base, ID>;
+};
+
+default_concept_interface boost_type_erasure_find_interface(...);
+
+template<class Concept, class Base, class ID>
+struct choose_concept_interface
+{
+ typedef decltype(boost_type_erasure_find_interface(::boost::declval<Concept>())) finder;
+ typedef typename finder::template apply<Concept, Base, ID> type;
+};
+
+#endif
+
+#ifndef BOOST_TYPE_ERASURE_USE_MP11
+
template<class Derived, class Concept, class T>
struct compute_bases
{
- typedef typename ::boost::mpl::fold<
+ typedef typename ::boost::mpl::reverse_fold<
typename ::boost::type_erasure::detail::collect_concepts<
Concept
>::type,
::boost::type_erasure::any_base<Derived>,
- ::boost::type_erasure::concept_interface<
+ ::boost::type_erasure::detail::choose_concept_interface<
::boost::mpl::_2,
::boost::mpl::_1,
T
@@ -74,6 +118,30 @@ struct compute_bases
>::type type;
};
+#else
+
+template<class ID>
+struct compute_bases_f
+{
+ template<class Concept, class Base>
+ using apply = typename ::boost::type_erasure::detail::choose_concept_interface<Concept, Base, ID>::type;
+};
+
+template<class Derived, class Concept, class T>
+using compute_bases_t =
+ ::boost::mp11::mp_reverse_fold<
+ typename ::boost::type_erasure::detail::collect_concepts_t<
+ Concept
+ >,
+ ::boost::type_erasure::any_base<Derived>,
+ ::boost::type_erasure::detail::compute_bases_f<T>::template apply
+ >;
+
+template<class Derived, class Concept, class T>
+using compute_bases = ::boost::mpl::identity< ::boost::type_erasure::detail::compute_bases_t<Derived, Concept, T> >;
+
+#endif
+
template<class T>
T make(T*) { return T(); }
@@ -90,6 +158,22 @@ no check_overload(const void*);
struct fallback {};
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+template<class T>
+fallback make_fallback(T&&, boost::mpl::false_)
+{
+ return fallback();
+}
+
+template<class T>
+T&& make_fallback(T&& arg, boost::mpl::true_)
+{
+ return std::forward<T>(arg);
+}
+
+#else
+
template<class T>
fallback make_fallback(const T&, boost::mpl::false_)
{
@@ -102,20 +186,470 @@ const T& make_fallback(const T& arg, boost::mpl::true_)
return arg;
}
+#endif
+
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_TYPE_ERASURE_SFINAE_FRIENDLY_CONSTRUCTORS
+
+template<class Any, class... U>
+struct has_constructor :
+ ::boost::mpl::bool_<
+ sizeof(
+ ::boost::type_erasure::detail::check_overload(
+ ::boost::declval<Any&>().
+ _boost_type_erasure_deduce_constructor(::boost::declval<U>()...)
+ )
+ ) == sizeof(::boost::type_erasure::detail::yes)
+ >
+{};
+
+template<class Any>
+using has_copy_constructor =
+ ::boost::type_erasure::is_subconcept<
+ ::boost::type_erasure::constructible<
+ typename ::boost::type_erasure::placeholder_of<Any>::type(typename ::boost::type_erasure::placeholder_of<Any>::type const&)
+ >,
+ typename ::boost::type_erasure::concept_of<Any>::type
+ >;
+
+template<class Any>
+using has_move_constructor =
+ ::boost::type_erasure::is_subconcept<
+ ::boost::type_erasure::constructible<
+ typename ::boost::type_erasure::placeholder_of<Any>::type(typename ::boost::type_erasure::placeholder_of<Any>::type &&)
+ >,
+ typename ::boost::type_erasure::concept_of<Any>::type
+ >;
+
+template<class Any>
+using has_mutable_copy_constructor =
+ ::boost::type_erasure::is_subconcept<
+ ::boost::type_erasure::constructible<
+ typename ::boost::type_erasure::placeholder_of<Any>::type(typename ::boost::type_erasure::placeholder_of<Any>::type &)
+ >,
+ typename ::boost::type_erasure::concept_of<Any>::type
+ >;
+
+struct empty {};
+
+template<class T>
+struct is_binding_arg : ::boost::mpl::false_ {};
+template<class T>
+struct is_binding_arg<binding<T> > : ::boost::mpl::true_ {};
+template<class T>
+struct is_binding_arg<binding<T>&&> : ::boost::mpl::true_ {};
+template<class T>
+struct is_binding_arg<binding<T>&> : ::boost::mpl::true_ {};
+template<class T>
+struct is_binding_arg<binding<T> const&> : ::boost::mpl::true_ {};
+
+template<class T>
+struct is_static_binding_arg : ::boost::mpl::false_ {};
+template<class T>
+struct is_static_binding_arg<static_binding<T> > : ::boost::mpl::true_ {};
+template<class T>
+struct is_static_binding_arg<static_binding<T>&&> : ::boost::mpl::true_ {};
+template<class T>
+struct is_static_binding_arg<static_binding<T>&> : ::boost::mpl::true_ {};
+template<class T>
+struct is_static_binding_arg<static_binding<T> const&> : ::boost::mpl::true_ {};
+
+template<class T>
+struct is_any_arg : ::boost::mpl::false_ {};
+template<class Concept, class T>
+struct is_any_arg<any<Concept, T> > : ::boost::mpl::true_ {};
+template<class Concept, class T>
+struct is_any_arg<any<Concept, T>&&> : ::boost::mpl::true_ {};
+template<class Concept, class T>
+struct is_any_arg<any<Concept, T>&> : ::boost::mpl::true_ {};
+template<class Concept, class T>
+struct is_any_arg<any<Concept, T> const&> : ::boost::mpl::true_ {};
+
+template<class T>
+struct safe_concept_of;
+template<class Concept, class T>
+struct safe_concept_of<any<Concept, T> > { typedef Concept type; };
+template<class Concept, class T>
+struct safe_concept_of<any<Concept, T>&&> { typedef Concept type; };
+template<class Concept, class T>
+struct safe_concept_of<any<Concept, T>&> { typedef Concept type; };
+template<class Concept, class T>
+struct safe_concept_of<any<Concept, T> const&> { typedef Concept type; };
+
+template<class T>
+struct safe_placeholder_of;
+template<class Concept, class T>
+struct safe_placeholder_of<any<Concept, T> > { typedef T type; };
+template<class Concept, class T>
+struct safe_placeholder_of<any<Concept, T>&&> { typedef T type; };
+template<class Concept, class T>
+struct safe_placeholder_of<any<Concept, T>&> { typedef T type; };
+template<class Concept, class T>
+struct safe_placeholder_of<any<Concept, T> const&> { typedef T type; };
+
+template<class T>
+using safe_placeholder_t = ::boost::remove_cv_t< ::boost::remove_reference_t<typename safe_placeholder_of<T>::type> >;
+
}
-#ifdef BOOST_MSVC
-#pragma warning(push)
-#pragma warning(disable:4355)
-#pragma warning(disable:4521)
+// Enables or deletes the copy/move constructors depending on the Concept.
+template<class Base, class Enable = void>
+struct any_constructor_control : Base
+{
+ using Base::Base;
+};
+
+template<class Base>
+struct any_constructor_control<
+ Base,
+ typename boost::enable_if_c<
+ !::boost::type_erasure::detail::has_copy_constructor<Base>::value &&
+ ::boost::type_erasure::detail::has_move_constructor<Base>::value &&
+ ::boost::type_erasure::detail::has_mutable_copy_constructor<Base>::value
+ >::type
+> : Base
+{
+ using Base::Base;
+ any_constructor_control() = default;
+ any_constructor_control(any_constructor_control&) = default;
+ any_constructor_control(any_constructor_control&&) = default;
+ any_constructor_control& operator=(any_constructor_control const& other) { static_cast<Base&>(*this) = static_cast<Base const&>(other); return *this; }
+ any_constructor_control& operator=(any_constructor_control & other) { static_cast<Base&>(*this) = static_cast<Base&>(other); return *this; }
+ any_constructor_control& operator=(any_constructor_control &&) = default;
+};
+
+template<class Base>
+struct any_constructor_control<
+ Base,
+ typename boost::enable_if_c<
+ !::boost::type_erasure::detail::has_copy_constructor<Base>::value &&
+ !::boost::type_erasure::detail::has_move_constructor<Base>::value &&
+ ::boost::type_erasure::detail::has_mutable_copy_constructor<Base>::value
+ >::type
+> : Base
+{
+ using Base::Base;
+ any_constructor_control() = default;
+ any_constructor_control(any_constructor_control&) = default;
+ any_constructor_control(any_constructor_control&&) = delete;
+ any_constructor_control& operator=(any_constructor_control const& other) { static_cast<Base&>(*this) = static_cast<Base const&>(other); return *this; }
+ any_constructor_control& operator=(any_constructor_control & other) { static_cast<Base&>(*this) = static_cast<Base&>(other); return *this; }
+ any_constructor_control& operator=(any_constructor_control &&) = default;
+};
+
+template<class Base>
+struct any_constructor_control<
+ Base,
+ typename boost::enable_if_c<
+ !::boost::type_erasure::detail::has_copy_constructor<Base>::value &&
+ ::boost::type_erasure::detail::has_move_constructor<Base>::value &&
+ !::boost::type_erasure::detail::has_mutable_copy_constructor<Base>::value
+ >::type
+> : Base
+{
+ using Base::Base;
+ any_constructor_control() = default;
+ any_constructor_control(any_constructor_control const&) = delete;
+ any_constructor_control(any_constructor_control&&) = default;
+ any_constructor_control& operator=(any_constructor_control const& other) { static_cast<Base&>(*this) = static_cast<Base const&>(other); return *this; }
+ any_constructor_control& operator=(any_constructor_control & other) { static_cast<Base&>(*this) = static_cast<Base&>(other); return *this; }
+ any_constructor_control& operator=(any_constructor_control &&) = default;
+};
+
+template<class Base>
+struct any_constructor_control<
+ Base,
+ typename boost::enable_if_c<
+ !::boost::type_erasure::detail::has_copy_constructor<Base>::value &&
+ !::boost::type_erasure::detail::has_move_constructor<Base>::value &&
+ !::boost::type_erasure::detail::has_mutable_copy_constructor<Base>::value
+ >::type
+> : Base
+{
+ using Base::Base;
+ any_constructor_control() = default;
+ any_constructor_control(any_constructor_control const&) = delete;
+ any_constructor_control(any_constructor_control&&) = delete;
+ any_constructor_control& operator=(any_constructor_control const& other) { static_cast<Base&>(*this) = static_cast<Base const&>(other); return *this; }
+ any_constructor_control& operator=(any_constructor_control & other) { static_cast<Base&>(*this) = static_cast<Base&>(other); return *this; }
+ any_constructor_control& operator=(any_constructor_control &&) = default;
+};
+
+template<class Concept, class T>
+struct any_constructor_impl :
+ ::boost::type_erasure::detail::compute_bases<
+ ::boost::type_erasure::any<Concept, T>,
+ Concept,
+ T
+ >::type
+{
+ typedef typename ::boost::type_erasure::detail::compute_bases<
+ ::boost::type_erasure::any<Concept, T>,
+ Concept,
+ T
+ >::type _boost_type_erasure_base;
+ // Internal constructors
+ typedef ::boost::type_erasure::binding<Concept> _boost_type_erasure_table_type;
+ any_constructor_impl(const ::boost::type_erasure::detail::storage& data_arg, const _boost_type_erasure_table_type& table_arg)
+ : _boost_type_erasure_table(table_arg),
+ _boost_type_erasure_data(data_arg)
+ {}
+ any_constructor_impl(::boost::type_erasure::detail::storage&& data_arg, const _boost_type_erasure_table_type& table_arg)
+ : _boost_type_erasure_table(table_arg),
+ _boost_type_erasure_data(data_arg)
+ {}
+ // default constructor
+ any_constructor_impl()
+ {
+ BOOST_MPL_ASSERT((::boost::type_erasure::is_relaxed<Concept>));
+ _boost_type_erasure_data.data = 0;
+ }
+ // capturing constructor
+ template<class U,
+ typename ::boost::enable_if_c<
+ !::boost::type_erasure::detail::is_any_arg<U>::value &&
+ !::boost::type_erasure::detail::is_binding_arg<U>::value &&
+ !::boost::type_erasure::detail::is_static_binding_arg<U>::value
+ >::type* = nullptr
+ >
+ any_constructor_impl(U&& data_arg)
+ : _boost_type_erasure_table((
+ BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, ::boost::decay_t<U>),
+ ::boost::type_erasure::make_binding<
+ ::boost::mpl::map1< ::boost::mpl::pair<T, ::boost::decay_t<U> > >
+ >()
+ )),
+ _boost_type_erasure_data(std::forward<U>(data_arg))
+ {}
+ template<class U, class Map,
+ typename ::boost::enable_if_c<
+ !::boost::type_erasure::detail::is_any_arg<U>::value &&
+ !::boost::type_erasure::detail::is_binding_arg<U>::value &&
+ !::boost::type_erasure::detail::is_static_binding_arg<U>::value
+ >::type* = nullptr
+ >
+ any_constructor_impl(U&& data_arg, const static_binding<Map>& b)
+ : _boost_type_erasure_table((
+ BOOST_TYPE_ERASURE_INSTANTIATE(Concept, Map),
+ b
+ )),
+ _boost_type_erasure_data(std::forward<U>(data_arg))
+ {
+ BOOST_MPL_ASSERT((::boost::is_same<
+ typename ::boost::mpl::at<Map, T>::type, ::boost::decay_t<U> >));
+ }
+ // converting constructor
+ template<class U,
+ typename ::boost::enable_if_c<
+ ::boost::type_erasure::is_subconcept<
+ Concept, typename ::boost::type_erasure::detail::safe_concept_of<U>::type,
+ typename ::boost::mpl::if_c< ::boost::is_same<T, ::boost::type_erasure::detail::safe_placeholder_t<U> >::value,
+ void,
+ ::boost::mpl::map1<
+ ::boost::mpl::pair<T, ::boost::type_erasure::detail::safe_placeholder_t<U> >
+ >
+ >::type
+ >::value
+ >::type* = nullptr
+ >
+ any_constructor_impl(U&& other)
+ : _boost_type_erasure_table(
+ ::boost::type_erasure::detail::access::table(other),
+ typename ::boost::mpl::if_c< ::boost::is_same<T, ::boost::type_erasure::detail::safe_placeholder_t<U> >::value,
+#ifndef BOOST_TYPE_ERASURE_USE_MP11
+ ::boost::type_erasure::detail::substitution_map< ::boost::mpl::map0<> >,
+#else
+ ::boost::type_erasure::detail::make_identity_placeholder_map<Concept>,
+#endif
+ ::boost::mpl::map1<
+ ::boost::mpl::pair<
+ T,
+ ::boost::type_erasure::detail::safe_placeholder_t<U>
+ >
+ >
+ >::type()
+ ),
+ _boost_type_erasure_data(::boost::type_erasure::call(
+ ::boost::type_erasure::detail::make(
+ false? other._boost_type_erasure_deduce_constructor(std::forward<U>(other)) : 0
+ ), std::forward<U>(other))
+ )
+ {}
+ template<class U,
+ typename ::boost::enable_if_c<
+ ::boost::type_erasure::detail::is_any_arg<U>::value
+ >::type* = nullptr
+ >
+ any_constructor_impl(U&& other, const binding<Concept>& binding_arg)
+ : _boost_type_erasure_table(binding_arg),
+ _boost_type_erasure_data(::boost::type_erasure::call(
+ ::boost::type_erasure::detail::make(
+ false? other._boost_type_erasure_deduce_constructor(std::forward<U>(other)) : 0
+ ), std::forward<U>(other))
+ )
+ {}
+ template<class U, class Map,
+ typename ::boost::enable_if_c<
+ ::boost::type_erasure::is_subconcept<
+ Concept, typename ::boost::type_erasure::detail::safe_concept_of<U>::type,
+ Map
+ >::value
+ >::type* = nullptr
+ >
+ any_constructor_impl(U&& other, const static_binding<Map>& binding_arg)
+ : _boost_type_erasure_table(::boost::type_erasure::detail::access::table(other), binding_arg),
+ _boost_type_erasure_data(::boost::type_erasure::call(
+ ::boost::type_erasure::detail::make(
+ false? other._boost_type_erasure_deduce_constructor(std::forward<U>(other)) : 0
+ ), std::forward<U>(other))
+ )
+ {}
+ // copy and move constructors are a special case of the converting
+ // constructors, but must be defined separately to keep C++ happy.
+ any_constructor_impl(const any_constructor_impl& other)
+ : _boost_type_erasure_table(
+ ::boost::type_erasure::detail::access::table(other)
+ ),
+ _boost_type_erasure_data(::boost::type_erasure::call(
+ ::boost::type_erasure::detail::make(
+ false? other._boost_type_erasure_deduce_constructor(
+ static_cast<typename _boost_type_erasure_base::_boost_type_erasure_derived_type const&>(other)) : 0
+ ), other)
+ )
+ {}
+ any_constructor_impl(any_constructor_impl& other)
+ : _boost_type_erasure_table(
+ ::boost::type_erasure::detail::access::table(other)
+ ),
+ _boost_type_erasure_data(::boost::type_erasure::call(
+ ::boost::type_erasure::detail::make(
+ false? other._boost_type_erasure_deduce_constructor(
+ static_cast<typename _boost_type_erasure_base::_boost_type_erasure_derived_type &>(other)) : 0
+ ), other)
+ )
+ {}
+ any_constructor_impl(any_constructor_impl&& other)
+ : _boost_type_erasure_table(
+ ::boost::type_erasure::detail::access::table(other)
+ ),
+ _boost_type_erasure_data(::boost::type_erasure::call(
+ ::boost::type_erasure::detail::make(
+ false? other._boost_type_erasure_deduce_constructor(
+ static_cast<typename _boost_type_erasure_base::_boost_type_erasure_derived_type &&>(other)) : 0
+ ), std::move(other))
+ )
+ {}
+
+ template<class R, class... A, class... U>
+ const _boost_type_erasure_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...);
+ }
+ // forwarding constructor
+ template<class... U,
+ typename ::boost::enable_if_c<
+ ::boost::type_erasure::detail::has_constructor<any_constructor_impl, U...>::value
+ >::type* = nullptr
+ >
+ explicit any_constructor_impl(U&&... u)
+ : _boost_type_erasure_table(
+ _boost_type_erasure_extract_table(
+ false? this->_boost_type_erasure_deduce_constructor(std::forward<U>(u)...) : 0,
+ std::forward<U>(u)...
+ )
+ ),
+ _boost_type_erasure_data(
+ ::boost::type_erasure::call(
+ ::boost::type_erasure::detail::make(
+ false? this->_boost_type_erasure_deduce_constructor(std::forward<U>(u)...) : 0
+ ),
+ std::forward<U>(u)...
+ )
+ )
+ {}
+ template<class... U,
+ typename ::boost::enable_if_c<
+ ::boost::type_erasure::detail::has_constructor<any_constructor_impl, U...>::value
+ >::type* = nullptr
+ >
+ explicit any_constructor_impl(const binding<Concept>& binding_arg, U&&... u)
+ : _boost_type_erasure_table(binding_arg),
+ _boost_type_erasure_data(
+ ::boost::type_erasure::call(
+ binding_arg,
+ ::boost::type_erasure::detail::make(
+ false? this->_boost_type_erasure_deduce_constructor(std::forward<U>(u)...) : 0
+ ),
+ std::forward<U>(u)...
+ )
+ )
+ {}
+
+ // The assignment operator and destructor must be defined here rather
+ // than in any to avoid implicitly deleting the move constructor.
+
+ any_constructor_impl& operator=(const any_constructor_impl& other)
+ {
+ static_cast<typename _boost_type_erasure_base::_boost_type_erasure_derived_type*>(this)->_boost_type_erasure_resolve_assign(
+ static_cast<const typename _boost_type_erasure_base::_boost_type_erasure_derived_type&>(other));
+ return *this;
+ }
+
+ any_constructor_impl& operator=(any_constructor_impl& other)
+ {
+ static_cast<typename _boost_type_erasure_base::_boost_type_erasure_derived_type*>(this)->_boost_type_erasure_resolve_assign(
+ static_cast<typename _boost_type_erasure_base::_boost_type_erasure_derived_type&>(other));
+ return *this;
+ }
+
+ any_constructor_impl& operator=(any_constructor_impl&& other)
+ {
+ static_cast<typename _boost_type_erasure_base::_boost_type_erasure_derived_type*>(this)->_boost_type_erasure_resolve_assign(
+ static_cast<typename _boost_type_erasure_base::_boost_type_erasure_derived_type&&>(other));
+ return *this;
+ }
+
+ ~any_constructor_impl()
+ {
+ _boost_type_erasure_table.template find<
+ ::boost::type_erasure::destructible<T>
+ >()(_boost_type_erasure_data);
+ }
+
+protected:
+ friend struct ::boost::type_erasure::detail::access;
+
+ _boost_type_erasure_table_type _boost_type_erasure_table;
+ ::boost::type_erasure::detail::storage _boost_type_erasure_data;
+};
+
+namespace detail {
+
#endif
+template<class T>
+struct is_rvalue_for_any :
+ ::boost::mpl::not_<
+ ::boost::is_lvalue_reference<T>
+ >
+{};
+
+template<class C, class P>
+struct is_rvalue_for_any<any<C, P> > :
+ ::boost::mpl::not_<
+ ::boost::is_lvalue_reference<P>
+ >
+{};
+
+}
+
/**
* The class template @ref any can store any object that
* models a specific \Concept. It dispatches all
@@ -129,16 +663,37 @@ struct is_any<any<Concept, T> > : ::boost::mpl::true_ {};
*/
template<class Concept, class T = _self>
class any :
+#ifdef BOOST_TYPE_ERASURE_SFINAE_FRIENDLY_CONSTRUCTORS
+ public ::boost::type_erasure::any_constructor_control<
+ ::boost::type_erasure::any_constructor_impl<
+
+ Concept,
+ T
+ >
+ >
+#else
public ::boost::type_erasure::detail::compute_bases<
::boost::type_erasure::any<Concept, T>,
Concept,
T
>::type
+#endif
{
typedef ::boost::type_erasure::binding<Concept> table_type;
public:
/** INTERNAL ONLY */
typedef Concept _boost_type_erasure_concept_type;
+
+#if defined(BOOST_TYPE_ERASURE_SFINAE_FRIENDLY_CONSTRUCTORS)
+ using _boost_type_erasure_base = ::boost::type_erasure::any_constructor_control<
+ ::boost::type_erasure::any_constructor_impl<
+ Concept,
+ T
+ >
+ >;
+ using _boost_type_erasure_base::_boost_type_erasure_base;
+#else
+
/** INTERNAL ONLY */
any(const ::boost::type_erasure::detail::storage& data_arg, const table_type& table_arg)
: table(table_arg),
@@ -183,7 +738,7 @@ public:
: table((
BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, U),
::boost::type_erasure::make_binding<
- ::boost::mpl::map< ::boost::mpl::pair<T, U> >
+ ::boost::mpl::map1< ::boost::mpl::pair<T, U> >
>()
)),
data(data_arg)
@@ -224,7 +779,7 @@ public:
: 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> >
+ ::boost::mpl::map1< ::boost::mpl::pair<T, typename ::boost::remove_cv<typename ::boost::remove_reference<U>::type>::type> >
>()
)),
data(std::forward<U>(data_arg))
@@ -269,7 +824,7 @@ public:
: table((
BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, U*),
::boost::type_erasure::make_binding<
- ::boost::mpl::map< ::boost::mpl::pair<T, U*> >
+ ::boost::mpl::map1< ::boost::mpl::pair<T, U*> >
>()
)),
data(data_arg)
@@ -307,7 +862,7 @@ public:
*
* \param other The object to make a copy of.
*
- * \pre @c Concept must contain @ref constructible<T(const T&)>.
+ * \pre @c Concept must contain @ref constructible "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
@@ -320,7 +875,7 @@ public:
any(const any<Concept2, Tag2>& other)
: table(
::boost::type_erasure::detail::access::table(other),
- ::boost::mpl::map<
+ ::boost::mpl::map1<
::boost::mpl::pair<
T,
typename ::boost::remove_const<
@@ -344,7 +899,7 @@ public:
* \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 Concept must contain @ref constructible "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.
@@ -372,7 +927,7 @@ public:
* \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 @c Concept must contain @ref constructible "constructible<T(const T&)>".
* \pre The type stored in @c other must match the type expected by
* @c binding.
*
@@ -467,7 +1022,7 @@ public:
any(any<Concept2, Tag2>& other)
: table(
::boost::type_erasure::detail::access::table(other),
- ::boost::mpl::map<
+ ::boost::mpl::map1<
::boost::mpl::pair<
T,
typename ::boost::remove_const<
@@ -486,7 +1041,7 @@ public:
any(any<Concept2, Tag2>&& other)
: table(
::boost::type_erasure::detail::access::table(other),
- ::boost::mpl::map<
+ ::boost::mpl::map1<
::boost::mpl::pair<
T,
typename ::boost::remove_const<
@@ -884,7 +1439,7 @@ public:
#endif
-#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template<class R, class... A, class... U>
const table_type& _boost_type_erasure_extract_table(
@@ -926,7 +1481,7 @@ public:
)
{}
- // disambiguate
+ // disambiguating overloads
template<class U0, class... U>
any(binding<Concept>& binding_arg, U0&& u0, U&&... u)
: table(binding_arg),
@@ -961,28 +1516,44 @@ public:
#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.
- */
+
+ /** INTERNAL ONLY */
any& operator=(const any& other)
{
_boost_type_erasure_resolve_assign(other);
return *this;
}
+ /** INTERNAL ONLY */
+ any& operator=(any& other)
+ {
+ _boost_type_erasure_resolve_assign(other);
+ return *this;
+ }
+
+#endif // BOOST_TYPE_ERASURE_SFINAE_FRIENDLY_CONSTRUCTORS
+
+#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
+ template<class U>
+ any& operator=(U& other)
+ {
+ _boost_type_erasure_resolve_assign(other);
+ return *this;
+ }
+ template<class U>
+ any& operator=(const U& other)
+ {
+ _boost_type_erasure_resolve_assign(other);
+ return *this;
+ }
+#else
+#ifndef BOOST_TYPE_ERASURE_SFINAE_FRIENDLY_CONSTRUCTORS
+ /** INTERNAL ONLY */
+ any& operator=(any&& other)
+ {
+ _boost_type_erasure_resolve_assign(std::move(other));
+ return *this;
+ }
+#endif
/**
* Assigns to an @ref any.
*
@@ -990,45 +1561,123 @@ public:
* and @ref relaxed is in @c Concept, falls back on
* constructing from @c other.
*
+ * \note If @c U is an @ref any, then this can decide dynamically
+ * whether to use construction based on the type stored in 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
+ * throws @c std::bad_alloc or whatever the move (or copy)
* constructor of the contained type throws. In
- * this case assignment provides the strong exception
- * guarantee. When calling an assignment operator
+ * this case move assignment provides the strong exception
+ * guarantee. When calling a (move) assignment operator
* of the contained type, the exception guarantee is
* whatever the contained type provides.
*/
template<class U>
- any& operator=(const U& other)
+ any& operator=(U&& other)
{
- _boost_type_erasure_resolve_assign(other);
+ _boost_type_erasure_resolve_assign(std::forward<U>(other));
return *this;
}
+#endif
+
+#ifndef BOOST_TYPE_ERASURE_SFINAE_FRIENDLY_CONSTRUCTORS
/**
* \pre @c Concept includes @ref destructible "destructible<T>".
*/
~any()
{
- table.template find<destructible<T> >()(data);
+ ::boost::type_erasure::detail::access::table(*this).template find<
+ ::boost::type_erasure::destructible<T>
+ >()(::boost::type_erasure::detail::access::data(*this));
}
+#endif
-#ifndef BOOST_NO_FUNCTION_REFERENCE_QUALIFIERS
+#ifndef BOOST_NO_CXX11_REF_QUALIFIERS
/** INTERNAL ONLY */
- operator param<Concept, T&>() & { return param<Concept, T&>(data, table); }
+ operator param<Concept, T&>() &
+ {
+ return param<Concept, T&>(
+ boost::type_erasure::detail::access::data(*this),
+ boost::type_erasure::detail::access::table(*this));
+ }
/** INTERNAL ONLY */
- operator param<Concept, T&&>() && { return param<Concept, T&&>(data, table); }
+ operator param<Concept, T&&>() && {
+ return param<Concept, T&&>(
+ boost::type_erasure::detail::access::data(*this),
+ boost::type_erasure::detail::access::table(*this));
+ }
#endif
private:
+#ifndef BOOST_TYPE_ERASURE_SFINAE_FRIENDLY_CONSTRUCTORS
/** INTERNAL ONLY */
void _boost_type_erasure_swap(any& other)
{
::std::swap(data, other.data);
::std::swap(table, other.table);
}
+#else
+ void _boost_type_erasure_swap(any& other)
+ {
+ ::std::swap(this->_boost_type_erasure_data, other._boost_type_erasure_data);
+ ::std::swap(this->_boost_type_erasure_table, other._boost_type_erasure_table);
+ }
+#endif
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ /** INTERNAL ONLY */
+ template<class Other>
+ void _boost_type_erasure_resolve_assign(Other&& other)
+ {
+ _boost_type_erasure_assign_impl(
+ std::forward<Other>(other),
+ false? this->_boost_type_erasure_deduce_assign(
+ ::boost::type_erasure::detail::make_fallback(
+ std::forward<Other>(other),
+ ::boost::mpl::bool_<
+ sizeof(
+ ::boost::type_erasure::detail::check_overload(
+ ::boost::declval<any&>().
+ _boost_type_erasure_deduce_assign(std::forward<Other>(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, std::forward<Other>(other));
+ }
+ /** INTERNAL ONLY */
+ template<class Other, class U>
+ void _boost_type_erasure_assign_impl(
+ Other&& other,
+ const assignable<T, U>*,
+ ::boost::mpl::true_)
+ {
+ ::boost::type_erasure::call(assignable<T, U>(), *this, std::forward<Other>(other));
+ }
+ /** INTERNAL ONLY */
+ template<class Other>
+ void _boost_type_erasure_assign_impl(
+ Other&& other,
+ const void*,
+ ::boost::mpl::true_)
+ {
+ any temp(std::forward<Other>(other));
+ _boost_type_erasure_swap(temp);
+ }
+#else
/** INTERNAL ONLY */
template<class Other>
- void _boost_type_erasure_resolve_assign(const Other& other)
+ void _boost_type_erasure_resolve_assign(Other& other)
{
_boost_type_erasure_assign_impl(
other,
@@ -1051,7 +1700,7 @@ private:
/** INTERNAL ONLY */
template<class Other, class U>
void _boost_type_erasure_assign_impl(
- const Other& other,
+ Other& other,
const assignable<T, U>*,
::boost::mpl::false_)
{
@@ -1060,7 +1709,7 @@ private:
/** INTERNAL ONLY */
template<class Other, class U>
void _boost_type_erasure_assign_impl(
- const Other& other,
+ Other& other,
const assignable<T, U>*,
::boost::mpl::true_)
{
@@ -1069,17 +1718,122 @@ private:
/** INTERNAL ONLY */
template<class Other>
void _boost_type_erasure_assign_impl(
- const Other& other,
+ Other& other,
const void*,
::boost::mpl::true_)
{
any temp(other);
_boost_type_erasure_swap(temp);
}
+#endif
/** INTERNAL ONLY */
template<class Concept2, class Tag2>
void _boost_type_erasure_resolve_assign(const any<Concept2, Tag2>& other)
{
+ _boost_type_erasure_resolve_assign_any(other);
+ }
+ /** INTERNAL ONLY */
+ template<class Concept2, class Tag2>
+ void _boost_type_erasure_resolve_assign(any<Concept2, Tag2>& other)
+ {
+ _boost_type_erasure_resolve_assign_any(other);
+ }
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ /** INTERNAL ONLY */
+ template<class Concept2, class Tag2>
+ void _boost_type_erasure_resolve_assign(any<Concept2, Tag2>&& other)
+ {
+ _boost_type_erasure_resolve_assign_any(std::move(other));
+ }
+ /** INTERNAL ONLY */
+ template<class Other>
+ void _boost_type_erasure_resolve_assign_any(Other&& other)
+ {
+ _boost_type_erasure_assign_impl(
+ std::forward<Other>(other),
+ false? this->_boost_type_erasure_deduce_assign(
+ ::boost::type_erasure::detail::make_fallback(
+ std::forward<Other>(other),
+ ::boost::mpl::bool_<
+ sizeof(
+ ::boost::type_erasure::detail::check_overload(
+ ::boost::declval<any&>().
+ _boost_type_erasure_deduce_assign(std::forward<Other>(other))
+ )
+ ) == sizeof(::boost::type_erasure::detail::yes)
+ >()
+ )
+ ) : 0,
+ false? this->_boost_type_erasure_deduce_constructor(
+ ::boost::type_erasure::detail::make_fallback(
+ std::forward<Other>(other),
+ ::boost::mpl::bool_<
+ sizeof(
+ ::boost::type_erasure::detail::check_overload(
+ ::boost::declval<any&>().
+ _boost_type_erasure_deduce_constructor(std::forward<Other>(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>*,
+ const void*,
+ ::boost::mpl::false_)
+ {
+ ::boost::type_erasure::call(assignable<T, U>(), *this, std::forward<Other>(other));
+ }
+ /** INTERNAL ONLY */
+ template<class Other, class U>
+ void _boost_type_erasure_assign_impl(
+ Other&& other,
+ const assignable<T, U>*,
+ const void*,
+ ::boost::mpl::true_)
+ {
+ ::boost::type_erasure::call(assignable<T, U>(), *this, std::forward<Other>(other));
+ }
+ /** INTERNAL ONLY */
+ template<class Other, class Sig>
+ void _boost_type_erasure_assign_impl(
+ Other&& other,
+ const void*,
+ const constructible<Sig>*,
+ ::boost::mpl::true_)
+ {
+ any temp(std::forward<Other>(other));
+ _boost_type_erasure_swap(temp);
+ }
+ /** INTERNAL ONLY */
+ template<class Other, class U, class Sig>
+ void _boost_type_erasure_assign_impl(
+ Other&& other,
+ const assignable<T, U>*,
+ const constructible<Sig>*,
+ ::boost::mpl::true_)
+ {
+ if(::boost::type_erasure::check_match(assignable<T, U>(), *this, other)) // const reference to other is enough!
+ {
+ ::boost::type_erasure::unchecked_call(assignable<T, U>(), *this, std::forward<Other>(other));
+ }
+ else
+ {
+ any temp(std::forward<Other>(other));
+ _boost_type_erasure_swap(temp);
+ }
+ }
+#else
+ /** INTERNAL ONLY */
+ template<class Other>
+ void _boost_type_erasure_resolve_assign_any(Other& other)
+ {
_boost_type_erasure_assign_impl(
other,
false? this->_boost_type_erasure_deduce_assign(
@@ -1114,7 +1868,7 @@ private:
/** INTERNAL ONLY */
template<class Other, class U>
void _boost_type_erasure_assign_impl(
- const Other& other,
+ Other& other,
const assignable<T, U>*,
const void*,
::boost::mpl::false_)
@@ -1124,7 +1878,7 @@ private:
/** INTERNAL ONLY */
template<class Other, class U>
void _boost_type_erasure_assign_impl(
- const Other& other,
+ Other& other,
const assignable<T, U>*,
const void*,
::boost::mpl::true_)
@@ -1134,7 +1888,7 @@ private:
/** INTERNAL ONLY */
template<class Other, class Sig>
void _boost_type_erasure_assign_impl(
- const Other& other,
+ Other& other,
const void*,
const constructible<Sig>*,
::boost::mpl::true_)
@@ -1145,7 +1899,7 @@ private:
/** INTERNAL ONLY */
template<class Other, class U, class Sig>
void _boost_type_erasure_assign_impl(
- const Other& other,
+ Other& other,
const assignable<T, U>*,
const constructible<Sig>*,
::boost::mpl::true_)
@@ -1160,11 +1914,17 @@ private:
_boost_type_erasure_swap(temp);
}
}
+#endif
friend struct ::boost::type_erasure::detail::access;
+#ifndef BOOST_TYPE_ERASURE_SFINAE_FRIENDLY_CONSTRUCTORS
// The table has to be initialized first for exception
// safety in some constructors.
table_type table;
::boost::type_erasure::detail::storage data;
+#else
+ template<class Concept2, class T2>
+ friend struct ::boost::type_erasure::any_constructor_impl;
+#endif
};
template<class Concept, class T>
@@ -1209,7 +1969,7 @@ public:
: table((
BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, U),
::boost::type_erasure::make_binding<
- ::boost::mpl::map< ::boost::mpl::pair<T, U> >
+ ::boost::mpl::map1< ::boost::mpl::pair<T, U> >
>()
))
{
@@ -1293,7 +2053,7 @@ public:
: data(::boost::type_erasure::detail::access::data(other)),
table(
::boost::type_erasure::detail::access::table(other),
- ::boost::mpl::map<
+ ::boost::mpl::map1<
::boost::mpl::pair<
T,
Tag2
@@ -1326,7 +2086,7 @@ public:
: data(::boost::type_erasure::detail::access::data(other)),
table(
::boost::type_erasure::detail::access::table(other),
- ::boost::mpl::map<
+ ::boost::mpl::map1<
::boost::mpl::pair<
T,
typename ::boost::remove_reference<Tag2>::type
@@ -1432,26 +2192,27 @@ public:
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.
- */
+ /** INTERNAL ONLY */
any& operator=(const any& other)
{
_boost_type_erasure_resolve_assign(other);
return *this;
}
+ /** INTERNAL ONLY */
+ any& operator=(any& other)
+ {
+ _boost_type_erasure_resolve_assign(other);
+ return *this;
+ }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ /** INTERNAL ONLY */
+ any& operator=(any&& other)
+ {
+ _boost_type_erasure_resolve_assign(std::move(other));
+ return *this;
+ }
/**
* Assigns to an @ref any.
*
@@ -1461,40 +2222,35 @@ public:
*
* \throws Whatever the assignment operator of the contained
* type throws. When falling back on construction,
- * throws @c std::bad_alloc. In this case assignment
+ * can only throw @c std::bad_alloc if @c U is an @ref any
+ * that uses a different @c Concept. 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(std::forward<U>(other));
+ return *this;
+ }
+#else
+ 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;
}
+#endif
-#ifndef BOOST_NO_FUNCTION_REFERENCE_QUALIFIERS
+#ifndef BOOST_NO_CXX11_REF_QUALIFIERS
/** INTERNAL ONLY */
operator param<Concept, T&>() const { return param<Concept, T&>(data, table); }
#endif
@@ -1506,6 +2262,71 @@ private:
::std::swap(data, other.data);
::std::swap(table, other.table);
}
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ /** INTERNAL ONLY */
+ template<class Other>
+ void _boost_type_erasure_resolve_assign(Other&& other)
+ {
+ _boost_type_erasure_assign_impl(
+ std::forward<Other>(other),
+ false? this->_boost_type_erasure_deduce_assign(
+ ::boost::type_erasure::detail::make_fallback(
+ std::forward<Other>(other),
+ ::boost::mpl::bool_<
+ sizeof(
+ ::boost::type_erasure::detail::check_overload(
+ ::boost::declval<any&>().
+ _boost_type_erasure_deduce_assign(std::forward<Other>(other))
+ )
+ ) == sizeof(::boost::type_erasure::detail::yes)
+ >()
+ )
+ ) : 0,
+ ::boost::mpl::and_<
+ ::boost::type_erasure::is_relaxed<Concept>,
+ ::boost::is_convertible<Other, any>
+#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1900))
+ , ::boost::mpl::not_<
+ ::boost::type_erasure::detail::is_rvalue_for_any<Other>
+ >
+#endif
+ >()
+ );
+ }
+ /** 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, std::forward<Other>(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, std::forward<Other>(other));
+ } else {
+ any temp(std::forward<Other>(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(std::forward<Other>(other));
+ _boost_type_erasure_swap(temp);
+ }
+#else
/** INTERNAL ONLY */
template<class Other>
void _boost_type_erasure_resolve_assign(Other& other)
@@ -1525,7 +2346,10 @@ private:
>()
)
) : 0,
- ::boost::type_erasure::is_relaxed<Concept>()
+ ::boost::mpl::and_<
+ ::boost::type_erasure::is_relaxed<Concept>,
+ ::boost::is_convertible<Other&, any>
+ >()
);
}
/** INTERNAL ONLY */
@@ -1561,6 +2385,7 @@ private:
any temp(other);
_boost_type_erasure_swap(temp);
}
+#endif
friend struct ::boost::type_erasure::detail::access;
::boost::type_erasure::detail::storage data;
@@ -1604,7 +2429,7 @@ public:
: table((
BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, U),
::boost::type_erasure::make_binding<
- ::boost::mpl::map< ::boost::mpl::pair<T, U> >
+ ::boost::mpl::map1< ::boost::mpl::pair<T, U> >
>()
))
{
@@ -1701,7 +2526,7 @@ public:
: data(::boost::type_erasure::detail::access::data(other)),
table(
::boost::type_erasure::detail::access::table(other),
- ::boost::mpl::map<
+ ::boost::mpl::map1<
::boost::mpl::pair<
T,
typename ::boost::remove_const<
@@ -1780,7 +2605,7 @@ public:
return *this;
}
-#ifndef BOOST_NO_FUNCTION_REFERENCE_QUALIFIERS
+#ifndef BOOST_NO_CXX11_REF_QUALIFIERS
/** INTERNAL ONLY */
operator param<Concept, const T&>() const { return param<Concept, const T&>(data, table); }
#endif
@@ -1841,7 +2666,7 @@ public:
: table((
BOOST_TYPE_ERASURE_INSTANTIATE1(Concept, T, U),
::boost::type_erasure::make_binding<
- ::boost::mpl::map< ::boost::mpl::pair<T, U> >
+ ::boost::mpl::map1< ::boost::mpl::pair<T, U> >
>()
))
{
@@ -1926,7 +2751,7 @@ public:
: data(::boost::type_erasure::detail::access::data(other)),
table(
std::move(::boost::type_erasure::detail::access::table(other)),
- ::boost::mpl::map<
+ ::boost::mpl::map1<
::boost::mpl::pair<
T,
Tag2
@@ -1959,7 +2784,7 @@ public:
: data(::boost::type_erasure::detail::access::data(other)),
table(
std::move(::boost::type_erasure::detail::access::table(other)),
- ::boost::mpl::map<
+ ::boost::mpl::map1<
::boost::mpl::pair<
T,
typename ::boost::remove_reference<Tag2>::type
@@ -2065,20 +2890,7 @@ public:
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.
- */
+ /** INTERNAL ONLY */
any& operator=(const any& other)
{
_boost_type_erasure_resolve_assign(other);
@@ -2094,40 +2906,20 @@ public:
*
* \throws Whatever the assignment operator of the contained
* type throws. When falling back on construction,
- * throws @c std::bad_alloc. In this case assignment
+ * can only throw @c std::bad_alloc if @c U is an @ref any
+ * that uses a different @c Concept. 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)
+ any& operator=(U&& other)
{
- _boost_type_erasure_resolve_assign(other);
+ _boost_type_erasure_resolve_assign(std::forward<U>(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
+#ifndef BOOST_NO_CXX11_REF_QUALIFIERS
/** INTERNAL ONLY */
operator param<Concept, T&&>() const { return param<Concept, T&&>(data, table); }
#endif
@@ -2141,57 +2933,68 @@ private:
}
/** INTERNAL ONLY */
template<class Other>
- void _boost_type_erasure_resolve_assign(Other& other)
+ void _boost_type_erasure_resolve_assign(Other&& other)
{
_boost_type_erasure_assign_impl(
- other,
+ std::forward<Other>(other),
false? this->_boost_type_erasure_deduce_assign(
::boost::type_erasure::detail::make_fallback(
- other,
+ std::forward<Other>(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::check_overload(
+ ::boost::declval<any&>().
+ _boost_type_erasure_deduce_assign(std::forward<Other>(other))
+ )
) == sizeof(::boost::type_erasure::detail::yes)
>()
)
) : 0,
- ::boost::type_erasure::is_relaxed<Concept>()
+ ::boost::mpl::and_<
+ ::boost::type_erasure::is_relaxed<Concept>,
+ ::boost::is_convertible<Other, any>
+ >()
);
}
/** INTERNAL ONLY */
template<class Other, class U>
void _boost_type_erasure_assign_impl(
- Other& other,
+ Other&& other,
const assignable<T, U>*,
::boost::mpl::false_)
{
- ::boost::type_erasure::call(assignable<T, U>(), *this, other);
+ ::boost::type_erasure::call(
+ assignable<T, U>(),
+ // lose rvalueness of this
+ ::boost::type_erasure::param<Concept, T&>(data, table),
+ std::forward<Other>(other));
}
/** INTERNAL ONLY */
template<class Other, class U>
void _boost_type_erasure_assign_impl(
- Other& other,
+ 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);
+ ::boost::type_erasure::unchecked_call(
+ assignable<T, U>(),
+ // lose rvalueness of this
+ ::boost::type_erasure::param<Concept, T&>(data, table),
+ std::forward<Other>(other));
} else {
- any temp(other);
+ any temp(std::forward<Other>(other));
_boost_type_erasure_swap(temp);
}
}
/** INTERNAL ONLY */
template<class Other>
void _boost_type_erasure_assign_impl(
- Other& other,
+ Other&& other,
const void*,
::boost::mpl::true_)
{
- any temp(other);
+ any temp(std::forward<Other>(other));
_boost_type_erasure_swap(temp);
}
@@ -2202,6 +3005,17 @@ private:
#endif
+#ifndef BOOST_NO_CXX11_TEMPLATE_ALIASES
+template<class Concept, class T>
+using any_ref = any<Concept, T&>;
+template<class Concept, class T>
+using any_cref = any<Concept, const T&>;
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+template<class Concept, class T>
+using any_rvref = any<Concept, T&&>;
+#endif
+#endif
+
}
}