Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r84941 - in trunk: boost/circular_buffer libs/circular_buffer/test
From: antoshkka_at_[hidden]
Date: 2013-07-02 09:51:56


Author: apolukhin
Date: 2013-07-02 09:51:55 EDT (Tue, 02 Jul 2013)
New Revision: 84941
URL: http://svn.boost.org/trac/boost/changeset/84941

Log:
Basic commit of C++11 move constructor and move assignment for circular_buffer (refs #7888). some of the functions marked with BOOST_NOEXCEPT

Text files modified:
   trunk/boost/circular_buffer/base.hpp | 77 ++++++++++++++++++++++++++++-----------
   trunk/libs/circular_buffer/test/base_test.cpp | 33 +++++++++++++++++
   2 files changed, 88 insertions(+), 22 deletions(-)

Modified: trunk/boost/circular_buffer/base.hpp
==============================================================================
--- trunk/boost/circular_buffer/base.hpp Tue Jul 2 09:08:42 2013 (r84940)
+++ trunk/boost/circular_buffer/base.hpp 2013-07-02 09:51:55 EDT (Tue, 02 Jul 2013) (r84941)
@@ -15,6 +15,7 @@
     #pragma once
 #endif
 
+#include <boost/config.hpp>
 #include <boost/call_traits.hpp>
 #include <boost/concept_check.hpp>
 #include <boost/limits.hpp>
@@ -215,7 +216,7 @@
              Constant (in the size of the <code>circular_buffer</code>).
         \sa <code>get_allocator()</code> for obtaining an allocator %reference.
     */
- allocator_type get_allocator() const { return m_alloc; }
+ allocator_type get_allocator() const BOOST_NOEXCEPT { return m_alloc; }
 
     //! Get the allocator reference.
     /*!
@@ -231,7 +232,7 @@
               although use of stateful allocators in STL is discouraged.
         \sa <code>get_allocator() const</code>
     */
- allocator_type& get_allocator() { return m_alloc; }
+ allocator_type& get_allocator() BOOST_NOEXCEPT { return m_alloc; }
 
 // Element access
 
@@ -249,7 +250,7 @@
              Constant (in the size of the <code>circular_buffer</code>).
         \sa <code>end()</code>, <code>rbegin()</code>, <code>rend()</code>
     */
- iterator begin() { return iterator(this, empty() ? 0 : m_first); }
+ iterator begin() BOOST_NOEXCEPT { return iterator(this, empty() ? 0 : m_first); }
 
     //! Get the iterator pointing to the end of the <code>circular_buffer</code>.
     /*!
@@ -265,7 +266,7 @@
              Constant (in the size of the <code>circular_buffer</code>).
         \sa <code>begin()</code>, <code>rbegin()</code>, <code>rend()</code>
     */
- iterator end() { return iterator(this, 0); }
+ iterator end() BOOST_NOEXCEPT { return iterator(this, 0); }
 
     //! Get the const iterator pointing to the beginning of the <code>circular_buffer</code>.
     /*!
@@ -281,7 +282,7 @@
              Constant (in the size of the <code>circular_buffer</code>).
         \sa <code>end() const</code>, <code>rbegin() const</code>, <code>rend() const</code>
     */
- const_iterator begin() const { return const_iterator(this, empty() ? 0 : m_first); }
+ const_iterator begin() const BOOST_NOEXCEPT { return const_iterator(this, empty() ? 0 : m_first); }
 
     //! Get the const iterator pointing to the end of the <code>circular_buffer</code>.
     /*!
@@ -297,7 +298,7 @@
              Constant (in the size of the <code>circular_buffer</code>).
         \sa <code>begin() const</code>, <code>rbegin() const</code>, <code>rend() const</code>
     */
- const_iterator end() const { return const_iterator(this, 0); }
+ const_iterator end() const BOOST_NOEXCEPT { return const_iterator(this, 0); }
 
     //! Get the iterator pointing to the beginning of the "reversed" <code>circular_buffer</code>.
     /*!
@@ -313,7 +314,7 @@
              Constant (in the size of the <code>circular_buffer</code>).
         \sa <code>rend()</code>, <code>begin()</code>, <code>end()</code>
     */
- reverse_iterator rbegin() { return reverse_iterator(end()); }
+ reverse_iterator rbegin() BOOST_NOEXCEPT { return reverse_iterator(end()); }
 
     //! Get the iterator pointing to the end of the "reversed" <code>circular_buffer</code>.
     /*!
@@ -329,7 +330,7 @@
              Constant (in the size of the <code>circular_buffer</code>).
         \sa <code>rbegin()</code>, <code>begin()</code>, <code>end()</code>
     */
- reverse_iterator rend() { return reverse_iterator(begin()); }
+ reverse_iterator rend() BOOST_NOEXCEPT { return reverse_iterator(begin()); }
 
     //! Get the const iterator pointing to the beginning of the "reversed" <code>circular_buffer</code>.
     /*!
@@ -345,7 +346,7 @@
              Constant (in the size of the <code>circular_buffer</code>).
         \sa <code>rend() const</code>, <code>begin() const</code>, <code>end() const</code>
     */
- const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
+ const_reverse_iterator rbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); }
 
     //! Get the const iterator pointing to the end of the "reversed" <code>circular_buffer</code>.
     /*!
@@ -361,7 +362,7 @@
              Constant (in the size of the <code>circular_buffer</code>).
         \sa <code>rbegin() const</code>, <code>begin() const</code>, <code>end() const</code>
     */
