$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r85408 - in branches/release: boost/variant boost/variant/detail libs/variant/test
From: antoshkka_at_[hidden]
Date: 2013-08-20 05:03:29
Author: apolukhin
Date: 2013-08-20 05:03:29 EDT (Tue, 20 Aug 2013)
New Revision: 85408
URL: http://svn.boost.org/trac/boost/changeset/85408
Log:
Merge from trunk:
* Fix issue with const rvalue references in Boost.Variant (fixes #8988)
* Get rid of Boost.Variant hand written non-usable move emulation and use Boost.Move instead(refs #7601). This does not mean that Boost.Variant supports move emulation now, but removes duplicate/non-working code and makes sure that Boost.Variant is able to work with boost::move
Text files modified: 
   branches/release/boost/variant/detail/move.hpp     |    92 ---------------------------------       
   branches/release/boost/variant/variant.hpp         |     6 +                                       
   branches/release/libs/variant/test/rvalue_test.cpp |   107 ++++++++++++++++++++++++++++----------- 
   3 files changed, 81 insertions(+), 124 deletions(-)
Modified: branches/release/boost/variant/detail/move.hpp
==============================================================================
--- branches/release/boost/variant/detail/move.hpp	Tue Aug 20 04:57:49 2013	(r85407)
+++ branches/release/boost/variant/detail/move.hpp	2013-08-20 05:03:29 EDT (Tue, 20 Aug 2013)	(r85408)
@@ -24,100 +24,12 @@
 
 #include "boost/config.hpp"
 #include "boost/detail/workaround.hpp"
-#include "boost/mpl/if.hpp"
-#include "boost/type_traits/is_base_and_derived.hpp"
+#include "boost/move/move.hpp"
 
 namespace boost {
 namespace detail { namespace variant {
 
-//////////////////////////////////////////////////////////////////////////
-// forward declares
-//
-// NOTE: Incomplete until (if?) Boost.Move becomes part of Boost.
-//
-template <typename Deriving> class moveable;
-template <typename T>        class move_source;
-template <typename T>        class move_return;
-
-namespace detail {
-
-// (detail) moveable_tag
-//
-// Concrete type from which moveable<T> derives.
-//
-// TODO: Move into moveable_fwd.hpp and define has_move_constructor.
-//
-template <typename Deriving>
-struct moveable_tag
-{
-};
-
-} // namespace detail
-
-//////////////////////////////////////////////////////////////////////////
-// function template move
-//
-// Takes a T& and returns, if T derives moveable<T>, a move_source<T> for
-// the object; else, returns the T&.
-//
-
-namespace detail {
-
-// (detail) class template move_type
-//
-// Metafunction that, given moveable T, provides move_source<T>, else T&.
-//
-template <typename T>
-struct move_type
-{
-public: // metafunction result
-
-    typedef typename mpl::if_<
-          is_base_and_derived<detail::moveable_tag<T>, T>
-        , move_source<T>
-        , T&
-        >::type type;
-
-};
-
-} // namespace detail
-
-#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
-
-template <typename T>
-inline
-    typename detail::move_type<T>::type
-move(T& source)
-{
-    typedef typename detail::move_type<T>::type
-        move_t;
-
-    return move_t(source);
-}
-
-#else
-
-using std::move;
-
-#endif
-
-//////////////////////////////////////////////////////////////////////////
-// class template return_t
-//
-// Metafunction that, given moveable T, provides move_return<T>, else T.
-//
-template <typename T>
-struct return_t
-{
-public: // metafunction result
-
-    typedef typename mpl::if_<
-          is_base_and_derived<moveable<T>, T>
-        , move_return<T>
-        , T
-        >::type type;
-
-};
+using boost::move;
 
 //////////////////////////////////////////////////////////////////////////
 // function template move_swap
Modified: branches/release/boost/variant/variant.hpp
==============================================================================
--- branches/release/boost/variant/variant.hpp	Tue Aug 20 04:57:49 2013	(r85407)
+++ branches/release/boost/variant/variant.hpp	2013-08-20 05:03:29 EDT (Tue, 20 Aug 2013)	(r85408)
@@ -1776,7 +1776,8 @@
     
 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
     template <class T>
-    variant(T&& operand, typename boost::enable_if<boost::is_rvalue_reference<T&&> >::type* = 0)
+    variant(T&& operand, typename boost::enable_if<boost::is_rvalue_reference<T&&> >::type* = 0, 
+        typename boost::disable_if<boost::is_const<T> >::type* = 0)
     {
         convert_construct( detail::variant::move(operand), 1L);
     }
@@ -2187,7 +2188,8 @@
 
 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
     template <class T>
-    typename boost::enable_if<boost::is_rvalue_reference<T&&>, variant& >::type operator=(T&& rhs)
+    typename boost::enable_if_c<boost::is_rvalue_reference<T&&>::value && !boost::is_const<T>::value, variant& >::type 
+        operator=(T&& rhs)
     {
         move_assign( detail::variant::move(rhs) );
         return *this;
Modified: branches/release/libs/variant/test/rvalue_test.cpp
==============================================================================
--- branches/release/libs/variant/test/rvalue_test.cpp	Tue Aug 20 04:57:49 2013	(r85407)
+++ branches/release/libs/variant/test/rvalue_test.cpp	2013-08-20 05:03:29 EDT (Tue, 20 Aug 2013)	(r85408)
@@ -15,13 +15,56 @@
 #include "boost/variant.hpp"
 #include "boost/type_traits/is_nothrow_move_assignable.hpp"
 
-// This test requires rvalue references support
+// Most part of tests from this file require rvalue references support
+
+
+class move_copy_conting_class {
+public:
+    static unsigned int moves_count;
+    static unsigned int copy_count;
+
+    move_copy_conting_class(){}
+    move_copy_conting_class(BOOST_RV_REF(move_copy_conting_class) ) {
+        ++ moves_count;
+    }
+
+    move_copy_conting_class& operator=(BOOST_RV_REF(move_copy_conting_class) ) {
+        ++ moves_count;
+        return *this;
+    }
+
+    move_copy_conting_class(const move_copy_conting_class&) {
+        ++ copy_count;
+    }
+    move_copy_conting_class& operator=(BOOST_COPY_ASSIGN_REF(move_copy_conting_class) ) {
+        ++ copy_count;
+        return *this;
+    }
+};
+
+unsigned int move_copy_conting_class::moves_count = 0;
+unsigned int move_copy_conting_class::copy_count = 0;
 
 #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
 
 void run()
 {
-    BOOST_CHECK(true);
+    // Making sure that internals of Boost.Move do not interfere with
+    // internals of Boost.Variant and in case of C++03 or C++98 compilation 
+    // is still possible.
+    typedef boost::variant<int, move_copy_conting_class> variant_I_type;
+    variant_I_type v1, v2;
+    v1 = move_copy_conting_class();
+    v2 = v1; 
+    v2 = boost::move(v1);
+    v1.swap(v2);
+
+    move_copy_conting_class val;
+    v2 = boost::move(val);
+    v2 = 10;
+
+    variant_I_type v3(boost::move(val));
+    variant_I_type v4(boost::move(v1));
 }
 
 void run1()
@@ -39,34 +82,15 @@
     BOOST_CHECK(true);
 }
 
-#else 
 
-class move_copy_conting_class {
-public:
-    static unsigned int moves_count;
-    static unsigned int copy_count;
+void run_const_rvalues()
+{
+    BOOST_CHECK(true);
+}
 
-    move_copy_conting_class(){}
-    move_copy_conting_class(move_copy_conting_class&&) {
-        ++ moves_count;
-    }
 
-    move_copy_conting_class& operator=(move_copy_conting_class&&) {
-        ++ moves_count;
-        return *this;
-    }
-
-    move_copy_conting_class(const move_copy_conting_class&) {
-        ++ copy_count;
-    }
-    move_copy_conting_class& operator=(const move_copy_conting_class&) {
-        ++ copy_count;
-        return *this;
-    }
-};
+#else 
 
-unsigned int move_copy_conting_class::moves_count = 0;
-unsigned int move_copy_conting_class::copy_count = 0;
 
 void run()
 {
@@ -92,7 +116,7 @@
 
     move_copy_conting_class::moves_count = 0;
     move_copy_conting_class::copy_count = 0;
-    v2 = static_cast<variant_I_type&&>(v1);
+    v2 = boost::move(v1);
     // Assuring that `move_copy_conting_class` in v1 was moved at least once and was not copied
     BOOST_CHECK(move_copy_conting_class::moves_count != 0);
     BOOST_CHECK(move_copy_conting_class::copy_count == 0);
@@ -100,7 +124,7 @@
     v1 = move_copy_conting_class();
     move_copy_conting_class::moves_count = 0;
     move_copy_conting_class::copy_count = 0;
-    v2 = static_cast<variant_I_type&&>(v1);
+    v2 = boost::move(v1);
     // Assuring that `move_copy_conting_class` in v1 was moved at least once and was not copied
     BOOST_CHECK(move_copy_conting_class::moves_count != 0);
     BOOST_CHECK(move_copy_conting_class::copy_count == 0);
@@ -116,19 +140,19 @@
     variant_II_type v3;
     move_copy_conting_class::moves_count = 0;
     move_copy_conting_class::copy_count = 0;
-    v1 = static_cast<variant_II_type&&>(v3);
+    v1 = boost::move(v3);
     // Assuring that `move_copy_conting_class` in v3 was moved at least once (v1 and v3 have different types)
     BOOST_CHECK(move_copy_conting_class::moves_count != 0);
 
     move_copy_conting_class::moves_count = 0;
     move_copy_conting_class::copy_count = 0;
-    v2 = static_cast<variant_I_type&&>(v1);
+    v2 = boost::move(v1);
     // Assuring that `move_copy_conting_class` in v1 was moved at least once (v1 and v3 have different types)
     BOOST_CHECK(move_copy_conting_class::moves_count != 0);
 
     move_copy_conting_class::moves_count = 0;
     move_copy_conting_class::copy_count = 0;
-    variant_I_type v5(static_cast<variant_I_type&&>(v1));
+    variant_I_type v5(boost::move(v1));
     // Assuring that `move_copy_conting_class` in v1 was moved at least once and was not copied
     BOOST_CHECK(move_copy_conting_class::moves_count != 0);
     BOOST_CHECK(move_copy_conting_class::copy_count == 0);
@@ -148,7 +172,7 @@
 
     move_copy_conting_class c1;
     typedef boost::variant<int, move_copy_conting_class> variant_I_type;
-    variant_I_type v1(static_cast<move_copy_conting_class&&>(c1));
+    variant_I_type v1(boost::move(c1));
     
     // Assuring that `move_copy_conting_class` was not copyied
     BOOST_CHECK(move_copy_conting_class::copy_count == 0);
@@ -194,6 +218,24 @@
 #endif
 }
 
+inline const std::string get_string() { return "test"; } 
+inline const boost::variant<int, std::string> get_variant() { return std::string("test"); } 
+inline const boost::variant<std::string, int> get_variant2() { return std::string("test"); } 
+
+void run_const_rvalues()
+{
+    typedef boost::variant<int, std::string> variant_t;
+    const variant_t v1(get_string());
+    const variant_t v2(get_variant());
+    const variant_t v3(get_variant2());
+    
+    variant_t v4, v5, v6, v7;
+    v4 = get_string();
+    v5 = get_variant();
+    v6 = get_variant2();
+    v7 = boost::move(v1);
+}
+
 #endif
 
 struct nothrow_copyable_throw_movable {
@@ -221,5 +263,6 @@
    run_move_only();
    run_moves_are_noexcept();
    run_tricky_compilation_test();
+   run_const_rvalues();
    return 0;
 }