1622#ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
1634 class = bsl::enable_if_t<
1635 bsl::is_convertible_v<
1638 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1645 class INPUT_ITERATOR,
1647 typename BloombergLP::bslstl::IteratorUtil::IterVal_t<INPUT_ITERATOR>
1656 class INPUT_ITERATOR,
1659 typename BloombergLP::bslstl::IteratorUtil::IterVal_t<INPUT_ITERATOR>,
1660 class = bsl::enable_if_t<bsl::IsStdAllocator_v<ALLOCATOR>>>
1668 class INPUT_ITERATOR,
1671 typename BloombergLP::bslstl::IteratorUtil::IterVal_t<INPUT_ITERATOR>,
1673 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1675deque(INPUT_ITERATOR, INPUT_ITERATOR, ALLOC *)
1686 class = bsl::enable_if_t<bsl::is_convertible_v<ALLOC *, DEFAULT_ALLOCATOR>>
1688deque(std::initializer_list<VALUE>, ALLOC *)
1691#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_CONCEPTS) \
1692 && defined(BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES)
1695template <ranges::input_range t_RANGE,
1713template <
class VALUE_TYPE,
class ALLOCATOR>
1717#ifndef BSLS_COMPILERFEATURES_SUPPORT_THREE_WAY_COMPARISON
1726template <
class VALUE_TYPE,
class ALLOCATOR>
1731#ifdef BSLALG_SYNTHTHREEWAYUTIL_AVAILABLE
1736template <
class VALUE_TYPE,
class ALLOCATOR>
1737BloombergLP::bslalg::SynthThreeWayUtil::Result<VALUE_TYPE> operator<=>(
1754template <
class VALUE_TYPE,
class ALLOCATOR>
1766template <
class VALUE_TYPE,
class ALLOCATOR>
1778template <
class VALUE_TYPE,
class ALLOCATOR>
1790template <
class VALUE_TYPE,
class ALLOCATOR>
1800template <
class VALUE_TYPE,
class ALLOCATOR,
class BDE_OTHER_TYPE>
1806template <
class VALUE_TYPE,
class ALLOCATOR,
class PREDICATE>
1824template <
class VALUE_TYPE,
class ALLOCATOR>
1840template <
class VALUE_TYPE,
class ALLOCATOR>
1848 typedef BloombergLP::bslalg::DequeImpUtil<VALUE_TYPE,
1850 typedef typename Imp::Block Block;
1851 typedef typename Imp::BlockPtr BlockPtr;
1852 typedef std::size_t size_type;
1856 BlockPtr *d_boundary_p;
1879 void insertAtFront(size_type n);
1884 void insertAtBack(size_type n);
1894 BlockPtr *reserveBlockSlots(size_type numNewBlocks,
bool atFront);
1912template <
class VALUE_TYPE,
class ALLOCATOR>
1920 typedef BloombergLP::bslalg::DequeImpUtil<VALUE_TYPE,
1923 typedef typename Imp::BlockPtr BlockPtr;
1928 BlockPtr *d_boundary_p;
1973template <
class VALUE_TYPE,
class ALLOCATOR>
1977 typedef BloombergLP::bslalg::ContainerBase<ALLOCATOR> ContainerBase;
2021template <
class VALUE_TYPE,
class ALLOCATOR>
2029 typedef BloombergLP::bslalg::DequeIterator<VALUE_TYPE,
2030 BLOCK_LENGTH> IteratorImp;
2031 typedef BloombergLP::bslalg::DequePrimitives<VALUE_TYPE,
2032 BLOCK_LENGTH> DequePrimitives;
2036 std::size_t d_count;
2063 std::size_t operator++();
2066 std::size_t operator--();
2096template <
class VALUE_TYPE>
2104template <
class VALUE_TYPE>
2112template <
class VALUE_TYPE>
2120template <
class VALUE_TYPE>
2128template <
class VALUE_TYPE>
2135 return *(
begin() + position);
2138template <
class VALUE_TYPE>
2145 BloombergLP::bslstl::StdExceptUtil::throwOutOfRange(
2146 "deque<...>::at(n): invalid position");
2148 return *(
begin() + position);
2151template <
class VALUE_TYPE>
2161template <
class VALUE_TYPE>
2168 IteratorImp backIterator =
d_finish;
2170 return *backIterator;
2174template <
class VALUE_TYPE>
2182template <
class VALUE_TYPE>
2190template <
class VALUE_TYPE>
2198template <
class VALUE_TYPE>
2206template <
class VALUE_TYPE>
2214template <
class VALUE_TYPE>
2222template <
class VALUE_TYPE>
2230template <
class VALUE_TYPE>
2238template <
class VALUE_TYPE>
2246template <
class VALUE_TYPE>
2271 last += BLOCK_LENGTH - 1;
2282 return frontCapacity < backCapacity ? frontCapacity : backCapacity;
2285template <
class VALUE_TYPE>
2292template <
class VALUE_TYPE>
2299 return *(
begin() + position);
2302template <
class VALUE_TYPE>
2309 BloombergLP::bslstl::StdExceptUtil::throwOutOfRange(
2310 "const deque<...>::at(n): invalid position");
2312 return *(
begin() + position);
2315template <
class VALUE_TYPE>
2325template <
class VALUE_TYPE>
2332 IteratorImp backIterator =
d_finish;
2334 return *backIterator;
2342template <
class VALUE_TYPE,
class ALLOCATOR>
2348 this->d_blocks_p = 0;
2352template <
class VALUE_TYPE,
class ALLOCATOR>
2354typename deque<VALUE_TYPE, ALLOCATOR>::Block *
2355deque<VALUE_TYPE, ALLOCATOR>::allocateBlock()
2357 return AllocatorUtil::allocateObject<Block>(this->allocatorRef());
2360template <
class VALUE_TYPE,
class ALLOCATOR>
2362typename deque<VALUE_TYPE, ALLOCATOR>::BlockPtr *
2363deque<VALUE_TYPE, ALLOCATOR>::allocateBlockPtrs(std::size_t n)
2365 return AllocatorUtil::allocateObject<BlockPtr>(this->allocatorRef(), n);
2368template <
class VALUE_TYPE,
class ALLOCATOR>
2370void deque<VALUE_TYPE, ALLOCATOR>::deallocateBlock(Block *p)
2372 AllocatorUtil::deallocateObject(this->allocatorRef(), p);
2375template <
class VALUE_TYPE,
class ALLOCATOR>
2378deque<VALUE_TYPE, ALLOCATOR>::deallocateBlockPtrs(BlockPtr *p, std::size_t n)
2380 AllocatorUtil::deallocateObject(this->allocatorRef(), p, n);
2383template <
class VALUE_TYPE,
class ALLOCATOR>
2384template <
class INPUT_ITERATOR,
class SENTINEL>
2386typename deque<VALUE_TYPE, ALLOCATOR>::size_type
2390 if (first == last) {
2393 typedef typename iterator_traits<INPUT_ITERATOR>::iterator_category Tag;
2394 return privateAppend(first, last, Tag());
2397template <
class VALUE_TYPE,
class ALLOCATOR>
2398template <
class INPUT_ITERATOR,
class SENTINEL>
2401 INPUT_ITERATOR first,
2403 std::random_access_iterator_tag)
2405 BlockCreator newBlocks(
this);
2406 Guard guard(
this,
true);
2409 BloombergLP::bslstl::IteratorUtil::insertDistance(first, last);
2411 numElements > max_size() - this->size())) {
2414 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
2415 "deque<...>::insert(pos,n,v): deque too big");
2418 for ( ; first != last; ++first) {
2419 IteratorImp insertPoint = guard.end();
2427 if (1 == insertPoint.remainingInBlock()) {
2428 newBlocks.insertAtBack(1);
2429 insertPoint = guard.end();
2432 AllocatorTraits::construct(this->allocatorRef(),
2438 this->d_finish += guard.count();
2444template <
class VALUE_TYPE,
class ALLOCATOR>
2445template <
class INPUT_ITERATOR,
class SENTINEL>
2449 std::input_iterator_tag)
2451 BlockCreator newBlocks(
this);
2452 Guard guard(
this,
true);
2455 size_type maxNumElements = max_size() - this->size();
2456 for ( ; first != last; ++first) {
2459 numElements > maxNumElements)) {
2462 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
2463 "deque<...>::insert(pos,n,v): deque too big");
2465 IteratorImp insertPoint = guard.end();
2473 if (1 == insertPoint.remainingInBlock()) {
2474 newBlocks.insertAtBack(1);
2475 insertPoint = guard.end();
2479 AllocatorTraits::construct(this->allocatorRef(),
2485 this->d_finish += guard.count();
2491template <
class VALUE_TYPE,
class ALLOCATOR>
2493 size_type numElements)
2498 size_type numNewBlocks = (this->d_finish.offsetInBlock() + numElements) /
2500 BlockCreator newBlocks(
this);
2501 newBlocks.insertAtBack(numNewBlocks);
2502 DequePrimitives::valueInititalizeN(&this->d_finish,
2505 this->allocatorRef());
2508template <
class VALUE_TYPE,
class ALLOCATOR>
2509void deque<VALUE_TYPE, ALLOCATOR>::privateAppendRaw(
2510 size_type numElements,
2511 const VALUE_TYPE& value)
2516 size_type numNewBlocks = (this->d_finish.offsetInBlock() + numElements) /
2518 BlockCreator newBlocks(
this);
2519 newBlocks.insertAtBack(numNewBlocks);
2521 DequePrimitives::uninitializedFillNBack(&this->d_finish,
2525 this->allocatorRef());
2528template <
class VALUE_TYPE,
class ALLOCATOR>
2529template <
class t_ITERATOR,
class t_SENTINEL>
2530void deque<VALUE_TYPE, ALLOCATOR>::privateAssign(t_ITERATOR first,
2533 typedef typename iterator_traits<t_ITERATOR>::iterator_category Tag;
2542 ClearGuard guard(
this);
2547 for (i = this->d_start; !(i == this->d_finish) && first != last;
2552 if (!(i == this->d_finish)) {
2560 privateAppend(first, last, Tag());
2566template <
class VALUE_TYPE,
class ALLOCATOR>
2567void deque<VALUE_TYPE, ALLOCATOR>::privateInit(size_type numElements)
2569 size_type blocksLength = numElements / BLOCK_LENGTH + 1 +
2570 2 * Imp::BLOCK_ARRAY_PADDING;
2574 this->d_blocks_p = this->allocateBlockPtrs(blocksLength);
2576 this->d_blocksLength = blocksLength;
2581 BlockPtr *firstBlockPtr = &this->d_blocks_p[Imp::BLOCK_ARRAY_PADDING];
2582 *firstBlockPtr = this->allocateBlock();
2592 const int offset =
static_cast<int>(
2593 (BLOCK_LENGTH - 1 - numElements % BLOCK_LENGTH) / 2);
2597 this->d_start = this->d_finish = IteratorImp(
2599 (*firstBlockPtr)->d_data + offset);
2602template <
class VALUE_TYPE,
class ALLOCATOR>
2603template <
class INTEGRAL_TYPE>
2607 INTEGRAL_TYPE numElements,
2608 INTEGRAL_TYPE value,
2609 BloombergLP::bslmf::MatchArithmeticType,
2610 BloombergLP::bslmf::Nil)
2614 static_cast<VALUE_TYPE
>(value));
2617template <
class VALUE_TYPE,
class ALLOCATOR>
2618template <
class INPUT_ITERATOR>
2620 const_iterator position,
2621 INPUT_ITERATOR first,
2622 INPUT_ITERATOR last,
2623 BloombergLP::bslmf::MatchAnyType,
2624 BloombergLP::bslmf::MatchAnyType)
2626 typedef typename iterator_traits<INPUT_ITERATOR>::iterator_category Tag;
2628 if (first == last) {
2632 if (position == this->cbegin()) {
2633 privatePrepend(first, last, Tag());
2637 if (position == this->
cend()) {
2638 privateAppend(first, last, Tag());
2642 privateInsert(position, first, last, Tag());
2645template <
class VALUE_TYPE,
class ALLOCATOR>
2646template <
class INPUT_ITERATOR,
class SENTINEL>
2648void deque<VALUE_TYPE, ALLOCATOR>::privateInsert(const_iterator position,
2649 INPUT_ITERATOR first,
2652 if (first == last) {
2656 typedef typename iterator_traits<INPUT_ITERATOR>::iterator_category Tag;
2657 if (position == this->
cbegin()) {
2658 privatePrepend(first, last, Tag());
2660 else if (position == this->
cend()) {
2661 privateAppend(first, last, Tag());
2664 privateInsert(position, first, last, Tag());
2668template <
class VALUE_TYPE,
class ALLOCATOR>
2669template <
class INPUT_ITERATOR,
class SENTINEL>
2670void deque<VALUE_TYPE, ALLOCATOR>::privateInsert(
2671 const_iterator position,
2672 INPUT_ITERATOR first,
2674 std::input_iterator_tag tag)
2678 iterator pos(position.imp());
2679 const size_type currentSize = this->
size();
2680 const size_type posIdx = pos - this->
begin();
2682 deque temp(k_RAW_INIT, this->get_allocator());
2683 privateSplit(&temp, position.imp());
2685 if (posIdx <= currentSize / 2) {
2687 static_cast<Base *
>(
this),
static_cast<Base *
>(&temp));
2688 privatePrepend(first, last, tag);
2689 privateJoinPrepend(&temp);
2692 privateAppend(first, last, tag);
2693 privateJoinAppend(&temp);
2697template <
class VALUE_TYPE,
class ALLOCATOR>
2698void deque<VALUE_TYPE, ALLOCATOR>::privateSplit(
2699 deque<VALUE_TYPE, ALLOCATOR> *other,
2734 if (pos.blockPtr() == this->d_finish.blockPtr()) {
2738 difference_type numAfter = this->d_finish.valuePtr() - pos.valuePtr();
2739 other->privateInit(numAfter);
2740 BloombergLP::bslalg::ArrayPrimitives::destructiveMove(
2741 other->d_start.valuePtr(),
2743 this->d_finish.valuePtr(),
2744 this->allocatorRef());
2745 other->d_finish += numAfter;
2746 this->d_finish = pos;
2750 if (pos.blockPtr() == this->d_start.blockPtr()) {
2754 difference_type numBefore = pos.valuePtr() - this->d_start.valuePtr();
2755 other->privateInit(numBefore);
2756 BloombergLP::bslalg::ArrayPrimitives::destructiveMove(
2757 other->d_start.valuePtr(),
2758 this->d_start.valuePtr(),
2760 this->allocatorRef());
2761 other->d_finish += numBefore;
2762 this->d_start = pos;
2764 static_cast<Base *
>(
this),
static_cast<Base *
>(other));
2770 difference_type numMoveBlocks = this->d_finish.blockPtr() - pos.blockPtr();
2772 size_type otherBlocksLength = numMoveBlocks + 1 +
2773 2 * Imp::BLOCK_ARRAY_PADDING;
2775 other->d_blocks_p = this->allocateBlockPtrs(otherBlocksLength);
2776 other->d_blocksLength = otherBlocksLength;
2780 Block *newBlock = this->allocateBlock();
2785 std::memcpy(other->d_blocks_p + 1 + Imp::BLOCK_ARRAY_PADDING,
2787 sizeof(BlockPtr) * numMoveBlocks);
2789 other->d_start = IteratorImp(&other->d_blocks_p[
2790 1 + Imp::BLOCK_ARRAY_PADDING]);
2791 other->d_finish = IteratorImp(other->d_start.blockPtr() +
2793 this->d_finish.valuePtr());
2795 BlockPtr *newBlockPtr = pos.blockPtr() + 1;
2796 *newBlockPtr = newBlock;
2797 this->d_finish = IteratorImp(newBlockPtr);
2823 size_type splitOffset = pos.offsetInBlock();
2824 if (splitOffset >= pos.remainingInBlock()) {
2827 value_type *splitValuePtr = newBlock->d_data + splitOffset;
2828 BloombergLP::bslalg::ArrayPrimitives::destructiveMove(
2832 this->allocatorRef());
2838 BloombergLP::bslalg::ArrayPrimitives::destructiveMove(
2842 this->allocatorRef());
2843 *newBlockPtr = *pos.blockPtr();
2844 *pos.blockPtr() = newBlock;
2849 this->d_finish = IteratorImp(&newBlockPtr[-1],
2850 newBlockPtr[-1]->d_data + splitOffset);
2851 other->d_start.previousBlock();
2852 *(other->d_start.blockPtr()) = *newBlockPtr;
2853 other->d_start = IteratorImp(other->d_start.blockPtr(),
2854 other->d_start.blockBegin() + splitOffset);
2857template <
class VALUE_TYPE,
class ALLOCATOR>
2859void deque<VALUE_TYPE, ALLOCATOR>::privateJoinPrepend(
2860 deque<VALUE_TYPE, ALLOCATOR> *other)
2862 privatePrepend(other->begin(),
2864 std::random_access_iterator_tag());
2868 deque<VALUE_TYPE, ALLOCATOR> temp(k_RAW_INIT, other->allocatorRef());
2872template <
class VALUE_TYPE,
class ALLOCATOR>
2874void deque<VALUE_TYPE, ALLOCATOR>::privateJoinAppend(
2875 deque<VALUE_TYPE, ALLOCATOR> *other)
2877 privateAppend(other->begin(),
2879 std::random_access_iterator_tag());
2883 deque<VALUE_TYPE, ALLOCATOR> temp(k_RAW_INIT, other->allocatorRef());
2887template <
class VALUE_TYPE,
class ALLOCATOR>
2888template <
class INPUT_ITERATOR,
class SENTINEL>
2889void deque<VALUE_TYPE, ALLOCATOR>::privateInsert(
2890 const_iterator position,
2891 INPUT_ITERATOR first,
2893 std::random_access_iterator_tag tag)
2897 if (position == this->
cbegin()) {
2898 privatePrepend(first, last, tag);
2902 if (position == this->
cend()) {
2903 privateAppend(first, last, tag);
2907 const size_type currentSize = this->
size();
2908 const size_type numElements =
2909 BloombergLP::bslstl::IteratorUtil::insertDistance(first, last);
2911 numElements > max_size() - currentSize)) {
2914 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
2915 "deque<...>::insert(pos,n,v): deque too big");
2918 iterator pos(position.imp());
2919 const size_type posIdx = position - this->
cbegin();
2920 if (posIdx <= currentSize / 2) {
2924 size_type numNewBlocks = (this->d_start.remainingInBlock()
2925 + numElements - 1) / BLOCK_LENGTH;
2926 BlockCreator newBlocks(
this);
2927 newBlocks.insertAtFront(numNewBlocks);
2929 DequePrimitives::insertAndMoveToFront(&this->d_start,
2931 this->d_start + posIdx,
2935 this->allocatorRef());
2940 size_type numNewBlocks = (this->d_finish.offsetInBlock() + numElements)
2942 BlockCreator newBlocks(
this);
2943 newBlocks.insertAtBack(numNewBlocks);
2945 DequePrimitives::insertAndMoveToBack(&this->d_finish,
2947 this->d_start + posIdx,
2951 this->allocatorRef());
2955template <
class VALUE_TYPE,
class ALLOCATOR>
2956void deque<VALUE_TYPE, ALLOCATOR>::privatePrependRaw(
2957 size_type numElements,
2958 const VALUE_TYPE& value)
2963 size_type numNewBlocks = (this->d_start.remainingInBlock() +
2964 numElements - 1) / BLOCK_LENGTH;
2965 BlockCreator newBlocks(
this);
2966 newBlocks.insertAtFront(numNewBlocks);
2968 DequePrimitives::uninitializedFillNFront(&this->d_start,
2972 this->allocatorRef());
2975template <
class VALUE_TYPE,
class ALLOCATOR>
2976template <
class INPUT_ITERATOR,
class SENTINEL>
2978typename deque<VALUE_TYPE, ALLOCATOR>::size_type
2982 if (first == last) {
2985 typedef typename iterator_traits<INPUT_ITERATOR>::iterator_category Tag;
2986 return privatePrepend(first, last, Tag());
2989template <
class VALUE_TYPE,
class ALLOCATOR>
2990template <
class INPUT_ITERATOR,
class SENTINEL>
2994 std::input_iterator_tag tag)
2996 deque temp(k_RAW_INIT, this->get_allocator());
2997 temp.privateInit(this->size() + 1);
2998 size_type numElements = temp.privateAppend(first, last, tag);
3002 if (numElements > this->size()) {
3004 privateJoinAppend(&temp);
3007 privateJoinPrepend(&temp);
3013template <
class VALUE_TYPE,
class ALLOCATOR>
3014template <
class INPUT_ITERATOR,
class SENTINEL>
3017 INPUT_ITERATOR first,
3019 std::bidirectional_iterator_tag)
3022 BlockCreator newBlocks(
this);
3023 Guard guard(
this,
false);
3026 size_type maxNumElements = max_size() - this->size();
3030 numElements > maxNumElements)) {
3033 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3034 "deque<...>::insert(pos,n,v): deque too big");
3037 IteratorImp insertPoint = guard.begin();
3042 if (insertPoint.valuePtr() == insertPoint.blockBegin()) {
3043 newBlocks.insertAtFront(1);
3044 insertPoint = guard.begin();
3048 AllocatorTraits::construct(this->allocatorRef(),
3052 }
while (first != last);
3054 this->d_start -= guard.count();
3059template <
class VALUE_TYPE,
class ALLOCATOR>
3060template <
class INPUT_ITERATOR,
class SENTINEL>
3063 INPUT_ITERATOR first,
3065 std::random_access_iterator_tag)
3068 ::canCalculateInsertDistance<INPUT_ITERATOR, SENTINEL>()));
3070 BloombergLP::bslstl::IteratorUtil::insertDistance(first, last);
3072 numElements > max_size() - this->size())) {
3075 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3076 "deque<...>::insert(pos,n,v): deque too big");
3079 BlockCreator newBlocks(
this);
3080 Guard guard(
this,
false);
3082#ifdef BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES
3084 if constexpr (std::is_same_v<INPUT_ITERATOR, SENTINEL>) {
3088 end = first + numElements;
3092 INPUT_ITERATOR
end = last;
3095 IteratorImp insertPoint = guard.begin();
3100 if (insertPoint.valuePtr() == insertPoint.blockBegin()) {
3101 newBlocks.insertAtFront(1);
3102 insertPoint = guard.begin();
3106 AllocatorTraits::construct(this->allocatorRef(),
3110 }
while (first !=
end);
3112 this->d_start -= guard.count();
3118template <
class VALUE_TYPE,
class ALLOCATOR>
3121, ContainerBase(ALLOCATOR())
3124 temp.privateInit(0);
3128template <
class VALUE_TYPE,
class ALLOCATOR>
3131, ContainerBase(basicAllocator)
3134 temp.privateInit(0);
3138template <
class VALUE_TYPE,
class ALLOCATOR>
3140 const ALLOCATOR& basicAllocator)
3142, ContainerBase(basicAllocator)
3147 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3148 "deque<...>::deque(n): deque too big");
3151 temp.privateInit(numElements);
3152 temp.privateAppendDefaultInsertable(numElements);
3156template <
class VALUE_TYPE,
class ALLOCATOR>
3158 const VALUE_TYPE& value,
3159 const ALLOCATOR& basicAllocator)
3161, ContainerBase(basicAllocator)
3166 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3167 "deque<...>::deque(n,v): deque too big");
3170 temp.privateInit(numElements);
3171 temp.privateAppendRaw(numElements, value);
3175template <
class VALUE_TYPE,
class ALLOCATOR>
3176template <
class INPUT_ITERATOR>
3178 INPUT_ITERATOR last,
3179 const ALLOCATOR& basicAllocator)
3181, ContainerBase(basicAllocator)
3184 temp.privateInit(0);
3189template <
class VALUE_TYPE,
class ALLOCATOR>
3190template <
class t_RANGE>
3195 const ALLOCATOR& basicAllocator)
3197, ContainerBase(basicAllocator)
3199 deque temp(k_RAW_INIT, this->get_allocator());
3200 temp.privateInit(0);
3205template <
class VALUE_TYPE,
class ALLOCATOR>
3208, ContainerBase(
AllocatorTraits::select_on_container_copy_construction(
3209 original.get_allocator()))
3212 temp.privateInit(original.
size());
3213 temp.privateAppend(original.
begin(),
3215 std::random_access_iterator_tag());
3219template <
class VALUE_TYPE,
class ALLOCATOR>
3221 const deque& original,
3222 const typename type_identity<ALLOCATOR>::type& basicAllocator)
3224, ContainerBase(basicAllocator)
3227 temp.privateInit(original.
size());
3228 temp.privateAppend(original.
begin(),
3230 std::random_access_iterator_tag());
3234template <
class VALUE_TYPE,
class ALLOCATOR>
3236 BloombergLP::bslmf::MovableRef<deque> original)
3238, ContainerBase(MoveUtil::access(original).get_allocator())
3241 temp.privateInit(0);
3244 deque& lvalue = original;
3248template <
class VALUE_TYPE,
class ALLOCATOR>
3250 BloombergLP::bslmf::MovableRef<deque> original,
3251 const typename type_identity<ALLOCATOR>::type& basicAllocator)
3253, ContainerBase(basicAllocator)
3256 temp.privateInit(0);
3258 deque& lvalue = original;
3263 static_cast<Base *
>(&temp));
3265 static_cast<Base *
>(&lvalue));
3271 temp.
push_back(MoveUtil::move(lvalue[pos]));
3274 static_cast<Base *
>(&temp));
3278#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
3279template <
class VALUE_TYPE,
class ALLOCATOR>
3282 std::initializer_list<value_type> values,
3283 const ALLOCATOR& basicAllocator)
3289template <
class VALUE_TYPE,
class ALLOCATOR>
3292 if (0 == this->d_blocks_p) {
3298 if (0 != this->d_start.blockPtr()) {
3303 this->deallocateBlock(*this->d_start.blockPtr());
3307 this->deallocateBlockPtrs(this->d_blocks_p, this->d_blocksLength);
3311template <
class VALUE_TYPE,
class ALLOCATOR>
3319 if (Propagate::value && get_allocator() !=
rhs.get_allocator()) {
3323 static_cast<Base *
>(&other));
3324 AllocatorUtil::swap(&this->allocatorRef(), &other.allocatorRef(),
3332 if (origSize > rhsSize) {
3342 privateAppend(
rhs.begin() + minSize,
3344 std::random_access_iterator_tag());
3349 IteratorImp from =
rhs.d_start;
3350 IteratorImp to = this->d_start;
3351 for (
size_type i = 0; i < minSize; ++i) {
3362template <
class VALUE_TYPE,
class ALLOCATOR>
3365 BloombergLP::bslmf::MovableRef<deque>
rhs)
3367 AllocatorTraits::is_always_equal::value)
3372 AllocatorTraits::propagate_on_container_move_assignment Propagate;
3376 static_cast<Base *
>(&lvalue));
3378 else if (Propagate::value) {
3379 deque other(MoveUtil::move(lvalue));
3381 static_cast<Base *
>(&other));
3382 AllocatorUtil::swap(&this->allocatorRef(), &other.allocatorRef(),
3386 deque other(MoveUtil::move(lvalue), get_allocator());
3388 static_cast<Base *
>(&other));
3394#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
3395template <
class VALUE_TYPE,
class ALLOCATOR>
3397deque<VALUE_TYPE, ALLOCATOR>&
3399 std::initializer_list<value_type> values)
3401 assign(values.begin(), values.end());
3406template <
class VALUE_TYPE,
class ALLOCATOR>
3407template <
class INPUT_ITERATOR>
3409 INPUT_ITERATOR last)
3411 privateAssign(first, last);
3414template <
class VALUE_TYPE,
class ALLOCATOR>
3416 const VALUE_TYPE& value)
3421 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3422 "deque<...>::assign(n,v): deque too big");
3432 ClearGuard guard(
this);
3437 if (numElements < origSize) {
3438 minSize = numElements;
3443 privateAppendRaw(numElements - origSize, value);
3446 IteratorImp to = this->d_start;
3447 for (
size_type i = 0; i < minSize; ++i) {
3455#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
3456template <
class VALUE_TYPE,
class ALLOCATOR>
3459 std::initializer_list<value_type> values)
3461 assign(values.begin(), values.end());
3465template <
class VALUE_TYPE,
class ALLOCATOR>
3466template <
class t_RANGE>
3468void
deque<VALUE_TYPE, ALLOCATOR>::assign_range(
3471 privateAssign(ranges::begin(range), ranges::end(range));
3474template <
class VALUE_TYPE,
class ALLOCATOR>
3481 max_size() - (BLOCK_LENGTH - 1))) {
3484 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3485 "deque<...>::reserve(n): deque too big");
3495 if (this->d_start.blockPtr() > this->d_blocks_p) {
3496 this->d_blocks_p[0] = 0;
3498 if (this->d_finish.blockPtr() < this->d_blocks_p + this->d_blocksLength-1){
3499 this->d_blocks_p[this->d_blocksLength - 1] = 0;
3502 const IteratorImp first(this->d_blocks_p);
3503 IteratorImp last( this->d_blocks_p + this->d_blocksLength - 1);
3504 last += BLOCK_LENGTH - 1;
3506 const size_type frontRoom = this->d_start - first;
3507 const size_type backRoom = last - this->d_finish;
3509 size_type numFrontBlocks = numElements > frontRoom
3510 ? (numElements - frontRoom + BLOCK_LENGTH - 1) /
3513 size_type numBackBlocks = numElements > backRoom
3514 ? (numElements - backRoom + BLOCK_LENGTH - 1) /
3518 if (0 == numFrontBlocks && 0 == numBackBlocks) {
3526 (max_size() - existingSpace) / BLOCK_LENGTH
3527 || (existingSpace += numFrontBlocks * BLOCK_LENGTH,
3529 (max_size() - existingSpace) / BLOCK_LENGTH))) {
3532 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3533 "deque<...>::reserve(n): deque too big");
3539 BlockCreator newBlocks(
this);
3540 newBlocks.reserveBlockSlots(numFrontBlocks,
true);
3541 newBlocks.reserveBlockSlots(numBackBlocks,
false);
3544template <
class VALUE_TYPE,
class ALLOCATOR>
3550 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3551 "deque<...>::resize(n): deque too big");
3556 if (newSize <= origSize) {
3561 IteratorImp oldEnd = this->d_finish;
3562 IteratorImp newEnd = this->d_start + newSize;
3563 DequePrimitives::destruct(newEnd, oldEnd, this->allocatorRef());
3565 for (; oldEnd.blockPtr() != newEnd.blockPtr();
3566 oldEnd.previousBlock()) {
3567 this->deallocateBlock(*oldEnd.blockPtr());
3569 this->d_finish = newEnd;
3572 privateAppendDefaultInsertable(newSize - origSize);
3576template <
class VALUE_TYPE,
class ALLOCATOR>
3578 const VALUE_TYPE& value)
3583 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3584 "deque<...>::resize(n,v): deque too big");
3589 if (newSize <= origSize) {
3593 privateAppendRaw(newSize - origSize, value);
3597template <
class VALUE_TYPE,
class ALLOCATOR>
3605 this->d_finish.blockPtr() - this->d_start.blockPtr() + 1;
3607 if (newBlocksLength == this->d_blocksLength) {
3611 const size_type offsetStart = this->d_start.offsetInBlock();
3612 const size_type offsetFinish = this->d_finish.offsetInBlock();
3614 BlockPtr *newBlocks = this->allocateBlockPtrs(newBlocksLength);
3616 std::memmove(newBlocks,
3617 this->d_start.blockPtr(),
3618 newBlocksLength *
sizeof(BlockPtr));
3620 this->deallocateBlockPtrs(this->d_blocks_p, this->d_blocksLength);
3622 this->d_blocks_p = newBlocks;
3623 this->d_blocksLength = newBlocksLength;
3625 this->d_start.setBlock(newBlocks);
3626 this->d_start += offsetStart;
3628 this->d_finish.setBlock(newBlocks + newBlocksLength - 1);
3629 this->d_finish += offsetFinish;
3632template <
class VALUE_TYPE,
class ALLOCATOR>
3633template <
class t_RANGE>
3635void
deque<VALUE_TYPE, ALLOCATOR>::append_range(
3638 privateAppend(ranges::begin(range), ranges::end(range));
3641template <
class VALUE_TYPE,
class ALLOCATOR>
3642template <
class t_RANGE>
3644void
deque<VALUE_TYPE, ALLOCATOR>::prepend_range(
3647 privatePrepend(ranges::begin(range), ranges::end(range));
3650template <
class VALUE_TYPE,
class ALLOCATOR>
3656 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3657 "deque<...>::push_front(v): deque too big");
3661 0 == this->d_start.offsetInBlock())) {
3664 BlockCreator newBlocks(
this);
3665 newBlocks.insertAtFront(1);
3667 AllocatorTraits::construct(
3668 this->allocatorRef(), (this->d_start - 1).valuePtr(), value);
3676 AllocatorTraits::construct(
3677 this->allocatorRef(), this->d_start.valuePtr() - 1, value);
3678 this->d_start.valuePtrDecrement();
3682template <
class VALUE_TYPE,
class ALLOCATOR>
3684 BloombergLP::bslmf::MovableRef<value_type> value)
3689 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3690 "deque<...>::push_front(v): deque too big");
3693 VALUE_TYPE& lvalue = value;
3696 0 == this->d_start.offsetInBlock())) {
3699 BlockCreator newBlocks(
this);
3700 newBlocks.insertAtFront(1);
3702 AllocatorTraits::construct(this->allocatorRef(),
3703 (this->d_start - 1).valuePtr(),
3704 MoveUtil::move(lvalue));
3711 AllocatorTraits::construct(this->allocatorRef(),
3712 this->d_start.valuePtr() - 1,
3713 MoveUtil::move(lvalue));
3714 this->d_start.valuePtrDecrement();
3718template <
class VALUE_TYPE,
class ALLOCATOR>
3724 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3725 "deque<...>::push_back(v): deque too big");
3729 1 < this->d_finish.remainingInBlock())) {
3730 AllocatorTraits::construct(
3731 this->allocatorRef(), this->d_finish.valuePtr(), value);
3732 this->d_finish.valuePtrIncrement();
3737 BlockCreator newBlocks(
this);
3738 newBlocks.insertAtBack(1);
3740 AllocatorTraits::construct(
3741 this->allocatorRef(), this->d_finish.valuePtr(), value);
3742 this->d_finish.nextBlock();
3746template <
class VALUE_TYPE,
class ALLOCATOR>
3748 BloombergLP::bslmf::MovableRef<value_type> value)
3753 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3754 "deque<...>::push_back(v): deque too big");
3757 VALUE_TYPE& lvalue = value;
3760 1 < this->d_finish.remainingInBlock())) {
3761 AllocatorTraits::construct(this->allocatorRef(),
3762 this->d_finish.valuePtr(),
3763 MoveUtil::move(lvalue));
3764 this->d_finish.valuePtrIncrement();
3769 BlockCreator newBlocks(
this);
3770 newBlocks.insertAtBack(1);
3772 AllocatorTraits::construct(this->allocatorRef(),
3773 this->d_finish.valuePtr(),
3774 MoveUtil::move(lvalue));
3775 this->d_finish.nextBlock();
3779#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
3780template <
class VALUE_TYPE,
class ALLOCATOR>
3781template <
class... Args>
3788 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3789 "deque<...>::emplace_front(args): deque too big");
3793 0 == this->d_start.offsetInBlock())) {
3796 BlockCreator newBlocks(
this);
3797 newBlocks.insertAtFront(1);
3799 AllocatorTraits::construct(
3800 this->allocatorRef(),
3801 (this->d_start - 1).valuePtr(),
3809 AllocatorTraits::construct(
3810 this->allocatorRef(),
3811 this->d_start.valuePtr() - 1,
3813 this->d_start.valuePtrDecrement();
3815 return *(this->d_start);
3818template <
class VALUE_TYPE,
class ALLOCATOR>
3819template <
class... Args>
3826 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3827 "deque<...>::emplace_back(args): deque too big");
3831 1 < this->d_finish.remainingInBlock())) {
3832 AllocatorTraits::construct(
3833 this->allocatorRef(),
3834 this->d_finish.valuePtr(),
3836 this->d_finish.valuePtrIncrement();
3841 BlockCreator newBlocks(
this);
3842 newBlocks.insertAtBack(1);
3844 AllocatorTraits::construct(
3845 this->allocatorRef(),
3846 this->d_finish.valuePtr(),
3848 this->d_finish.nextBlock();
3850 return *(this->d_finish - 1);
3854#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
3855template <
class VALUE_TYPE,
class ALLOCATOR>
3856template <
class... Args>
3859 Args&&... arguments)
3864 if (position == this->
cbegin()) {
3866 return this->
begin();
3869 if (position == this->
cend()) {
3871 return iterator(this->d_finish - 1);
3877 const size_type currentSize = this->size();
3881 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3882 "deque<...>::emplace(args): deque too big");
3887 if (posIdx <= currentSize / 2) {
3888 BlockCreator newBlocks(
this);
3889 if (this->d_start.remainingInBlock() == BLOCK_LENGTH) {
3890 newBlocks.insertAtFront(1);
3893 BlockProctor proctor(
this,
true);
3894 DequePrimitives::emplaceAndMoveToFront(
3897 this->d_start + posIdx,
3898 this->allocatorRef(),
3903 BlockCreator newBlocks(
this);
3904 if (this->d_finish.offsetInBlock() == BLOCK_LENGTH - 1) {
3905 newBlocks.insertAtBack(1);
3908 BlockProctor proctor(
this,
false);
3909 DequePrimitives::emplaceAndMoveToBack(
3912 this->d_start + posIdx,
3913 this->allocatorRef(),
3917 return this->
begin() + posIdx;
3921template <
class VALUE_TYPE,
class ALLOCATOR>
3926 BloombergLP::bslma::DestructionUtil::destroy(this->d_start.valuePtr());
3928 if (1 == this->d_start.remainingInBlock()) {
3929 this->deallocateBlock(*this->d_start.blockPtr());
3930 this->d_start.nextBlock();
3934 this->d_start.valuePtrIncrement();
3937template <
class VALUE_TYPE,
class ALLOCATOR>
3942 if (0 == this->d_finish.offsetInBlock()) {
3944 BloombergLP::bslma::DestructionUtil::destroy(
3945 this->d_finish.valuePtr());
3946 this->deallocateBlock(this->d_finish.blockPtr()[1]);
3950 this->d_finish.valuePtrDecrement();
3951 BloombergLP::bslma::DestructionUtil::destroy(this->d_finish.valuePtr());
3954template <
class VALUE_TYPE,
class ALLOCATOR>
3957 const VALUE_TYPE& value)
3962 if (position == this->
cbegin()) {
3964 return this->
begin();
3967 if (position == this->
cend()) {
3969 return iterator(this->d_finish - 1);
3975 const size_type currentSize = this->size();
3979 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
3980 "deque<...>::insert(pos,n,v): deque too big");
3985 if (posIdx <= currentSize / 2) {
3986 BlockCreator newBlocks(
this);
3987 if (this->d_start.remainingInBlock() == BLOCK_LENGTH) {
3988 newBlocks.insertAtFront(1);
3990 DequePrimitives::insertAndMoveToFront(&this->d_start,
3992 this->d_start + posIdx,
3995 this->allocatorRef());
3998 BlockCreator newBlocks(
this);
3999 if (this->d_finish.offsetInBlock() == BLOCK_LENGTH - 1) {
4000 newBlocks.insertAtBack(1);
4002 DequePrimitives::insertAndMoveToBack(&this->d_finish,
4004 this->d_start + posIdx,
4007 this->allocatorRef());
4009 return this->
begin() + posIdx;
4012template <
class VALUE_TYPE,
class ALLOCATOR>
4016 BloombergLP::bslmf::MovableRef<VALUE_TYPE> value)
4021 VALUE_TYPE& lvalue = value;
4023 if (position == this->
cbegin()) {
4024 push_front(MoveUtil::move(lvalue));
4025 return this->
begin();
4028 if (position == this->
cend()) {
4029 push_back(MoveUtil::move(lvalue));
4030 return iterator(this->d_finish - 1);
4036 const size_type currentSize = this->size();
4040 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
4041 "deque<...>::insert(pos,n,v): deque too big");
4046 if (posIdx <= currentSize / 2) {
4047 BlockCreator newBlocks(
this);
4048 if (this->d_start.remainingInBlock() == BLOCK_LENGTH) {
4049 newBlocks.insertAtFront(1);
4051 DequePrimitives::moveInsertAndMoveToFront(&this->d_start,
4053 this->d_start + posIdx,
4054 MoveUtil::move(lvalue),
4055 this->allocatorRef());
4058 BlockCreator newBlocks(
this);
4059 if (this->d_finish.offsetInBlock() == BLOCK_LENGTH - 1) {
4060 newBlocks.insertAtBack(1);
4062 DequePrimitives::moveInsertAndMoveToBack(&this->d_finish,
4064 this->d_start + posIdx,
4065 MoveUtil::move(lvalue),
4066 this->allocatorRef());
4068 return this->
begin() + posIdx;
4071template <
class VALUE_TYPE,
class ALLOCATOR>
4075 const VALUE_TYPE& value)
4082 if (0 == numElements) {
4083 return this->
begin() + posIdx;
4086 const size_type currentSize = this->size();
4088 numElements > max_size() - currentSize)) {
4091 BloombergLP::bslstl::StdExceptUtil::throwLengthError(
4092 "deque<...>::insert(pos,n,v): deque too big");
4095 if (position == this->cbegin()) {
4096 privatePrependRaw(numElements, value);
4098 return this->
begin();
4101 if (position == this->
cend()) {
4102 privateAppendRaw(numElements, value);
4104 return this->
begin() + posIdx;
4107 if (posIdx <= currentSize / 2) {
4111 size_type numNewBlocks = (this->d_start.remainingInBlock()
4112 + numElements - 1) / BLOCK_LENGTH;
4113 BlockCreator newBlocks(
this);
4114 newBlocks.insertAtFront(numNewBlocks);
4116 DequePrimitives::insertAndMoveToFront(&this->d_start,
4118 this->d_start + posIdx,
4121 this->allocatorRef());
4127 size_type numNewBlocks = (this->d_finish.offsetInBlock() + numElements)
4129 BlockCreator newBlocks(
this);
4130 newBlocks.insertAtBack(numNewBlocks);
4132 DequePrimitives::insertAndMoveToBack(&this->d_finish,
4134 this->d_start + posIdx,
4137 this->allocatorRef());
4140 return this->
begin() + posIdx;
4143template <
class VALUE_TYPE,
class ALLOCATOR>
4144template <
class INPUT_ITERATOR>
4148 INPUT_ITERATOR first,
4149 INPUT_ITERATOR last)
4156 privateInsertDispatch(position,
4160 BloombergLP::bslmf::Nil());
4162 return this->
begin() + posIdx;
4165#if defined(BSLS_COMPILERFEATURES_SUPPORT_GENERALIZED_INITIALIZERS)
4166template <
class VALUE_TYPE,
class ALLOCATOR>
4170 const_iterator position,
4171 std::initializer_list<value_type> values)
4176 return insert(position, values.begin(), values.end());
4180template <
class VALUE_TYPE,
class ALLOCATOR>
4181template <
class t_RANGE>
4183typename deque<VALUE_TYPE, ALLOCATOR>::iterator
4189 privateInsert(position, ranges::begin(range), ranges::end(range));
4190 return this->
begin() + posIdx;
4193template <
class VALUE_TYPE,
class ALLOCATOR>
4202 return this->
begin();
4210 return erase(position, position + 1);
4213template <
class VALUE_TYPE,
class ALLOCATOR>
4232 this->allocatorRef()));
4236 for ( ; oldStart.imp().blockPtr() != this->d_start.blockPtr();
4237 oldStart.imp().nextBlock()) {
4238 this->deallocateBlock(oldStart.imp().blockPtr()[0]);
4240 for ( ; oldFinish.imp().blockPtr() != this->d_finish.blockPtr();
4241 oldFinish.imp().previousBlock()) {
4242 this->deallocateBlock(oldFinish.imp().blockPtr()[0]);
4247template <
class VALUE_TYPE,
class ALLOCATOR>
4250 AllocatorTraits::is_always_equal::value)
4253 AllocatorTraits::propagate_on_container_swap Propagate;
4254 if (Propagate::value) {
4256 static_cast<Base *
>(&other));
4257 AllocatorUtil::swap(&this->allocatorRef(), &other.allocatorRef(),
4262 this->get_allocator() == other.get_allocator())) {
4264 static_cast<Base *
>(&other));
4269 deque toOtherCopy(MoveUtil::move(*
this), other.get_allocator());
4270 deque toThisCopy( MoveUtil::move(other), this->get_allocator());
4273 static_cast<Base *
>(
this));
4275 static_cast<Base *
>(&other));
4280template <
class VALUE_TYPE,
class ALLOCATOR>
4283 DequePrimitives::destruct(this->d_start,
4285 this->allocatorRef());
4289 BlockPtr *startBlock = this->d_start.blockPtr();
4290 BlockPtr *finishBlock = this->d_finish.blockPtr();
4291 for ( ; startBlock != finishBlock; ++startBlock) {
4292 this->deallocateBlock(*startBlock);
4297 size_type blockOffset = this->d_blocksLength / 2;
4298 int offset = BLOCK_LENGTH / 2;
4299 BlockPtr *blockPtr = this->d_blocks_p + blockOffset;
4301 *blockPtr = *finishBlock;
4303 this->d_start = this->d_finish = IteratorImp(blockPtr,
4304 (*blockPtr)->d_data + offset);
4308template <
class VALUE_TYPE,
class ALLOCATOR>
4310typename deque<VALUE_TYPE, ALLOCATOR>::allocator_type
4313 return this->allocatorRef();
4316template <
class VALUE_TYPE,
class ALLOCATOR>
4321 return AllocatorTraits::max_size(this->get_allocator());