- const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
+ const_reverse_iterator rend() const BOOST_NOEXCEPT { return const_reverse_iterator(begin()); }
 
     //! Get the element at the <code>index</code> position.
     /*!
@@ -703,7 +704,7 @@
              Constant (in the size of the <code>circular_buffer</code>).
         \sa <code>linearize()</code>, <code>array_one()</code>, <code>array_two()</code>
     */
- bool is_linearized() const { return m_first < m_last || m_last == m_buff; }
+ bool is_linearized() const BOOST_NOEXCEPT { return m_first < m_last || m_last == m_buff; }
 
     //! Rotate elements in the <code>circular_buffer</code>.
     /*!
@@ -770,7 +771,7 @@
         \sa <code>capacity()</code>, <code>max_size()</code>, <code>reserve()</code>,
             <code>\link resize() resize(size_type, const_reference)\endlink</code>
     */
- size_type size() const { return m_size; }
+ size_type size() const BOOST_NOEXCEPT { return m_size; }
 
     /*! \brief Get the largest possible size or capacity of the <code>circular_buffer</code>. (It depends on
                allocator's %max_size()).
@@ -784,7 +785,7 @@
              Constant (in the size of the <code>circular_buffer</code>).
         \sa <code>size()</code>, <code>capacity()</code>, <code>reserve()</code>
     */
