Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r82158 - sandbox/static_vector/boost/container
From: adam.wulkiewicz_at_[hidden]
Date: 2012-12-21 17:13:35


Author: awulkiew
Date: 2012-12-21 17:13:34 EST (Fri, 21 Dec 2012)
New Revision: 82158
URL: http://svn.boost.org/trac/boost/changeset/82158

Log:
Implemented optimized, nonthrowing move ctor, move assignment and switch for static_vector with different template parameters.
Text files modified:
   sandbox/static_vector/boost/container/static_vector.hpp | 98 ++++++++++++++++++++++-----------------
   1 files changed, 54 insertions(+), 44 deletions(-)

Modified: sandbox/static_vector/boost/container/static_vector.hpp
==============================================================================
--- sandbox/static_vector/boost/container/static_vector.hpp (original)
+++ sandbox/static_vector/boost/container/static_vector.hpp 2012-12-21 17:13:34 EST (Fri, 21 Dec 2012)
@@ -135,6 +135,9 @@
     }
 #endif
 
+ template <typename V, std::size_t C, typename S>
+ friend class static_vector;
+
 public:
     typedef Value value_type;
     typedef stored_size_type size_type;
@@ -231,7 +234,7 @@
         other.m_size = 0;
     }
 
- // nothrow or basic (depends on traits)
+ // nothrow or strong (depends on stragety)
     // (note: linear complexity)
     template <std::size_t C, typename S>
 #if defined(BOOST_NO_RVALUE_REFERENCES)
@@ -239,9 +242,12 @@
 #else
     static_vector(static_vector<value_type, C, S> && other)
 #endif
- : m_size(0)
+ : m_size(other.m_size)
     {
- this->swap(other);
+ errh::check_capacity(*this, other.size()); // may throw
+
+ ::memcpy(this->data(), other.data(), sizeof(Value) * other.m_size);
+ other.m_size = 0;
     }
 
     // Move assignments
@@ -257,7 +263,7 @@
         return *this;
     }
 
- // nothrow or basic (depends on traits)
+ // nothrow or strong (depends on stragety)
     template <std::size_t C, typename S>
 #if defined(BOOST_NO_RVALUE_REFERENCES)
     static_vector & operator=(boost::rv< static_vector<value_type, C, S> > & other)
@@ -265,10 +271,13 @@
     static_vector & operator=(static_vector<value_type, C, S> && other)
 #endif
     {
+ errh::check_capacity(*this, other.size()); // may throw
+
         this->clear();
- this->swap(other);
- //this->swap(other);
- //other.clear();
+
+ ::memcpy(this->data(), other.data(), sizeof(Value) * other.m_size);
+ boost::swap(m_size, other.m_size);
+
         return *this;
     }
 
@@ -291,7 +300,7 @@
         this->swap_dispatch(other, use_nonthrowing_swap());
     }
 
- // basic
+ // nothrow, strong or basic (depends on traits and strategy)
     // swap (note: linear complexity)
     template <std::size_t C, typename S>
     void swap(static_vector<value_type, C, S> & other)
@@ -299,23 +308,12 @@
         errh::check_capacity(*this, other.size());
         errh::check_capacity(other, this->size());
 
- iterator it = this->begin();
- iterator other_it = other.begin();
+ typedef typename
+ static_vector_detail::static_vector_traits<
+ Value, Capacity, Strategy
+ >::use_nonthrowing_swap use_nonthrowing_swap;
 
- if ( this->size() < other.size() )
- {
- for (; it != this->end() ; ++it, ++other_it)
- boost::swap(*it, *other_it); // may throw
- this->insert(it, other_it, other.end()); // may throw
- other.erase(other_it, other.end());
- }
- else
- {
- for (; other_it != other.end() ; ++it, ++other_it)
- boost::swap(*it, *other_it); // may throw
- other.insert(other_it,it,this->end()); // may throw
- this->erase(it, this->end());
- }
+ this->swap_dispatch(other, use_nonthrowing_swap());
     }
 
     // strong
@@ -617,39 +615,51 @@
 
     // swap
 
- void swap_dispatch(static_vector & other, boost::true_type const& /*nonthrowing_version*/)
+ template <std::size_t C, typename S>
+ void swap_dispatch(static_vector<value_type, C, S> & other, boost::true_type const& /*nonthrowing_version*/)
     {
- // TODO - this may be too big for stack
- aligned_storage_type temp;
+ typedef typename
+ boost::mpl::if_c<
+ Capacity < C,
+ aligned_storage_type,
+ typename static_vector<value_type, C, S>::aligned_storage_type
+ >::type
+ storage_type;
+
+ storage_type temp;
         Value * temp_ptr = reinterpret_cast<Value*>(temp.address());
+
         ::memcpy(temp_ptr, this->data(), sizeof(Value) * this->size());
         ::memcpy(this->data(), other.data(), sizeof(Value) * other.size());
         ::memcpy(other.data(), temp_ptr, sizeof(Value) * this->size());
+
         boost::swap(m_size, other.m_size);
     }
 
- void swap_dispatch(static_vector & other, boost::false_type const& /*throwing_version*/)
+ template <std::size_t C, typename S>
+ void swap_dispatch(static_vector<value_type, C, S> & other, boost::false_type const& /*throwing_version*/)
     {
         namespace sv = static_vector_detail;
- iterator it = this->begin();
- iterator other_it = other.begin();
 
         if ( this->size() < other.size() )
- {
- for (; it != this->end() ; ++it, ++other_it)
- boost::swap(*it, *other_it); // may throw
- sv::uninitialized_copy(other_it, other.end(), it); // may throw
- sv::destroy(other_it, other.end());
- boost::swap(m_size, other.m_size);
- }
+ swap_dispatch_impl(this->begin(), this->end(), other.begin(), other.end()); // may throw
         else
- {
- for (; other_it != other.end() ; ++it, ++other_it)
- boost::swap(*it, *other_it); // may throw
- sv::uninitialized_copy(it, this->end(), other_it); // may throw
- sv::destroy(it, this->end());
- boost::swap(m_size, other.m_size);
- }
+ swap_dispatch_impl(other.begin(), other.end(), this->begin(), this->end()); // may throw
+ boost::swap(m_size, other.m_size);
+ }
+
+ template <typename ItSm, typename ItLa>
+ void swap_dispatch_impl(ItSm first_sm, ItSm last_sm, ItLa first_la, ItLa last_la)
+ {
+ //BOOST_ASSERT_MSG(std::distance(first_sm, last_sm) <= std::distance(first_la, last_la));
+
+ // TODO - use move instead of copy
+
+ namespace sv = static_vector_detail;
+ for (; first_sm != last_sm ; ++first_sm, ++first_la)
+ boost::swap(*first_sm, *first_la); // may throw
+ sv::uninitialized_copy(first_la, last_la, first_sm); // may throw
+ sv::destroy(first_la, last_la);
     }
 
     // insert


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