Skip to content

Commit 59d760c

Browse files
committed
Document block_size option in deque_options.
1 parent 20ad12f commit 59d760c

26 files changed

+711
-358
lines changed

include/boost/container/deque.hpp

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1318,28 +1318,13 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
13181318
|| allocator_traits_type::is_always_equal::value)
13191319
{
13201320
if (BOOST_LIKELY(this != &x)) {
1321-
allocator_type &this_alloc = this->alloc();
1322-
allocator_type &x_alloc = x.alloc();
1323-
const bool propagate_alloc = allocator_traits_type::
1324-
propagate_on_container_move_assignment::value;
1325-
dtl::bool_<propagate_alloc> flag;
1326-
const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal;
1327-
//Resources can be transferred if both allocators are
1328-
//going to be equal after this function (either propagated or already equal)
1329-
if(propagate_alloc || allocators_equal){
1330-
//Destroy objects but retain memory in case x reuses it in the future
1331-
this->clear();
1332-
//Move allocator if needed
1333-
dtl::move_alloc(this_alloc, x_alloc, flag);
1334-
dtl::move_alloc(this->ptr_alloc(), x.ptr_alloc(), flag);
1335-
//Nothrow swap
1336-
this->swap_members(x);
1337-
}
1338-
//Else do a one by one move
1339-
else{
1340-
this->assign( boost::make_move_iterator(x.begin())
1341-
, boost::make_move_iterator(x.end()));
1342-
}
1321+
//We know resources can be transferred at comiple time if both allocators are
1322+
//always equal or the allocator is going to be propagated
1323+
const bool can_steal_resources_alloc
1324+
= allocator_traits_type::propagate_on_container_move_assignment::value
1325+
|| allocator_traits_type::is_always_equal::value;
1326+
dtl::bool_<can_steal_resources_alloc> flag;
1327+
this->priv_move_assign(boost::move(x), flag);
13431328
}
13441329
return *this;
13451330
}
@@ -2378,6 +2363,30 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
23782363
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
23792364
private:
23802365

