diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2016-10-06 10:41:18 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2016-10-06 10:43:11 +0900 |
commit | f763a99a501650eff2c60288aa6f10ef916d769e (patch) | |
tree | 02af7e13f9a38c888ebf340fe764cbe7dae99da9 /boost/variant/variant.hpp | |
parent | 5cde13f21d36c7224b0e13d11c4b49379ae5210d (diff) | |
download | boost-f763a99a501650eff2c60288aa6f10ef916d769e.tar.gz boost-f763a99a501650eff2c60288aa6f10ef916d769e.tar.bz2 boost-f763a99a501650eff2c60288aa6f10ef916d769e.zip |
Imported Upstream version 1.62.0upstream/1.62.0
Change-Id: I9d4c1ddb7b7d8f0069217ecc582700f9fda6dd4c
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'boost/variant/variant.hpp')
-rw-r--r-- | boost/variant/variant.hpp | 325 |
1 files changed, 194 insertions, 131 deletions
diff --git a/boost/variant/variant.hpp b/boost/variant/variant.hpp index fa09eb5641..6296238507 100644 --- a/boost/variant/variant.hpp +++ b/boost/variant/variant.hpp @@ -4,7 +4,7 @@ //----------------------------------------------------------------------------- // // Copyright (c) 2002-2003 Eric Friedman, Itay Maman -// Copyright (c) 2012-2014 Antony Polukhin +// Copyright (c) 2012-2016 Antony Polukhin // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -18,72 +18,74 @@ #include <cstddef> // for std::size_t #include <new> // for placement new -#include "boost/type_index.hpp" - -#include "boost/variant/detail/config.hpp" -#include "boost/mpl/aux_/value_wknd.hpp" - -#include "boost/variant/variant_fwd.hpp" -#include "boost/variant/detail/backup_holder.hpp" -#include "boost/variant/detail/enable_recursive_fwd.hpp" -#include "boost/variant/detail/forced_return.hpp" -#include "boost/variant/detail/initializer.hpp" -#include "boost/variant/detail/make_variant_list.hpp" -#include "boost/variant/detail/over_sequence.hpp" -#include "boost/variant/detail/visitation_impl.hpp" -#include "boost/variant/detail/hash_variant.hpp" - -#include "boost/variant/detail/generic_result_type.hpp" -#include "boost/variant/detail/move.hpp" - -#include "boost/detail/no_exceptions_support.hpp" -#include "boost/detail/reference_content.hpp" -#include "boost/aligned_storage.hpp" -#include "boost/blank.hpp" -#include "boost/math/common_factor_ct.hpp" -#include "boost/static_assert.hpp" -#include "boost/preprocessor/cat.hpp" -#include "boost/preprocessor/repeat.hpp" -#include "boost/type_traits/alignment_of.hpp" -#include "boost/type_traits/add_const.hpp" -#include "boost/type_traits/has_nothrow_constructor.hpp" -#include "boost/type_traits/has_nothrow_copy.hpp" -#include "boost/type_traits/is_nothrow_move_assignable.hpp" -#include "boost/type_traits/is_nothrow_move_constructible.hpp" -#include "boost/type_traits/is_const.hpp" -#include "boost/type_traits/is_same.hpp" -#include "boost/type_traits/is_rvalue_reference.hpp" -#include "boost/utility/enable_if.hpp" -#include "boost/utility/declval.hpp" -#include "boost/variant/recursive_wrapper_fwd.hpp" -#include "boost/variant/static_visitor.hpp" - -#include "boost/mpl/assert.hpp" -#include "boost/mpl/begin_end.hpp" -#include "boost/mpl/bool.hpp" -#include "boost/mpl/deref.hpp" -#include "boost/mpl/empty.hpp" -#include "boost/mpl/eval_if.hpp" -#include "boost/mpl/find_if.hpp" -#include "boost/mpl/fold.hpp" -#include "boost/mpl/front.hpp" -#include "boost/mpl/identity.hpp" -#include "boost/mpl/if.hpp" -#include "boost/mpl/int.hpp" -#include "boost/mpl/is_sequence.hpp" -#include "boost/mpl/iterator_range.hpp" -#include "boost/mpl/iter_fold_if.hpp" -#include "boost/mpl/logical.hpp" -#include "boost/mpl/max_element.hpp" -#include "boost/mpl/next.hpp" -#include "boost/mpl/not.hpp" -#include "boost/mpl/pair.hpp" -#include "boost/mpl/protect.hpp" -#include "boost/mpl/push_front.hpp" -#include "boost/mpl/same_as.hpp" -#include "boost/mpl/size_t.hpp" -#include "boost/mpl/sizeof.hpp" -#include "boost/mpl/transform.hpp" +#include <boost/type_index.hpp> + +#include <boost/variant/detail/config.hpp> +#include <boost/mpl/aux_/value_wknd.hpp> + +#include <boost/variant/variant_fwd.hpp> +#include <boost/variant/detail/backup_holder.hpp> +#include <boost/variant/detail/enable_recursive_fwd.hpp> +#include <boost/variant/detail/forced_return.hpp> +#include <boost/variant/detail/initializer.hpp> +#include <boost/variant/detail/make_variant_list.hpp> +#include <boost/variant/detail/over_sequence.hpp> +#include <boost/variant/detail/visitation_impl.hpp> +#include <boost/variant/detail/hash_variant.hpp> + +#include <boost/variant/detail/generic_result_type.hpp> +#include <boost/variant/detail/move.hpp> + +#include <boost/detail/no_exceptions_support.hpp> +#include <boost/detail/reference_content.hpp> +#include <boost/aligned_storage.hpp> +#include <boost/blank.hpp> +#include <boost/math/common_factor_ct.hpp> +#include <boost/static_assert.hpp> +#include <boost/preprocessor/cat.hpp> +#include <boost/preprocessor/repeat.hpp> +#include <boost/type_traits/alignment_of.hpp> +#include <boost/type_traits/add_const.hpp> +#include <boost/type_traits/has_nothrow_constructor.hpp> +#include <boost/type_traits/has_nothrow_copy.hpp> +#include <boost/type_traits/is_nothrow_move_assignable.hpp> +#include <boost/type_traits/is_nothrow_move_constructible.hpp> +#include <boost/type_traits/is_const.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/type_traits/is_rvalue_reference.hpp> +#include <boost/type_traits/is_constructible.hpp> +#include <boost/type_traits/add_lvalue_reference.hpp> +#include <boost/utility/enable_if.hpp> +#include <boost/utility/declval.hpp> +#include <boost/variant/recursive_wrapper_fwd.hpp> +#include <boost/variant/static_visitor.hpp> + +#include <boost/mpl/assert.hpp> +#include <boost/mpl/begin_end.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/mpl/deref.hpp> +#include <boost/mpl/empty.hpp> +#include <boost/mpl/eval_if.hpp> +#include <boost/mpl/find_if.hpp> +#include <boost/mpl/fold.hpp> +#include <boost/mpl/front.hpp> +#include <boost/mpl/identity.hpp> +#include <boost/mpl/if.hpp> +#include <boost/mpl/int.hpp> +#include <boost/mpl/is_sequence.hpp> +#include <boost/mpl/iterator_range.hpp> +#include <boost/mpl/iter_fold_if.hpp> +#include <boost/mpl/logical.hpp> +#include <boost/mpl/max_element.hpp> +#include <boost/mpl/next.hpp> +#include <boost/mpl/not.hpp> +#include <boost/mpl/pair.hpp> +#include <boost/mpl/protect.hpp> +#include <boost/mpl/push_front.hpp> +#include <boost/mpl/same_as.hpp> +#include <boost/mpl/size_t.hpp> +#include <boost/mpl/sizeof.hpp> +#include <boost/mpl/transform.hpp> /////////////////////////////////////////////////////////////////////////////// // Implementation Macros: @@ -99,14 +101,14 @@ #if defined(BOOST_VARIANT_MINIMIZE_SIZE) # include <climits> // for SCHAR_MAX -# include "boost/mpl/eval_if.hpp" -# include "boost/mpl/equal_to.hpp" -# include "boost/mpl/identity.hpp" -# include "boost/mpl/int.hpp" -# include "boost/mpl/if.hpp" -# include "boost/mpl/less.hpp" -# include "boost/mpl/long.hpp" -# include "boost/mpl/O1_size.hpp" +# include <boost/mpl/eval_if.hpp> +# include <boost/mpl/equal_to.hpp> +# include <boost/mpl/identity.hpp> +# include <boost/mpl/int.hpp> +# include <boost/mpl/if.hpp> +# include <boost/mpl/less.hpp> +# include <boost/mpl/long.hpp> +# include <boost/mpl/O1_size.hpp> #endif @@ -254,6 +256,72 @@ struct is_variant_move_noexcept_assignable { #endif // BOOST_NO_CXX11_NOEXCEPT /////////////////////////////////////////////////////////////////////////////// +// (detail) metafunction is_variant_constructible_from +// +// Derives from true_type if at least one variant's type is constructible from T. +// +template <class T1, class T2> +struct is_constructible_ext: + boost::mpl::or_< + boost::is_constructible< + T1, + T2 + >, + boost::is_constructible< + T1, + typename boost::add_lvalue_reference<T2>::type + > + > +{}; + +template <class T, class Types> +struct is_variant_constructible_from: + boost::mpl::not_< boost::is_same< + typename boost::mpl::find_if< + Types, + is_constructible_ext<boost::mpl::_1, T> + >::type, + typename boost::mpl::end<Types>::type + > > +{}; + +template <BOOST_VARIANT_ENUM_PARAMS(typename T), class Types> +struct is_variant_constructible_from< boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Types >: + boost::is_same< + typename boost::mpl::find_if< + typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::recursive_enabled_types, + mpl::not_< is_variant_constructible_from< boost::mpl::_1, Types> > + >::type, + typename boost::mpl::end< typename boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::recursive_enabled_types >::type + > +{}; + +template <BOOST_VARIANT_ENUM_PARAMS(typename T), class Types> +struct is_variant_constructible_from< const boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>& , Types >: + is_variant_constructible_from<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Types > +{}; + +template <BOOST_VARIANT_ENUM_PARAMS(typename T), class Types> +struct is_variant_constructible_from< boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>& , Types >: + is_variant_constructible_from<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Types > +{}; + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +template <BOOST_VARIANT_ENUM_PARAMS(typename T), class Types> +struct is_variant_constructible_from< boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>&& , Types >: + is_variant_constructible_from<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Types > +{}; + +template <BOOST_VARIANT_ENUM_PARAMS(typename T), class Types> +struct is_variant_constructible_from< boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const && , Types >: + is_variant_constructible_from<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>, Types > +{}; + +#endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCE + + +/////////////////////////////////////////////////////////////////////////////// // (detail) metafunction make_storage // // Provides an aligned storage type capable of holding any of the types @@ -899,10 +967,10 @@ public: // structors public: // visitor interfaces template <typename T> - bool operator()(const T& rhs_content) const + bool operator()(T& rhs_content) const { // Since the precondition ensures lhs and rhs types are same, get T... - known_get<const T> getter; + known_get<T> getter; const T& lhs_content = lhs_.apply_visitor(getter); // ...and compare lhs and rhs contents: @@ -1120,6 +1188,7 @@ private: // helpers, for typedefs (below) ::boost::mpl::not_< mpl::empty<specified_types> >::value )); +public: // public typedefs typedef typename mpl::eval_if< is_recursive_ , mpl::transform< @@ -1129,9 +1198,7 @@ private: // helpers, for typedefs (below) > > , mpl::identity< specified_types > - >::type recursive_enabled_types; - -public: // public typedefs + >::type recursive_enabled_types; // used by is_variant_constructible_from<> trait typedef typename mpl::transform< recursive_enabled_types @@ -1648,7 +1715,10 @@ private: // helpers, for structors, below #endif template <BOOST_VARIANT_ENUM_PARAMS(typename U)> - void convert_construct( + typename boost::enable_if<mpl::or_< + boost::is_same<boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>, variant>, + boost::detail::variant::is_variant_constructible_from<boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>&, internal_types> + > >::type convert_construct( boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>& operand , long ) @@ -1657,7 +1727,10 @@ private: // helpers, for structors, below } template <BOOST_VARIANT_ENUM_PARAMS(typename U)> - void convert_construct( + typename boost::enable_if<mpl::or_< + boost::is_same<boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>, variant>, + boost::detail::variant::is_variant_constructible_from<const boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>&, internal_types> + > >::type convert_construct( const boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>& operand , long ) @@ -1667,7 +1740,10 @@ private: // helpers, for structors, below #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES template <BOOST_VARIANT_ENUM_PARAMS(typename U)> - void convert_construct( + typename boost::enable_if<mpl::or_< + boost::is_same<boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>, variant>, + boost::detail::variant::is_variant_constructible_from<boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>&&, internal_types> + > >::type convert_construct( boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>&& operand , long ) @@ -1678,27 +1754,12 @@ private: // helpers, for structors, below public: // structors, cont. -#if !defined(BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING) - template <typename T> - variant(const T& operand) - { - convert_construct(operand, 1L); - } - - template <typename T> - variant(T& operand) - { - convert_construct(operand, 1L); - } - -#elif defined(BOOST_VARIANT_AUX_HAS_CONSTRUCTOR_TEMPLATE_ORDERING_SFINAE_WKND) - - // For compilers that cannot distinguish between T& and const T& in - // template constructors, but do fully support SFINAE, we can workaround: - - template <typename T> - variant(const T& operand) + variant(const T& operand, + typename boost::enable_if<mpl::and_< + mpl::not_< boost::is_same<T, variant> >, + boost::detail::variant::is_variant_constructible_from<const T&, internal_types> + > >::type* = 0) { convert_construct(operand, 1L); } @@ -1706,31 +1767,25 @@ public: // structors, cont. template <typename T> variant( T& operand - , typename enable_if< - mpl::not_< is_const<T> > - , void - >::type* = 0 + , typename boost::enable_if<mpl::and_< + mpl::not_< is_const<T> >, + mpl::not_< boost::is_same<T, variant> >, + boost::detail::variant::is_variant_constructible_from<T&, internal_types> + > >::type* = 0 ) { convert_construct(operand, 1L); } -#else // !defined(BOOST_VARIANT_AUX_HAS_CONSTRUCTOR_TEMPLATE_ORDERING_SFINAE_WKND) - - // For compilers that cannot distinguish between T& and const T& in - // template constructors, and do NOT support SFINAE, we can't workaround: - - template <typename T> - variant(const T& operand) - { - convert_construct(operand, 1L); - } -#endif // BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING workarounds - #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES template <class T> - variant(T&& operand, typename boost::enable_if<boost::is_rvalue_reference<T&&> >::type* = 0, - typename boost::disable_if<boost::is_const<T> >::type* = 0) + variant(T&& operand, + typename boost::enable_if<mpl::and_< + boost::is_rvalue_reference<T&&>, + mpl::not_< boost::is_const<T> >, + mpl::not_< boost::is_same<T, variant> >, + boost::detail::variant::is_variant_constructible_from<T&&, internal_types> + > >::type* = 0) { convert_construct( detail::variant::move(operand), 1L); } @@ -1748,7 +1803,7 @@ public: // structors, cont. // ...and activate the *this's primary storage on success: indicate_which(operand.which()); } - + #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES variant(variant&& operand) BOOST_NOEXCEPT_IF(variant_move_noexcept_constructible::type::value) { @@ -2122,8 +2177,14 @@ public: // modifiers #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES template <class T> - typename boost::enable_if_c<boost::is_rvalue_reference<T&&>::value && !boost::is_const<T>::value, variant& >::type - operator=(T&& rhs) + typename boost::enable_if< + boost::mpl::and_< + boost::is_rvalue_reference<T&&>, + mpl::not_< boost::is_const<T> >, + boost::detail::variant::is_variant_constructible_from<T&&, internal_types> + >, + variant& + >::type operator=(T&& rhs) { move_assign( detail::variant::move(rhs) ); return *this; @@ -2131,7 +2192,13 @@ public: // modifiers #endif // BOOST_NO_CXX11_RVALUE_REFERENCES template <typename T> - variant& operator=(const T& rhs) + typename boost::enable_if< + mpl::or_< + boost::is_same<T, variant>, + boost::detail::variant::is_variant_constructible_from<const T&, internal_types> + >, + variant& + >::type operator=(const T& rhs) { assign(rhs); return *this; @@ -2146,7 +2213,7 @@ public: // modifiers #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES variant& operator=(variant&& rhs) -#if !defined(__GNUC__) || (__GNUC__ != 4) || (__GNUC_MINOR__ > 6) +#if !defined(__GNUC__) || (__GNUC__ != 4) || (__GNUC_MINOR__ > 6) || defined(__clang__) BOOST_NOEXCEPT_IF(variant_move_noexcept_constructible::type::value && variant_move_noexcept_assignable::type::value) #endif { @@ -2192,10 +2259,6 @@ public: // queries public: // prevent comparison with foreign types -// Obsolete. Remove. -# define BOOST_VARIANT_AUX_FAIL_COMPARISON_RETURN_TYPE \ - void - template <typename U> void operator==(const U&) const { @@ -2412,7 +2475,7 @@ inline void swap( // implementation additions #if !defined(BOOST_NO_IOSTREAM) -#include "boost/variant/detail/variant_io.hpp" +#include <boost/variant/detail/variant_io.hpp> #endif // BOOST_NO_IOSTREAM #endif // BOOST_VARIANT_VARIANT_HPP |