|
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