- size_type max_size() const {
+ size_type max_size() const BOOST_NOEXCEPT {
         return (std::min<size_type>)(m_alloc.max_size(), (std::numeric_limits<difference_type>::max)());
     }
 
@@ -801,7 +802,7 @@
              Constant (in the size of the <code>circular_buffer</code>).
         \sa <code>full()</code>
     */
- bool empty() const { return size() == 0; }
+ bool empty() const BOOST_NOEXCEPT { return size() == 0; }
 
     //! Is the <code>circular_buffer</code> full?
     /*!
@@ -816,7 +817,7 @@
              Constant (in the size of the <code>circular_buffer</code>).
         \sa <code>empty()</code>
     */
- bool full() const { return capacity() == size(); }
+ bool full() const BOOST_NOEXCEPT { return capacity() == size(); }
 
     /*! \brief Get the maximum number of elements which can be inserted into the <code>circular_buffer</code> without
                overwriting any of already stored elements.
@@ -830,7 +831,7 @@
              Constant (in the size of the <code>circular_buffer</code>).
         \sa <code>capacity()</code>, <code>size()</code>, <code>max_size()</code>
     */
- size_type reserve() const { return capacity() - size(); }
+ size_type reserve() const BOOST_NOEXCEPT { return capacity() - size(); }
 
     //! Get the capacity of the <code>circular_buffer</code>.
     /*!
@@ -845,7 +846,7 @@
         \sa <code>reserve()</code>, <code>size()</code>, <code>max_size()</code>,
             <code>set_capacity(capacity_type)</code>
     */
- capacity_type capacity() const { return m_end - m_buff; }
+ capacity_type capacity() const BOOST_NOEXCEPT { return m_end - m_buff; }
 
     //! Change the capacity of the <code>circular_buffer</code>.
     /*!
@@ -1105,6 +1106,22 @@
         if (m_last == m_end)
             m_last = m_buff;
     }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ //! The move constructor.
+ /*! \brief Move constructs a <code>circular_buffer</code> from <code>cb</code>, leaving <code>cb</code> empty.
+ \pre C++ compiler with rvalue references support.
+ \post <code>cb.empty()</code>
+ \param cb <code>circular_buffer</code> to 'steal' value from.
+ \throws Nothing.
+ \par Constant.
+ */
+ circular_buffer(circular_buffer<T, Alloc>&& cb) BOOST_NOEXCEPT
+ : m_buff(0), m_end(0), m_first(0), m_last(0), m_size(0), m_alloc(cb.get_allocator()) {
+ cb.swap(*this);
+ }
+#endif // BOOST_NO_CXX11_RVALUE_REFERENCES
+
 
 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
 
@@ -1189,7 +1206,7 @@
              Constant (in the size of the <code>circular_buffer</code>) for scalar types; linear for other types.
         \sa <code>clear()</code>
     */
- ~circular_buffer() {
+ ~circular_buffer() BOOST_NOEXCEPT {
         destroy();
 #if BOOST_CB_ENABLE_DEBUG
         invalidate_all_iterators();
@@ -1234,6 +1251,22 @@
         return *this;
     }
 
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ /*! \brief Move constructs a <code>circular_buffer</code> from <code>cb</code>, leaving <code>cb</code> empty.
+ \pre C++ compiler with rvalue references support.
+ \post <code>cb.empty()</code>
+ \param cb <code>circular_buffer</code> to 'steal' value from.
+ \throws Nothing.
+ \par Constant.
+ */
+ circular_buffer<T, Alloc>& operator = (circular_buffer<T, Alloc>&& cb) BOOST_NOEXCEPT {
+ swap(cb); // now `this` holds `cb`
+ circular_buffer<T, Alloc>(get_allocator()) // temprary that holds initial `cb` allocator
+ .swap(cb); // makes `cb` empty
+ return *this;
+ }
+#endif // BOOST_NO_CXX11_RVALUE_REFERENCES
+
     //! Assign <code>n</code> items into the <code>circular_buffer</code>.
     /*!
         The content of the <code>circular_buffer</code> will be removed and replaced with <code>n</code> copies of the
@@ -1381,7 +1414,7 @@
              Constant (in the size of the <code>circular_buffer</code>).
         \sa <code>swap(circular_buffer<T, Alloc>&, circular_buffer<T, Alloc>&)</code>
     */
- void swap(circular_buffer<T, Alloc>& cb) {
+ void swap(circular_buffer<T, Alloc>& cb) BOOST_NOEXCEPT {
         swap_allocator(cb, is_stateless<allocator_type>());
         std::swap(m_buff, cb.m_buff);
         std::swap(m_end, cb.m_end);
@@ -2051,7 +2084,7 @@
             <code>rerase(iterator)</code>, <code>rerase(iterator, iterator)</code>,
             <code>erase_begin(size_type)</code>, <code>erase_end(size_type)</code>
     */
- void clear() {
+ void clear() BOOST_NOEXCEPT {
         destroy_content();
         m_size = 0;
     }
@@ -2175,7 +2208,7 @@
     }
 
     //! Destroy content and free allocated memory.
- void destroy() {
+ void destroy() BOOST_NOEXCEPT {
         destroy_content();
         deallocate(m_buff, capacity());
 #if BOOST_CB_ENABLE_DEBUG
@@ -2824,7 +2857,7 @@
     \sa <code>\link circular_buffer::swap(circular_buffer<T, Alloc>&) swap(circular_buffer<T, Alloc>&)\endlink</code>
 */
 template <class T, class Alloc>
-inline void swap(circular_buffer<T, Alloc>& lhs, circular_buffer<T, Alloc>& rhs) {
+inline void swap(circular_buffer<T, Alloc>& lhs, circular_buffer<T, Alloc>& rhs) BOOST_NOEXCEPT {
     lhs.swap(rhs);
 }
 

Modified: trunk/libs/circular_buffer/test/base_test.cpp
==============================================================================
--- trunk/libs/circular_buffer/test/base_test.cpp Tue Jul 2 09:08:42 2013 (r84940)
+++ trunk/libs/circular_buffer/test/base_test.cpp 2013-07-02 09:51:55 EDT (Tue, 02 Jul 2013) (r84941)
@@ -738,6 +738,38 @@
 #endif // #if !defined(BOOST_NO_EXCEPTIONS)
 }
 
+void move_container_on_cpp11() {
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ circular_buffer<MyInteger> cb1(10);
+ cb1.push_back(1);
+ cb1.push_back(2);
+ cb1.push_back(3);
+ cb1.push_back(4);
+ cb1.push_back(5);
+ cb1.push_back(6);
+
+ // Checking move constructor
+ circular_buffer<MyInteger> cb2(static_cast<circular_buffer<MyInteger>&& >(cb1));
+ circular_buffer<MyInteger>::iterator it2 = cb2.begin() + 1;
+
+ BOOST_CHECK(cb1.empty());
+ BOOST_CHECK(!cb2.empty());
+ BOOST_CHECK(it2[0] == 2);
+ BOOST_CHECK(it2[-1] == 1);
+ BOOST_CHECK(it2[2] == 4);
+
+ // Checking move assignment
+ cb1 = static_cast<circular_buffer<MyInteger>&& >(cb2);
+ circular_buffer<MyInteger>::iterator it1 = cb1.begin() + 1;
+
+ BOOST_CHECK(!cb1.empty());
+ BOOST_CHECK(cb2.empty());
+ BOOST_CHECK(it1[0] == 2);
+ BOOST_CHECK(it1[-1] == 1);
+ BOOST_CHECK(it1[2] == 4);
+#endif
+}
+
 // test main
 test_suite* init_unit_test_suite(int /*argc*/, char* /*argv*/[]) {
 
@@ -755,6 +787,7 @@
     tests->add(BOOST_TEST_CASE(&iterator_comparison_test));
     tests->add(BOOST_TEST_CASE(&iterator_invalidation_test));
     tests->add(BOOST_TEST_CASE(&exception_safety_test));
+ tests->add(BOOST_TEST_CASE(&move_container_on_cpp11));
 
     return tests;
 }


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