2366+
void priv_move_assign(BOOST_RV_REF(deque) x, dtl::bool_<true> /*steal_resources*/)
2367+
{
2368+
//Destroy objects but retain memory in case x reuses it in the future
2369+
this->clear();
2370+
//Move allocator if needed
2371+
dtl::bool_<allocator_traits_type::propagate_on_container_move_assignment::value> flag;
2372+
dtl::move_alloc(this->alloc(), x.alloc(), flag);
2373+
dtl::move_alloc(this->ptr_alloc(), x.ptr_alloc(), flag);
2374+
//Nothrow swap
2375+
this->swap_members(x);
2376+
}
2377+
2378+
void priv_move_assign(BOOST_RV_REF(deque) x, dtl::bool_<false> /*steal_resources*/)
2379+
{
2380+
//We can't guarantee a compile-time equal allocator or propagation so fallback to runtime
2381+
//Resources can be transferred if both allocators are equal
2382+
if (this->alloc() == x.alloc()) {
2383+
this->priv_move_assign(boost::move(x), dtl::true_());
2384+
}
2385+
else {
2386+
this->assign(boost::make_move_iterator(x.begin()), boost::make_move_iterator(x.end()));
2387+
}
2388+
}
2389+
23812390
inline size_type priv_index_of(const_iterator p) const
23822391
{
23832392
BOOST_ASSERT(this->cbegin() <= p);
@@ -2493,7 +2502,8 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
24932502

24942503
void priv_destroy_range(iterator p, iterator p2)
24952504
{
2496-
if(!Base::traits_t::trivial_dctr){
2505+
(void)p; (void)p2;
2506+
BOOST_IF_CONSTEXPR(!Base::traits_t::trivial_dctr){
24972507
for(;p != p2; ++p){
24982508
allocator_traits_type::destroy(this->alloc(), boost::movelib::iterator_to_raw_pointer(p));
24992509
}
@@ -2502,7 +2512,8 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
25022512

25032513
void priv_destroy_range(pointer p, pointer p2)
25042514
{
2505-
if(!Base::traits_t::trivial_dctr){
2515+
(void)p; (void)p2;
2516+
BOOST_IF_CONSTEXPR(!Base::traits_t::trivial_dctr){
25062517
for(;p != p2; ++p){
25072518
allocator_traits_type::destroy(this->alloc(), boost::movelib::iterator_to_raw_pointer(p));
25082519
}

include/boost/container/detail/tree.hpp

Lines changed: 43 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -688,40 +688,13 @@ class tree
688688
boost::container::dtl::is_nothrow_move_assignable<Compare>::value)
689689
{
690690
if (BOOST_LIKELY(this != &x)) {
691-
NodeAlloc &this_alloc = this->node_alloc();
692-
NodeAlloc &x_alloc = x.node_alloc();
693-
const bool propagate_alloc = allocator_traits<NodeAlloc>::
694-
propagate_on_container_move_assignment::value;
695-
const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal;
696-
//Resources can be transferred if both allocators are
697-
//going to be equal after this function (either propagated or already equal)
698-
if(propagate_alloc || allocators_equal){
699-
//Destroy
700-
this->clear();
701-
//Move allocator if needed
702-
this->AllocHolder::move_assign_alloc(x);
703-
//Obtain resources
704-
this->icont() = boost::move(x.icont());
705-
}
706-
//Else do a one by one move
707-
else{
708-
//Transfer all the nodes to a temporary tree
709-
//If anything goes wrong, all the nodes will be destroyed
710-
//automatically
711-
Icont other_tree(::boost::move(this->icont()));
712-
713-
//Now recreate the source tree reusing nodes stored by other_tree
714-
this->icont().clone_from
715-
(::boost::move(x.icont())
716-
, RecyclingCloner<AllocHolder, true>(*this, other_tree)
717-
, Destroyer(this->node_alloc()));
718-
719-
//If there are remaining nodes, destroy them
720-
NodePtr p;
721-
while((p = other_tree.unlink_leftmost_without_rebalance())){
722-
AllocHolder::destroy_node(p);
723-
}
724-
}
691+
//We know resources can be transferred at comiple time if both allocators are
692+
//always equal or the allocator is going to be propagated
693+
const bool can_steal_resources_alloc
694+
= allocator_traits_type::propagate_on_container_move_assignment::value
695+
|| allocator_traits_type::is_always_equal::value;
696+
dtl::bool_<can_steal_resources_alloc> flag;
697+
this->priv_move_assign(boost::move(x), flag);
725698
}
726699
return *this;
727700
}
@@ -895,6 +868,42 @@ class tree
895868

896869

897870
private:
871+
void priv_move_assign(BOOST_RV_REF(tree) x, dtl::bool_<true> /*steal_resources*/)
872+
{
873+
//Destroy objects but retain memory in case x reuses it in the future
874+
this->clear();
875+
//Move allocator if needed
876+
this->AllocHolder::move_assign_alloc(x);
877+
//Obtain resources
878+
this->icont() = boost::move(x.icont());
879+
}
880+
881+
void priv_move_assign(BOOST_RV_REF(tree) x, dtl::bool_<false> /*steal_resources*/)
882+
{
883+
//We can't guarantee a compile-time equal allocator or propagation so fallback to runtime
884+
//Resources can be transferred if both allocators are equal
885+
if (this->node_alloc() == x.node_alloc()) {
886+
this->priv_move_assign(boost::move(x), dtl::true_());
887+
}
888+
else {
889+
//Transfer all the nodes to a temporary tree
890+
//If anything goes wrong, all the nodes will be destroyed
891+
//automatically
892+
Icont other_tree(::boost::move(this->icont()));
893+
894+
//Now recreate the source tree reusing nodes stored by other_tree
895+
this->icont().clone_from
896+
(::boost::move(x.icont())
897+
, RecyclingCloner<AllocHolder, true>(*this, other_tree)
898+
, Destroyer(this->node_alloc()));
899+
900+
//If there are remaining nodes, destroy them
901+
NodePtr p;
902+
while ((p = other_tree.unlink_leftmost_without_rebalance())) {
903+
AllocHolder::destroy_node(p);
904+
}
905+
}
906+
}
898907

899908
template<class KeyConvertible, class M>
900909
iiterator priv_insert_or_assign_commit

0 commit comments

Comments
 (0)