8#ifndef INCLUDED_BSLSTL_DEQUE
9#define INCLUDED_BSLSTL_DEQUE
448#include <bslscm_version.h>
489#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
490#include <initializer_list>
493#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
497#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
502#if BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
506# define COMPILING_BSLSTL_DEQUE_H
508# undef COMPILING_BSLSTL_DEQUE_H
513template <
class VALUE_TYPE,
class ALLOCATOR>
514class Deque_BlockCreator;
515template <
class VALUE_TYPE,
class ALLOCATOR>
516class Deque_BlockProctor;
517template <
class VALUE_TYPE,
class ALLOCATOR>
518class Deque_ClearGuard;
519template <
class VALUE_TYPE,
class ALLOCATOR>
529template <
class VALUE_TYPE>
558 static void move(
void *dst,
void *src);
562 static void swap(
void *a,
void *b);
578template <
class VALUE_TYPE>
586 typedef BloombergLP::bslalg::DequeImpUtil<VALUE_TYPE,
588 typedef typename Imp::Block Block;
589 typedef typename Imp::BlockPtr BlockPtr;
590 typedef BloombergLP::bslalg::DequeIterator<VALUE_TYPE,
591 BLOCK_LENGTH> IteratorImp;
592 typedef BloombergLP::
593 bslstl::RandomAccessIterator<VALUE_TYPE, IteratorImp>
596 typedef BloombergLP::
597 bslstl::RandomAccessIterator<const VALUE_TYPE, IteratorImp>
770template <class VALUE_TYPE, class ALLOCATOR =
allocator<VALUE_TYPE> >
772 , private BloombergLP::
bslalg::ContainerBase<ALLOCATOR> {
781 typedef BloombergLP::bslalg::ContainerBase<ALLOCATOR> ContainerBase;
783 typedef BloombergLP::bslalg::DequeImpUtil<VALUE_TYPE,
785 typedef typename Imp::Block Block;
786 typedef typename Imp::BlockPtr BlockPtr;
788 typedef BloombergLP::bslalg::DequeIterator<VALUE_TYPE,
789 BLOCK_LENGTH> IteratorImp;
791 typedef BloombergLP::
792 bslstl::RandomAccessIterator<VALUE_TYPE,
793 IteratorImp> Iterator;
795 typedef BloombergLP::
796 bslstl::RandomAccessIterator<
const VALUE_TYPE,
797 IteratorImp> ConstIterator;
804 typedef BloombergLP::bslalg::DequePrimitives<VALUE_TYPE,
805 BLOCK_LENGTH> DequePrimitives;
807 typedef BloombergLP::bslma::AllocatorUtil AllocatorUtil;
812 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
816 enum RawInit { k_RAW_INIT = 0 };
864 Block *allocateBlock();
869 BlockPtr *allocateBlockPtrs(std::size_t n);
874 void deallocateBlock(Block *p);
880 void deallocateBlockPtrs(BlockPtr *p, std::size_t n);
887 template <
class INPUT_ITERATOR>
888 size_type privateAppend(INPUT_ITERATOR first,
890 std::input_iterator_tag);
891 template <
class INPUT_ITERATOR>
892 size_type privateAppend(INPUT_ITERATOR first,
894 std::random_access_iterator_tag);
898 void privateAppendDefaultInsertable(
size_type numElements);
902 void privateAppendRaw(
size_type numElements,
const VALUE_TYPE& value);
919 template <
class INTEGER_TYPE>
920 void privateInsertDispatch(
922 INTEGER_TYPE numElements,
924 BloombergLP::bslmf::MatchArithmeticType,
925 BloombergLP::bslmf::Nil);
934 template <
class INPUT_ITERATOR>
936 INPUT_ITERATOR first,
938 BloombergLP::bslmf::MatchAnyType,
939 BloombergLP::bslmf::MatchAnyType);
942 template <
class INPUT_ITERATOR>
944 INPUT_ITERATOR first,
946 std::input_iterator_tag);
950 template <
class INPUT_ITERATOR>
952 INPUT_ITERATOR first,
954 std::random_access_iterator_tag);
959 void privateJoinPrepend(
deque *other);
964 void privateJoinAppend(
deque *other);
971 template <
class INPUT_ITERATOR>
972 size_type privatePrepend(INPUT_ITERATOR first,
974 std::input_iterator_tag);
975 template <
class INPUT_ITERATOR>
976 size_type privatePrepend(INPUT_ITERATOR first,
978 std::bidirectional_iterator_tag);
979 template <
class INPUT_ITERATOR>
980 size_type privatePrepend(INPUT_ITERATOR first,
982 std::random_access_iterator_tag);
986 void privatePrependRaw(
size_type numElements,
const VALUE_TYPE& value);
994 void privateSplit(
deque *other, IteratorImp pos);
997 template <
class VALUE_TYPE2,
class ALLOCATOR2>
1000 template <
class VALUE_TYPE2,
class ALLOCATOR2>
1003 template <
class VALUE_TYPE2,
class ALLOCATOR2>
1020 explicit deque(
const ALLOCATOR& basicAllocator);
1036 const ALLOCATOR& basicAllocator = ALLOCATOR());
1052 const VALUE_TYPE& value,
1053 const ALLOCATOR& basicAllocator = ALLOCATOR());
1076 template <
class INPUT_ITERATOR>
1078 INPUT_ITERATOR last,
1079 const ALLOCATOR& basicAllocator = ALLOCATOR());
1107 deque(BloombergLP::bslmf::MovableRef<deque> original);
1120 deque(BloombergLP::bslmf::MovableRef<deque> original,
1123#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1135 deque(std::initializer_list<value_type> values,
1136 const ALLOCATOR& basicAllocator = ALLOCATOR());
1154 deque& operator=(BloombergLP::bslmf::MovableRef<deque> rhs)
1156 AllocatorTraits::is_always_equal::value);
1172#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1179 deque& operator=(std::initializer_list<value_type> values);
1194 template <
class INPUT_ITERATOR>
1195 void assign(INPUT_ITERATOR first, INPUT_ITERATOR last);
1204#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1210 void assign(std::initializer_list<value_type> values);
1261 void push_front(BloombergLP::bslmf::MovableRef<value_type> value);
1277 void push_back(BloombergLP::bslmf::MovableRef<value_type> value);
1279#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1291 template <
class... Args>
1305 template <
class... Args>
1309#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1323 template <
class... Args>
1359 BloombergLP::bslmf::MovableRef<value_type> value);
1374 const VALUE_TYPE& value);
1393 template <
class INPUT_ITERATOR>
1395 INPUT_ITERATOR first,
1396 INPUT_ITERATOR last);
1398#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
1411 std::initializer_list<value_type> values);
1435 AllocatorTraits::is_always_equal::value);
1471#ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
1483 class = bsl::enable_if_t<
1484 bsl::is_convertible_v<
1487 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1494 class INPUT_ITERATOR,
1496 typename BloombergLP::bslstl::IteratorUtil::IterVal_t<INPUT_ITERATOR>
1505 class INPUT_ITERATOR,
1508 typename BloombergLP::bslstl::IteratorUtil::IterVal_t<INPUT_ITERATOR>,
1509 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>>
1517 class INPUT_ITERATOR,
1520 typename BloombergLP::bslstl::IteratorUtil::IterVal_t<INPUT_ITERATOR>,
1522 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1524deque(INPUT_ITERATOR, INPUT_ITERATOR, ALLOC *)
1535 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1537deque(std::initializer_list<VALUE>, ALLOC *)
1551template <
class VALUE_TYPE,
class ALLOCATOR>
1555#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
1556template <
class VALUE_TYPE,
class ALLOCATOR>
1569#ifdef BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
1574template <
class VALUE_TYPE,
class ALLOCATOR>
1575BloombergLP::bslalg::SynthThreeWayUtil::Result<VALUE_TYPE> operator<=>(
1581template <
class VALUE_TYPE,
class ALLOCATOR>
1596template <
class VALUE_TYPE,
class ALLOCATOR>
1607template <
class VALUE_TYPE,
class ALLOCATOR>
1618template <
class VALUE_TYPE,
class ALLOCATOR>
1635template <
class VALUE_TYPE,
class ALLOCATOR,
class BDE_OTHER_TYPE>
1641template <
class VALUE_TYPE,
class ALLOCATOR,
class PREDICATE>
1645template <
class VALUE_TYPE,
class ALLOCATOR>
1674template <
class VALUE_TYPE,
class ALLOCATOR>
1682 typedef BloombergLP::bslalg::DequeImpUtil<VALUE_TYPE,
1684 typedef typename Imp::Block Block;
1685 typedef typename Imp::BlockPtr BlockPtr;
1686 typedef std::size_t size_type;
1690 BlockPtr *d_boundary_p;
1713 void insertAtFront(size_type n);
1718 void insertAtBack(size_type n);
1728 BlockPtr *reserveBlockSlots(size_type numNewBlocks,
bool atFront);
1746template <
class VALUE_TYPE,
class ALLOCATOR>
1754 typedef BloombergLP::bslalg::DequeImpUtil<VALUE_TYPE,
1757 typedef typename Imp::BlockPtr BlockPtr;
1762 BlockPtr *d_boundary_p;
1807template <
class VALUE_TYPE,
class ALLOCATOR>
1811 typedef BloombergLP::bslalg::ContainerBase<ALLOCATOR> ContainerBase;
1855template <
class VALUE_TYPE,
class ALLOCATOR>
1863 typedef BloombergLP::bslalg::DequeIterator<VALUE_TYPE,
1864 BLOCK_LENGTH> IteratorImp;
1865 typedef BloombergLP::bslalg::DequePrimitives<VALUE_TYPE,
1866 BLOCK_LENGTH> DequePrimitives;
1870 std::size_t d_count;
1897 std::size_t operator++();
1900 std::size_t operator--();
1929template <
class VALUE_TYPE>
1937template <
class VALUE_TYPE>
1945template <
class VALUE_TYPE>
1953template <
class VALUE_TYPE>
1961template <
class VALUE_TYPE>
1968 return *(
begin() + position);
1971template <
class VALUE_TYPE>
1978 BloombergLP::bslstl::StdExceptUtil::throwOutOfRange(
1979 "deque<...>::at(n): invalid position");
1981 return *(
begin() + position);
1984template <
class VALUE_TYPE>
1994template <
class VALUE_TYPE>
2001 IteratorImp backIterator =
d_finish;
2003 return *backIterator;
2007template <
class VALUE_TYPE>
2015template <
class VALUE_TYPE>
2023template <
class VALUE_TYPE>
2031template <
class VALUE_TYPE>
2039template <
class VALUE_TYPE>
2047template <
class VALUE_TYPE>
2055template <
class VALUE_TYPE>
2063template <
class VALUE_TYPE>
2071template <
class VALUE_TYPE>
2079template <
class VALUE_TYPE>
2104 last += BLOCK_LENGTH - 1;
2115 return frontCapacity < backCapacity ? frontCapacity : backCapacity;
2118template <
class VALUE_TYPE>
2125template <
class VALUE_TYPE>
2132 return *(
begin() + position);
2135template <
class VALUE_TYPE>
2142 BloombergLP::bslstl::StdExceptUtil::throwOutOfRange(
2143 "const deque<...>::at(n): invalid position");
2145 return *(
begin() + position);
2148template <
class VALUE_TYPE>
2158template <
class VALUE_TYPE>
2165 IteratorImp backIterator =
d_finish;
2167 return *backIterator;
2175template <
class VALUE_TYPE,
class ALLOCATOR>
2181 this->d_blocks_p = 0;
2185template <
class VALUE_TYPE,
class ALLOCATOR>
2187typename deque<VALUE_TYPE, ALLOCATOR>::Block *
2188deque<VALUE_TYPE, ALLOCATOR>::allocateBlock()
2190 return AllocatorUtil::allocateObject<Block>(this->allocatorRef());
2193template <
class VALUE_TYPE,
class ALLOCATOR>
2195typename deque<VALUE_TYPE, ALLOCATOR>::BlockPtr *
2196deque<VALUE_TYPE, ALLOCATOR>::allocateBlockPtrs(std::size_t n)
2198 return AllocatorUtil::allocateObject<BlockPtr>(this->allocatorRef(), n);
2201template <
class VALUE_TYPE,
class ALLOCATOR>
2203void deque<VALUE_TYPE, ALLOCATOR>::deallocateBlock(Block *p)
2205 AllocatorUtil::deallocateObject(this->allocatorRef(), p);
2208template <
class VALUE_TYPE,
class ALLOCATOR>
2211deque<VALUE_TYPE, ALLOCATOR>::deallocateBlockPtrs(BlockPtr *p, std::size_t n)
2213 AllocatorUtil::deallocateObject(this->allocatorRef(), p, n);
2216template <
class VALUE_TYPE,
class ALLOCATOR>
2217template <
class INPUT_ITERATOR>
2218typename deque<VALUE_TYPE, ALLOCATOR>::size_type
2220 INPUT_ITERATOR first,
2221 INPUT_ITERATOR last,
2222 std::random_access_iterator_tag)
2225 Guard guard(
this,
true);
2227 const size_type numElements = bsl::distance(first, last);
2229 numElements > max_size() - this->
size())) {
2232 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
2233 "deque<...>::insert(pos,n,v): deque too big");
2236 for ( ; first != last; ++first) {
2237 IteratorImp insertPoint = guard.
end();
2245 if (1 == insertPoint.remainingInBlock()) {
2247 insertPoint = guard.
end();
2250 AllocatorTraits::construct(this->allocatorRef(),
2256 this->d_finish += guard.
count();
2262template <
class VALUE_TYPE,
class ALLOCATOR>
2263template <
class INPUT_ITERATOR>
2266 INPUT_ITERATOR last,
2267 std::input_iterator_tag)
2270 Guard guard(
this,
true);
2274 for ( ; first != last; ++first) {
2277 numElements > maxNumElements)) {
2280 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
2281 "deque<...>::insert(pos,n,v): deque too big");
2283 IteratorImp insertPoint = guard.
end();
2291 if (1 == insertPoint.remainingInBlock()) {
2293 insertPoint = guard.
end();
2297 AllocatorTraits::construct(this->allocatorRef(),
2303 this->d_finish += guard.
count();
2309template <
class VALUE_TYPE,
class ALLOCATOR>
2311 size_type numElements)
2316 size_type numNewBlocks = (this->d_finish.offsetInBlock() + numElements) /
2318 BlockCreator newBlocks(
this);
2319 newBlocks.insertAtBack(numNewBlocks);
2320 DequePrimitives::valueInititalizeN(&this->d_finish,
2323 this->allocatorRef());
2326template <
class VALUE_TYPE,
class ALLOCATOR>
2327void deque<VALUE_TYPE, ALLOCATOR>::privateAppendRaw(
2328 size_type numElements,
2329 const VALUE_TYPE& value)
2334 size_type numNewBlocks = (this->d_finish.offsetInBlock() + numElements) /
2336 BlockCreator newBlocks(
this);
2337 newBlocks.insertAtBack(numNewBlocks);
2339 DequePrimitives::uninitializedFillNBack(&this->d_finish,
2343 this->allocatorRef());
2346template <
class VALUE_TYPE,
class ALLOCATOR>
2347void deque<VALUE_TYPE, ALLOCATOR>::privateInit(size_type numElements)
2349 size_type blocksLength = numElements / BLOCK_LENGTH + 1 +
2350 2 * Imp::BLOCK_ARRAY_PADDING;
2354 this->d_blocks_p = this->allocateBlockPtrs(blocksLength);
2356 this->d_blocksLength = blocksLength;
2361 BlockPtr *firstBlockPtr = &this->d_blocks_p[Imp::BLOCK_ARRAY_PADDING];
2362 *firstBlockPtr = this->allocateBlock();
2372 const int offset =
static_cast<int>(
2373 (BLOCK_LENGTH - 1 - numElements % BLOCK_LENGTH) / 2);
2377 this->d_start = this->d_finish = IteratorImp(
2379 (*firstBlockPtr)->d_data + offset);
2382template <
class VALUE_TYPE,
class ALLOCATOR>
2383template <
class INTEGRAL_TYPE>
2387 INTEGRAL_TYPE numElements,
2388 INTEGRAL_TYPE value,
2389 BloombergLP::bslmf::MatchArithmeticType,
2390 BloombergLP::bslmf::Nil)
2394 static_cast<VALUE_TYPE
>(value));
2397template <
class VALUE_TYPE,
class ALLOCATOR>
2398template <
class INPUT_ITERATOR>
2400 const_iterator position,
2401 INPUT_ITERATOR first,
2402 INPUT_ITERATOR last,
2403 BloombergLP::bslmf::MatchAnyType,
2404 BloombergLP::bslmf::MatchAnyType)
2406 typedef typename iterator_traits<INPUT_ITERATOR>::iterator_category Tag;
2408 if (first == last) {
2412 if (position == this->
cbegin()) {
2413 privatePrepend(first, last, Tag());
2417 if (position == this->
cend()) {
2418 privateAppend(first, last, Tag());
2422 privateInsert(position, first, last, Tag());
2425template <
class VALUE_TYPE,
class ALLOCATOR>
2426template <
class INPUT_ITERATOR>
2427void deque<VALUE_TYPE, ALLOCATOR>::privateInsert(
2428 const_iterator position,
2429 INPUT_ITERATOR first,
2430 INPUT_ITERATOR last,
2431 std::input_iterator_tag tag)
2435 iterator pos(position.imp());
2436 const size_type currentSize = this->
size();
2437 const size_type posIdx = pos - this->
begin();
2439 deque temp(k_RAW_INIT, this->get_allocator());
2440 privateSplit(&temp, position.imp());
2442 if (posIdx <= currentSize / 2) {
2444 static_cast<Base *
>(
this),
static_cast<Base *
>(&temp));
2445 privatePrepend(first, last, tag);
2446 privateJoinPrepend(&temp);
2449 privateAppend(first, last, tag);
2450 privateJoinAppend(&temp);
2454template <
class VALUE_TYPE,
class ALLOCATOR>
2455void deque<VALUE_TYPE, ALLOCATOR>::privateSplit(
2456 deque<VALUE_TYPE, ALLOCATOR> *other,
2491 if (pos.blockPtr() == this->d_finish.blockPtr()) {
2495 difference_type numAfter = this->d_finish.valuePtr() - pos.valuePtr();
2496 other->privateInit(numAfter);
2497 BloombergLP::bslalg::ArrayPrimitives::destructiveMove(
2498 other->d_start.valuePtr(),
2500 this->d_finish.valuePtr(),
2501 this->allocatorRef());
2502 other->d_finish += numAfter;
2503 this->d_finish = pos;
2507 if (pos.blockPtr() == this->d_start.blockPtr()) {
2511 difference_type numBefore = pos.valuePtr() - this->d_start.valuePtr();
2512 other->privateInit(numBefore);
2513 BloombergLP::bslalg::ArrayPrimitives::destructiveMove(
2514 other->d_start.valuePtr(),
2515 this->d_start.valuePtr(),
2517 this->allocatorRef());
2518 other->d_finish += numBefore;
2519 this->d_start = pos;
2521 static_cast<Base *
>(
this),
static_cast<Base *
>(other));
2527 difference_type numMoveBlocks = this->d_finish.blockPtr() - pos.blockPtr();
2529 size_type otherBlocksLength = numMoveBlocks + 1 +
2530 2 * Imp::BLOCK_ARRAY_PADDING;
2532 other->d_blocks_p = this->allocateBlockPtrs(otherBlocksLength);
2533 other->d_blocksLength = otherBlocksLength;
2537 Block *newBlock = this->allocateBlock();
2542 std::memcpy(other->d_blocks_p + 1 + Imp::BLOCK_ARRAY_PADDING,
2544 sizeof(BlockPtr) * numMoveBlocks);
2546 other->d_start = IteratorImp(&other->d_blocks_p[
2547 1 + Imp::BLOCK_ARRAY_PADDING]);
2548 other->d_finish = IteratorImp(other->d_start.blockPtr() +
2550 this->d_finish.valuePtr());
2552 BlockPtr *newBlockPtr = pos.blockPtr() + 1;
2553 *newBlockPtr = newBlock;
2554 this->d_finish = IteratorImp(newBlockPtr);
2580 size_type splitOffset = pos.offsetInBlock();
2581 if (splitOffset >= pos.remainingInBlock()) {
2584 value_type *splitValuePtr = newBlock->d_data + splitOffset;
2585 BloombergLP::bslalg::ArrayPrimitives::destructiveMove(
2589 this->allocatorRef());
2595 BloombergLP::bslalg::ArrayPrimitives::destructiveMove(
2599 this->allocatorRef());
2600 *newBlockPtr = *pos.blockPtr();
2601 *pos.blockPtr() = newBlock;
2606 this->d_finish = IteratorImp(&newBlockPtr[-1],
2607 newBlockPtr[-1]->d_data + splitOffset);
2608 other->d_start.previousBlock();
2609 *(other->d_start.blockPtr()) = *newBlockPtr;
2610 other->d_start = IteratorImp(other->d_start.blockPtr(),
2611 other->d_start.blockBegin() + splitOffset);
2614template <
class VALUE_TYPE,
class ALLOCATOR>
2616void deque<VALUE_TYPE, ALLOCATOR>::privateJoinPrepend(
2617 deque<VALUE_TYPE, ALLOCATOR> *other)
2619 privatePrepend(other->begin(),
2621 std::random_access_iterator_tag());
2625 deque<VALUE_TYPE, ALLOCATOR> temp(k_RAW_INIT, other->allocatorRef());
2629template <
class VALUE_TYPE,
class ALLOCATOR>
2631void deque<VALUE_TYPE, ALLOCATOR>::privateJoinAppend(
2632 deque<VALUE_TYPE, ALLOCATOR> *other)
2634 privateAppend(other->begin(),
2636 std::random_access_iterator_tag());
2640 deque<VALUE_TYPE, ALLOCATOR> temp(k_RAW_INIT, other->allocatorRef());
2644template <
class VALUE_TYPE,
class ALLOCATOR>
2645template <
class INPUT_ITERATOR>
2646void deque<VALUE_TYPE, ALLOCATOR>::privateInsert(
2647 const_iterator position,
2648 INPUT_ITERATOR first,
2649 INPUT_ITERATOR last,
2650 std::random_access_iterator_tag tag)
2654 if (position == this->
cbegin()) {
2655 privatePrepend(first, last, tag);
2659 if (position == this->
cend()) {
2660 privateAppend(first, last, tag);
2664 const size_type currentSize = this->
size();
2665 const size_type numElements = bsl::distance(first, last);
2667 numElements > max_size() - currentSize)) {
2670 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
2671 "deque<...>::insert(pos,n,v): deque too big");
2674 iterator pos(position.imp());
2675 const size_type posIdx = position - this->
cbegin();
2676 if (posIdx <= currentSize / 2) {
2680 size_type numNewBlocks = (this->d_start.remainingInBlock()
2681 + numElements - 1) / BLOCK_LENGTH;
2682 BlockCreator newBlocks(
this);
2683 newBlocks.insertAtFront(numNewBlocks);
2685 DequePrimitives::insertAndMoveToFront(&this->d_start,
2687 this->d_start + posIdx,
2691 this->allocatorRef());
2696 size_type numNewBlocks = (this->d_finish.offsetInBlock() + numElements)
2698 BlockCreator newBlocks(
this);
2699 newBlocks.insertAtBack(numNewBlocks);
2701 DequePrimitives::insertAndMoveToBack(&this->d_finish,
2703 this->d_start + posIdx,
2707 this->allocatorRef());
2711template <
class VALUE_TYPE,
class ALLOCATOR>
2712void deque<VALUE_TYPE, ALLOCATOR>::privatePrependRaw(
2713 size_type numElements,
2714 const VALUE_TYPE& value)
2719 size_type numNewBlocks = (this->d_start.remainingInBlock() +
2720 numElements - 1) / BLOCK_LENGTH;
2721 BlockCreator newBlocks(
this);
2722 newBlocks.insertAtFront(numNewBlocks);
2724 DequePrimitives::uninitializedFillNFront(&this->d_start,
2728 this->allocatorRef());
2731template <
class VALUE_TYPE,
class ALLOCATOR>
2732template <
class INPUT_ITERATOR>
2733typename deque<VALUE_TYPE, ALLOCATOR>::size_type
2735 INPUT_ITERATOR last,
2736 std::input_iterator_tag tag)
2738 deque temp(k_RAW_INIT, this->get_allocator());
2739 temp.privateInit(this->
size() + 1);
2740 size_type numElements = temp.privateAppend(first, last, tag);
2744 if (numElements > this->
size()) {
2746 privateJoinAppend(&temp);
2749 privateJoinPrepend(&temp);
2755template <
class VALUE_TYPE,
class ALLOCATOR>
2756template <
class INPUT_ITERATOR>
2759 INPUT_ITERATOR first,
2760 INPUT_ITERATOR last,
2761 std::bidirectional_iterator_tag)
2765 Guard guard(
this,
false);
2772 numElements > maxNumElements)) {
2775 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
2776 "deque<...>::insert(pos,n,v): deque too big");
2779 IteratorImp insertPoint = guard.
begin();
2784 if (insertPoint.valuePtr() == insertPoint.blockBegin()) {
2786 insertPoint = guard.
begin();
2790 AllocatorTraits::construct(this->allocatorRef(),
2794 }
while (first != last);
2796 this->d_start -= guard.
count();
2801template <
class VALUE_TYPE,
class ALLOCATOR>
2802template <
class INPUT_ITERATOR>
2805 INPUT_ITERATOR first,
2806 INPUT_ITERATOR last,
2807 std::random_access_iterator_tag)
2810 const size_type numElements = bsl::distance(first, last);
2812 numElements > max_size() - this->
size())) {
2815 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
2816 "deque<...>::insert(pos,n,v): deque too big");
2820 Guard guard(
this,
false);
2823 IteratorImp insertPoint = guard.
begin();
2828 if (insertPoint.valuePtr() == insertPoint.blockBegin()) {
2830 insertPoint = guard.
begin();
2834 AllocatorTraits::construct(this->allocatorRef(),
2838 }
while (first != last);
2840 this->d_start -= guard.
count();
2846template <
class VALUE_TYPE,
class ALLOCATOR>
2849, ContainerBase(ALLOCATOR())
2852 temp.privateInit(0);
2856template <
class VALUE_TYPE,
class ALLOCATOR>
2859, ContainerBase(basicAllocator)
2862 temp.privateInit(0);
2866template <
class VALUE_TYPE,
class ALLOCATOR>
2868 const ALLOCATOR& basicAllocator)
2870, ContainerBase(basicAllocator)
2875 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
2876 "deque<...>::deque(n): deque too big");
2879 temp.privateInit(numElements);
2880 temp.privateAppendDefaultInsertable(numElements);
2884template <
class VALUE_TYPE,
class ALLOCATOR>
2886 const VALUE_TYPE& value,
2887 const ALLOCATOR& basicAllocator)
2889, ContainerBase(basicAllocator)
2894 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
2895 "deque<...>::deque(n,v): deque too big");
2898 temp.privateInit(numElements);
2899 temp.privateAppendRaw(numElements, value);
2903template <
class VALUE_TYPE,
class ALLOCATOR>
2904template <
class INPUT_ITERATOR>
2906 INPUT_ITERATOR last,
2907 const ALLOCATOR& basicAllocator)
2909, ContainerBase(basicAllocator)
2912 temp.privateInit(0);
2917template <
class VALUE_TYPE,
class ALLOCATOR>
2920, ContainerBase(
AllocatorTraits::select_on_container_copy_construction(
2921 original.get_allocator()))
2924 temp.privateInit(original.
size());
2925 temp.privateAppend(original.
begin(),
2927 std::random_access_iterator_tag());
2931template <
class VALUE_TYPE,
class ALLOCATOR>
2933 const deque& original,
2936, ContainerBase(basicAllocator)
2939 temp.privateInit(original.
size());
2940 temp.privateAppend(original.
begin(),
2942 std::random_access_iterator_tag());
2946template <
class VALUE_TYPE,
class ALLOCATOR>
2948 BloombergLP::bslmf::MovableRef<deque> original)
2950, ContainerBase(MoveUtil::access(original).get_allocator())
2953 temp.privateInit(0);
2956 deque& lvalue = original;
2960template <
class VALUE_TYPE,
class ALLOCATOR>
2962 BloombergLP::bslmf::MovableRef<deque> original,
2965, ContainerBase(basicAllocator)
2968 temp.privateInit(0);
2970 deque& lvalue = original;
2975 static_cast<Base *
>(&temp));
2977 static_cast<Base *
>(&lvalue));
2983 temp.
push_back(MoveUtil::move(lvalue[pos]));
2986 static_cast<Base *
>(&temp));
2990#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
2991template <
class VALUE_TYPE,
class ALLOCATOR>
2994 std::initializer_list<value_type> values,
2995 const ALLOCATOR& basicAllocator)
3001template <
class VALUE_TYPE,
class ALLOCATOR>
3004 if (0 == this->d_blocks_p) {
3010 if (0 != this->d_start.blockPtr()) {
3015 this->deallocateBlock(*this->d_start.blockPtr());
3019 this->deallocateBlockPtrs(this->d_blocks_p, this->d_blocksLength);
3023template <
class VALUE_TYPE,
class ALLOCATOR>
3031 if (Propagate::value && get_allocator() != rhs.
get_allocator()) {
3035 static_cast<Base *
>(&other));
3036 AllocatorUtil::swap(&this->allocatorRef(), &other.allocatorRef(),
3041 size_type rhsSize = rhs.
size();
3044 if (origSize > rhsSize) {
3054 privateAppend(rhs.
begin() + minSize,
3056 std::random_access_iterator_tag());
3061 IteratorImp from = rhs.
d_start;
3062 IteratorImp to = this->d_start;
3063 for (
size_type i = 0; i < minSize; ++i) {
3074template <
class VALUE_TYPE,
class ALLOCATOR>
3077 BloombergLP::bslmf::MovableRef<deque> rhs)
3079 AllocatorTraits::is_always_equal::value)
3081 deque& lvalue = rhs;
3084 AllocatorTraits::propagate_on_container_move_assignment Propagate;
3088 static_cast<Base *
>(&lvalue));
3090 else if (Propagate::value) {
3091 deque other(MoveUtil::move(lvalue));
3093 static_cast<Base *
>(&other));
3094 AllocatorUtil::swap(&this->allocatorRef(), &other.allocatorRef(),
3098 deque other(MoveUtil::move(lvalue), get_allocator());
3100 static_cast<Base *
>(&other));
3106#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
3107template <
class VALUE_TYPE,
class ALLOCATOR>
3109deque<VALUE_TYPE, ALLOCATOR>&
3111 std::initializer_list<value_type> values)
3113 assign(values.begin(), values.end());
3118template <
class VALUE_TYPE,
class ALLOCATOR>
3119template <
class INPUT_ITERATOR>
3121 INPUT_ITERATOR last)
3123 typedef typename iterator_traits<INPUT_ITERATOR>::iterator_category Tag;
3137 for (i = this->d_start; !(i == this->d_finish) && first != last;
3142 if (!(i == this->d_finish)) {
3150 privateAppend(first, last, Tag());
3156template <
class VALUE_TYPE,
class ALLOCATOR>
3158 const VALUE_TYPE& value)
3163 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3164 "deque<...>::assign(n,v): deque too big");
3179 if (numElements < origSize) {
3180 minSize = numElements;
3185 privateAppendRaw(numElements - origSize, value);
3188 IteratorImp to = this->d_start;
3189 for (
size_type i = 0; i < minSize; ++i) {
3197#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
3198template <
class VALUE_TYPE,
class ALLOCATOR>
3201 std::initializer_list<value_type> values)
3203 assign(values.begin(), values.end());
3207template <
class VALUE_TYPE,
class ALLOCATOR>
3214 max_size() - (BLOCK_LENGTH - 1))) {
3217 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3218 "deque<...>::reserve(n): deque too big");
3228 if (this->d_start.blockPtr() > this->d_blocks_p) {
3229 this->d_blocks_p[0] = 0;
3231 if (this->d_finish.blockPtr() < this->d_blocks_p + this->d_blocksLength-1){
3232 this->d_blocks_p[this->d_blocksLength - 1] = 0;
3235 const IteratorImp first(this->d_blocks_p);
3236 IteratorImp last( this->d_blocks_p + this->d_blocksLength - 1);
3237 last += BLOCK_LENGTH - 1;
3239 const size_type frontRoom = this->d_start - first;
3240 const size_type backRoom = last - this->d_finish;
3242 size_type numFrontBlocks = numElements > frontRoom
3243 ? (numElements - frontRoom + BLOCK_LENGTH - 1) /
3246 size_type numBackBlocks = numElements > backRoom
3247 ? (numElements - backRoom + BLOCK_LENGTH - 1) /
3251 if (0 == numFrontBlocks && 0 == numBackBlocks) {
3259 (max_size() - existingSpace) / BLOCK_LENGTH
3260 || (existingSpace += numFrontBlocks * BLOCK_LENGTH,
3262 (max_size() - existingSpace) / BLOCK_LENGTH))) {
3265 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3266 "deque<...>::reserve(n): deque too big");
3277template <
class VALUE_TYPE,
class ALLOCATOR>
3283 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3284 "deque<...>::resize(n): deque too big");
3289 if (newSize <= origSize) {
3294 IteratorImp oldEnd = this->d_finish;
3295 IteratorImp newEnd = this->d_start + newSize;
3296 DequePrimitives::destruct(newEnd, oldEnd, this->allocatorRef());
3298 for (; oldEnd.blockPtr() != newEnd.blockPtr();
3299 oldEnd.previousBlock()) {
3300 this->deallocateBlock(*oldEnd.blockPtr());
3302 this->d_finish = newEnd;
3305 privateAppendDefaultInsertable(newSize - origSize);
3309template <
class VALUE_TYPE,
class ALLOCATOR>
3311 const VALUE_TYPE& value)
3316 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3317 "deque<...>::resize(n,v): deque too big");
3322 if (newSize <= origSize) {
3326 privateAppendRaw(newSize - origSize, value);
3330template <
class VALUE_TYPE,
class ALLOCATOR>
3338 this->d_finish.blockPtr() - this->d_start.blockPtr() + 1;
3340 if (newBlocksLength == this->d_blocksLength) {
3344 const size_type offsetStart = this->d_start.offsetInBlock();
3345 const size_type offsetFinish = this->d_finish.offsetInBlock();
3347 BlockPtr *newBlocks = this->allocateBlockPtrs(newBlocksLength);
3349 std::memmove(newBlocks,
3350 this->d_start.blockPtr(),
3351 newBlocksLength *
sizeof(BlockPtr));
3353 this->deallocateBlockPtrs(this->d_blocks_p, this->d_blocksLength);
3355 this->d_blocks_p = newBlocks;
3356 this->d_blocksLength = newBlocksLength;
3358 this->d_start.setBlock(newBlocks);
3359 this->d_start += offsetStart;
3361 this->d_finish.setBlock(newBlocks + newBlocksLength - 1);
3362 this->d_finish += offsetFinish;
3365template <
class VALUE_TYPE,
class ALLOCATOR>
3371 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3372 "deque<...>::push_front(v): deque too big");
3376 0 == this->d_start.offsetInBlock())) {
3382 AllocatorTraits::construct(
3383 this->allocatorRef(), (this->d_start - 1).valuePtr(), value);
3391 AllocatorTraits::construct(
3392 this->allocatorRef(), this->d_start.valuePtr() - 1, value);
3393 this->d_start.valuePtrDecrement();
3397template <
class VALUE_TYPE,
class ALLOCATOR>
3399 BloombergLP::bslmf::MovableRef<value_type> value)
3404 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3405 "deque<...>::push_front(v): deque too big");
3408 VALUE_TYPE& lvalue = value;
3411 0 == this->d_start.offsetInBlock())) {
3417 AllocatorTraits::construct(this->allocatorRef(),
3418 (this->d_start - 1).valuePtr(),
3419 MoveUtil::move(lvalue));
3426 AllocatorTraits::construct(this->allocatorRef(),
3427 this->d_start.valuePtr() - 1,
3428 MoveUtil::move(lvalue));
3429 this->d_start.valuePtrDecrement();
3433template <
class VALUE_TYPE,
class ALLOCATOR>
3439 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3440 "deque<...>::push_back(v): deque too big");
3444 1 < this->d_finish.remainingInBlock())) {
3445 AllocatorTraits::construct(
3446 this->allocatorRef(), this->d_finish.valuePtr(), value);
3447 this->d_finish.valuePtrIncrement();
3455 AllocatorTraits::construct(
3456 this->allocatorRef(), this->d_finish.valuePtr(), value);
3457 this->d_finish.nextBlock();
3461template <
class VALUE_TYPE,
class ALLOCATOR>
3463 BloombergLP::bslmf::MovableRef<value_type> value)
3468 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3469 "deque<...>::push_back(v): deque too big");
3472 VALUE_TYPE& lvalue = value;
3475 1 < this->d_finish.remainingInBlock())) {
3476 AllocatorTraits::construct(this->allocatorRef(),
3477 this->d_finish.valuePtr(),
3478 MoveUtil::move(lvalue));
3479 this->d_finish.valuePtrIncrement();
3487 AllocatorTraits::construct(this->allocatorRef(),
3488 this->d_finish.valuePtr(),
3489 MoveUtil::move(lvalue));
3490 this->d_finish.nextBlock();
3494#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
3495template <
class VALUE_TYPE,
class ALLOCATOR>
3496template <
class... Args>
3503 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3504 "deque<...>::emplace_front(args): deque too big");
3508 0 == this->d_start.offsetInBlock())) {
3514 AllocatorTraits::construct(
3515 this->allocatorRef(),
3516 (this->d_start - 1).valuePtr(),
3524 AllocatorTraits::construct(
3525 this->allocatorRef(),
3526 this->d_start.valuePtr() - 1,
3528 this->d_start.valuePtrDecrement();
3530 return *(this->d_start);
3533template <
class VALUE_TYPE,
class ALLOCATOR>
3534template <
class... Args>
3541 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3542 "deque<...>::emplace_back(args): deque too big");
3546 1 < this->d_finish.remainingInBlock())) {
3547 AllocatorTraits::construct(
3548 this->allocatorRef(),
3549 this->d_finish.valuePtr(),
3551 this->d_finish.valuePtrIncrement();
3559 AllocatorTraits::construct(
3560 this->allocatorRef(),
3561 this->d_finish.valuePtr(),
3563 this->d_finish.nextBlock();
3565 return *(this->d_finish - 1);
3569#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
3570template <
class VALUE_TYPE,
class ALLOCATOR>
3571template <
class... Args>
3574 Args&&... arguments)
3579 if (position == this->
cbegin()) {
3581 return this->
begin();
3584 if (position == this->
cend()) {
3586 return iterator(this->d_finish - 1);
3596 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3597 "deque<...>::emplace(args): deque too big");
3602 if (posIdx <= currentSize / 2) {
3604 if (this->d_start.remainingInBlock() == BLOCK_LENGTH) {
3609 DequePrimitives::emplaceAndMoveToFront(
3612 this->d_start + posIdx,
3613 this->allocatorRef(),
3619 if (this->d_finish.offsetInBlock() == BLOCK_LENGTH - 1) {
3624 DequePrimitives::emplaceAndMoveToBack(
3627 this->d_start + posIdx,
3628 this->allocatorRef(),
3632 return this->
begin() + posIdx;
3636template <
class VALUE_TYPE,
class ALLOCATOR>
3641 BloombergLP::bslma::DestructionUtil::destroy(this->d_start.valuePtr());
3643 if (1 == this->d_start.remainingInBlock()) {
3644 this->deallocateBlock(*this->d_start.blockPtr());
3645 this->d_start.nextBlock();
3649 this->d_start.valuePtrIncrement();
3652template <
class VALUE_TYPE,
class ALLOCATOR>
3657 if (0 == this->d_finish.offsetInBlock()) {
3659 BloombergLP::bslma::DestructionUtil::destroy(
3660 this->d_finish.valuePtr());
3661 this->deallocateBlock(this->d_finish.blockPtr()[1]);
3665 this->d_finish.valuePtrDecrement();
3666 BloombergLP::bslma::DestructionUtil::destroy(this->d_finish.valuePtr());
3669template <
class VALUE_TYPE,
class ALLOCATOR>
3672 const VALUE_TYPE& value)
3677 if (position == this->
cbegin()) {
3679 return this->
begin();
3682 if (position == this->
cend()) {
3684 return iterator(this->d_finish - 1);
3694 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3695 "deque<...>::insert(pos,n,v): deque too big");
3700 if (posIdx <= currentSize / 2) {
3702 if (this->d_start.remainingInBlock() == BLOCK_LENGTH) {
3705 DequePrimitives::insertAndMoveToFront(&this->d_start,
3707 this->d_start + posIdx,
3710 this->allocatorRef());
3714 if (this->d_finish.offsetInBlock() == BLOCK_LENGTH - 1) {
3717 DequePrimitives::insertAndMoveToBack(&this->d_finish,
3719 this->d_start + posIdx,
3722 this->allocatorRef());
3724 return this->
begin() + posIdx;
3727template <
class VALUE_TYPE,
class ALLOCATOR>
3731 BloombergLP::bslmf::MovableRef<VALUE_TYPE> value)
3736 VALUE_TYPE& lvalue = value;
3738 if (position == this->
cbegin()) {
3739 push_front(MoveUtil::move(lvalue));
3740 return this->
begin();
3743 if (position == this->
cend()) {
3744 push_back(MoveUtil::move(lvalue));
3745 return iterator(this->d_finish - 1);
3755 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3756 "deque<...>::insert(pos,n,v): deque too big");
3761 if (posIdx <= currentSize / 2) {
3763 if (this->d_start.remainingInBlock() == BLOCK_LENGTH) {
3766 DequePrimitives::moveInsertAndMoveToFront(&this->d_start,
3768 this->d_start + posIdx,
3769 MoveUtil::move(lvalue),
3770 this->allocatorRef());
3774 if (this->d_finish.offsetInBlock() == BLOCK_LENGTH - 1) {
3777 DequePrimitives::moveInsertAndMoveToBack(&this->d_finish,
3779 this->d_start + posIdx,
3780 MoveUtil::move(lvalue),
3781 this->allocatorRef());
3783 return this->
begin() + posIdx;
3786template <
class VALUE_TYPE,
class ALLOCATOR>
3790 const VALUE_TYPE& value)
3797 if (0 == numElements) {
3798 return this->
begin() + posIdx;
3803 numElements > max_size() - currentSize)) {
3806 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3807 "deque<...>::insert(pos,n,v): deque too big");
3810 if (position == this->
cbegin()) {
3811 privatePrependRaw(numElements, value);
3813 return this->
begin();
3816 if (position == this->
cend()) {
3817 privateAppendRaw(numElements, value);
3819 return this->
begin() + posIdx;
3822 if (posIdx <= currentSize / 2) {
3826 size_type numNewBlocks = (this->d_start.remainingInBlock()
3827 + numElements - 1) / BLOCK_LENGTH;
3831 DequePrimitives::insertAndMoveToFront(&this->d_start,
3833 this->d_start + posIdx,
3836 this->allocatorRef());
3842 size_type numNewBlocks = (this->d_finish.offsetInBlock() + numElements)
3847 DequePrimitives::insertAndMoveToBack(&this->d_finish,
3849 this->d_start + posIdx,
3852 this->allocatorRef());
3855 return this->
begin() + posIdx;
3858template <
class VALUE_TYPE,
class ALLOCATOR>
3859template <
class INPUT_ITERATOR>
3863 INPUT_ITERATOR first,
3864 INPUT_ITERATOR last)
3871 privateInsertDispatch(position,
3875 BloombergLP::bslmf::Nil());
3877 return this->
begin() + posIdx;
3880#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
3881template <
class VALUE_TYPE,
class ALLOCATOR>
3885 const_iterator position,
3886 std::initializer_list<value_type> values)
3891 return insert(position, values.begin(), values.end());
3895template <
class VALUE_TYPE,
class ALLOCATOR>
3896typename deque<VALUE_TYPE, ALLOCATOR>::iterator
3904 return this->
begin();
3912 return erase(position, position + 1);
3915template <
class VALUE_TYPE,
class ALLOCATOR>
3925 iterator last_imp = this->
begin() + (last - this->
cbegin());
3926 iterator oldStart = this->
begin();
3927 iterator oldFinish = this->
end();
3928 iterator result =
iterator(DequePrimitives::erase(&this->d_start,
3934 this->allocatorRef()));
3938 for ( ; oldStart.imp().blockPtr() != this->d_start.blockPtr();
3939 oldStart.imp().nextBlock()) {
3940 this->deallocateBlock(oldStart.imp().blockPtr()[0]);
3942 for ( ; oldFinish.imp().blockPtr() != this->d_finish.blockPtr();
3943 oldFinish.imp().previousBlock()) {
3944 this->deallocateBlock(oldFinish.imp().blockPtr()[0]);
3949template <
class VALUE_TYPE,
class ALLOCATOR>
3952 AllocatorTraits::is_always_equal::value)
3955 AllocatorTraits::propagate_on_container_swap Propagate;
3956 if (Propagate::value) {
3958 static_cast<Base *
>(&other));
3959 AllocatorUtil::swap(&this->allocatorRef(), &other.allocatorRef(),
3964 this->get_allocator() == other.get_allocator())) {
3966 static_cast<Base *
>(&other));
3971 deque toOtherCopy(MoveUtil::move(*
this), other.get_allocator());
3972 deque toThisCopy( MoveUtil::move(other), this->get_allocator());
3975 static_cast<Base *
>(
this));
3977 static_cast<Base *
>(&other));
3982template <
class VALUE_TYPE,
class ALLOCATOR>
3985 DequePrimitives::destruct(this->d_start,
3987 this->allocatorRef());
3991 BlockPtr *startBlock = this->d_start.blockPtr();
3992 BlockPtr *finishBlock = this->d_finish.blockPtr();
3993 for ( ; startBlock != finishBlock; ++startBlock) {
3994 this->deallocateBlock(*startBlock);
3999 size_type blockOffset = this->d_blocksLength / 2;
4000 int offset = BLOCK_LENGTH / 2;
4001 BlockPtr *blockPtr = this->d_blocks_p + blockOffset;
4003 *blockPtr = *finishBlock;
4005 this->d_start = this->d_finish = IteratorImp(blockPtr,
4006 (*blockPtr)->d_data + offset);
4010template <
class VALUE_TYPE,
class ALLOCATOR>
4012typename deque<VALUE_TYPE, ALLOCATOR>::allocator_type
4015 return this->allocatorRef();
4018template <
class VALUE_TYPE,
class ALLOCATOR>
4023 return AllocatorTraits::max_size(this->get_allocator());
4027template <
class VALUE_TYPE,
class ALLOCATOR>
4039 typedef BloombergLP::bslalg::DequeIterator<VALUE_TYPE,
4040 BLOCK_LENGTH> Iterator;
4042 Iterator lhsBegin = lhs.
begin().imp();
4043 Iterator lhsEnd = lhs.
end().imp();
4044 Iterator rhsBegin = rhs.
begin().imp();
4046 for (; !(lhsBegin == lhsEnd); ++lhsBegin, ++rhsBegin) {
4047 if (!(*lhsBegin == *rhsBegin)) {
4054#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
4056template <
class VALUE_TYPE,
class ALLOCATOR>
4061 return !(lhs == rhs);
4066#ifdef BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
4068template <
class VALUE_TYPE,
class ALLOCATOR>
4070BloombergLP::bslalg::SynthThreeWayUtil::Result<VALUE_TYPE> operator<=>(
4071 const deque<VALUE_TYPE, ALLOCATOR>& lhs,
4072 const deque<VALUE_TYPE, ALLOCATOR>& rhs)
4074 return bsl::lexicographical_compare_three_way(
4079 BloombergLP::bslalg::SynthThreeWayUtil::compare);
4084template <
class VALUE_TYPE,
class ALLOCATOR>
4089 return 0 > BloombergLP::bslalg::RangeCompare::lexicographical(lhs.
begin(),
4097template <
class VALUE_TYPE,
class ALLOCATOR>
4105template <
class VALUE_TYPE,
class ALLOCATOR>
4110 return !(rhs < lhs);
4113template <
class VALUE_TYPE,
class ALLOCATOR>
4118 return !(lhs < rhs);
4124template <
class VALUE_TYPE,
class ALLOCATOR,
class BDE_OTHER_TYPE>
4125inline typename deque<VALUE_TYPE, ALLOCATOR>::size_type
4130 return oldSize - deq.
size();
4133template <
class VALUE_TYPE,
class ALLOCATOR,
class PREDICATE>
4134inline typename deque<VALUE_TYPE, ALLOCATOR>::size_type
4139 return oldSize - deq.
size();
4142template <
class VALUE_TYPE,
class ALLOCATOR>
4156template <
class VALUE_TYPE,
class ALLOCATOR>
4165template <
class VALUE_TYPE,
class ALLOCATOR>
4168 if (0 != d_boundary_p) {
4169 BlockPtr *delFirst, *delLast;
4170 if (d_boundary_p <= d_deque_p->d_start.blockPtr()) {
4171 delFirst = d_boundary_p;
4172 delLast = d_deque_p->d_start.blockPtr();
4175 delFirst = d_deque_p->d_finish.blockPtr() + 1;
4176 delLast = d_boundary_p;
4179 for (; delFirst != delLast; ++delFirst) {
4181 d_deque_p->deallocateBlock(*delFirst);
4187template <
class VALUE_TYPE,
class ALLOCATOR>
4190 d_boundary_p = reserveBlockSlots(n,
true);
4191 for ( ; n > 0; --n) {
4192 d_boundary_p[-1] = d_deque_p->allocateBlock();
4198template <
class VALUE_TYPE,
class ALLOCATOR>
4201 d_boundary_p = reserveBlockSlots(n,
false);
4202 for ( ; n > 0; --n) {
4203 *d_boundary_p = d_deque_p->allocateBlock();
4208template <
class VALUE_TYPE,
class ALLOCATOR>
4209typename Deque_BlockCreator<VALUE_TYPE, ALLOCATOR>::BlockPtr *
4211 size_type numNewBlocks,
4214 BlockPtr *blocks = d_deque_p->d_blocks_p;
4215 size_type blocksLength = d_deque_p->d_blocksLength;
4217 BlockPtr *firstSlot = d_deque_p->d_start.blockPtr();
4218 BlockPtr *lastSlot = d_deque_p->d_finish.blockPtr() + 1;
4222 firstSlot = d_boundary_p;
4224 if (size_type(firstSlot - blocks) >= numNewBlocks) {
4232 lastSlot = d_boundary_p;
4234 if (size_type(blocks + blocksLength - lastSlot) >= numNewBlocks) {
4241 BlockPtr *newBlocks = blocks;
4242 size_type newBlocksLength = blocksLength;
4243 size_type numUsedBlocks = lastSlot - firstSlot;
4244 size_type blockOffsetStart = d_deque_p->d_start.blockPtr() - firstSlot;
4245 size_type numCommittedBlocks = (d_deque_p->d_finish.blockPtr() -
4246 d_deque_p->d_start.blockPtr() + 1);
4247 size_type newNumUsedBlocks = numUsedBlocks + numNewBlocks;
4249 if (newNumUsedBlocks > blocksLength) {
4250 const size_type newThreshold = newNumUsedBlocks +
4251 2 * Imp::BLOCK_ARRAY_PADDING;
4252 while (newThreshold > newBlocksLength) {
4258 newBlocksLength *= 2;
4260 newBlocks = d_deque_p->allocateBlockPtrs(newBlocksLength);
4265 BlockPtr *newFirstSlot = newBlocks +
4266 (newBlocksLength - newNumUsedBlocks) / 2;
4269 newFirstSlot += numNewBlocks;
4275 const size_type offsetStart = d_deque_p->d_start.offsetInBlock();
4276 const size_type offsetFinish = d_deque_p->d_finish.offsetInBlock();
4280 std::memmove(newFirstSlot, firstSlot, numUsedBlocks *
sizeof(BlockPtr));
4282 if (newBlocks != blocks) {
4286 d_deque_p->deallocateBlockPtrs(blocks, d_deque_p->d_blocksLength);
4288 d_deque_p->d_blocks_p = newBlocks;
4289 d_deque_p->d_blocksLength = newBlocksLength;
4294 d_deque_p->d_start.setBlock(newFirstSlot + blockOffsetStart);
4295 d_deque_p->d_start += offsetStart;
4296 d_deque_p->d_finish.setBlock(newFirstSlot + blockOffsetStart +
4297 numCommittedBlocks - 1);
4298 d_deque_p->d_finish += offsetFinish;
4300 BlockPtr *ret = newFirstSlot;
4302 ret += numUsedBlocks;
4308template <
class VALUE_TYPE,
class ALLOCATOR>
4320template <
class VALUE_TYPE,
class ALLOCATOR>
4325, d_boundary_p(atFront
4326 ? d_deque_p->d_start.blockPtr()
4327 : d_deque_p->d_finish.blockPtr())
4332template <
class VALUE_TYPE,
class ALLOCATOR>
4335 if (0 != d_deque_p) {
4336 BlockPtr *delFirst, *delLast;
4338 if (d_atFront && d_boundary_p < d_deque_p->d_start.blockPtr()) {
4342 delFirst = d_boundary_p;
4343 delLast = d_deque_p->d_start.blockPtr();
4345 else if (!d_atFront && d_boundary_p > d_deque_p->d_finish.blockPtr()) {
4349 delFirst = d_deque_p->d_finish.blockPtr() + 1;
4350 delLast = d_boundary_p + 1;
4356 for (; delFirst != delLast; ++delFirst) {
4359 d_deque_p->deallocateBlock(*delFirst);
4365template <
class VALUE_TYPE,
class ALLOCATOR>
4377template <
class VALUE_TYPE,
class ALLOCATOR>
4385template <
class VALUE_TYPE,
class ALLOCATOR>
4395template <
class VALUE_TYPE,
class ALLOCATOR>
4407template <
class VALUE_TYPE,
class ALLOCATOR>
4418template <
class VALUE_TYPE,
class ALLOCATOR>
4428 begin = d_deque_p->d_finish;
4432 end = d_deque_p->d_start;
4436 DequePrimitives::destruct(
begin,
end, d_deque_p->get_allocator());
4440template <
class VALUE_TYPE,
class ALLOCATOR>
4447template <
class VALUE_TYPE,
class ALLOCATOR>
4454template <
class VALUE_TYPE,
class ALLOCATOR>
4462template <
class VALUE_TYPE,
class ALLOCATOR>
4470template <
class VALUE_TYPE,
class ALLOCATOR>
4472typename Deque_Guard<VALUE_TYPE, ALLOCATOR>::IteratorImp
4475 return d_deque_p->d_start - d_count;
4478template <
class VALUE_TYPE,
class ALLOCATOR>
4480typename Deque_Guard<VALUE_TYPE, ALLOCATOR>::IteratorImp
4483 return d_deque_p->d_finish + d_count;
4503template <
class VALUE_TYPE,
class ALLOCATOR>
4512template <
class VALUE_TYPE,
class ALLOCATOR>
4522template <
class VALUE_TYPE,
class ALLOCATOR>
Definition bslstl_deque.h:579
IteratorImp d_finish
Definition bslstl_deque.h:625
const_reverse_iterator crend() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_deque.h:2066
iterator end() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_deque.h:1940
reference back()
Definition bslstl_deque.h:1997
reverse_iterator rbegin() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_deque.h:1948
reference operator[](size_type position)
Definition bslstl_deque.h:1964
size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the number of elements contained by this deque.
Definition bslstl_deque.h:2074
const_iterator cbegin() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_deque.h:2018
bsl::reverse_iterator< Iterator > reverse_iterator
Definition bslstl_deque.h:617
std::size_t d_blocksLength
Definition bslstl_deque.h:623
reverse_iterator rend() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_deque.h:1956
bsl::reverse_iterator< ConstIterator > const_reverse_iterator
Definition bslstl_deque.h:618
reference front()
Definition bslstl_deque.h:1987
BlockPtr * d_blocks_p
Definition bslstl_deque.h:622
Iterator iterator
Definition bslstl_deque.h:604
ConstIterator const_iterator
Definition bslstl_deque.h:605
VALUE_TYPE value_type
Definition bslstl_deque.h:608
iterator begin() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_deque.h:1932
const VALUE_TYPE & const_reference
Definition bslstl_deque.h:603
size_type capacity() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_deque.h:2081
std::size_t size_type
Definition bslstl_deque.h:606
reference at(size_type position)
Definition bslstl_deque.h:1973
const_iterator cend() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_deque.h:2034
bool empty() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_deque.h:2120
const_reverse_iterator crbegin() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_deque.h:2050
VALUE_TYPE & reference
Definition bslstl_deque.h:602
IteratorImp d_start
Definition bslstl_deque.h:624
std::ptrdiff_t difference_type
Definition bslstl_deque.h:607
Definition bslstl_deque.h:1675
BlockPtr * reserveBlockSlots(size_type numNewBlocks, bool atFront)
Definition bslstl_deque.h:4210
void release()
Definition bslstl_deque.h:4310
~Deque_BlockCreator()
Definition bslstl_deque.h:4166
void insertAtFront(size_type n)
Definition bslstl_deque.h:4188
void insertAtBack(size_type n)
Definition bslstl_deque.h:4199
Definition bslstl_deque.h:1747
~Deque_BlockProctor()
Definition bslstl_deque.h:4333
void release()
Definition bslstl_deque.h:4367
Definition bslstl_deque.h:1808
~Deque_ClearGuard()
Definition bslstl_deque.h:4387
void release()
Release from management the deque proctored by this object.
Definition bslstl_deque.h:4397
Definition bslstl_deque.h:1856
void release()
Definition bslstl_deque.h:4456
std::size_t count() const BSLS_KEYWORD_NOEXCEPT
Return the current count maintained by this guard.
Definition bslstl_deque.h:4465
IteratorImp begin() const BSLS_KEYWORD_NOEXCEPT
Return a pointer after the first item in the guarded range.
Definition bslstl_deque.h:4473
~Deque_Guard()
Definition bslstl_deque.h:4419
IteratorImp end() const BSLS_KEYWORD_NOEXCEPT
Return a pointer after the last item in the guarded range.
Definition bslstl_deque.h:4481
std::size_t operator--()
Decrement the count of this guard, and return the new count.
Definition bslstl_deque.h:4449
std::size_t operator++()
Increment the count of this guard, and return the new count.
Definition bslstl_deque.h:4442
Definition bslma_bslallocator.h:580
Definition bslstl_deque.h:772
ALLOCATOR allocator_type
Definition bslstl_deque.h:828
iterator insert(const_iterator position, const VALUE_TYPE &value)
Definition bslstl_deque.h:3671
ConstIterator const_iterator
Definition bslstl_deque.h:823
bsl::reverse_iterator< ConstIterator > const_reverse_iterator
Definition bslstl_deque.h:835
size_type max_size() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_deque.h:4021
deque & operator=(const deque &rhs)
Definition bslstl_deque.h:3025
VALUE_TYPE value_type
Definition bslstl_deque.h:826
AllocatorTraits::pointer pointer
Definition bslstl_deque.h:829
AllocatorTraits::const_pointer const_pointer
Definition bslstl_deque.h:830
deque()
Definition bslstl_deque.h:2847
deque(const deque &original)
Definition bslstl_deque.h:2918
iterator erase(const_iterator position)
Definition bslstl_deque.h:3897
void assign(size_type numElements, const VALUE_TYPE &value)
Definition bslstl_deque.h:3157
const VALUE_TYPE & const_reference
Definition bslstl_deque.h:821
reference emplace_back(Args &&... arguments)
void swap(deque< VALUE_TYPE, ALLOCATOR > &other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocatorTraits void clear() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_deque.h:1454
void pop_back()
Definition bslstl_deque.h:3653
void pop_front()
Definition bslstl_deque.h:3637
iterator emplace(const_iterator position, Args &&... arguments)
deque(BloombergLP::bslmf::MovableRef< deque > original)
Definition bslstl_deque.h:2947
void push_back(const VALUE_TYPE &value)
Definition bslstl_deque.h:3434
void push_back(BloombergLP::bslmf::MovableRef< value_type > value)
Definition bslstl_deque.h:3462
void shrink_to_fit()
Definition bslstl_deque.h:3331
deque &operator=(BloombergLP::bslmf::MovableRef< deque > rhs) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocatorTraits void assign(INPUT_ITERATOR first, INPUT_ITERATOR last)
Iterator iterator
Definition bslstl_deque.h:822
std::ptrdiff_t difference_type
Definition bslstl_deque.h:825
iterator insert(const_iterator position, INPUT_ITERATOR first, INPUT_ITERATOR last)
deque(BloombergLP::bslmf::MovableRef< deque > original, const typename type_identity< ALLOCATOR >::type &basicAllocator)
Definition bslstl_deque.h:2961
reference emplace_front(Args &&... arguments)
allocator_type get_allocator() const BSLS_KEYWORD_NOEXCEPT
Return the allocator used by this deque to supply memory.
Definition bslstl_deque.h:4013
VALUE_TYPE & reference
Definition bslstl_deque.h:820
iterator erase(const_iterator first, const_iterator last)
Definition bslstl_deque.h:3917
iterator insert(const_iterator position, size_type numElements, const VALUE_TYPE &value)
Definition bslstl_deque.h:3788
void resize(size_type newSize, const VALUE_TYPE &value)
Definition bslstl_deque.h:3310
bsl::reverse_iterator< Iterator > reverse_iterator
Definition bslstl_deque.h:834
~deque()
Destroy this object.
Definition bslstl_deque.h:3002
deque(const ALLOCATOR &basicAllocator)
Definition bslstl_deque.h:2857
deque(INPUT_ITERATOR first, INPUT_ITERATOR last, const ALLOCATOR &basicAllocator=ALLOCATOR())
Definition bslstl_deque.h:2905
void resize(size_type newSize)
Definition bslstl_deque.h:3278
deque(size_type numElements, const ALLOCATOR &basicAllocator=ALLOCATOR())
Definition bslstl_deque.h:2867
deque(size_type numElements, const VALUE_TYPE &value, const ALLOCATOR &basicAllocator=ALLOCATOR())
Definition bslstl_deque.h:2885
void reserve(size_type numElements)
Definition bslstl_deque.h:3208
void push_front(BloombergLP::bslmf::MovableRef< value_type > value)
Definition bslstl_deque.h:3398
void push_front(const VALUE_TYPE &value)
Definition bslstl_deque.h:3366
std::size_t size_type
Definition bslstl_deque.h:824
iterator insert(const_iterator position, BloombergLP::bslmf::MovableRef< value_type > value)
Definition bslstl_deque.h:3729
deque(const deque &original, const typename type_identity< ALLOCATOR >::type &basicAllocator)
Definition bslstl_deque.h:2932
Definition bslstl_sharedptr.h:1830
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:229
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_COMPILERFEATURES_FORWARD(T, V)
Definition bsls_compilerfeatures.h:2018
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_NOEXCEPT_OPERATOR(...)
Definition bsls_keyword.h:635
#define BSLS_KEYWORD_NOEXCEPT
Definition bsls_keyword.h:632
#define BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(...)
Definition bsls_keyword.h:634
#define BSLS_UTIL_ADDRESSOF(OBJ)
Definition bsls_util.h:289
int assign(LHS_TYPE *lhs, const RHS_TYPE &rhs)
Definition bdlb_printmethods.h:283
T::const_iterator cend(const T &container)
Definition bslstl_iterator.h:1611
deque< VALUE_TYPE, ALLOCATOR >::size_type erase(deque< VALUE_TYPE, ALLOCATOR > &deq, const BDE_OTHER_TYPE &value)
Definition bslstl_deque.h:4126
T::iterator begin(T &container)
Definition bslstl_iterator.h:1495
T::const_iterator cbegin(const T &container)
Definition bslstl_iterator.h:1553
BSLS_KEYWORD_CONSTEXPR size_t size(const TYPE(&)[DIMENSION]) BSLS_KEYWORD_NOEXCEPT
Return the dimension of the specified array argument.
Definition bslstl_iterator.h:1331
T::iterator end(T &container)
Definition bslstl_iterator.h:1523
deque< VALUE_TYPE, ALLOCATOR >::size_type erase_if(deque< VALUE_TYPE, ALLOCATOR > &deq, PREDICATE predicate)
Definition bslstl_deque.h:4135
BSLS_KEYWORD_CONSTEXPR bool empty(const CONTAINER &container)
Definition bslstl_iterator.h:1279
Definition bdlc_flathashmap.h:1805
Definition balxml_encoderoptions.h:68
Definition bdlbb_blob.h:576
Definition bslstl_deque.h:530
@ DEFAULT_BLOCK_SIZE
Definition bslstl_deque.h:534
@ BLOCK_LENGTH
Definition bslstl_deque.h:536
Definition bslstl_deque.h:552
static void swap(void *a, void *b)
static void move(void *dst, void *src)
Definition bslma_allocatortraits.h:1061
BloombergLP::bslma::AllocatorTraits_ConstPointerType< ALLOCATOR >::type const_pointer
Definition bslma_allocatortraits.h:1152
BloombergLP::bslma::AllocatorTraits_PropOnCopyAssign< ALLOCATOR >::type propagate_on_container_copy_assignment
Definition bslma_allocatortraits.h:1297
BloombergLP::bslma::AllocatorTraits_SizeType< ALLOCATOR_TYPE >::type size_type
Definition bslma_allocatortraits.h:1165
BloombergLP::bslma::AllocatorTraits_PointerType< ALLOCATOR >::type pointer
Definition bslma_allocatortraits.h:1149
Definition bslmf_isconvertible.h:867
Definition bslmf_issame.h:146
t_TYPE type
Definition bslmf_typeidentity.h:216
Definition bslma_usesbslmaallocator.h:343
Definition bslmf_isbitwisemoveable.h:718