|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r84988 - in trunk: boost/circular_buffer libs/circular_buffer/test
From: antoshkka_at_[hidden]
Date: 2013-07-09 05:32:45
Author: apolukhin
Date: 2013-07-09 05:32:45 EDT (Tue, 09 Jul 2013)
New Revision: 84988
URL: http://svn.boost.org/trac/boost/changeset/84988
Log:
Improved rvalues move support for elements of circular_buffer (refs #7888):
* move_if_noexcept uses is_copy_constructible trait
* more tests, tests are now more strict
* linearize() now works with move-only types
Text files modified:
trunk/boost/circular_buffer/base.hpp | 9 ++-
trunk/libs/circular_buffer/test/base_test.cpp | 88 +++++++++++++++++++++++++++++++++++-----
2 files changed, 82 insertions(+), 15 deletions(-)
Modified: trunk/boost/circular_buffer/base.hpp
==============================================================================
--- trunk/boost/circular_buffer/base.hpp Tue Jul 9 03:49:44 2013 (r84987)
+++ trunk/boost/circular_buffer/base.hpp 2013-07-09 05:32:45 EDT (Tue, 09 Jul 2013) (r84988)
@@ -2,6 +2,7 @@
// Copyright (c) 2003-2008 Jan Gaspar
// Copyright (c) 2013 Paul A. Bristow // Doxygen comments changed.
+// Copyright (c) 2013 Antony Polukhin // Move semantics implementation.
// Use, modification, and distribution is subject to the Boost Software
@@ -25,6 +26,7 @@
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_scalar.hpp>
#include <boost/type_traits/is_nothrow_move_constructible.hpp>
+#include <boost/type_traits/is_copy_constructible.hpp>
#include <boost/type_traits/conditional.hpp>
#include <boost/move/move.hpp>
#include <algorithm>
@@ -185,12 +187,11 @@
private:
// TODO: move to Boost.Move
- // TODO: Improve!
template <class ValT>
static inline typename boost::conditional<
- (boost::is_nothrow_move_constructible<ValT>::value /* || !boost::has_copy_constructor<T>::value*/)
+ (boost::is_nothrow_move_constructible<ValT>::value || !boost::is_copy_constructible<ValT>::value)
#ifdef BOOST_NO_CXX11_DELETED_FUNCTIONS
- && has_move_emulation_enabled<T>::value
+ && has_move_emulation_enabled<ValT>::value
#endif
,
rvalue_type,
@@ -690,7 +691,7 @@
break;
}
if (is_uninitialized(dest)) {
- new (dest) value_type(*src);
+ new (dest) value_type(this_type::move_if_noexcept(*src));
++constructed;
} else {
value_type tmp = this_type::move_if_noexcept(*src);
Modified: trunk/libs/circular_buffer/test/base_test.cpp
==============================================================================
--- trunk/libs/circular_buffer/test/base_test.cpp Tue Jul 9 03:49:44 2013 (r84987)
+++ trunk/libs/circular_buffer/test/base_test.cpp 2013-07-09 05:32:45 EDT (Tue, 09 Jul 2013) (r84988)
@@ -771,22 +771,30 @@
}
-struct noncopyable_movable_test_t {
+struct noncopyable_movable_test_t
+ : private boost::noncopyable // required, until there will be no support for is_copy_constructible added to Boost.Move
+{
private:
BOOST_MOVABLE_BUT_NOT_COPYABLE(noncopyable_movable_test_t)
bool is_moved_;
+ int value_;
public:
+ static int next_value;
+
explicit noncopyable_movable_test_t()
: is_moved_(false)
+ , value_(next_value ++)
{}
noncopyable_movable_test_t(BOOST_RV_REF(noncopyable_movable_test_t) x) BOOST_NOEXCEPT {
is_moved_ = x.is_moved_;
+ value_ = x.value_;
x.is_moved_ = true;
}
noncopyable_movable_test_t& operator=(BOOST_RV_REF(noncopyable_movable_test_t) x) BOOST_NOEXCEPT {
is_moved_ = x.is_moved_;
+ value_ = x.value_;
x.is_moved_ = true;
return *this;
}
@@ -795,56 +803,103 @@
return is_moved_;
}
- void reinit() { is_moved_ = false; }
+ int value() const {
+ return value_;
+ }
+
+ void reinit() { is_moved_ = false; value_ = next_value ++; }
};
-// Required for C++03 compilers
-namespace boost {
- template <>
- struct is_nothrow_move_constructible<noncopyable_movable_test_t> {
- BOOST_STATIC_CONSTANT(bool, value = true);
- };
-} // namespace boost
+int noncopyable_movable_test_t::next_value = 1;
void move_container_values() {
+ noncopyable_movable_test_t::next_value = 1;
+
CB_CONTAINER<noncopyable_movable_test_t> cb1(40);
noncopyable_movable_test_t var;
cb1.push_back(boost::move(var));
BOOST_CHECK(!cb1.back().is_moved());
+ BOOST_CHECK(cb1.back().value() == 1);
BOOST_CHECK(var.is_moved());
BOOST_CHECK(cb1.size() == 1);
var.reinit();
cb1.push_front(boost::move(var));
BOOST_CHECK(!cb1.front().is_moved());
+ BOOST_CHECK(cb1.front().value() == 2);
BOOST_CHECK(var.is_moved());
BOOST_CHECK(cb1.size() == 2);
cb1.push_back();
BOOST_CHECK(!cb1.back().is_moved());
+ BOOST_CHECK(cb1.back().value() == 3);
BOOST_CHECK(cb1.size() == 3);
cb1.push_front();
BOOST_CHECK(!cb1.front().is_moved());
+ BOOST_CHECK(cb1.front().value() == 4);
BOOST_CHECK(cb1.size() == 4);
cb1.insert(cb1.begin());
BOOST_CHECK(!cb1.front().is_moved());
+ BOOST_CHECK(cb1.front().value() == 5);
BOOST_CHECK(cb1.size() == 5);
var.reinit();
cb1.insert(cb1.begin(), boost::move(var));
BOOST_CHECK(!cb1.front().is_moved());
+ BOOST_CHECK(cb1.front().value() == 6);
BOOST_CHECK(cb1.size() == 6);
cb1.rinsert(cb1.begin());
- BOOST_CHECK(!cb1.back().is_moved());
+ BOOST_CHECK(!cb1.front().is_moved());
+ BOOST_CHECK(cb1.front().value() == 7);
BOOST_CHECK(cb1.size() == 7);
var.reinit();
cb1.rinsert(cb1.begin(), boost::move(var));
- BOOST_CHECK(!cb1.back().is_moved());
+ BOOST_CHECK(!cb1.front().is_moved());
+ BOOST_CHECK(cb1.front().value() == 8);
BOOST_CHECK(cb1.size() == 8);
+
+
+ BOOST_CHECK(cb1[0].value() == 8);
+ BOOST_CHECK(cb1[1].value() == 7);
+ BOOST_CHECK(cb1[2].value() == 6);
+ BOOST_CHECK(cb1[3].value() == 5);
+ BOOST_CHECK(cb1[4].value() == 4);
+ BOOST_CHECK(cb1[5].value() == 2);
+ BOOST_CHECK(cb1[6].value() == 1);
+ BOOST_CHECK(cb1[7].value() == 3);
+ cb1.rotate(cb1.begin() + 2);
+ BOOST_CHECK(cb1[0].value() == 6);
+ BOOST_CHECK(cb1[1].value() == 5);
+ BOOST_CHECK(cb1[2].value() == 4);
+ BOOST_CHECK(cb1[3].value() == 2);
+ BOOST_CHECK(cb1[4].value() == 1);
+ BOOST_CHECK(cb1[5].value() == 3);
+ BOOST_CHECK(cb1[6].value() == 8);
+ BOOST_CHECK(cb1[7].value() == 7);
+
+ BOOST_CHECK(!cb1[0].is_moved());
+ BOOST_CHECK(!cb1[1].is_moved());
+ BOOST_CHECK(!cb1[2].is_moved());
+ BOOST_CHECK(!cb1[3].is_moved());
+ BOOST_CHECK(!cb1[4].is_moved());
+ BOOST_CHECK(!cb1[5].is_moved());
+ BOOST_CHECK(!cb1[6].is_moved());
+ BOOST_CHECK(!cb1[7].is_moved());
+
+
+ cb1.linearize();
+ BOOST_CHECK(!cb1[0].is_moved());
+ BOOST_CHECK(!cb1[1].is_moved());
+ BOOST_CHECK(!cb1[2].is_moved());
+ BOOST_CHECK(!cb1[3].is_moved());
+ BOOST_CHECK(!cb1[4].is_moved());
+ BOOST_CHECK(!cb1[5].is_moved());
+ BOOST_CHECK(!cb1[6].is_moved());
+ BOOST_CHECK(!cb1[7].is_moved());
}
void move_container_values_resetting() {
@@ -920,6 +975,17 @@
BOOST_CHECK(cb1.size() == 1);
var = boost::move(cb1.back());
BOOST_CHECK(cb1.back().is_moved());
+ cb1.push_back();
+ BOOST_CHECK(!cb1[0].is_moved());
+
+ const int val = cb1[0].value();
+ cb1.linearize();
+ BOOST_CHECK(!cb1[0].is_moved());
+ BOOST_CHECK(cb1[0].value() == val);
+
+ cb1.rotate(cb1.begin());
+ BOOST_CHECK(!cb1[0].is_moved());
+ BOOST_CHECK(cb1[0].value() == val);
}
// test main
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