@@ -1318,28 +1318,13 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
1318
1318
|| allocator_traits_type::is_always_equal::value)
1319
1319
{
1320
1320
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);
1343
1328
}
1344
1329
return *this ;
1345
1330
}
@@ -2378,6 +2363,30 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
2378
2363
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
2379
2364
private:
2380
2365
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
+
2381
2390
inline size_type priv_index_of (const_iterator p) const
2382
2391
{
2383
2392
BOOST_ASSERT (this ->cbegin () <= p);
@@ -2493,7 +2502,8 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
2493
2502
2494
2503
void priv_destroy_range (iterator p, iterator p2)
2495
2504
{
2496
- if (!Base::traits_t ::trivial_dctr){
2505
+ (void )p; (void )p2;
2506
+ BOOST_IF_CONSTEXPR (!Base::traits_t ::trivial_dctr){
2497
2507
for (;p != p2; ++p){
2498
2508
allocator_traits_type::destroy (this ->alloc (), boost::movelib::iterator_to_raw_pointer (p));
2499
2509
}
@@ -2502,7 +2512,8 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
2502
2512
2503
2513
void priv_destroy_range (pointer p, pointer p2)
2504
2514
{
2505
- if (!Base::traits_t ::trivial_dctr){
2515
+ (void )p; (void )p2;
2516
+ BOOST_IF_CONSTEXPR (!Base::traits_t ::trivial_dctr){
2506
2517
for (;p != p2; ++p){
2507
2518
allocator_traits_type::destroy (this ->alloc (), boost::movelib::iterator_to_raw_pointer (p));
2508
2519
}
0 commit comments