Boost logo

Boost-Commit :

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;
 }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk