Index: boost/detail/make_reference_wrapper.hpp =================================================================== --- boost/detail/make_reference_wrapper.hpp (revision 0) +++ boost/detail/make_reference_wrapper.hpp (revision 0) @@ -0,0 +1,62 @@ +#ifndef BOOST_DETAIL_REFERENCE_WRAPPER_HPP +#define BOOST_DETAIL_REFERENCE_WRAPPER_HPP + +#include "boost/config.hpp" +#include "boost/type_traits/remove_reference.hpp" + +namespace boost { +namespace detail { + +/////////////////////////////////////////////////////////////////////////////// +// (detail) metafunction make_reference_wrapper +// +// Wraps with reference_wrapper if specified type is reference. +// + +template struct make_reference_wrapper; + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + +template +struct make_reference_wrapper +{ + typedef T type; +}; + +template +struct make_reference_wrapper< T& > +{ + typedef reference_wrapper type; +}; + +#else // defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) + +template +struct make_reference_wrapper + : mpl::if_< + is_reference + , reference_wrapper< typename remove_reference::type > + , T + > +{ +}; + +#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION workaround + +template <> +struct make_reference_wrapper< mpl::void_ > +{ + template + struct apply + : make_reference_wrapper + { + }; + + typedef mpl::void_ type; +}; + +} // namespace detail + +} // namespace boost + +#endif // BOOST_DETAIL_REFERENCE_WRAPPER_HPP Index: boost/variant/detail/initializer.hpp =================================================================== --- boost/variant/detail/initializer.hpp (revision 51573) +++ boost/variant/detail/initializer.hpp (working copy) @@ -18,7 +18,7 @@ #include "boost/config.hpp" #include "boost/call_traits.hpp" -#include "boost/detail/reference_content.hpp" +#include "boost/detail/make_reference_wrapper.hpp" #include "boost/variant/recursive_wrapper_fwd.hpp" #if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) @@ -88,7 +88,7 @@ static int initialize(void* dest, param_T operand) { - typedef typename boost::detail::make_reference_content< + typedef typename boost::detail::make_reference_wrapper< recursive_enabled_T >::type internal_T; @@ -164,7 +164,7 @@ , BOOST_PP_CAT(param_T,N) operand \ ) \ { \ - typedef typename boost::detail::make_reference_content< \ + typedef typename boost::detail::make_reference_wrapper< \ BOOST_PP_CAT(recursive_enabled_T,N) \ >::type internal_T; \ \ Index: boost/variant/get.hpp =================================================================== --- boost/variant/get.hpp (revision 51573) +++ boost/variant/get.hpp (working copy) @@ -23,6 +23,9 @@ #include "boost/type_traits/add_reference.hpp" #include "boost/type_traits/add_pointer.hpp" +#include "boost/type_traits/remove_reference.hpp" +#include "boost/ref.hpp" + #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) # include "boost/mpl/bool.hpp" # include "boost/mpl/or.hpp" @@ -70,6 +73,7 @@ typedef typename add_pointer::type pointer; typedef typename add_reference::type reference; + typedef typename ::boost::reference_wrapper< typename remove_reference::type > wrapped_reference; public: // visitor typedefs @@ -84,6 +88,11 @@ return boost::addressof(operand); } + pointer operator()( wrapped_reference operand ) const + { + return operand.get_pointer(); + } + template pointer operator()(const U&) const { Index: boost/variant/variant.hpp =================================================================== --- boost/variant/variant.hpp (revision 51573) +++ boost/variant/variant.hpp (working copy) @@ -34,7 +34,8 @@ #include "boost/variant/detail/has_nothrow_move.hpp" #include "boost/variant/detail/move.hpp" -#include "boost/detail/reference_content.hpp" +//#include "boost/detail/reference_content.hpp" +#include "boost/detail/make_reference_wrapper.hpp" #include "boost/aligned_storage.hpp" #include "boost/blank.hpp" #include "boost/static_assert.hpp" @@ -865,14 +866,14 @@ template BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type) - internal_visit(boost::detail::reference_content& operand, long) + internal_visit(boost::reference_wrapper& operand, long) { return internal_visit( operand.get(), 1L ); } template BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type) - internal_visit(const boost::detail::reference_content& operand, long) + internal_visit(const boost::reference_wrapper& operand, long) { return internal_visit( operand.get(), 1L ); } @@ -965,7 +966,7 @@ typedef typename mpl::transform< recursive_enabled_types - , mpl::protect< detail::make_reference_content<> > + , mpl::protect< detail::make_reference_wrapper<> > >::type internal_types; typedef typename mpl::front< @@ -1020,7 +1021,7 @@ private: // helpers, for internal typedefs (below) #define BOOST_VARIANT_AUX_MAKE_REFERENCE_CONTENT_TYPEDEFS(z,N,_) \ - typedef detail::make_reference_content< \ + typedef detail::make_reference_wrapper< \ BOOST_PP_CAT(recursive_enabled_T,N) \ >::type BOOST_PP_CAT(internal_T,N); \ /**/ @@ -1213,13 +1214,13 @@ # endif template - int internal_visit(boost::detail::reference_content& operand, long) const + int internal_visit(boost::reference_wrapper& operand, long) const { return internal_visit( operand.get(), 1L ); } template - int internal_visit(const boost::detail::reference_content& operand, long) const + int internal_visit(const boost::reference_wrapper& operand, long) const { return internal_visit( operand.get(), 1L ); } @@ -1565,7 +1566,7 @@ private: // helpers, for modifiers (below) template - void assign(const T& rhs) + inline void assign( const T& rhs ) { // If direct T-to-T assignment is not possible... detail::variant::direct_assigner direct_assign(rhs); @@ -1582,6 +1583,24 @@ } } + template + inline void assign( T& rhs ) + { + // If direct T-to-T assignment is not possible... + detail::variant::direct_assigner direct_assign(rhs); + if (this->apply_visitor(direct_assign) == false) + { + // ...then convert rhs to variant and assign: + // + // While potentially inefficient, the following construction of a + // variant allows T as any type convertible to one of the bounded + // types without excessive code redundancy. + // + variant temp(rhs); + variant_assign( detail::variant::move(temp) ); + } + } + public: // modifiers template @@ -1591,6 +1610,14 @@ return *this; } + template + variant& operator=(T& rhs) + { + assign(rhs); + return *this; + } + + // [MSVC6 requires copy assign appear after templated operator=] variant& operator=(const variant& rhs) { Index: boost/ref.hpp =================================================================== --- boost/ref.hpp (revision 51573) +++ boost/ref.hpp (working copy) @@ -32,15 +32,16 @@ template class reference_wrapper { public: + typedef reference_wrapper self_type; typedef T type; #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, < 1300 ) - explicit reference_wrapper(T& t): t_(&t) {} + reference_wrapper(T& t): t_(&t) {} #else - explicit reference_wrapper(T& t): t_(boost::addressof(t)) {} + reference_wrapper(T& t): t_(boost::addressof(t)) {} #endif