mirror of
https://github.com/boostorg/container.git
synced 2025-08-02 14:04:26 +02:00
Merge branch 'develop'
This commit is contained in:
@@ -298,7 +298,7 @@ public:
|
|||||||
//! @param count The number of values which will be contained in the container.
|
//! @param count The number of values which will be contained in the container.
|
||||||
//!
|
//!
|
||||||
//! @par Throws
|
//! @par Throws
|
||||||
//! If Value's default constructor throws.
|
//! If Value's value initialization throws.
|
||||||
//! @internal
|
//! @internal
|
||||||
//! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
|
//! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
|
||||||
//! @endinternal
|
//! @endinternal
|
||||||
@@ -621,7 +621,7 @@ public:
|
|||||||
//! @param count The number of elements which will be stored in the container.
|
//! @param count The number of elements which will be stored in the container.
|
||||||
//!
|
//!
|
||||||
//! @par Throws
|
//! @par Throws
|
||||||
//! If Value's default constructor throws.
|
//! If Value's value initialization throws.
|
||||||
//! @internal
|
//! @internal
|
||||||
//! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
|
//! @li If a throwing error handler is specified, throws when the capacity is exceeded. (not by default).
|
||||||
//! @endinternal
|
//! @endinternal
|
||||||
|
@@ -97,7 +97,7 @@ public:
|
|||||||
//! @param count The number of values which will be contained in the container.
|
//! @param count The number of values which will be contained in the container.
|
||||||
//!
|
//!
|
||||||
//! @par Throws
|
//! @par Throws
|
||||||
//! If Value's default constructor throws.
|
//! If Value's value initialization throws.
|
||||||
//!
|
//!
|
||||||
//! @par Complexity
|
//! @par Complexity
|
||||||
//! Linear O(N).
|
//! Linear O(N).
|
||||||
@@ -317,7 +317,7 @@ public:
|
|||||||
//! @param count The number of elements which will be stored in the container.
|
//! @param count The number of elements which will be stored in the container.
|
||||||
//!
|
//!
|
||||||
//! @par Throws
|
//! @par Throws
|
||||||
//! If Value's default constructor throws.
|
//! If Value's value initialization throws.
|
||||||
//!
|
//!
|
||||||
//! @par Complexity
|
//! @par Complexity
|
||||||
//! Linear O(N).
|
//! Linear O(N).
|
||||||
|
@@ -963,6 +963,10 @@ use [*Boost.Container]? There are several reasons for that:
|
|||||||
* Fixed bugs:
|
* Fixed bugs:
|
||||||
* [@https://svn.boost.org/trac/boost/ticket/9338 #9338: ['"VS2005 compiler errors in swap() definition after including container/memory_util.hpp"]].
|
* [@https://svn.boost.org/trac/boost/ticket/9338 #9338: ['"VS2005 compiler errors in swap() definition after including container/memory_util.hpp"]].
|
||||||
* [@https://svn.boost.org/trac/boost/ticket/9648 #9648: ['"string construction optimization - char_traits::copy could be used ..."]].
|
* [@https://svn.boost.org/trac/boost/ticket/9648 #9648: ['"string construction optimization - char_traits::copy could be used ..."]].
|
||||||
|
* [@https://svn.boost.org/trac/boost/ticket/9915 #9915: ['"Documentation issues regarding vector constructors and resize methods - value/default initialization"]].
|
||||||
|
* [@https://svn.boost.org/trac/boost/ticket/9916 #9916: ['"Allocator propagation incorrect in the assignment operator of most"]].
|
||||||
|
* [@https://svn.boost.org/trac/boost/ticket/9931 #9931: ['"flat_map::insert(ordered_unique_range_t...) fails with move_iterators"]].
|
||||||
|
* [@https://svn.boost.org/trac/boost/ticket/9932 #9932: ['"Missing assignment operator from related static_vector"]].
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
|
@@ -35,7 +35,7 @@ int main ()
|
|||||||
l.emplace(l.begin(), 0);
|
l.emplace(l.begin(), 0);
|
||||||
assert(l.size() == 1);
|
assert(l.size() == 1);
|
||||||
|
|
||||||
//A new element will be built calling the default constructor
|
//A new element will be value initialized
|
||||||
l.emplace(l.begin());
|
l.emplace(l.begin());
|
||||||
assert(l.size() == 2);
|
assert(l.size() == 2);
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -335,32 +335,7 @@ class adaptive_pool
|
|||||||
//!instance can be deallocated by another instance
|
//!instance can be deallocated by another instance
|
||||||
friend bool operator!=(const adaptive_pool &, const adaptive_pool &) BOOST_CONTAINER_NOEXCEPT
|
friend bool operator!=(const adaptive_pool &, const adaptive_pool &) BOOST_CONTAINER_NOEXCEPT
|
||||||
{ return false; }
|
{ return false; }
|
||||||
/*
|
|
||||||
//!Returns address of mutable object.
|
|
||||||
//!Never throws
|
|
||||||
pointer address(reference value) const
|
|
||||||
{ return pointer(boost::addressof(value)); }
|
|
||||||
|
|
||||||
//!Returns address of non mutable object.
|
|
||||||
//!Never throws
|
|
||||||
const_pointer address(const_reference value) const
|
|
||||||
{ return const_pointer(boost::addressof(value)); }
|
|
||||||
|
|
||||||
//!Default construct an object.
|
|
||||||
//!Throws if T's default constructor throws
|
|
||||||
void construct(const pointer &ptr)
|
|
||||||
{ new(ptr) value_type; }
|
|
||||||
|
|
||||||
//!Construct a copy of the passed object.
|
|
||||||
//!Throws if T's copy constructor throws
|
|
||||||
void construct(pointer ptr, const_reference t)
|
|
||||||
{ new(ptr) value_type(t); }
|
|
||||||
|
|
||||||
//!Destroys object. Throws if object's
|
|
||||||
//!destructor throws
|
|
||||||
void destroy(const pointer &ptr)
|
|
||||||
{ (void)ptr; BOOST_ASSERT(ptr); (*ptr).~value_type(); }
|
|
||||||
*/
|
|
||||||
private:
|
private:
|
||||||
std::pair<pointer, bool> priv_allocation_command
|
std::pair<pointer, bool> priv_allocation_command
|
||||||
(allocation_type command, std::size_t limit_size
|
(allocation_type command, std::size_t limit_size
|
||||||
|
@@ -67,7 +67,7 @@ class allocator<void, Version, AllocationDisableMask>
|
|||||||
|
|
||||||
//!Default constructor
|
//!Default constructor
|
||||||
//!Never throws
|
//!Never throws
|
||||||
allocator()
|
allocator()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//!Constructor from other allocator.
|
//!Constructor from other allocator.
|
||||||
|
@@ -541,8 +541,8 @@ class deque : protected deque_base<Allocator>
|
|||||||
//! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
|
//! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
|
||||||
//! and inserts n value initialized values.
|
//! and inserts n value initialized values.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor
|
//! <b>Throws</b>: If allocator_type's default constructor
|
||||||
//! throws or T's default or copy constructor throws.
|
//! throws or T's value initialization throws.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear to n.
|
//! <b>Complexity</b>: Linear to n.
|
||||||
explicit deque(size_type n)
|
explicit deque(size_type n)
|
||||||
@@ -556,8 +556,8 @@ class deque : protected deque_base<Allocator>
|
|||||||
//! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
|
//! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
|
||||||
//! and inserts n default initialized values.
|
//! and inserts n default initialized values.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor
|
//! <b>Throws</b>: If allocator_type's default constructor
|
||||||
//! throws or T's default or copy constructor throws.
|
//! throws or T's default initialization or copy constructor throws.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear to n.
|
//! <b>Complexity</b>: Linear to n.
|
||||||
//!
|
//!
|
||||||
@@ -573,8 +573,8 @@ class deque : protected deque_base<Allocator>
|
|||||||
//! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
|
//! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
|
||||||
//! and inserts n copies of value.
|
//! and inserts n copies of value.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor
|
//! <b>Throws</b>: If allocator_type's default constructor
|
||||||
//! throws or T's default or copy constructor throws.
|
//! throws or T's copy constructor throws.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear to n.
|
//! <b>Complexity</b>: Linear to n.
|
||||||
deque(size_type n, const value_type& value,
|
deque(size_type n, const value_type& value,
|
||||||
@@ -585,8 +585,8 @@ class deque : protected deque_base<Allocator>
|
|||||||
//! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
|
//! <b>Effects</b>: Constructs a deque that will use a copy of allocator a
|
||||||
//! and inserts a copy of the range [first, last) in the deque.
|
//! and inserts a copy of the range [first, last) in the deque.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor
|
//! <b>Throws</b>: If allocator_type's default constructor
|
||||||
//! throws or T's constructor taking an dereferenced InIt throws.
|
//! throws or T's constructor taking a dereferenced InIt throws.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear to the range [first, last).
|
//! <b>Complexity</b>: Linear to the range [first, last).
|
||||||
template <class InIt>
|
template <class InIt>
|
||||||
@@ -704,35 +704,39 @@ class deque : protected deque_base<Allocator>
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! <b>Effects</b>: Move assignment. All mx's values are transferred to *this.
|
//! <b>Effects</b>: Move assignment. All x's values are transferred to *this.
|
||||||
//!
|
//!
|
||||||
//! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
|
//! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
|
||||||
//! before the function.
|
//! is false and (allocation throws or value_type's move constructor throws)
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If allocator_type's copy constructor throws.
|
//! <b>Complexity</b>: Constant if allocator_traits_type::
|
||||||
//!
|
//! propagate_on_container_move_assignment is true or
|
||||||
//! <b>Complexity</b>: Linear.
|
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
|
||||||
deque& operator= (BOOST_RV_REF(deque) x)
|
deque& operator= (BOOST_RV_REF(deque) x)
|
||||||
|
BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value)
|
||||||
{
|
{
|
||||||
if (&x != this){
|
BOOST_ASSERT(this != &x);
|
||||||
allocator_type &this_alloc = this->alloc();
|
allocator_type &this_alloc = this->alloc();
|
||||||
allocator_type &x_alloc = x.alloc();
|
allocator_type &x_alloc = x.alloc();
|
||||||
//If allocators are equal we can just swap pointers
|
const bool propagate_alloc = allocator_traits_type::
|
||||||
if(this_alloc == x_alloc){
|
propagate_on_container_move_assignment::value;
|
||||||
//Destroy objects but retain memory in case x reuses it in the future
|
container_detail::bool_<propagate_alloc> flag;
|
||||||
this->clear();
|
const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal;
|
||||||
this->swap_members(x);
|
//Resources can be transferred if both allocators are
|
||||||
//Move allocator if needed
|
//going to be equal after this function (either propagated or already equal)
|
||||||
container_detail::bool_<allocator_traits_type::
|
if(propagate_alloc || allocators_equal){
|
||||||
propagate_on_container_move_assignment::value> flag;
|
//Destroy objects but retain memory in case x reuses it in the future
|
||||||
container_detail::move_alloc(this_alloc, x_alloc, flag);
|
this->clear();
|
||||||
container_detail::move_alloc(this->ptr_alloc(), x.ptr_alloc(), flag);
|
//Move allocator if needed
|
||||||
}
|
container_detail::move_alloc(this_alloc, x_alloc, flag);
|
||||||
//If unequal allocators, then do a one by one move
|
container_detail::move_alloc(this->ptr_alloc(), x.ptr_alloc(), flag);
|
||||||
else{
|
//Nothrow swap
|
||||||
this->assign( boost::make_move_iterator(x.begin())
|
this->swap_members(x);
|
||||||
, boost::make_move_iterator(x.end()));
|
}
|
||||||
}
|
//Else do a one by one move
|
||||||
|
else{
|
||||||
|
this->assign( boost::make_move_iterator(x.begin())
|
||||||
|
, boost::make_move_iterator(x.end()));
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@@ -476,21 +476,36 @@ class flat_tree
|
|||||||
const const_iterator b(this->cbegin());
|
const const_iterator b(this->cbegin());
|
||||||
const_iterator pos(b);
|
const_iterator pos(b);
|
||||||
//Loop in burst sizes
|
//Loop in burst sizes
|
||||||
while(len){
|
bool back_insert = false;
|
||||||
const size_type burst = len < BurstSize ? len : BurstSize;
|
while(len && !back_insert){
|
||||||
|
size_type burst = len < BurstSize ? len : BurstSize;
|
||||||
const const_iterator ce(this->cend());
|
const const_iterator ce(this->cend());
|
||||||
len -= burst;
|
|
||||||
for(size_type i = 0; i != burst; ++i){
|
for(size_type i = 0; i != burst; ++i){
|
||||||
//Get the insertion position for each key
|
//Get the insertion position for each key, use std::iterator_traits<BidirIt>::value_type
|
||||||
pos = const_cast<const flat_tree&>(*this).priv_upper_bound(pos, ce, KeyOfValue()(*first));
|
//because it can be different from container::value_type
|
||||||
positions[i] = static_cast<size_type>(pos - b);
|
//(e.g. conversion between std::pair<A, B> -> boost::container::pair<A, B>
|
||||||
++first;
|
const typename std::iterator_traits<BidirIt>::value_type & val = *first;
|
||||||
|
pos = const_cast<const flat_tree&>(*this).priv_upper_bound(pos, ce, KeyOfValue()(val));
|
||||||
|
if(pos == this->cend()){ //this element and the remaining should be back inserted
|
||||||
|
burst = i;
|
||||||
|
back_insert = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
positions[i] = static_cast<size_type>(pos - b);
|
||||||
|
++first;
|
||||||
|
--len;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//Insert all in a single step in the precalculated positions
|
//Insert all in a single step in the precalculated positions
|
||||||
this->m_data.m_vect.insert_ordered_at(burst, positions + burst, first);
|
this->m_data.m_vect.insert_ordered_at(burst, positions + burst, first);
|
||||||
//Next search position updated
|
//Next search position updated, iterator still valid because we've preserved the vector
|
||||||
pos += burst;
|
pos += burst;
|
||||||
}
|
}
|
||||||
|
if(first != last){
|
||||||
|
//The remaining range should be back inserted
|
||||||
|
this->m_data.m_vect.insert(this->m_data.m_vect.cend(), len, first, last);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class InIt>
|
template <class InIt>
|
||||||
@@ -532,34 +547,47 @@ class flat_tree
|
|||||||
const value_compare &val_cmp = this->m_data;
|
const value_compare &val_cmp = this->m_data;
|
||||||
skips[0u] = 0u;
|
skips[0u] = 0u;
|
||||||
//Loop in burst sizes
|
//Loop in burst sizes
|
||||||
while(len){
|
bool back_insert = false;
|
||||||
|
while(len && !back_insert){
|
||||||
const size_type burst = len < BurstSize ? len : BurstSize;
|
const size_type burst = len < BurstSize ? len : BurstSize;
|
||||||
size_type unique_burst = 0u;
|
size_type unique_burst = 0u;
|
||||||
const const_iterator ce(this->cend());
|
const const_iterator ce(this->cend());
|
||||||
while(unique_burst < burst && len > 0){
|
while(unique_burst < burst && len > 0){
|
||||||
//Get the insertion position for each key
|
//Get the insertion position for each key, use std::iterator_traits<BidirIt>::value_type
|
||||||
const value_type & val = *first++;
|
//because it can be different from container::value_type
|
||||||
--len;
|
//(e.g. conversion between std::pair<A, B> -> boost::container::pair<A, B>
|
||||||
|
const typename std::iterator_traits<BidirIt>::value_type & val = *first;
|
||||||
pos = const_cast<const flat_tree&>(*this).priv_lower_bound(pos, ce, KeyOfValue()(val));
|
pos = const_cast<const flat_tree&>(*this).priv_lower_bound(pos, ce, KeyOfValue()(val));
|
||||||
//Check if already present
|
//Check if already present
|
||||||
if(pos != ce && !val_cmp(val, *pos)){
|
if (pos != ce){
|
||||||
if(unique_burst > 0){
|
++first;
|
||||||
++skips[unique_burst-1];
|
--len;
|
||||||
|
if(!val_cmp(val, *pos)){
|
||||||
|
if(unique_burst > 0){
|
||||||
|
++skips[unique_burst-1];
|
||||||
|
}
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
continue;
|
//If not present, calculate position
|
||||||
|
positions[unique_burst] = static_cast<size_type>(pos - b);
|
||||||
|
skips[unique_burst++] = 0u;
|
||||||
|
}
|
||||||
|
else{ //this element and the remaining should be back inserted
|
||||||
|
back_insert = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//If not present, calculate position
|
|
||||||
positions[unique_burst] = static_cast<size_type>(pos - b);
|
|
||||||
skips[unique_burst++] = 0u;
|
|
||||||
}
|
}
|
||||||
if(unique_burst){
|
if(unique_burst){
|
||||||
//Insert all in a single step in the precalculated positions
|
//Insert all in a single step in the precalculated positions
|
||||||
this->m_data.m_vect.insert_ordered_at(unique_burst, positions + unique_burst, skips + unique_burst, first);
|
this->m_data.m_vect.insert_ordered_at(unique_burst, positions + unique_burst, skips + unique_burst, first);
|
||||||
//Next search position updated
|
//Next search position updated, iterator still valid because we've preserved the vector
|
||||||
pos += unique_burst;
|
pos += unique_burst;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(first != last){
|
||||||
|
//The remaining range should be back inserted
|
||||||
|
this->m_data.m_vect.insert(this->m_data.m_vect.cend(), len, first, last);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
|
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
|
||||||
|
@@ -69,18 +69,32 @@ struct disable_if : public enable_if_c<!Cond::value, T> {};
|
|||||||
template <bool B, class T = void>
|
template <bool B, class T = void>
|
||||||
struct disable_if_c : public enable_if_c<!B, T> {};
|
struct disable_if_c : public enable_if_c<!B, T> {};
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||||
|
|
||||||
|
template <class T, class U>
|
||||||
|
struct is_convertible
|
||||||
|
{
|
||||||
|
static const bool value = __is_convertible_to(T, U);
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
template <class T, class U>
|
template <class T, class U>
|
||||||
class is_convertible
|
class is_convertible
|
||||||
{
|
{
|
||||||
typedef char true_t;
|
typedef char true_t;
|
||||||
class false_t { char dummy[2]; };
|
class false_t { char dummy[2]; };
|
||||||
static true_t dispatch(U);
|
//use any_conversion as first parameter since in MSVC
|
||||||
|
//overaligned types can't go through ellipsis
|
||||||
static false_t dispatch(...);
|
static false_t dispatch(...);
|
||||||
static T trigger();
|
static true_t dispatch(U);
|
||||||
|
static T &trigger();
|
||||||
public:
|
public:
|
||||||
enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) };
|
static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
template<
|
template<
|
||||||
bool C
|
bool C
|
||||||
, typename T1
|
, typename T1
|
||||||
|
@@ -685,35 +685,39 @@ class tree
|
|||||||
|
|
||||||
tree& operator=(BOOST_RV_REF(tree) x)
|
tree& operator=(BOOST_RV_REF(tree) x)
|
||||||
{
|
{
|
||||||
if (&x != this){
|
BOOST_ASSERT(this != &x);
|
||||||
NodeAlloc &this_alloc = this->get_stored_allocator();
|
NodeAlloc &this_alloc = this->node_alloc();
|
||||||
const NodeAlloc &x_alloc = x.get_stored_allocator();
|
NodeAlloc &x_alloc = x.node_alloc();
|
||||||
//If allocators are equal we can just swap pointers
|
const bool propagate_alloc = allocator_traits<NodeAlloc>::
|
||||||
if(this_alloc == x_alloc){
|
propagate_on_container_move_assignment::value;
|
||||||
//Destroy and swap pointers
|
const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal;
|
||||||
this->clear();
|
//Resources can be transferred if both allocators are
|
||||||
this->icont() = ::boost::move(x.icont());
|
//going to be equal after this function (either propagated or already equal)
|
||||||
//Move allocator if needed
|
if(propagate_alloc || allocators_equal){
|
||||||
this->AllocHolder::move_assign_alloc(x);
|
//Destroy
|
||||||
}
|
this->clear();
|
||||||
//If unequal allocators, then do a one by one move
|
//Move allocator if needed
|
||||||
else{
|
this->AllocHolder::move_assign_alloc(x);
|
||||||
//Transfer all the nodes to a temporary tree
|
//Obtain resources
|
||||||
//If anything goes wrong, all the nodes will be destroyed
|
this->icont() = boost::move(x.icont());
|
||||||
//automatically
|
}
|
||||||
Icont other_tree(::boost::move(this->icont()));
|
//Else do a one by one move
|
||||||
|
else{
|
||||||
|
//Transfer all the nodes to a temporary tree
|
||||||
|
//If anything goes wrong, all the nodes will be destroyed
|
||||||
|
//automatically
|
||||||
|
Icont other_tree(::boost::move(this->icont()));
|
||||||
|
|
||||||
//Now recreate the source tree reusing nodes stored by other_tree
|
//Now recreate the source tree reusing nodes stored by other_tree
|
||||||
this->icont().clone_from
|
this->icont().clone_from
|
||||||
(x.icont()
|
(x.icont()
|
||||||
, RecyclingCloner<AllocHolder, true>(*this, other_tree)
|
, RecyclingCloner<AllocHolder, true>(*this, other_tree)
|
||||||
, Destroyer(this->node_alloc()));
|
, Destroyer(this->node_alloc()));
|
||||||
|
|
||||||
//If there are remaining nodes, destroy them
|
//If there are remaining nodes, destroy them
|
||||||
NodePtr p;
|
NodePtr p;
|
||||||
while((p = other_tree.unlink_leftmost_without_rebalance())){
|
while((p = other_tree.unlink_leftmost_without_rebalance())){
|
||||||
AllocHolder::destroy_node(p);
|
AllocHolder::destroy_node(p);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
|
@@ -81,7 +81,13 @@ struct version<T, true>
|
|||||||
template <class T>
|
template <class T>
|
||||||
struct version
|
struct version
|
||||||
: public container_detail::integral_constant<unsigned, impl::version<T>::value>
|
: public container_detail::integral_constant<unsigned, impl::version<T>::value>
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<class T, unsigned N>
|
||||||
|
struct is_version
|
||||||
{
|
{
|
||||||
|
static const bool value =
|
||||||
|
is_same< typename version<T>::type, integral_constant<unsigned, N> >::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
} //namespace container_detail {
|
} //namespace container_detail {
|
||||||
|
@@ -135,6 +135,7 @@ class flat_map
|
|||||||
typedef Key key_type;
|
typedef Key key_type;
|
||||||
typedef T mapped_type;
|
typedef T mapped_type;
|
||||||
typedef std::pair<Key, T> value_type;
|
typedef std::pair<Key, T> value_type;
|
||||||
|
typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
|
||||||
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
|
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||||
typedef typename boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
|
typedef typename boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
|
||||||
typedef typename boost::container::allocator_traits<Allocator>::reference reference;
|
typedef typename boost::container::allocator_traits<Allocator>::reference reference;
|
||||||
@@ -275,11 +276,15 @@ class flat_map
|
|||||||
//! <b>Effects</b>: Move constructs a flat_map.
|
//! <b>Effects</b>: Move constructs a flat_map.
|
||||||
//! Constructs *this using x's resources.
|
//! Constructs *this using x's resources.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Construct.
|
//! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
|
||||||
|
//! is false and (allocation throws or value_type's move constructor throws)
|
||||||
//!
|
//!
|
||||||
//! <b>Postcondition</b>: x is emptied.
|
//! <b>Complexity</b>: Constant if allocator_traits_type::
|
||||||
flat_map& operator=(BOOST_RV_REF(flat_map) mx)
|
//! propagate_on_container_move_assignment is true or
|
||||||
{ m_flat_tree = boost::move(mx.m_flat_tree); return *this; }
|
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
|
||||||
|
flat_map& operator=(BOOST_RV_REF(flat_map) x)
|
||||||
|
BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value)
|
||||||
|
{ m_flat_tree = boost::move(x.m_flat_tree); return *this; }
|
||||||
|
|
||||||
//! <b>Effects</b>: Returns a copy of the Allocator that
|
//! <b>Effects</b>: Returns a copy of the Allocator that
|
||||||
//! was passed to the object's constructor.
|
//! was passed to the object's constructor.
|
||||||
@@ -1029,6 +1034,7 @@ class flat_multimap
|
|||||||
typedef Key key_type;
|
typedef Key key_type;
|
||||||
typedef T mapped_type;
|
typedef T mapped_type;
|
||||||
typedef std::pair<Key, T> value_type;
|
typedef std::pair<Key, T> value_type;
|
||||||
|
typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
|
||||||
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
|
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||||
typedef typename boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
|
typedef typename boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
|
||||||
typedef typename boost::container::allocator_traits<Allocator>::reference reference;
|
typedef typename boost::container::allocator_traits<Allocator>::reference reference;
|
||||||
@@ -1169,8 +1175,9 @@ class flat_multimap
|
|||||||
//! <b>Effects</b>: this->swap(x.get()).
|
//! <b>Effects</b>: this->swap(x.get()).
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Constant.
|
//! <b>Complexity</b>: Constant.
|
||||||
flat_multimap& operator=(BOOST_RV_REF(flat_multimap) mx)
|
flat_multimap& operator=(BOOST_RV_REF(flat_multimap) x)
|
||||||
{ m_flat_tree = boost::move(mx.m_flat_tree); return *this; }
|
BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value)
|
||||||
|
{ m_flat_tree = boost::move(x.m_flat_tree); return *this; }
|
||||||
|
|
||||||
//! <b>Effects</b>: Returns a copy of the Allocator that
|
//! <b>Effects</b>: Returns a copy of the Allocator that
|
||||||
//! was passed to the object's constructor.
|
//! was passed to the object's constructor.
|
||||||
|
@@ -72,6 +72,7 @@ class flat_set
|
|||||||
typedef Key value_type;
|
typedef Key value_type;
|
||||||
typedef Compare key_compare;
|
typedef Compare key_compare;
|
||||||
typedef Compare value_compare;
|
typedef Compare value_compare;
|
||||||
|
typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
|
||||||
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
|
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||||
typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
|
typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
|
||||||
typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
|
typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
|
||||||
@@ -181,11 +182,15 @@ class flat_set
|
|||||||
flat_set& operator=(BOOST_COPY_ASSIGN_REF(flat_set) x)
|
flat_set& operator=(BOOST_COPY_ASSIGN_REF(flat_set) x)
|
||||||
{ return static_cast<flat_set&>(this->base_t::operator=(static_cast<const base_t&>(x))); }
|
{ return static_cast<flat_set&>(this->base_t::operator=(static_cast<const base_t&>(x))); }
|
||||||
|
|
||||||
//! <b>Effects</b>: Makes *this a copy of the previous value of mx.
|
//! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
|
||||||
|
//! is false and (allocation throws or value_type's move constructor throws)
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear in x.size().
|
//! <b>Complexity</b>: Constant if allocator_traits_type::
|
||||||
flat_set& operator=(BOOST_RV_REF(flat_set) mx)
|
//! propagate_on_container_move_assignment is true or
|
||||||
{ return static_cast<flat_set&>(this->base_t::operator=(boost::move(static_cast<base_t&>(mx)))); }
|
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
|
||||||
|
flat_set& operator=(BOOST_RV_REF(flat_set) x)
|
||||||
|
BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value)
|
||||||
|
{ return static_cast<flat_set&>(this->base_t::operator=(boost::move(static_cast<base_t&>(x)))); }
|
||||||
|
|
||||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||||
//! <b>Effects</b>: Returns a copy of the Allocator that
|
//! <b>Effects</b>: Returns a copy of the Allocator that
|
||||||
@@ -725,6 +730,7 @@ class flat_multiset
|
|||||||
typedef Key value_type;
|
typedef Key value_type;
|
||||||
typedef Compare key_compare;
|
typedef Compare key_compare;
|
||||||
typedef Compare value_compare;
|
typedef Compare value_compare;
|
||||||
|
typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
|
||||||
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
|
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||||
typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
|
typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
|
||||||
typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
|
typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
|
||||||
@@ -804,6 +810,7 @@ class flat_multiset
|
|||||||
|
|
||||||
//! @copydoc ::boost::container::flat_set::operator=(flat_set &&)
|
//! @copydoc ::boost::container::flat_set::operator=(flat_set &&)
|
||||||
flat_multiset& operator=(BOOST_RV_REF(flat_multiset) mx)
|
flat_multiset& operator=(BOOST_RV_REF(flat_multiset) mx)
|
||||||
|
BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value)
|
||||||
{ return static_cast<flat_multiset&>(this->base_t::operator=(boost::move(static_cast<base_t&>(mx)))); }
|
{ return static_cast<flat_multiset&>(this->base_t::operator=(boost::move(static_cast<base_t&>(mx)))); }
|
||||||
|
|
||||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||||
|
@@ -220,7 +220,7 @@ class list
|
|||||||
//! <b>Effects</b>: Constructs a list that will use a copy of allocator a
|
//! <b>Effects</b>: Constructs a list that will use a copy of allocator a
|
||||||
//! and inserts n copies of value.
|
//! and inserts n copies of value.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor
|
//! <b>Throws</b>: If allocator_type's default constructor
|
||||||
//! throws or T's default or copy constructor throws.
|
//! throws or T's default or copy constructor throws.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear to n.
|
//! <b>Complexity</b>: Linear to n.
|
||||||
@@ -231,7 +231,7 @@ class list
|
|||||||
//! <b>Effects</b>: Constructs a list that will use a copy of allocator a
|
//! <b>Effects</b>: Constructs a list that will use a copy of allocator a
|
||||||
//! and inserts n copies of value.
|
//! and inserts n copies of value.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor
|
//! <b>Throws</b>: If allocator_type's default constructor
|
||||||
//! throws or T's default or copy constructor throws.
|
//! throws or T's default or copy constructor throws.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear to n.
|
//! <b>Complexity</b>: Linear to n.
|
||||||
@@ -243,7 +243,7 @@ class list
|
|||||||
//!
|
//!
|
||||||
//! <b>Postcondition</b>: x == *this.
|
//! <b>Postcondition</b>: x == *this.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
|
//! <b>Throws</b>: If allocator_type's default constructor throws.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear to the elements x contains.
|
//! <b>Complexity</b>: Linear to the elements x contains.
|
||||||
list(const list& x)
|
list(const list& x)
|
||||||
@@ -290,8 +290,8 @@ class list
|
|||||||
//! <b>Effects</b>: Constructs a list that will use a copy of allocator a
|
//! <b>Effects</b>: Constructs a list that will use a copy of allocator a
|
||||||
//! and inserts a copy of the range [first, last) in the list.
|
//! and inserts a copy of the range [first, last) in the list.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor
|
//! <b>Throws</b>: If allocator_type's default constructor
|
||||||
//! throws or T's constructor taking an dereferenced InIt throws.
|
//! throws or T's constructor taking a dereferenced InIt throws.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear to the range [first, last).
|
//! <b>Complexity</b>: Linear to the range [first, last).
|
||||||
template <class InpIt>
|
template <class InpIt>
|
||||||
@@ -332,32 +332,40 @@ class list
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! <b>Effects</b>: Move assignment. All mx's values are transferred to *this.
|
//! <b>Effects</b>: Move assignment. All x's values are transferred to *this.
|
||||||
//!
|
//!
|
||||||
//! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
|
//! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
|
||||||
//! before the function.
|
//! before the function.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If allocator_type's copy constructor throws.
|
//! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
|
||||||
|
//! is false and (allocation throws or value_type's move constructor throws)
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Constant.
|
//! <b>Complexity</b>: Constant if allocator_traits_type::
|
||||||
|
//! propagate_on_container_move_assignment is true or
|
||||||
|
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
|
||||||
list& operator=(BOOST_RV_REF(list) x)
|
list& operator=(BOOST_RV_REF(list) x)
|
||||||
|
BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value)
|
||||||
{
|
{
|
||||||
if (&x != this){
|
BOOST_ASSERT(this != &x);
|
||||||
NodeAlloc &this_alloc = this->node_alloc();
|
NodeAlloc &this_alloc = this->node_alloc();
|
||||||
NodeAlloc &x_alloc = x.node_alloc();
|
NodeAlloc &x_alloc = x.node_alloc();
|
||||||
//If allocators are equal we can just swap pointers
|
const bool propagate_alloc = allocator_traits_type::
|
||||||
if(this_alloc == x_alloc){
|
propagate_on_container_move_assignment::value;
|
||||||
//Destroy and swap pointers
|
const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal;
|
||||||
this->clear();
|
//Resources can be transferred if both allocators are
|
||||||
this->icont() = boost::move(x.icont());
|
//going to be equal after this function (either propagated or already equal)
|
||||||
//Move allocator if needed
|
if(propagate_alloc || allocators_equal){
|
||||||
this->AllocHolder::move_assign_alloc(x);
|
//Destroy
|
||||||
}
|
this->clear();
|
||||||
//If unequal allocators, then do a one by one move
|
//Move allocator if needed
|
||||||
else{
|
this->AllocHolder::move_assign_alloc(x);
|
||||||
this->assign( boost::make_move_iterator(x.begin())
|
//Obtain resources
|
||||||
, boost::make_move_iterator(x.end()));
|
this->icont() = boost::move(x.icont());
|
||||||
}
|
}
|
||||||
|
//Else do a one by one move
|
||||||
|
else{
|
||||||
|
this->assign( boost::make_move_iterator(x.begin())
|
||||||
|
, boost::make_move_iterator(x.end()));
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@@ -89,6 +89,7 @@ class map
|
|||||||
//////////////////////////////////////////////
|
//////////////////////////////////////////////
|
||||||
|
|
||||||
typedef Key key_type;
|
typedef Key key_type;
|
||||||
|
typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
|
||||||
typedef T mapped_type;
|
typedef T mapped_type;
|
||||||
typedef std::pair<const Key, T> value_type;
|
typedef std::pair<const Key, T> value_type;
|
||||||
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
|
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||||
@@ -232,8 +233,14 @@ class map
|
|||||||
|
|
||||||
//! <b>Effects</b>: this->swap(x.get()).
|
//! <b>Effects</b>: this->swap(x.get()).
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Constant.
|
//! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
|
||||||
|
//! is false and (allocation throws or value_type's move constructor throws)
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Constant if allocator_traits_type::
|
||||||
|
//! propagate_on_container_move_assignment is true or
|
||||||
|
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
|
||||||
map& operator=(BOOST_RV_REF(map) x)
|
map& operator=(BOOST_RV_REF(map) x)
|
||||||
|
BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value)
|
||||||
{ return static_cast<map&>(this->base_t::operator=(boost::move(static_cast<base_t&>(x)))); }
|
{ return static_cast<map&>(this->base_t::operator=(boost::move(static_cast<base_t&>(x)))); }
|
||||||
|
|
||||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||||
|
@@ -76,6 +76,7 @@ class set
|
|||||||
typedef Key value_type;
|
typedef Key value_type;
|
||||||
typedef Compare key_compare;
|
typedef Compare key_compare;
|
||||||
typedef Compare value_compare;
|
typedef Compare value_compare;
|
||||||
|
typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
|
||||||
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
|
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||||
typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
|
typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
|
||||||
typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
|
typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
|
||||||
@@ -184,8 +185,14 @@ class set
|
|||||||
|
|
||||||
//! <b>Effects</b>: this->swap(x.get()).
|
//! <b>Effects</b>: this->swap(x.get()).
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Constant.
|
//! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
|
||||||
|
//! is false and (allocation throws or value_type's move constructor throws)
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Constant if allocator_traits_type::
|
||||||
|
//! propagate_on_container_move_assignment is true or
|
||||||
|
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
|
||||||
set& operator=(BOOST_RV_REF(set) x)
|
set& operator=(BOOST_RV_REF(set) x)
|
||||||
|
BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value)
|
||||||
{ return static_cast<set&>(this->base_t::operator=(boost::move(static_cast<base_t&>(x)))); }
|
{ return static_cast<set&>(this->base_t::operator=(boost::move(static_cast<base_t&>(x)))); }
|
||||||
|
|
||||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||||
@@ -678,6 +685,7 @@ class multiset
|
|||||||
typedef Key value_type;
|
typedef Key value_type;
|
||||||
typedef Compare key_compare;
|
typedef Compare key_compare;
|
||||||
typedef Compare value_compare;
|
typedef Compare value_compare;
|
||||||
|
typedef ::boost::container::allocator_traits<Allocator> allocator_traits_type;
|
||||||
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
|
typedef typename ::boost::container::allocator_traits<Allocator>::pointer pointer;
|
||||||
typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
|
typedef typename ::boost::container::allocator_traits<Allocator>::const_pointer const_pointer;
|
||||||
typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
|
typedef typename ::boost::container::allocator_traits<Allocator>::reference reference;
|
||||||
|
@@ -252,7 +252,7 @@ class slist
|
|||||||
//! <b>Effects</b>: Constructs a list that will use a copy of allocator a
|
//! <b>Effects</b>: Constructs a list that will use a copy of allocator a
|
||||||
//! and inserts n copies of value.
|
//! and inserts n copies of value.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor
|
//! <b>Throws</b>: If allocator_type's default constructor
|
||||||
//! throws or T's default or copy constructor throws.
|
//! throws or T's default or copy constructor throws.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear to n.
|
//! <b>Complexity</b>: Linear to n.
|
||||||
@@ -263,8 +263,8 @@ class slist
|
|||||||
//! <b>Effects</b>: Constructs a list that will use a copy of allocator a
|
//! <b>Effects</b>: Constructs a list that will use a copy of allocator a
|
||||||
//! and inserts a copy of the range [first, last) in the list.
|
//! and inserts a copy of the range [first, last) in the list.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor
|
//! <b>Throws</b>: If allocator_type's default constructor
|
||||||
//! throws or T's constructor taking an dereferenced InIt throws.
|
//! throws or T's constructor taking a dereferenced InIt throws.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear to the range [first, last).
|
//! <b>Complexity</b>: Linear to the range [first, last).
|
||||||
template <class InpIt>
|
template <class InpIt>
|
||||||
@@ -276,7 +276,7 @@ class slist
|
|||||||
//!
|
//!
|
||||||
//! <b>Postcondition</b>: x == *this.
|
//! <b>Postcondition</b>: x == *this.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
|
//! <b>Throws</b>: If allocator_type's default constructor
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear to the elements x contains.
|
//! <b>Complexity</b>: Linear to the elements x contains.
|
||||||
slist(const slist& x)
|
slist(const slist& x)
|
||||||
@@ -296,7 +296,7 @@ class slist
|
|||||||
//!
|
//!
|
||||||
//! <b>Postcondition</b>: x == *this.
|
//! <b>Postcondition</b>: x == *this.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor throws.
|
//! <b>Throws</b>: If allocator_type's default constructor
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear to the elements x contains.
|
//! <b>Complexity</b>: Linear to the elements x contains.
|
||||||
slist(const slist& x, const allocator_type &a)
|
slist(const slist& x, const allocator_type &a)
|
||||||
@@ -358,27 +358,35 @@ class slist
|
|||||||
//! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
|
//! <b>Postcondition</b>: this->size() == x.size(). *this contains a copy
|
||||||
//! of each of x's elements.
|
//! of each of x's elements.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
|
//! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
|
||||||
|
//! is false and (allocation throws or value_type's move constructor throws)
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear to the number of elements in x.
|
//! <b>Complexity</b>: Constant if allocator_traits_type::
|
||||||
|
//! propagate_on_container_move_assignment is true or
|
||||||
|
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
|
||||||
slist& operator= (BOOST_RV_REF(slist) x)
|
slist& operator= (BOOST_RV_REF(slist) x)
|
||||||
|
BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value)
|
||||||
{
|
{
|
||||||
if (&x != this){
|
BOOST_ASSERT(this != &x);
|
||||||
NodeAlloc &this_alloc = this->node_alloc();
|
NodeAlloc &this_alloc = this->node_alloc();
|
||||||
NodeAlloc &x_alloc = x.node_alloc();
|
NodeAlloc &x_alloc = x.node_alloc();
|
||||||
//If allocators a re equal we can just swap pointers
|
const bool propagate_alloc = allocator_traits_type::
|
||||||
if(this_alloc == x_alloc){
|
propagate_on_container_move_assignment::value;
|
||||||
//Destroy and swap pointers
|
const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal;
|
||||||
this->clear();
|
//Resources can be transferred if both allocators are
|
||||||
this->icont() = boost::move(x.icont());
|
//going to be equal after this function (either propagated or already equal)
|
||||||
//Move allocator if needed
|
if(propagate_alloc || allocators_equal){
|
||||||
this->AllocHolder::move_assign_alloc(x);
|
//Destroy
|
||||||
}
|
this->clear();
|
||||||
//If unequal allocators, then do a one by one move
|
//Move allocator if needed
|
||||||
else{
|
this->AllocHolder::move_assign_alloc(x);
|
||||||
this->assign( boost::make_move_iterator(x.begin())
|
//Obtain resources
|
||||||
, boost::make_move_iterator(x.end()));
|
this->icont() = boost::move(x.icont());
|
||||||
}
|
}
|
||||||
|
//Else do a one by one move
|
||||||
|
else{
|
||||||
|
this->assign( boost::make_move_iterator(x.begin())
|
||||||
|
, boost::make_move_iterator(x.end()));
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@@ -573,7 +573,7 @@ class stable_vector
|
|||||||
//! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
|
//! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
|
||||||
//! and inserts n value initialized values.
|
//! and inserts n value initialized values.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor
|
//! <b>Throws</b>: If allocator_type's default constructor
|
||||||
//! throws or T's default or copy constructor throws.
|
//! throws or T's default or copy constructor throws.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear to n.
|
//! <b>Complexity</b>: Linear to n.
|
||||||
@@ -589,7 +589,7 @@ class stable_vector
|
|||||||
//! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
|
//! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
|
||||||
//! and inserts n default initialized values.
|
//! and inserts n default initialized values.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor
|
//! <b>Throws</b>: If allocator_type's default constructor
|
||||||
//! throws or T's default or copy constructor throws.
|
//! throws or T's default or copy constructor throws.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear to n.
|
//! <b>Complexity</b>: Linear to n.
|
||||||
@@ -607,7 +607,7 @@ class stable_vector
|
|||||||
//! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
|
//! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
|
||||||
//! and inserts n copies of value.
|
//! and inserts n copies of value.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor
|
//! <b>Throws</b>: If allocator_type's default constructor
|
||||||
//! throws or T's default or copy constructor throws.
|
//! throws or T's default or copy constructor throws.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear to n.
|
//! <b>Complexity</b>: Linear to n.
|
||||||
@@ -623,8 +623,8 @@ class stable_vector
|
|||||||
//! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
|
//! <b>Effects</b>: Constructs a stable_vector that will use a copy of allocator a
|
||||||
//! and inserts a copy of the range [first, last) in the stable_vector.
|
//! and inserts a copy of the range [first, last) in the stable_vector.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If allocator_type's default constructor or copy constructor
|
//! <b>Throws</b>: If allocator_type's default constructor
|
||||||
//! throws or T's constructor taking an dereferenced InIt throws.
|
//! throws or T's constructor taking a dereferenced InIt throws.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear to the range [first, last).
|
//! <b>Complexity</b>: Linear to the range [first, last).
|
||||||
template <class InputIterator>
|
template <class InputIterator>
|
||||||
@@ -743,35 +743,42 @@ class stable_vector
|
|||||||
//! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
|
//! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
|
||||||
//! before the function.
|
//! before the function.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If allocator_type's copy constructor throws.
|
//! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
|
||||||
|
//! is false and (allocation throws or T's move constructor throws)
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear.
|
//! <b>Complexity</b>: Constant if allocator_traits_type::
|
||||||
|
//! propagate_on_container_move_assignment is true or
|
||||||
|
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
|
||||||
stable_vector& operator=(BOOST_RV_REF(stable_vector) x)
|
stable_vector& operator=(BOOST_RV_REF(stable_vector) x)
|
||||||
|
BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value)
|
||||||
{
|
{
|
||||||
if (&x != this){
|
//for move constructor, no aliasing (&x != this) is assummed.
|
||||||
node_allocator_type &this_alloc = this->priv_node_alloc();
|
BOOST_ASSERT(this != &x);
|
||||||
node_allocator_type &x_alloc = x.priv_node_alloc();
|
node_allocator_type &this_alloc = this->priv_node_alloc();
|
||||||
//If allocators are equal we can just swap pointers
|
node_allocator_type &x_alloc = x.priv_node_alloc();
|
||||||
if(this_alloc == x_alloc){
|
const bool propagate_alloc = allocator_traits_type::
|
||||||
//Destroy objects but retain memory
|
propagate_on_container_move_assignment::value;
|
||||||
this->clear();
|
container_detail::bool_<propagate_alloc> flag;
|
||||||
this->index = boost::move(x.index);
|
const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal;
|
||||||
this->priv_swap_members(x);
|
//Resources can be transferred if both allocators are
|
||||||
//Move allocator if needed
|
//going to be equal after this function (either propagated or already equal)
|
||||||
container_detail::bool_<allocator_traits_type::
|
if(propagate_alloc || allocators_equal){
|
||||||
propagate_on_container_move_assignment::value> flag;
|
//Destroy objects but retain memory in case x reuses it in the future
|
||||||
container_detail::move_alloc(this->priv_node_alloc(), x.priv_node_alloc(), flag);
|
this->clear();
|
||||||
}
|
//Move allocator if needed
|
||||||
//If unequal allocators, then do a one by one move
|
container_detail::move_alloc(this_alloc, x_alloc, flag);
|
||||||
else{
|
//Take resources
|
||||||
this->assign( boost::make_move_iterator(x.begin())
|
this->index = boost::move(x.index);
|
||||||
, boost::make_move_iterator(x.end()));
|
this->priv_swap_members(x);
|
||||||
}
|
}
|
||||||
|
//Else do a one by one move
|
||||||
|
else{
|
||||||
|
this->assign( boost::make_move_iterator(x.begin())
|
||||||
|
, boost::make_move_iterator(x.end()));
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! <b>Effects</b>: Assigns the n copies of val to *this.
|
//! <b>Effects</b>: Assigns the n copies of val to *this.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
|
//! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
|
||||||
@@ -983,7 +990,7 @@ class stable_vector
|
|||||||
//! <b>Effects</b>: Inserts or erases elements at the end such that
|
//! <b>Effects</b>: Inserts or erases elements at the end such that
|
||||||
//! the size becomes n. New elements are value initialized.
|
//! the size becomes n. New elements are value initialized.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If memory allocation throws, or T's default constructor throws.
|
//! <b>Throws</b>: If memory allocation throws, or T's value initialization throws.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
|
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
|
||||||
void resize(size_type n)
|
void resize(size_type n)
|
||||||
@@ -999,7 +1006,7 @@ class stable_vector
|
|||||||
//! <b>Effects</b>: Inserts or erases elements at the end such that
|
//! <b>Effects</b>: Inserts or erases elements at the end such that
|
||||||
//! the size becomes n. New elements are default initialized.
|
//! the size becomes n. New elements are default initialized.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If memory allocation throws, or T's default constructor throws.
|
//! <b>Throws</b>: If memory allocation throws, or T's default initialization throws.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
|
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
|
||||||
//!
|
//!
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 2012-2013 Adam Wulkiewicz, Lodz, Poland.
|
// Copyright (c) 2012-2013 Adam Wulkiewicz, Lodz, Poland.
|
||||||
// Copyright (c) 2011-2013 Andrew Hundt.
|
// Copyright (c) 2011-2013 Andrew Hundt.
|
||||||
|
// Copyright (c) 2013-2014 Ion Gaztanaga
|
||||||
//
|
//
|
||||||
// Use, modification and distribution is subject to the Boost Software License,
|
// Use, modification and distribution is subject to the Boost Software License,
|
||||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
@@ -145,7 +146,7 @@ public:
|
|||||||
//! @param count The number of values which will be contained in the container.
|
//! @param count The number of values which will be contained in the container.
|
||||||
//!
|
//!
|
||||||
//! @par Throws
|
//! @par Throws
|
||||||
//! If Value's default constructor throws.
|
//! If Value's value initialization throws.
|
||||||
//!
|
//!
|
||||||
//! @par Complexity
|
//! @par Complexity
|
||||||
//! Linear O(N).
|
//! Linear O(N).
|
||||||
@@ -155,12 +156,12 @@ public:
|
|||||||
|
|
||||||
//! @pre <tt>count <= capacity()</tt>
|
//! @pre <tt>count <= capacity()</tt>
|
||||||
//!
|
//!
|
||||||
//! @brief Constructs a static_vector containing count value initialized values.
|
//! @brief Constructs a static_vector containing count default initialized values.
|
||||||
//!
|
//!
|
||||||
//! @param count The number of values which will be contained in the container.
|
//! @param count The number of values which will be contained in the container.
|
||||||
//!
|
//!
|
||||||
//! @par Throws
|
//! @par Throws
|
||||||
//! If Value's default constructor throws.
|
//! If Value's default initialization throws.
|
||||||
//!
|
//!
|
||||||
//! @par Complexity
|
//! @par Complexity
|
||||||
//! Linear O(N).
|
//! Linear O(N).
|
||||||
@@ -231,45 +232,9 @@ public:
|
|||||||
//! @par Complexity
|
//! @par Complexity
|
||||||
//! Linear O(N).
|
//! Linear O(N).
|
||||||
template <std::size_t C>
|
template <std::size_t C>
|
||||||
static_vector(static_vector<value_type, C> const& other) : base_t(other) {}
|
static_vector(static_vector<value_type, C> const& other)
|
||||||
|
: base_t(other)
|
||||||
//! @brief Copy assigns Values stored in the other static_vector to this one.
|
{}
|
||||||
//!
|
|
||||||
//! @param other The static_vector which content will be copied to this one.
|
|
||||||
//!
|
|
||||||
//! @par Throws
|
|
||||||
//! If Value's copy constructor or copy assignment throws.
|
|
||||||
//!
|
|
||||||
//! @par Complexity
|
|
||||||
//! Linear O(N).
|
|
||||||
static_vector & operator=(BOOST_COPY_ASSIGN_REF(static_vector) other)
|
|
||||||
{
|
|
||||||
base_t::operator=(static_cast<base_t const&>(other));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @pre <tt>other.size() <= capacity()</tt>
|
|
||||||
//!
|
|
||||||
//! @brief Copy assigns Values stored in the other static_vector to this one.
|
|
||||||
//!
|
|
||||||
//! @param other The static_vector which content will be copied to this one.
|
|
||||||
//!
|
|
||||||
//! @par Throws
|
|
||||||
//! If Value's copy constructor or copy assignment throws.
|
|
||||||
//!
|
|
||||||
//! @par Complexity
|
|
||||||
//! Linear O(N).
|
|
||||||
template <std::size_t C>
|
|
||||||
// TEMPORARY WORKAROUND
|
|
||||||
#if defined(BOOST_NO_RVALUE_REFERENCES)
|
|
||||||
static_vector & operator=(::boost::rv< static_vector<value_type, C> > const& other)
|
|
||||||
#else
|
|
||||||
static_vector & operator=(static_vector<value_type, C> const& other)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
base_t::operator=(static_cast<static_vector<value_type, C> const&>(other));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! @brief Move constructor. Moves Values stored in the other static_vector to this one.
|
//! @brief Move constructor. Moves Values stored in the other static_vector to this one.
|
||||||
//!
|
//!
|
||||||
@@ -302,6 +267,38 @@ public:
|
|||||||
: base_t(boost::move(static_cast<typename static_vector<value_type, C>::base_t&>(other)))
|
: base_t(boost::move(static_cast<typename static_vector<value_type, C>::base_t&>(other)))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
//! @brief Copy assigns Values stored in the other static_vector to this one.
|
||||||
|
//!
|
||||||
|
//! @param other The static_vector which content will be copied to this one.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! If Value's copy constructor or copy assignment throws.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
static_vector & operator=(BOOST_COPY_ASSIGN_REF(static_vector) other)
|
||||||
|
{
|
||||||
|
return static_cast<static_vector&>(base_t::operator=(static_cast<base_t const&>(other)));
|
||||||
|
}
|
||||||
|
|
||||||
|
//! @pre <tt>other.size() <= capacity()</tt>
|
||||||
|
//!
|
||||||
|
//! @brief Copy assigns Values stored in the other static_vector to this one.
|
||||||
|
//!
|
||||||
|
//! @param other The static_vector which content will be copied to this one.
|
||||||
|
//!
|
||||||
|
//! @par Throws
|
||||||
|
//! If Value's copy constructor or copy assignment throws.
|
||||||
|
//!
|
||||||
|
//! @par Complexity
|
||||||
|
//! Linear O(N).
|
||||||
|
template <std::size_t C>
|
||||||
|
static_vector & operator=(static_vector<value_type, C> const& other)
|
||||||
|
{
|
||||||
|
return static_cast<static_vector&>(base_t::operator=
|
||||||
|
(static_cast<typename static_vector<value_type, C>::base_t const&>(other)));
|
||||||
|
}
|
||||||
|
|
||||||
//! @brief Move assignment. Moves Values stored in the other static_vector to this one.
|
//! @brief Move assignment. Moves Values stored in the other static_vector to this one.
|
||||||
//!
|
//!
|
||||||
//! @param other The static_vector which content will be moved to this one.
|
//! @param other The static_vector which content will be moved to this one.
|
||||||
@@ -314,8 +311,7 @@ public:
|
|||||||
//! Linear O(N).
|
//! Linear O(N).
|
||||||
static_vector & operator=(BOOST_RV_REF(static_vector) other)
|
static_vector & operator=(BOOST_RV_REF(static_vector) other)
|
||||||
{
|
{
|
||||||
base_t::operator=(boost::move(static_cast<base_t&>(other)));
|
return static_cast<static_vector&>(base_t::operator=(boost::move(static_cast<base_t&>(other))));
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @pre <tt>other.size() <= capacity()</tt>
|
//! @pre <tt>other.size() <= capacity()</tt>
|
||||||
@@ -333,8 +329,8 @@ public:
|
|||||||
template <std::size_t C>
|
template <std::size_t C>
|
||||||
static_vector & operator=(BOOST_RV_REF_BEG static_vector<value_type, C> BOOST_RV_REF_END other)
|
static_vector & operator=(BOOST_RV_REF_BEG static_vector<value_type, C> BOOST_RV_REF_END other)
|
||||||
{
|
{
|
||||||
base_t::operator=(boost::move(static_cast<typename static_vector<value_type, C>::base_t&>(other)));
|
return static_cast<static_vector&>(base_t::operator=
|
||||||
return *this;
|
(boost::move(static_cast<typename static_vector<value_type, C>::base_t&>(other))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||||
@@ -383,7 +379,7 @@ public:
|
|||||||
//! @param count The number of elements which will be stored in the container.
|
//! @param count The number of elements which will be stored in the container.
|
||||||
//!
|
//!
|
||||||
//! @par Throws
|
//! @par Throws
|
||||||
//! If Value's default constructor throws.
|
//! If Value's value initialization throws.
|
||||||
//!
|
//!
|
||||||
//! @par Complexity
|
//! @par Complexity
|
||||||
//! Linear O(N).
|
//! Linear O(N).
|
||||||
@@ -397,7 +393,7 @@ public:
|
|||||||
//! @param count The number of elements which will be stored in the container.
|
//! @param count The number of elements which will be stored in the container.
|
||||||
//!
|
//!
|
||||||
//! @par Throws
|
//! @par Throws
|
||||||
//! If Value's default constructor throws.
|
//! If Value's default initialization throws.
|
||||||
//!
|
//!
|
||||||
//! @par Complexity
|
//! @par Complexity
|
||||||
//! Linear O(N).
|
//! Linear O(N).
|
||||||
|
@@ -592,7 +592,7 @@ class basic_string
|
|||||||
//!
|
//!
|
||||||
//! <b>Postcondition</b>: x == *this.
|
//! <b>Postcondition</b>: x == *this.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If allocator_type's default constructor throws.
|
//! <b>Throws</b>: If allocator_type's default constructor or allocation throws.
|
||||||
basic_string(const basic_string& s)
|
basic_string(const basic_string& s)
|
||||||
: base_t(allocator_traits_type::select_on_container_copy_construction(s.alloc()))
|
: base_t(allocator_traits_type::select_on_container_copy_construction(s.alloc()))
|
||||||
{
|
{
|
||||||
@@ -733,30 +733,38 @@ class basic_string
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
|
//! <b>Effects</b>: Move constructor. Moves x's resources to *this.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If allocator_type's copy constructor throws.
|
//! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
|
||||||
|
//! is false and allocation throws
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Constant.
|
//! <b>Complexity</b>: Constant if allocator_traits_type::
|
||||||
basic_string& operator=(BOOST_RV_REF(basic_string) x) BOOST_CONTAINER_NOEXCEPT
|
//! propagate_on_container_move_assignment is true or
|
||||||
|
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
|
||||||
|
basic_string& operator=(BOOST_RV_REF(basic_string) x)
|
||||||
|
BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value)
|
||||||
{
|
{
|
||||||
if (&x != this){
|
//for move constructor, no aliasing (&x != this) is assummed.
|
||||||
allocator_type &this_alloc = this->alloc();
|
BOOST_ASSERT(this != &x);
|
||||||
allocator_type &x_alloc = x.alloc();
|
allocator_type &this_alloc = this->alloc();
|
||||||
//If allocators are equal we can just swap pointers
|
allocator_type &x_alloc = x.alloc();
|
||||||
if(this_alloc == x_alloc){
|
const bool propagate_alloc = allocator_traits_type::
|
||||||
//Destroy objects but retain memory in case x reuses it in the future
|
propagate_on_container_move_assignment::value;
|
||||||
this->clear();
|
container_detail::bool_<propagate_alloc> flag;
|
||||||
this->swap_data(x);
|
const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal;
|
||||||
//Move allocator if needed
|
//Resources can be transferred if both allocators are
|
||||||
container_detail::bool_<allocator_traits_type::
|
//going to be equal after this function (either propagated or already equal)
|
||||||
propagate_on_container_move_assignment::value> flag;
|
if(propagate_alloc || allocators_equal){
|
||||||
container_detail::move_alloc(this_alloc, x_alloc, flag);
|
//Destroy objects but retain memory in case x reuses it in the future
|
||||||
}
|
this->clear();
|
||||||
//If unequal allocators, then do a one by one move
|
//Move allocator if needed
|
||||||
else{
|
container_detail::move_alloc(this_alloc, x_alloc, flag);
|
||||||
this->assign( x.begin(), x.end());
|
//Nothrow swap
|
||||||
}
|
this->swap_data(x);
|
||||||
|
}
|
||||||
|
//Else do a one by one move
|
||||||
|
else{
|
||||||
|
this->assign( x.begin(), x.end());
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@@ -65,7 +65,7 @@ template <class Pointer, bool IsConst>
|
|||||||
class vec_iterator
|
class vec_iterator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::random_access_iterator_tag iterator_category;
|
typedef std::random_access_iterator_tag iterator_category;
|
||||||
typedef typename boost::intrusive::pointer_traits<Pointer>::element_type value_type;
|
typedef typename boost::intrusive::pointer_traits<Pointer>::element_type value_type;
|
||||||
typedef typename boost::intrusive::pointer_traits<Pointer>::difference_type difference_type;
|
typedef typename boost::intrusive::pointer_traits<Pointer>::difference_type difference_type;
|
||||||
typedef typename if_c
|
typedef typename if_c
|
||||||
@@ -256,10 +256,7 @@ struct vector_value_traits
|
|||||||
|
|
||||||
//!This struct deallocates and allocated memory
|
//!This struct deallocates and allocated memory
|
||||||
template < class Allocator
|
template < class Allocator
|
||||||
, class AllocatorVersion = container_detail::integral_constant
|
, class AllocatorVersion = typename container_detail::version<Allocator>::type
|
||||||
< unsigned
|
|
||||||
, boost::container::container_detail::version<Allocator>::value
|
|
||||||
>
|
|
||||||
>
|
>
|
||||||
struct vector_alloc_holder
|
struct vector_alloc_holder
|
||||||
: public Allocator
|
: public Allocator
|
||||||
@@ -370,8 +367,8 @@ struct vector_alloc_holder
|
|||||||
|
|
||||||
void move_from_empty(vector_alloc_holder &x) BOOST_CONTAINER_NOEXCEPT
|
void move_from_empty(vector_alloc_holder &x) BOOST_CONTAINER_NOEXCEPT
|
||||||
{
|
{
|
||||||
|
//this->m_size was previously initialized
|
||||||
this->m_start = x.m_start;
|
this->m_start = x.m_start;
|
||||||
this->m_size = x.m_size;
|
|
||||||
this->m_capacity = x.m_capacity;
|
this->m_capacity = x.m_capacity;
|
||||||
x.m_start = pointer();
|
x.m_start = pointer();
|
||||||
x.m_size = x.m_capacity = 0;
|
x.m_size = x.m_capacity = 0;
|
||||||
@@ -538,9 +535,8 @@ template <class T, class Allocator>
|
|||||||
class vector
|
class vector
|
||||||
{
|
{
|
||||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||||
typedef container_detail::integral_constant
|
|
||||||
<unsigned, boost::container::container_detail::version
|
typedef typename container_detail::version<Allocator>::type alloc_version;
|
||||||
<Allocator>::value > alloc_version;
|
|
||||||
boost::container::container_detail::vector_alloc_holder
|
boost::container::container_detail::vector_alloc_holder
|
||||||
<Allocator, alloc_version> m_holder;
|
<Allocator, alloc_version> m_holder;
|
||||||
typedef allocator_traits<Allocator> allocator_traits_type;
|
typedef allocator_traits<Allocator> allocator_traits_type;
|
||||||
@@ -621,7 +617,7 @@ class vector
|
|||||||
//! and inserts n value initialized values.
|
//! and inserts n value initialized values.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If allocator_type's default constructor or allocation
|
//! <b>Throws</b>: If allocator_type's default constructor or allocation
|
||||||
//! throws or T's default constructor throws.
|
//! throws or T's value initialization throws.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear to n.
|
//! <b>Complexity</b>: Linear to n.
|
||||||
explicit vector(size_type n)
|
explicit vector(size_type n)
|
||||||
@@ -635,7 +631,7 @@ class vector
|
|||||||
//! and inserts n default initialized values.
|
//! and inserts n default initialized values.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If allocator_type's default constructor or allocation
|
//! <b>Throws</b>: If allocator_type's default constructor or allocation
|
||||||
//! throws or T's default constructor throws.
|
//! throws or T's default initialization throws.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear to n.
|
//! <b>Complexity</b>: Linear to n.
|
||||||
//!
|
//!
|
||||||
@@ -679,7 +675,7 @@ class vector
|
|||||||
//! and inserts a copy of the range [first, last) in the vector.
|
//! and inserts a copy of the range [first, last) in the vector.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If allocator_type's default constructor or allocation
|
//! <b>Throws</b>: If allocator_type's default constructor or allocation
|
||||||
//! throws or T's constructor taking an dereferenced InIt throws.
|
//! throws or T's constructor taking a dereferenced InIt throws.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear to the range [first, last).
|
//! <b>Complexity</b>: Linear to the range [first, last).
|
||||||
template <class InIt>
|
template <class InIt>
|
||||||
@@ -691,7 +687,7 @@ class vector
|
|||||||
//! and inserts a copy of the range [first, last) in the vector.
|
//! and inserts a copy of the range [first, last) in the vector.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If allocator_type's default constructor or allocation
|
//! <b>Throws</b>: If allocator_type's default constructor or allocation
|
||||||
//! throws or T's constructor taking an dereferenced InIt throws.
|
//! throws or T's constructor taking a dereferenced InIt throws.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear to the range [first, last).
|
//! <b>Complexity</b>: Linear to the range [first, last).
|
||||||
template <class InIt>
|
template <class InIt>
|
||||||
@@ -717,27 +713,30 @@ class vector
|
|||||||
, x.size(), container_detail::to_raw_pointer(this->m_holder.start()));
|
, x.size(), container_detail::to_raw_pointer(this->m_holder.start()));
|
||||||
}
|
}
|
||||||
|
|
||||||
//! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
|
//! <b>Effects</b>: Move constructor. Moves x's resources to *this.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: Nothing
|
//! <b>Throws</b>: Nothing
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Constant.
|
//! <b>Complexity</b>: Constant.
|
||||||
vector(BOOST_RV_REF(vector) mx) BOOST_CONTAINER_NOEXCEPT
|
vector(BOOST_RV_REF(vector) x) BOOST_CONTAINER_NOEXCEPT
|
||||||
: m_holder(boost::move(mx.m_holder))
|
: m_holder(boost::move(x.m_holder))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||||
|
|
||||||
//! <b>Effects</b>: Move constructor. Moves mx's resources to *this.
|
//! <b>Effects</b>: Move constructor. Moves x's resources to *this.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If T's move constructor or allocation throws
|
//! <b>Throws</b>: If T's move constructor or allocation throws
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear.
|
//! <b>Complexity</b>: Linear.
|
||||||
//!
|
//!
|
||||||
//! <b>Note</b>: Non-standard extension
|
//! <b>Note</b>: Non-standard extension to support static_vector
|
||||||
template<class OtherAllocator>
|
template<class OtherAllocator>
|
||||||
vector(BOOST_RV_REF_BEG vector<T, OtherAllocator> BOOST_RV_REF_END mx)
|
vector(BOOST_RV_REF_BEG vector<T, OtherAllocator> BOOST_RV_REF_END x
|
||||||
: m_holder(boost::move(mx.m_holder))
|
, typename container_detail::enable_if_c
|
||||||
|
< container_detail::is_version<OtherAllocator, 0>::value>::type * = 0
|
||||||
|
)
|
||||||
|
: m_holder(boost::move(x.m_holder))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||||
@@ -759,25 +758,24 @@ class vector
|
|||||||
}
|
}
|
||||||
|
|
||||||
//! <b>Effects</b>: Move constructor using the specified allocator.
|
//! <b>Effects</b>: Move constructor using the specified allocator.
|
||||||
//! Moves mx's resources to *this if a == allocator_type().
|
//! Moves x's resources to *this if a == allocator_type().
|
||||||
//! Otherwise copies values from x to *this.
|
//! Otherwise copies values from x to *this.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If allocation or T's copy constructor throws.
|
//! <b>Throws</b>: If allocation or T's copy constructor throws.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Constant if a == mx.get_allocator(), linear otherwise.
|
//! <b>Complexity</b>: Constant if a == x.get_allocator(), linear otherwise.
|
||||||
vector(BOOST_RV_REF(vector) mx, const allocator_type &a)
|
vector(BOOST_RV_REF(vector) x, const allocator_type &a)
|
||||||
: m_holder(a)
|
: m_holder(container_detail::uninitialized_size, a, x.size())
|
||||||
{
|
{
|
||||||
if(mx.m_holder.alloc() == a){
|
if(x.m_holder.alloc() == a){
|
||||||
this->m_holder.move_from_empty(mx.m_holder);
|
this->m_holder.move_from_empty(x.m_holder);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
const size_type n = mx.size();
|
const size_type n = x.size();
|
||||||
this->m_holder.first_allocation_same_allocator_type(n);
|
this->m_holder.first_allocation_same_allocator_type(n);
|
||||||
::boost::container::uninitialized_move_alloc_n_source
|
::boost::container::uninitialized_move_alloc_n_source
|
||||||
( this->m_holder.alloc(), container_detail::to_raw_pointer(mx.m_holder.start())
|
( this->m_holder.alloc(), container_detail::to_raw_pointer(x.m_holder.start())
|
||||||
, n, container_detail::to_raw_pointer(this->m_holder.start()));
|
, n, container_detail::to_raw_pointer(this->m_holder.start()));
|
||||||
this->m_holder.m_size = n;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -805,30 +803,32 @@ class vector
|
|||||||
vector& operator=(BOOST_COPY_ASSIGN_REF(vector) x)
|
vector& operator=(BOOST_COPY_ASSIGN_REF(vector) x)
|
||||||
{
|
{
|
||||||
if (&x != this){
|
if (&x != this){
|
||||||
this->priv_copy_assign(x, alloc_version());
|
this->priv_copy_assign(x);
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! <b>Effects</b>: Move assignment. All mx's values are transferred to *this.
|
//! <b>Effects</b>: Move assignment. All x's values are transferred to *this.
|
||||||
//!
|
//!
|
||||||
//! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
|
//! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
|
||||||
//! before the function.
|
//! before the function.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: Nothing
|
//! <b>Throws</b>: If allocator_traits_type::propagate_on_container_move_assignment
|
||||||
|
//! is false and (allocation throws or value_type's move constructor throws)
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear.
|
//! <b>Complexity</b>: Constant if allocator_traits_type::
|
||||||
|
//! propagate_on_container_move_assignment is true or
|
||||||
|
//! this->get>allocator() == x.get_allocator(). Linear otherwise.
|
||||||
vector& operator=(BOOST_RV_REF(vector) x)
|
vector& operator=(BOOST_RV_REF(vector) x)
|
||||||
//iG BOOST_CONTAINER_NOEXCEPT_IF(!allocator_type::propagate_on_container_move_assignment::value || is_nothrow_move_assignable<allocator_type>::value);)
|
BOOST_CONTAINER_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value)
|
||||||
BOOST_CONTAINER_NOEXCEPT
|
|
||||||
{
|
{
|
||||||
this->priv_move_assign(boost::move(x), alloc_version());
|
this->priv_move_assign(boost::move(x));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||||
|
|
||||||
//! <b>Effects</b>: Move assignment. All mx's values are transferred to *this.
|
//! <b>Effects</b>: Move assignment. All x's values are transferred to *this.
|
||||||
//!
|
//!
|
||||||
//! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
|
//! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
|
||||||
//! before the function.
|
//! before the function.
|
||||||
@@ -836,10 +836,37 @@ class vector
|
|||||||
//! <b>Throws</b>: If move constructor/assignment of T throws or allocation throws
|
//! <b>Throws</b>: If move constructor/assignment of T throws or allocation throws
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear.
|
//! <b>Complexity</b>: Linear.
|
||||||
template<class OtherAllocator, class OtherAllocatorVersion>
|
//!
|
||||||
vector& operator=(BOOST_RV_REF_BEG vector<OtherAllocator, OtherAllocatorVersion> BOOST_RV_REF_END x)
|
//! <b>Note</b>: Non-standard extension to support static_vector
|
||||||
|
template<class OtherAllocator>
|
||||||
|
typename container_detail::enable_if_c
|
||||||
|
< container_detail::is_version<OtherAllocator, 0>::value &&
|
||||||
|
!container_detail::is_same<OtherAllocator, allocator_type>::value
|
||||||
|
, vector& >::type
|
||||||
|
operator=(BOOST_RV_REF_BEG vector<value_type, OtherAllocator> BOOST_RV_REF_END x)
|
||||||
{
|
{
|
||||||
this->priv_move_assign(boost::move(x), alloc_version());
|
this->priv_move_assign(boost::move(x));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! <b>Effects</b>: Copy assignment. All x's values are copied to *this.
|
||||||
|
//!
|
||||||
|
//! <b>Postcondition</b>: x.empty(). *this contains a the elements x had
|
||||||
|
//! before the function.
|
||||||
|
//!
|
||||||
|
//! <b>Throws</b>: If move constructor/assignment of T throws or allocation throws
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Linear.
|
||||||
|
//!
|
||||||
|
//! <b>Note</b>: Non-standard extension to support static_vector
|
||||||
|
template<class OtherAllocator>
|
||||||
|
typename container_detail::enable_if_c
|
||||||
|
< container_detail::is_version<OtherAllocator, 0>::value &&
|
||||||
|
!container_detail::is_same<OtherAllocator, allocator_type>::value
|
||||||
|
, vector& >::type
|
||||||
|
operator=(const vector<value_type, OtherAllocator> &x)
|
||||||
|
{
|
||||||
|
this->priv_copy_assign(x);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -898,7 +925,7 @@ class vector
|
|||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
//For Fwd iterators the standard only requires EmplaceConstructible and assignble from *first
|
//For Fwd iterators the standard only requires EmplaceConstructible and assignable from *first
|
||||||
//so we can't do any backwards allocation
|
//so we can't do any backwards allocation
|
||||||
const size_type input_sz = static_cast<size_type>(std::distance(first, last));
|
const size_type input_sz = static_cast<size_type>(std::distance(first, last));
|
||||||
const size_type old_capacity = this->capacity();
|
const size_type old_capacity = this->capacity();
|
||||||
@@ -1117,16 +1144,16 @@ class vector
|
|||||||
//! <b>Effects</b>: Inserts or erases elements at the end such that
|
//! <b>Effects</b>: Inserts or erases elements at the end such that
|
||||||
//! the size becomes n. New elements are value initialized.
|
//! the size becomes n. New elements are value initialized.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If memory allocation throws, or T's constructor throws.
|
//! <b>Throws</b>: If memory allocation throws, or T's copy/move or value initialization throws.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
|
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
|
||||||
void resize(size_type new_size)
|
void resize(size_type new_size)
|
||||||
{ this->priv_resize(new_size, value_init); }
|
{ this->priv_resize(new_size, value_init); }
|
||||||
|
|
||||||
//! <b>Effects</b>: Inserts or erases elements at the end such that
|
//! <b>Effects</b>: Inserts or erases elements at the end such that
|
||||||
//! the size becomes n. New elements are value initialized.
|
//! the size becomes n. New elements are default initialized.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If memory allocation throws, or T's constructor throws.
|
//! <b>Throws</b>: If memory allocation throws, or T's copy/move or default initialization throws.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
|
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
|
||||||
//!
|
//!
|
||||||
@@ -1137,7 +1164,7 @@ class vector
|
|||||||
//! <b>Effects</b>: Inserts or erases elements at the end such that
|
//! <b>Effects</b>: Inserts or erases elements at the end such that
|
||||||
//! the size becomes n. New elements are copy constructed from x.
|
//! the size becomes n. New elements are copy constructed from x.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If memory allocation throws, or T's copy constructor throws.
|
//! <b>Throws</b>: If memory allocation throws, or T's copy/move constructor throws.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
|
//! <b>Complexity</b>: Linear to the difference between size() and new_size.
|
||||||
void resize(size_type new_size, const T& x)
|
void resize(size_type new_size, const T& x)
|
||||||
@@ -1303,7 +1330,7 @@ class vector
|
|||||||
//! std::forward<Args>(args)... in the end of the vector.
|
//! std::forward<Args>(args)... in the end of the vector.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If memory allocation throws or the in-place constructor throws or
|
//! <b>Throws</b>: If memory allocation throws or the in-place constructor throws or
|
||||||
//! T's move constructor throws.
|
//! T's copy/move constructor throws.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Amortized constant time.
|
//! <b>Complexity</b>: Amortized constant time.
|
||||||
template<class ...Args>
|
template<class ...Args>
|
||||||
@@ -1328,7 +1355,7 @@ class vector
|
|||||||
//! std::forward<Args>(args)... before position
|
//! std::forward<Args>(args)... before position
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If memory allocation throws or the in-place constructor throws or
|
//! <b>Throws</b>: If memory allocation throws or the in-place constructor throws or
|
||||||
//! T's move constructor/assignment throws.
|
//! T's copy/move constructor/assignment throws.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: If position is end(), amortized constant time
|
//! <b>Complexity</b>: If position is end(), amortized constant time
|
||||||
//! Linear time otherwise.
|
//! Linear time otherwise.
|
||||||
@@ -1389,10 +1416,10 @@ class vector
|
|||||||
void push_back(const T &x);
|
void push_back(const T &x);
|
||||||
|
|
||||||
//! <b>Effects</b>: Constructs a new element in the end of the vector
|
//! <b>Effects</b>: Constructs a new element in the end of the vector
|
||||||
//! and moves the resources of mx to this new element.
|
//! and moves the resources of x to this new element.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If memory allocation throws or
|
//! <b>Throws</b>: If memory allocation throws or
|
||||||
//! T's move constructor throws.
|
//! T's copy/move constructor throws.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Amortized constant time.
|
//! <b>Complexity</b>: Amortized constant time.
|
||||||
void push_back(T &&x);
|
void push_back(T &&x);
|
||||||
@@ -1413,7 +1440,7 @@ class vector
|
|||||||
|
|
||||||
//! <b>Requires</b>: position must be a valid iterator of *this.
|
//! <b>Requires</b>: position must be a valid iterator of *this.
|
||||||
//!
|
//!
|
||||||
//! <b>Effects</b>: Insert a new element before position with mx's resources.
|
//! <b>Effects</b>: Insert a new element before position with x's resources.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If memory allocation throws.
|
//! <b>Throws</b>: If memory allocation throws.
|
||||||
//!
|
//!
|
||||||
@@ -1430,7 +1457,7 @@ class vector
|
|||||||
//!
|
//!
|
||||||
//! <b>Returns</b>: an iterator to the first inserted element or p if n is 0.
|
//! <b>Returns</b>: an iterator to the first inserted element or p if n is 0.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
|
//! <b>Throws</b>: If memory allocation throws or T's copy/move constructor throws.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear to n.
|
//! <b>Complexity</b>: Linear to n.
|
||||||
iterator insert(const_iterator p, size_type n, const T& x)
|
iterator insert(const_iterator p, size_type n, const T& x)
|
||||||
@@ -1482,6 +1509,32 @@ class vector
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//! <b>Requires</b>: p must be a valid iterator of *this. num, must
|
||||||
|
//! be equal to std::distance(first, last)
|
||||||
|
//!
|
||||||
|
//! <b>Effects</b>: Insert a copy of the [first, last) range before pos.
|
||||||
|
//!
|
||||||
|
//! <b>Returns</b>: an iterator to the first inserted element or pos if first == last.
|
||||||
|
//!
|
||||||
|
//! <b>Throws</b>: If memory allocation throws, T's constructor from a
|
||||||
|
//! dereferenced InpIt throws or T's copy/move constructor/assignment throws.
|
||||||
|
//!
|
||||||
|
//! <b>Complexity</b>: Linear to std::distance [first, last).
|
||||||
|
//!
|
||||||
|
//! <b>Note</b>: This function avoids a linear operation to calculate std::distance[first, last)
|
||||||
|
//! for forward and bidirectional iterators, and a one by one insertion for input iterators. This is a
|
||||||
|
//! a non-standard extension.
|
||||||
|
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||||
|
template <class InIt>
|
||||||
|
iterator insert(const_iterator pos, size_type num, InIt first, InIt last)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(container_detail::is_input_iterator<InIt>::value ||
|
||||||
|
num == static_cast<size_type>(std::distance(first, last)));
|
||||||
|
container_detail::insert_range_proxy<Allocator, InIt, T*> proxy(first);
|
||||||
|
return this->priv_forward_range_insert(vector_iterator_get_ptr(pos), num, proxy, alloc_version());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//! <b>Effects</b>: Removes the last element from the vector.
|
//! <b>Effects</b>: Removes the last element from the vector.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: Nothing.
|
//! <b>Throws</b>: Nothing.
|
||||||
@@ -1537,7 +1590,7 @@ class vector
|
|||||||
//! <b>Throws</b>: Nothing.
|
//! <b>Throws</b>: Nothing.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Constant.
|
//! <b>Complexity</b>: Constant.
|
||||||
void swap(vector& x) BOOST_CONTAINER_NOEXCEPT_IF((!container_detail::is_same<alloc_version, allocator_v0>::value))
|
void swap(vector& x) BOOST_CONTAINER_NOEXCEPT_IF((!container_detail::is_version<Allocator, 0>::value))
|
||||||
{
|
{
|
||||||
//Just swap internals in case of !allocator_v0. Otherwise, deep swap
|
//Just swap internals in case of !allocator_v0. Otherwise, deep swap
|
||||||
this->m_holder.swap(x.m_holder);
|
this->m_holder.swap(x.m_holder);
|
||||||
@@ -1550,13 +1603,17 @@ class vector
|
|||||||
|
|
||||||
//! <b>Effects</b>: Swaps the contents of *this and x.
|
//! <b>Effects</b>: Swaps the contents of *this and x.
|
||||||
//!
|
//!
|
||||||
//! <b>Throws</b>: If T's move constructor throws.
|
//! <b>Throws</b>: Nothing.
|
||||||
//!
|
//!
|
||||||
//! <b>Complexity</b>: Linear
|
//! <b>Complexity</b>: Linear
|
||||||
//!
|
//!
|
||||||
//! <b>Note</b>: non-standard extension.
|
//! <b>Note</b>: Non-standard extension to support static_vector
|
||||||
template<class OtherAllocator>
|
template<class OtherAllocator>
|
||||||
void swap(vector<T, OtherAllocator> & x)
|
void swap(vector<T, OtherAllocator> & x
|
||||||
|
, typename container_detail::enable_if_c
|
||||||
|
< container_detail::is_version<OtherAllocator, 0>::value &&
|
||||||
|
!container_detail::is_same<OtherAllocator, allocator_type>::value >::type * = 0
|
||||||
|
)
|
||||||
{ this->m_holder.swap(x.m_holder); }
|
{ this->m_holder.swap(x.m_holder); }
|
||||||
|
|
||||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||||
@@ -1618,7 +1675,7 @@ class vector
|
|||||||
void insert_ordered_at(size_type element_count, BiDirPosConstIt last_position_it, BiDirValueIt last_value_it)
|
void insert_ordered_at(size_type element_count, BiDirPosConstIt last_position_it, BiDirValueIt last_value_it)
|
||||||
{
|
{
|
||||||
const size_type *dummy = 0;
|
const size_type *dummy = 0;
|
||||||
this->priv_insert_ordered_at(element_count, last_position_it, false, &dummy[0], last_value_it);
|
this->priv_insert_ordered_at(element_count, last_position_it, false, dummy, last_value_it);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Absolutely experimental. This function might change, disappear or simply crash!
|
//Absolutely experimental. This function might change, disappear or simply crash!
|
||||||
@@ -1631,36 +1688,15 @@ class vector
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
template<class OtherAllocator, class AllocVersion>
|
template<class OtherAllocator>
|
||||||
void priv_move_assign(BOOST_RV_REF_BEG vector<T, OtherAllocator> BOOST_RV_REF_END x
|
void priv_move_assign(BOOST_RV_REF_BEG vector<T, OtherAllocator> BOOST_RV_REF_END x
|
||||||
, AllocVersion
|
|
||||||
, typename container_detail::enable_if_c
|
, typename container_detail::enable_if_c
|
||||||
< container_detail::is_same<AllocVersion, allocator_v0>::value &&
|
< container_detail::is_version<OtherAllocator, 0>::value >::type * = 0)
|
||||||
!container_detail::is_same<OtherAllocator, allocator_type>::value
|
|
||||||
>::type * = 0)
|
|
||||||
{
|
{
|
||||||
if(this->capacity() < x.size()){
|
if(!container_detail::is_same<OtherAllocator, allocator_type>::value &&
|
||||||
|
this->capacity() < x.size()){
|
||||||
throw_bad_alloc();
|
throw_bad_alloc();
|
||||||
}
|
}
|
||||||
this->priv_move_assign_impl(boost::move(x), AllocVersion());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class OtherAllocator, class AllocVersion>
|
|
||||||
void priv_move_assign(BOOST_RV_REF_BEG vector<T, OtherAllocator> BOOST_RV_REF_END x
|
|
||||||
, AllocVersion
|
|
||||||
, typename container_detail::enable_if_c
|
|
||||||
< !container_detail::is_same<AllocVersion, allocator_v0>::value ||
|
|
||||||
container_detail::is_same<OtherAllocator, allocator_type>::value
|
|
||||||
>::type * = 0)
|
|
||||||
{ this->priv_move_assign_impl(boost::move(x), AllocVersion()); }
|
|
||||||
|
|
||||||
template<class OtherAllocator, class AllocVersion>
|
|
||||||
void priv_move_assign_impl(BOOST_RV_REF_BEG vector<T, OtherAllocator> BOOST_RV_REF_END x
|
|
||||||
, AllocVersion
|
|
||||||
, typename container_detail::enable_if_c
|
|
||||||
< container_detail::is_same<AllocVersion, allocator_v0>::value
|
|
||||||
>::type * = 0)
|
|
||||||
{
|
|
||||||
T* const this_start = container_detail::to_raw_pointer(m_holder.start());
|
T* const this_start = container_detail::to_raw_pointer(m_holder.start());
|
||||||
T* const other_start = container_detail::to_raw_pointer(x.m_holder.start());
|
T* const other_start = container_detail::to_raw_pointer(x.m_holder.start());
|
||||||
const size_type this_sz = m_holder.m_size;
|
const size_type this_sz = m_holder.m_size;
|
||||||
@@ -1669,40 +1705,46 @@ class vector
|
|||||||
this->m_holder.m_size = other_sz;
|
this->m_holder.m_size = other_sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class OtherAllocator, class AllocVersion>
|
template<class OtherAllocator>
|
||||||
void priv_move_assign_impl(BOOST_RV_REF_BEG vector<T, OtherAllocator> BOOST_RV_REF_END x
|
void priv_move_assign(BOOST_RV_REF_BEG vector<T, OtherAllocator> BOOST_RV_REF_END x
|
||||||
, AllocVersion
|
|
||||||
, typename container_detail::enable_if_c
|
, typename container_detail::enable_if_c
|
||||||
< !container_detail::is_same<AllocVersion, allocator_v0>::value
|
< !container_detail::is_version<OtherAllocator, 0>::value &&
|
||||||
>::type * = 0)
|
container_detail::is_same<OtherAllocator, allocator_type>::value>::type * = 0)
|
||||||
{
|
{
|
||||||
//for move constructor, no aliasing (&x != this) is assummed.
|
//for move constructor, no aliasing (&x != this) is assummed.
|
||||||
|
BOOST_ASSERT(this != &x);
|
||||||
allocator_type &this_alloc = this->m_holder.alloc();
|
allocator_type &this_alloc = this->m_holder.alloc();
|
||||||
allocator_type &x_alloc = x.m_holder.alloc();
|
allocator_type &x_alloc = x.m_holder.alloc();
|
||||||
//If allocators are equal we can just swap pointers
|
const bool propagate_alloc = allocator_traits_type::
|
||||||
if(this_alloc == x_alloc){
|
propagate_on_container_move_assignment::value;
|
||||||
|
container_detail::bool_<propagate_alloc> flag;
|
||||||
|
const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal;
|
||||||
|
//Resources can be transferred if both allocators are
|
||||||
|
//going to be equal after this function (either propagated or already equal)
|
||||||
|
if(propagate_alloc || allocators_equal){
|
||||||
//Destroy objects but retain memory in case x reuses it in the future
|
//Destroy objects but retain memory in case x reuses it in the future
|
||||||
this->clear();
|
this->clear();
|
||||||
this->m_holder.swap(x.m_holder);
|
|
||||||
//Move allocator if needed
|
//Move allocator if needed
|
||||||
container_detail::bool_<allocator_traits_type::
|
|
||||||
propagate_on_container_move_assignment::value> flag;
|
|
||||||
container_detail::move_alloc(this_alloc, x_alloc, flag);
|
container_detail::move_alloc(this_alloc, x_alloc, flag);
|
||||||
|
//Nothrow swap
|
||||||
|
this->m_holder.swap(x.m_holder);
|
||||||
}
|
}
|
||||||
//If unequal allocators, then do a one by one move
|
//Else do a one by one move
|
||||||
else{
|
else{
|
||||||
//TO-DO: optimize this
|
this->assign( boost::make_move_iterator(x.begin())
|
||||||
this->assign( boost::make_move_iterator(container_detail::to_raw_pointer(x.m_holder.start()))
|
, boost::make_move_iterator(x.end()));
|
||||||
, boost::make_move_iterator(container_detail::to_raw_pointer(x.m_holder.start() + x.m_holder.m_size)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class AllocVersion>
|
template<class OtherAllocator>
|
||||||
void priv_copy_assign(const vector &x, AllocVersion
|
void priv_copy_assign(const vector<T, OtherAllocator> &x
|
||||||
, typename container_detail::enable_if_c
|
, typename container_detail::enable_if_c
|
||||||
< container_detail::is_same<AllocVersion, allocator_v0>::value
|
< container_detail::is_version<OtherAllocator, 0>::value >::type * = 0)
|
||||||
>::type * = 0)
|
|
||||||
{
|
{
|
||||||
|
if(!container_detail::is_same<OtherAllocator, allocator_type>::value &&
|
||||||
|
this->capacity() < x.size()){
|
||||||
|
throw_bad_alloc();
|
||||||
|
}
|
||||||
T* const this_start = container_detail::to_raw_pointer(m_holder.start());
|
T* const this_start = container_detail::to_raw_pointer(m_holder.start());
|
||||||
T* const other_start = container_detail::to_raw_pointer(x.m_holder.start());
|
T* const other_start = container_detail::to_raw_pointer(x.m_holder.start());
|
||||||
const size_type this_sz = m_holder.m_size;
|
const size_type this_sz = m_holder.m_size;
|
||||||
@@ -1711,11 +1753,11 @@ class vector
|
|||||||
this->m_holder.m_size = other_sz;
|
this->m_holder.m_size = other_sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class AllocVersion>
|
template<class OtherAllocator>
|
||||||
void priv_copy_assign(const vector &x, AllocVersion
|
void priv_copy_assign(const vector<T, OtherAllocator> &x
|
||||||
, typename container_detail::enable_if_c
|
, typename container_detail::enable_if_c
|
||||||
< !container_detail::is_same<AllocVersion, allocator_v0>::value
|
< !container_detail::is_version<OtherAllocator, 0>::value &&
|
||||||
>::type * = 0)
|
container_detail::is_same<OtherAllocator, allocator_type>::value >::type * = 0)
|
||||||
{
|
{
|
||||||
allocator_type &this_alloc = this->m_holder.alloc();
|
allocator_type &this_alloc = this->m_holder.alloc();
|
||||||
const allocator_type &x_alloc = x.m_holder.alloc();
|
const allocator_type &x_alloc = x.m_holder.alloc();
|
||||||
|
@@ -486,7 +486,7 @@ void test_swap_and_move_nd()
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
static_vector<T, N> v1, v2, v3;
|
static_vector<T, N> v1, v2, v3;
|
||||||
static_vector<T, N/2> s1, s2;
|
static_vector<T, N/2> s1, s2, s3;
|
||||||
|
|
||||||
for (size_t i = 0 ; i < N/2 ; ++i )
|
for (size_t i = 0 ; i < N/2 ; ++i )
|
||||||
{
|
{
|
||||||
@@ -501,17 +501,19 @@ void test_swap_and_move_nd()
|
|||||||
}
|
}
|
||||||
|
|
||||||
s1.swap(v1);
|
s1.swap(v1);
|
||||||
|
s3 = v2;
|
||||||
s2 = boost::move(v2);
|
s2 = boost::move(v2);
|
||||||
static_vector<T, N/2> s3(boost::move(v3));
|
static_vector<T, N/2> s4(boost::move(v3));
|
||||||
|
|
||||||
BOOST_TEST(v1.size() == N/3);
|
BOOST_TEST(v1.size() == N/3);
|
||||||
BOOST_TEST(s1.size() == N/2);
|
BOOST_TEST(s1.size() == N/2);
|
||||||
//iG moving does not imply emptying source
|
//iG moving does not imply emptying source
|
||||||
//BOOST_TEST(v2.size() == 0);
|
//BOOST_TEST(v2.size() == 0);
|
||||||
BOOST_TEST(s2.size() == N/2);
|
BOOST_TEST(s2.size() == N/2);
|
||||||
|
BOOST_TEST(s3.size() == N/2);
|
||||||
//iG moving does not imply emptying source
|
//iG moving does not imply emptying source
|
||||||
//BOOST_TEST(v3.size() == 0);
|
//BOOST_TEST(v3.size() == 0);
|
||||||
BOOST_TEST(s3.size() == N/2);
|
BOOST_TEST(s4.size() == N/2);
|
||||||
for (size_t i = 0 ; i < N/3 ; ++i )
|
for (size_t i = 0 ; i < N/3 ; ++i )
|
||||||
BOOST_TEST(v1[i] == T(100 + i));
|
BOOST_TEST(v1[i] == T(100 + i));
|
||||||
for (size_t i = 0 ; i < N/2 ; ++i )
|
for (size_t i = 0 ; i < N/2 ; ++i )
|
||||||
@@ -519,6 +521,7 @@ void test_swap_and_move_nd()
|
|||||||
BOOST_TEST(s1[i] == T(i));
|
BOOST_TEST(s1[i] == T(i));
|
||||||
BOOST_TEST(s2[i] == T(i));
|
BOOST_TEST(s2[i] == T(i));
|
||||||
BOOST_TEST(s3[i] == T(i));
|
BOOST_TEST(s3[i] == T(i));
|
||||||
|
BOOST_TEST(s4[i] == T(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@@ -528,6 +531,7 @@ void test_swap_and_move_nd()
|
|||||||
BOOST_TEST_THROWS(s.swap(v), std::bad_alloc);
|
BOOST_TEST_THROWS(s.swap(v), std::bad_alloc);
|
||||||
v.resize(N, T(0));
|
v.resize(N, T(0));
|
||||||
BOOST_TEST_THROWS(s = boost::move(v), std::bad_alloc);
|
BOOST_TEST_THROWS(s = boost::move(v), std::bad_alloc);
|
||||||
|
BOOST_TEST_THROWS(s = v, std::bad_alloc);
|
||||||
v.resize(N, T(0));
|
v.resize(N, T(0));
|
||||||
BOOST_TEST_THROWS(small_vector_t s2(boost::move(v)), std::bad_alloc);
|
BOOST_TEST_THROWS(small_vector_t s2(boost::move(v)), std::bad_alloc);
|
||||||
}
|
}
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include <boost/container/static_vector.hpp>
|
#include <boost/container/static_vector.hpp>
|
||||||
|
|
||||||
|
#define BOOST_SP_DISABLE_THREADS
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include "movable_int.hpp"
|
#include "movable_int.hpp"
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user