Index: detail/initializer.hpp =================================================================== --- detail/initializer.hpp (revision 81552) +++ detail/initializer.hpp (working copy) @@ -20,6 +20,7 @@ #include "boost/call_traits.hpp" #include "boost/detail/reference_content.hpp" #include "boost/variant/recursive_wrapper_fwd.hpp" +#include "boost/variant/detail/move.hpp" #if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) # include "boost/mpl/aux_/value_wknd.hpp" @@ -79,8 +80,22 @@ recursive_enabled_T; typedef typename unwrap_recursive::type public_T; + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + typedef boost::is_reference + is_reference_content_t; + + typedef typename boost::mpl::if_::type + param_T; + + template struct disable_overload{}; + + typedef typename boost::mpl::if_, public_T&& >::type + param2_T; +#else typedef typename call_traits::param_type param_T; +#endif public: // static functions @@ -96,6 +111,18 @@ return BOOST_MPL_AUX_VALUE_WKND(index)::value; // which } +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + static int initialize(void* dest, param2_T operand) + { + // This assert must newer trigger, because all the reference contents are + // handled by the initilize(void* dest, param_T operand) function above + BOOST_ASSERT(!is_reference_content_t::value); + + typedef typename boost::mpl::if_::type value_T; + new(dest) value_T( boost::detail::variant::move(operand) ); + return BOOST_MPL_AUX_VALUE_WKND(index)::value; // which + } +#endif }; friend class initializer_node; Index: detail/backup_holder.hpp =================================================================== --- detail/backup_holder.hpp (revision 81552) +++ detail/backup_holder.hpp (working copy) @@ -13,7 +13,6 @@ #ifndef BOOST_VARIANT_DETAIL_BACKUP_HOLDER_HPP #define BOOST_VARIANT_DETAIL_BACKUP_HOLDER_HPP -#include "boost/config.hpp" #include "boost/assert.hpp" namespace boost { @@ -33,7 +32,7 @@ delete backup_; } - explicit backup_holder(T* backup) BOOST_NOEXCEPT + explicit backup_holder(T* backup) : backup_(backup) { } @@ -54,7 +53,7 @@ return *this; } - void swap(backup_holder& rhs) BOOST_NOEXCEPT + void swap(backup_holder& rhs) { T* tmp = rhs.backup_; rhs.backup_ = this->backup_; @@ -84,7 +83,7 @@ } template -void swap(backup_holder& lhs, backup_holder& rhs) BOOST_NOEXCEPT +void swap(backup_holder& lhs, backup_holder& rhs) { lhs.swap(rhs); } Index: variant.hpp =================================================================== --- variant.hpp (revision 81552) +++ variant.hpp (working copy) @@ -1468,6 +1468,74 @@ friend class convert_copy_into; +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + class convert_move_into + : public static_visitor + { + private: // representation + + void* storage_; + + public: // structors + + explicit convert_move_into(void* storage) BOOST_NOEXCEPT + : storage_(storage) + { + } + + public: // internal visitor interfaces (below) + + template + int internal_visit(T& operand, int) const + { + // NOTE TO USER : + // Compile error here indicates one of the source variant's types + // cannot be unambiguously converted to the destination variant's + // types (or that no conversion exists). + // + return initializer::initialize(storage_, detail::variant::move(operand) ); + } + + template + int internal_visit(boost::detail::reference_content& operand, long) const + { + return internal_visit( operand.get(), 1L ); + } + + template + int internal_visit(const boost::detail::reference_content& operand, long) const + { + return internal_visit( operand.get(), 1L ); + } + + template + int internal_visit(boost::detail::variant::backup_holder& operand, long) const + { + return internal_visit( operand.get(), 1L ); + } + + template + int internal_visit(const boost::detail::variant::backup_holder& operand, long) const + { + return internal_visit( operand.get(), 1L ); + } + + template + int internal_visit(boost::recursive_wrapper& operand, long) const + { + return internal_visit( operand.get(), 1L ); + } + + template + int internal_visit(const boost::recursive_wrapper& operand, long) const + { + return internal_visit( operand.get(), 1L ); + } + }; + + friend class convert_move_into; +#endif + private: // helpers, for structors, below template @@ -1490,6 +1558,28 @@ ); } +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template + typename boost::enable_if >::type convert_construct( + T&& operand + , int + , mpl::false_ = mpl::false_() // is_foreign_variant + ) + { + // NOTE TO USER : + // Compile error here indicates that the given type is not + // unambiguously convertible to one of the variant's types + // (or that no conversion exists). + // + indicate_which( + initializer::initialize( + storage_.address() + , detail::variant::move(operand) + ) + ); + } +#endif + template void convert_construct( Variant& operand @@ -1503,7 +1593,22 @@ ); } +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES template + typename boost::enable_if >::type convert_construct( + Variant&& operand + , long + , mpl::true_// is_foreign_variant + ) + { + convert_move_into visitor(storage_.address()); + indicate_which( + operand.internal_apply_visitor(visitor) + ); + } +#endif + + template void convert_construct_variant(Variant& operand) { // [Determine if the given variant is itself a bounded type, or if its @@ -1530,6 +1635,35 @@ ); } +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template + typename boost::enable_if >::type convert_construct_variant(Variant&& operand) + { + // [Determine if the given variant is itself a bounded type, or if its + // content needs to be converted (i.e., it is a 'foreign' variant):] + // + + typedef typename mpl::find_if< + types + , is_same< + add_const + , const Variant + > + >::type found_it; + + typedef typename mpl::end::type not_found; + typedef typename is_same< + found_it, not_found + >::type is_foreign_variant; + + // Convert move construct from operand: + convert_construct( + detail::variant::move(operand), 1L + , is_foreign_variant() + ); + } +#endif + template void convert_construct( boost::variant& operand @@ -1548,6 +1682,17 @@ convert_construct_variant(operand); } +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template + void convert_construct( + boost::variant&& operand + , long + ) + { + convert_construct_variant( detail::variant::move(operand) ); + } +#endif + public: // structors, cont. #if !defined(BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING) @@ -1597,8 +1742,15 @@ { convert_construct(operand, 1L); } - #endif // BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING workarounds + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template + variant(T&& operand, typename boost::enable_if >::type* = 0) + { + convert_construct( detail::variant::move(operand), 1L); + } +#endif public: // structors, cont.