Add support for move constructors in C++11 (#6947).

This commit is contained in:
Ahmed Charles
2014-02-21 03:14:11 -08:00
parent 4c6825716f
commit 86b177d3ee
4 changed files with 158 additions and 10 deletions

View File

@@ -1,6 +1,7 @@
// -----------------------------------------------------------
// Copyright (c) 2001 Jeremy Siek
// Copyright (c) 2003-2006, 2008 Gennaro Prota
// Copyright (c) 2014 Ahmed Charles
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -267,11 +268,12 @@ struct bitset_test {
}
}
// assignment operator (absent from std::bitset)
static void assignment_operator(const Bitset& lhs, const Bitset& rhs)
// copy assignment operator (absent from std::bitset)
static void copy_assignment_operator(const Bitset& lhs, const Bitset& rhs)
{
Bitset b(lhs);
b = rhs;
b = b; // self assignment check
BOOST_CHECK(b == rhs);
// Changes to the copy do not affect the original
@@ -282,6 +284,27 @@ struct bitset_test {
}
}
#ifndef BOOST_NO_RVALUE_REFERENCES
// move constructor (absent from std::bitset)
static void move_constructor(const Bitset& b)
{
Bitset copy(boost::move(b));
BOOST_CHECK(b == copy);
}
// move assignment operator (absent from std::bitset)
static void move_assignment_operator(const Bitset& lhs, const Bitset& rhs)
{
Bitset b(lhs);
Bitset c(rhs);
b = boost::move(c);
b = boost::move(b); // self assignment check
BOOST_CHECK(b == rhs);
}
#endif // BOOST_NO_RVALUE_REFERENCES
static void swap(const Bitset& lhs, const Bitset& rhs)
{
// bitsets must be swapped

View File

@@ -1,6 +1,7 @@
// -----------------------------------------------------------
// Copyright (c) 2001 Jeremy Siek
// Copyright (c) 2003-2006 Gennaro Prota
// Copyright (c) 2014 Ahmed Charles
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -237,29 +238,70 @@ void run_test_cases( BOOST_EXPLICIT_TEMPLATE_TYPE(Block) )
Tests::copy_constructor(b);
}
//=====================================================================
// Test assignment operator
// Test copy assignment operator
{
bitset_type a, b;
Tests::assignment_operator(a, b);
Tests::copy_assignment_operator(a, b);
}
{
bitset_type a(std::string("1")), b(std::string("0"));
Tests::assignment_operator(a, b);
Tests::copy_assignment_operator(a, b);
}
{
bitset_type a(long_string), b(long_string);
Tests::assignment_operator(a, b);
Tests::copy_assignment_operator(a, b);
}
{
bitset_type a;
bitset_type b(long_string); // b greater than a, a empty
Tests::assignment_operator(a, b);
Tests::copy_assignment_operator(a, b);
}
{
bitset_type a(std::string("0"));
bitset_type b(long_string); // b greater than a
Tests::assignment_operator(a, b);
Tests::copy_assignment_operator(a, b);
}
#ifndef BOOST_NO_RVALUE_REFERENCES
//=====================================================================
// Test move constructor
{
boost::dynamic_bitset<Block> b;
Tests::move_constructor(b);
}
{
boost::dynamic_bitset<Block> b(std::string("0"));
Tests::move_constructor(b);
}
{
boost::dynamic_bitset<Block> b(long_string);
Tests::move_constructor(b);
}
//=====================================================================
// Test move assignment operator
{
bitset_type a, b;
Tests::move_assignment_operator(a, b);
}
{
bitset_type a(std::string("1")), b(std::string("0"));
Tests::move_assignment_operator(a, b);
}
{
bitset_type a(long_string), b(long_string);
Tests::move_assignment_operator(a, b);
}
{
bitset_type a;
bitset_type b(long_string); // b greater than a, a empty
Tests::move_assignment_operator(a, b);
}
{
bitset_type a(std::string("0"));
bitset_type b(long_string); // b greater than a
Tests::move_assignment_operator(a, b);
}
#endif // BOOST_NO_RVALUE_REFERENCES
//=====================================================================
// Test swap
{

View File

@@ -6,6 +6,7 @@
<!--
Copyright (c) 2001 Jeremy Siek
Copyright (c) 2003-2004, 2008 Gennaro Prota
Copyright (c) 2014 Ahmed Charles
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
@@ -163,11 +164,17 @@ public:
<a href=
"#cons5">dynamic_bitset</a>(const dynamic_bitset&amp; b);
<a href=
"#move-cons">dynamic_bitset</a>(dynamic_bitset&amp;&amp; b);
void <a href="#swap">swap</a>(dynamic_bitset&amp; b);
dynamic_bitset&amp; <a href=
"#assign">operator=</a>(const dynamic_bitset&amp; b);
dynamic_bitset&amp; <a href=
"#move-assign">operator=</a>(dynamic_bitset&amp;&amp; b);
allocator_type <a href="#get_allocator">get_allocator()</a> const;
void <a href=
@@ -621,6 +628,20 @@ allocator in <tt>x</tt>. <br />
(Required by <a href=
"http://www.sgi.com/tech/stl/Assignable.html">Assignable</a>.)
<hr />
<pre>
<a id="move-cons">dynamic_bitset</a>(dynamic_bitset&amp;&amp; x)
</pre>
<b>Effects:</b> Constructs a bitset that is the same as the bitset
<tt>x</tt>, while using the resources from <tt>x</tt>. The allocator
for this bitset is moved from the allocator in <tt>x</tt>. <br />
<b>Postconditions:</b> For all <tt>i</tt> in the range
<tt>[0,x.size())</tt>, <tt>(*this)[i] == x[i]</tt>.<br />
<b>Throws:</b> An allocation error if memory is exhausted
(<tt>std::bad_alloc</tt> if
<tt>Allocator=std::allocator</tt>).
<hr />
<pre>
template &lt;typename BlockInputIterator&gt;
@@ -764,6 +785,20 @@ dynamic_bitset&amp; <a id=
(Required by <a href=
"http://www.sgi.com/tech/stl/Assignable.html">Assignable</a>.)
<hr />
<pre>
dynamic_bitset&amp; <a id=
"move-assign">operator=</a>(dynamic_bitset&amp;&amp; x)
</pre>
<b>Effects:</b> This bitset becomes the same as the bitset
<tt>x</tt>, while using the resources from <tt>x</tt>.<br />
<b>Postconditions:</b> For all <tt>i</tt> in the range
<tt>[0,x.size())</tt>, <tt>(*this)[i] == x[i]</tt>.<br />
<b>Returns:</b> <tt>*this</tt>.<br />
<b>Throws:</b> An allocation error if memory is exhausted
(<tt>std::bad_alloc</tt> if <tt>Allocator=std::allocator</tt>).
<hr />
<pre>
allocator_type <a id="get_allocator">get_allocator()</a> const;
@@ -1509,6 +1544,12 @@ exception guarantee.
<hr />
<h3><a id="changes-from-previous-ver">Changes from previous version(s)</a></h3>
<h4><i>Changes in Boost 1.56.0</i></h4>
<ul>
<li>Support for C++11 move constructors.</li>
<li>Warning fixes on MSVC 2013.</li>
</ul>
<h4><i>Changes in Boost 1.37.0</i></h4>
<ul>
<li>The constructor from a block range implements a "do the right thing"
@@ -1561,9 +1602,12 @@ applied to their corresponding <tt>dynamic_bitset</tt>s.
</li>
</ul>
<i>General improvements</i>
<br /><br />
<ul>
<li>
Several optimizations to member and non-member functions and to the
nested class <tt>reference</tt>.
</li>
</ul>
<hr />
<h3><a id="see-also">See also</a></h3>
@@ -1595,6 +1639,10 @@ href="mailto:cda@freshsources.com">cda@freshsources.com</a>)<br
href="http://gennaro-prota.50webs.com/">Gennaro Prota</a>
(name.surname yahoo.com)</td>
</tr>
<tr>
<td>Copyright &copy; 2014</td>
<td>Ahmed Charles (<a href="mailto:acharles@outlook.com">acharles@outlook.com</a>)</td>
</tr>
</table>
<br />
<div class="legalnotice">

View File

@@ -2,6 +2,7 @@
//
// Copyright (c) 2001-2002 Chuck Allison and Jeremy Siek
// Copyright (c) 2003-2006, 2008 Gennaro Prota
// Copyright (c) 2014 Ahmed Charles
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -36,9 +37,10 @@
#include "boost/dynamic_bitset_fwd.hpp"
#include "boost/detail/dynamic_bitset.hpp"
#include "boost/detail/iterator.hpp" // used to implement append(Iter, Iter)
#include "boost/static_assert.hpp"
#include "boost/move/move.hpp"
#include "boost/limits.hpp"
#include "boost/pending/lowest_bit.hpp"
#include "boost/static_assert.hpp"
namespace boost {
@@ -208,6 +210,11 @@ public:
void swap(dynamic_bitset& b);
dynamic_bitset& operator=(const dynamic_bitset& b);
#ifndef BOOST_NO_RVALUE_REFERENCES
dynamic_bitset(dynamic_bitset&& src);
dynamic_bitset& operator=(dynamic_bitset&& src);
#endif // BOOST_NO_RVALUE_REFERENCES
allocator_type get_allocator() const;
// size changing operations
@@ -633,6 +640,34 @@ operator=(const dynamic_bitset<Block, Allocator>& b)
return *this;
}
#ifndef BOOST_NO_RVALUE_REFERENCES
template <typename Block, typename Allocator>
inline dynamic_bitset<Block, Allocator>::
dynamic_bitset(dynamic_bitset<Block, Allocator>&& b)
: m_bits(boost::move(b.m_bits)), m_num_bits(boost::move(b.m_num_bits))
{
// Required so that assert(m_check_invariants()); works.
assert((b.m_bits = buffer_type()).empty());
b.m_num_bits = 0;
}
template <typename Block, typename Allocator>
inline dynamic_bitset<Block, Allocator>& dynamic_bitset<Block, Allocator>::
operator=(dynamic_bitset<Block, Allocator>&& b)
{
if (boost::addressof(b) == this) { return *this; }
m_bits = boost::move(b.m_bits);
m_num_bits = boost::move(b.m_num_bits);
// Required so that assert(m_check_invariants()); works.
assert((b.m_bits = buffer_type()).empty());
b.m_num_bits = 0;
return *this;
}
#endif // BOOST_NO_RVALUE_REFERENCES
template <typename Block, typename Allocator>
inline typename dynamic_bitset<Block, Allocator>::allocator_type
dynamic_bitset<Block, Allocator>::get_allocator() const