10b57cec5SDimitry Andric// -*- C++ -*-
281ad6265SDimitry Andric//===----------------------------------------------------------------------===//
381ad6265SDimitry Andric//
481ad6265SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
581ad6265SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
681ad6265SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
781ad6265SDimitry Andric//
881ad6265SDimitry Andric//===----------------------------------------------------------------------===//
90b57cec5SDimitry Andric
1081ad6265SDimitry Andric#ifndef _LIBCPP___SPLIT_BUFFER
1181ad6265SDimitry Andric#define _LIBCPP___SPLIT_BUFFER
1281ad6265SDimitry Andric
1381ad6265SDimitry Andric#include <__algorithm/max.h>
1481ad6265SDimitry Andric#include <__algorithm/move.h>
1581ad6265SDimitry Andric#include <__algorithm/move_backward.h>
160b57cec5SDimitry Andric#include <__config>
1781ad6265SDimitry Andric#include <__iterator/distance.h>
1881ad6265SDimitry Andric#include <__iterator/iterator_traits.h>
1981ad6265SDimitry Andric#include <__iterator/move_iterator.h>
20bdd1243dSDimitry Andric#include <__memory/allocate_at_least.h>
2181ad6265SDimitry Andric#include <__memory/allocator.h>
22bdd1243dSDimitry Andric#include <__memory/allocator_traits.h>
2381ad6265SDimitry Andric#include <__memory/compressed_pair.h>
24bdd1243dSDimitry Andric#include <__memory/pointer_traits.h>
25972a253aSDimitry Andric#include <__memory/swap_allocator.h>
26fe013be4SDimitry Andric#include <__type_traits/add_lvalue_reference.h>
27fe013be4SDimitry Andric#include <__type_traits/enable_if.h>
28fe013be4SDimitry Andric#include <__type_traits/integral_constant.h>
29fe013be4SDimitry Andric#include <__type_traits/is_nothrow_default_constructible.h>
30fe013be4SDimitry Andric#include <__type_traits/is_nothrow_move_assignable.h>
31fe013be4SDimitry Andric#include <__type_traits/is_nothrow_move_constructible.h>
32fe013be4SDimitry Andric#include <__type_traits/is_swappable.h>
33fe013be4SDimitry Andric#include <__type_traits/is_trivially_destructible.h>
34fe013be4SDimitry Andric#include <__type_traits/remove_reference.h>
35fe6060f1SDimitry Andric#include <__utility/forward.h>
36bdd1243dSDimitry Andric#include <__utility/move.h>
37fe013be4SDimitry Andric#include <cstddef>
380b57cec5SDimitry Andric
390b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
400b57cec5SDimitry Andric#  pragma GCC system_header
410b57cec5SDimitry Andric#endif
420b57cec5SDimitry Andric
430b57cec5SDimitry Andric_LIBCPP_PUSH_MACROS
440b57cec5SDimitry Andric#include <__undef_macros>
450b57cec5SDimitry Andric
460b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
470b57cec5SDimitry Andric
48bdd1243dSDimitry Andric// __split_buffer allocates a contiguous chunk of memory and stores objects in the range [__begin_, __end_).
49bdd1243dSDimitry Andric// It has uninitialized memory in the ranges  [__first_, __begin_) and [__end_, __end_cap_.first()). That allows
50bdd1243dSDimitry Andric// it to grow both in the front and back without having to move the data.
51bdd1243dSDimitry Andric
520b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator = allocator<_Tp> >
53*e710425bSDimitry Andricstruct __split_buffer {
540b57cec5SDimitry Andricpublic:
55fe013be4SDimitry Andric  using value_type      = _Tp;
56fe013be4SDimitry Andric  using allocator_type  = _Allocator;
57fe013be4SDimitry Andric  using __alloc_rr      = __libcpp_remove_reference_t<allocator_type>;
58fe013be4SDimitry Andric  using __alloc_traits  = allocator_traits<__alloc_rr>;
59fe013be4SDimitry Andric  using reference       = value_type&;
60fe013be4SDimitry Andric  using const_reference = const value_type&;
61fe013be4SDimitry Andric  using size_type       = typename __alloc_traits::size_type;
62fe013be4SDimitry Andric  using difference_type = typename __alloc_traits::difference_type;
63fe013be4SDimitry Andric  using pointer         = typename __alloc_traits::pointer;
64fe013be4SDimitry Andric  using const_pointer   = typename __alloc_traits::const_pointer;
65fe013be4SDimitry Andric  using iterator        = pointer;
66fe013be4SDimitry Andric  using const_iterator  = const_pointer;
670b57cec5SDimitry Andric
680b57cec5SDimitry Andric  pointer __first_;
690b57cec5SDimitry Andric  pointer __begin_;
700b57cec5SDimitry Andric  pointer __end_;
710b57cec5SDimitry Andric  __compressed_pair<pointer, allocator_type> __end_cap_;
720b57cec5SDimitry Andric
73fe013be4SDimitry Andric  using __alloc_ref       = __add_lvalue_reference_t<allocator_type>;
74fe013be4SDimitry Andric  using __alloc_const_ref = __add_lvalue_reference_t<allocator_type>;
750b57cec5SDimitry Andric
76fe013be4SDimitry Andric  __split_buffer(const __split_buffer&)            = delete;
77fe013be4SDimitry Andric  __split_buffer& operator=(const __split_buffer&) = delete;
78fe013be4SDimitry Andric
79fe013be4SDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer()
80fe013be4SDimitry Andric      _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
81fe013be4SDimitry Andric      : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __default_init_tag()) {}
82fe013be4SDimitry Andric
83fe013be4SDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit __split_buffer(__alloc_rr& __a)
84fe013be4SDimitry Andric      : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a) {}
85fe013be4SDimitry Andric
86fe013be4SDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit __split_buffer(const __alloc_rr& __a)
87fe013be4SDimitry Andric      : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a) {}
880b57cec5SDimitry Andric
89bdd1243dSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
90fe013be4SDimitry Andric  __split_buffer(size_type __cap, size_type __start, __alloc_rr& __a);
910b57cec5SDimitry Andric
92bdd1243dSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer(__split_buffer&& __c)
930b57cec5SDimitry Andric      _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
94fe013be4SDimitry Andric
95bdd1243dSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer(__split_buffer&& __c, const __alloc_rr& __a);
96fe013be4SDimitry Andric
97bdd1243dSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer& operator=(__split_buffer&& __c)
980b57cec5SDimitry Andric      _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value &&
990b57cec5SDimitry Andric                  is_nothrow_move_assignable<allocator_type>::value) ||
1000b57cec5SDimitry Andric                 !__alloc_traits::propagate_on_container_move_assignment::value);
1010b57cec5SDimitry Andric
102fe013be4SDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~__split_buffer();
103fe013be4SDimitry Andric
104fe013be4SDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __alloc_rr& __alloc() _NOEXCEPT { return __end_cap_.second(); }
105fe013be4SDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const __alloc_rr& __alloc() const _NOEXCEPT {
106fe013be4SDimitry Andric    return __end_cap_.second();
107fe013be4SDimitry Andric  }
108fe013be4SDimitry Andric
109fe013be4SDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer& __end_cap() _NOEXCEPT { return __end_cap_.first(); }
110fe013be4SDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const pointer& __end_cap() const _NOEXCEPT {
111fe013be4SDimitry Andric    return __end_cap_.first();
112fe013be4SDimitry Andric  }
113fe013be4SDimitry Andric
114bdd1243dSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __begin_; }
115bdd1243dSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __begin_; }
116fe013be4SDimitry Andric
117bdd1243dSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __end_; }
118bdd1243dSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __end_; }
1190b57cec5SDimitry Andric
120fe013be4SDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { __destruct_at_end(__begin_); }
121fe013be4SDimitry Andric
122fe013be4SDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type size() const {
123fe013be4SDimitry Andric    return static_cast<size_type>(__end_ - __begin_);
124fe013be4SDimitry Andric  }
125fe013be4SDimitry Andric
126bdd1243dSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool empty() const { return __end_ == __begin_; }
127fe013be4SDimitry Andric
128fe013be4SDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type capacity() const {
129fe013be4SDimitry Andric    return static_cast<size_type>(__end_cap() - __first_);
130fe013be4SDimitry Andric  }
131fe013be4SDimitry Andric
132fe013be4SDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __front_spare() const {
133fe013be4SDimitry Andric    return static_cast<size_type>(__begin_ - __first_);
134fe013be4SDimitry Andric  }
135fe013be4SDimitry Andric
136fe013be4SDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __back_spare() const {
137fe013be4SDimitry Andric    return static_cast<size_type>(__end_cap() - __end_);
138fe013be4SDimitry Andric  }
1390b57cec5SDimitry Andric
140bdd1243dSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference front() { return *__begin_; }
141bdd1243dSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference front() const { return *__begin_; }
142bdd1243dSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference back() { return *(__end_ - 1); }
143bdd1243dSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back() const { return *(__end_ - 1); }
1440b57cec5SDimitry Andric
145bdd1243dSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void reserve(size_type __n);
146bdd1243dSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void shrink_to_fit() _NOEXCEPT;
147bdd1243dSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_front(const_reference __x);
148bdd1243dSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_back(const_reference __x);
149bdd1243dSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __x);
150bdd1243dSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __x);
151fe013be4SDimitry Andric
1520b57cec5SDimitry Andric  template <class... _Args>
153bdd1243dSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void emplace_back(_Args&&... __args);
1540b57cec5SDimitry Andric
155bdd1243dSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void pop_front() { __destruct_at_begin(__begin_ + 1); }
156bdd1243dSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void pop_back() { __destruct_at_end(__end_ - 1); }
1570b57cec5SDimitry Andric
158bdd1243dSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end(size_type __n);
159bdd1243dSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end(size_type __n, const_reference __x);
160fe013be4SDimitry Andric
161c9157d92SDimitry Andric  template <class _InputIter, __enable_if_t<__has_exactly_input_iterator_category<_InputIter>::value, int> = 0>
162*e710425bSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end(_InputIter __first, _InputIter __last);
163fe013be4SDimitry Andric
164c9157d92SDimitry Andric  template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>
165*e710425bSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
166*e710425bSDimitry Andric  __construct_at_end(_ForwardIterator __first, _ForwardIterator __last);
1670b57cec5SDimitry Andric
168fe013be4SDimitry Andric  template <class _Iterator, class _Sentinel>
169*e710425bSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
170*e710425bSDimitry Andric  __construct_at_end_with_sentinel(_Iterator __first, _Sentinel __last);
1710b57cec5SDimitry Andric
172fe013be4SDimitry Andric  template <class _Iterator>
173*e710425bSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
174*e710425bSDimitry Andric  __construct_at_end_with_size(_Iterator __first, size_type __n);
175fe013be4SDimitry Andric
176fe013be4SDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_begin(pointer __new_begin) {
177fe013be4SDimitry Andric    __destruct_at_begin(__new_begin, is_trivially_destructible<value_type>());
178fe013be4SDimitry Andric  }
179fe013be4SDimitry Andric
180fe013be4SDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_begin(pointer __new_begin, false_type);
181fe013be4SDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_begin(pointer __new_begin, true_type);
182fe013be4SDimitry Andric
183fe013be4SDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_end(pointer __new_last) _NOEXCEPT {
184fe013be4SDimitry Andric    __destruct_at_end(__new_last, false_type());
185fe013be4SDimitry Andric  }
186fe013be4SDimitry Andric
187fe013be4SDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_end(pointer __new_last, false_type) _NOEXCEPT;
188fe013be4SDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_end(pointer __new_last, true_type) _NOEXCEPT;
1890b57cec5SDimitry Andric
190bdd1243dSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void swap(__split_buffer& __x)
191fe013be4SDimitry Andric      _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<__alloc_rr>::value);
1920b57cec5SDimitry Andric
193bdd1243dSDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const;
1940b57cec5SDimitry Andric
1950b57cec5SDimitry Andricprivate:
196fe013be4SDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__split_buffer& __c, true_type)
197fe013be4SDimitry Andric      _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) {
198c9157d92SDimitry Andric    __alloc() = std::move(__c.__alloc());
1990b57cec5SDimitry Andric  }
2000b57cec5SDimitry Andric
201fe013be4SDimitry Andric  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__split_buffer&, false_type) _NOEXCEPT {}
202e40139ffSDimitry Andric
203e40139ffSDimitry Andric  struct _ConstructTransaction {
204fe013be4SDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit _ConstructTransaction(
205fe013be4SDimitry Andric        pointer* __p, size_type __n) _NOEXCEPT
206fe013be4SDimitry Andric        : __pos_(*__p),
207fe013be4SDimitry Andric          __end_(*__p + __n),
208fe013be4SDimitry Andric          __dest_(__p) {}
209fe013be4SDimitry Andric
210fe013be4SDimitry Andric    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction() { *__dest_ = __pos_; }
211fe013be4SDimitry Andric
212e40139ffSDimitry Andric    pointer __pos_;
213e40139ffSDimitry Andric    const pointer __end_;
214fe013be4SDimitry Andric
215e40139ffSDimitry Andric  private:
216e40139ffSDimitry Andric    pointer* __dest_;
217e40139ffSDimitry Andric  };
2180b57cec5SDimitry Andric};
2190b57cec5SDimitry Andric
2200b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
221*e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 bool __split_buffer<_Tp, _Allocator>::__invariants() const {
222*e710425bSDimitry Andric  if (__first_ == nullptr) {
2230b57cec5SDimitry Andric    if (__begin_ != nullptr)
2240b57cec5SDimitry Andric      return false;
2250b57cec5SDimitry Andric    if (__end_ != nullptr)
2260b57cec5SDimitry Andric      return false;
2270b57cec5SDimitry Andric    if (__end_cap() != nullptr)
2280b57cec5SDimitry Andric      return false;
229*e710425bSDimitry Andric  } else {
2300b57cec5SDimitry Andric    if (__begin_ < __first_)
2310b57cec5SDimitry Andric      return false;
2320b57cec5SDimitry Andric    if (__end_ < __begin_)
2330b57cec5SDimitry Andric      return false;
2340b57cec5SDimitry Andric    if (__end_cap() < __end_)
2350b57cec5SDimitry Andric      return false;
2360b57cec5SDimitry Andric  }
2370b57cec5SDimitry Andric  return true;
2380b57cec5SDimitry Andric}
2390b57cec5SDimitry Andric
2400b57cec5SDimitry Andric//  Default constructs __n objects starting at __end_
2410b57cec5SDimitry Andric//  throws if construction throws
2420b57cec5SDimitry Andric//  Precondition:  __n > 0
2430b57cec5SDimitry Andric//  Precondition:  size() + __n <= capacity()
2440b57cec5SDimitry Andric//  Postcondition:  size() == size() + __n
2450b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
246*e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n) {
247e40139ffSDimitry Andric  _ConstructTransaction __tx(&this->__end_, __n);
248e40139ffSDimitry Andric  for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) {
249c9157d92SDimitry Andric    __alloc_traits::construct(this->__alloc(), std::__to_address(__tx.__pos_));
250e40139ffSDimitry Andric  }
2510b57cec5SDimitry Andric}
2520b57cec5SDimitry Andric
2530b57cec5SDimitry Andric//  Copy constructs __n objects starting at __end_ from __x
2540b57cec5SDimitry Andric//  throws if construction throws
2550b57cec5SDimitry Andric//  Precondition:  __n > 0
2560b57cec5SDimitry Andric//  Precondition:  size() + __n <= capacity()
2570b57cec5SDimitry Andric//  Postcondition:  size() == old size() + __n
2580b57cec5SDimitry Andric//  Postcondition:  [i] == __x for all i in [size() - __n, __n)
2590b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
260*e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void
261*e710425bSDimitry Andric__split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x) {
262e40139ffSDimitry Andric  _ConstructTransaction __tx(&this->__end_, __n);
263e40139ffSDimitry Andric  for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) {
264*e710425bSDimitry Andric    __alloc_traits::construct(this->__alloc(), std::__to_address(__tx.__pos_), __x);
265e40139ffSDimitry Andric  }
2660b57cec5SDimitry Andric}
2670b57cec5SDimitry Andric
2680b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
269c9157d92SDimitry Andrictemplate <class _InputIter, __enable_if_t<__has_exactly_input_iterator_category<_InputIter>::value, int> >
270*e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void
271*e710425bSDimitry Andric__split_buffer<_Tp, _Allocator>::__construct_at_end(_InputIter __first, _InputIter __last) {
272fe013be4SDimitry Andric  __construct_at_end_with_sentinel(__first, __last);
273fe013be4SDimitry Andric}
274fe013be4SDimitry Andric
275fe013be4SDimitry Andrictemplate <class _Tp, class _Allocator>
276fe013be4SDimitry Andrictemplate <class _Iterator, class _Sentinel>
277*e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void
278*e710425bSDimitry Andric__split_buffer<_Tp, _Allocator>::__construct_at_end_with_sentinel(_Iterator __first, _Sentinel __last) {
2790b57cec5SDimitry Andric  __alloc_rr& __a = this->__alloc();
280*e710425bSDimitry Andric  for (; __first != __last; ++__first) {
281*e710425bSDimitry Andric    if (__end_ == __end_cap()) {
2820b57cec5SDimitry Andric      size_type __old_cap = __end_cap() - __first_;
283c9157d92SDimitry Andric      size_type __new_cap = std::max<size_type>(2 * __old_cap, 8);
2840b57cec5SDimitry Andric      __split_buffer __buf(__new_cap, 0, __a);
285349cc55cSDimitry Andric      for (pointer __p = __begin_; __p != __end_; ++__p, (void)++__buf.__end_)
286*e710425bSDimitry Andric        __alloc_traits::construct(__buf.__alloc(), std::__to_address(__buf.__end_), std::move(*__p));
2870b57cec5SDimitry Andric      swap(__buf);
2880b57cec5SDimitry Andric    }
289c9157d92SDimitry Andric    __alloc_traits::construct(__a, std::__to_address(this->__end_), *__first);
2900b57cec5SDimitry Andric    ++this->__end_;
2910b57cec5SDimitry Andric  }
2920b57cec5SDimitry Andric}
293fe013be4SDimitry Andrictemplate <class _Tp, class _Allocator>
294c9157d92SDimitry Andrictemplate <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> >
295*e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void
296*e710425bSDimitry Andric__split_buffer<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last) {
297fe013be4SDimitry Andric  __construct_at_end_with_size(__first, std::distance(__first, __last));
298fe013be4SDimitry Andric}
2990b57cec5SDimitry Andric
3000b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
3010b57cec5SDimitry Andrictemplate <class _ForwardIterator>
302*e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void
303*e710425bSDimitry Andric__split_buffer<_Tp, _Allocator>::__construct_at_end_with_size(_ForwardIterator __first, size_type __n) {
304fe013be4SDimitry Andric  _ConstructTransaction __tx(&this->__end_, __n);
305349cc55cSDimitry Andric  for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, (void)++__first) {
306*e710425bSDimitry Andric    __alloc_traits::construct(this->__alloc(), std::__to_address(__tx.__pos_), *__first);
3070b57cec5SDimitry Andric  }
3080b57cec5SDimitry Andric}
3090b57cec5SDimitry Andric
3100b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
311*e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 inline void
312*e710425bSDimitry Andric__split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, false_type) {
3130b57cec5SDimitry Andric  while (__begin_ != __new_begin)
314c9157d92SDimitry Andric    __alloc_traits::destroy(__alloc(), std::__to_address(__begin_++));
3150b57cec5SDimitry Andric}
3160b57cec5SDimitry Andric
3170b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
318*e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 inline void
319*e710425bSDimitry Andric__split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, true_type) {
3200b57cec5SDimitry Andric  __begin_ = __new_begin;
3210b57cec5SDimitry Andric}
3220b57cec5SDimitry Andric
3230b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
324*e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI void
325*e710425bSDimitry Andric__split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, false_type) _NOEXCEPT {
3260b57cec5SDimitry Andric  while (__new_last != __end_)
327c9157d92SDimitry Andric    __alloc_traits::destroy(__alloc(), std::__to_address(--__end_));
3280b57cec5SDimitry Andric}
3290b57cec5SDimitry Andric
3300b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
331*e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI void
332*e710425bSDimitry Andric__split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, true_type) _NOEXCEPT {
3330b57cec5SDimitry Andric  __end_ = __new_last;
3340b57cec5SDimitry Andric}
3350b57cec5SDimitry Andric
3360b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
337bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
3380b57cec5SDimitry Andric__split_buffer<_Tp, _Allocator>::__split_buffer(size_type __cap, size_type __start, __alloc_rr& __a)
339*e710425bSDimitry Andric    : __end_cap_(nullptr, __a) {
34081ad6265SDimitry Andric  if (__cap == 0) {
34181ad6265SDimitry Andric    __first_ = nullptr;
34281ad6265SDimitry Andric  } else {
34381ad6265SDimitry Andric    auto __allocation = std::__allocate_at_least(__alloc(), __cap);
34481ad6265SDimitry Andric    __first_          = __allocation.ptr;
34581ad6265SDimitry Andric    __cap             = __allocation.count;
34681ad6265SDimitry Andric  }
3470b57cec5SDimitry Andric  __begin_ = __end_ = __first_ + __start;
3480b57cec5SDimitry Andric  __end_cap()       = __first_ + __cap;
3490b57cec5SDimitry Andric}
3500b57cec5SDimitry Andric
3510b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
352*e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 __split_buffer<_Tp, _Allocator>::~__split_buffer() {
3530b57cec5SDimitry Andric  clear();
3540b57cec5SDimitry Andric  if (__first_)
3550b57cec5SDimitry Andric    __alloc_traits::deallocate(__alloc(), __first_, capacity());
3560b57cec5SDimitry Andric}
3570b57cec5SDimitry Andric
3580b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
359*e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 __split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c)
3600b57cec5SDimitry Andric    _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
361c9157d92SDimitry Andric    : __first_(std::move(__c.__first_)),
362c9157d92SDimitry Andric      __begin_(std::move(__c.__begin_)),
363c9157d92SDimitry Andric      __end_(std::move(__c.__end_)),
364*e710425bSDimitry Andric      __end_cap_(std::move(__c.__end_cap_)) {
3650b57cec5SDimitry Andric  __c.__first_    = nullptr;
3660b57cec5SDimitry Andric  __c.__begin_    = nullptr;
3670b57cec5SDimitry Andric  __c.__end_      = nullptr;
3680b57cec5SDimitry Andric  __c.__end_cap() = nullptr;
3690b57cec5SDimitry Andric}
3700b57cec5SDimitry Andric
3710b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
372bdd1243dSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20
3730b57cec5SDimitry Andric__split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c, const __alloc_rr& __a)
374*e710425bSDimitry Andric    : __end_cap_(nullptr, __a) {
375*e710425bSDimitry Andric  if (__a == __c.__alloc()) {
3760b57cec5SDimitry Andric    __first_        = __c.__first_;
3770b57cec5SDimitry Andric    __begin_        = __c.__begin_;
3780b57cec5SDimitry Andric    __end_          = __c.__end_;
3790b57cec5SDimitry Andric    __end_cap()     = __c.__end_cap();
3800b57cec5SDimitry Andric    __c.__first_    = nullptr;
3810b57cec5SDimitry Andric    __c.__begin_    = nullptr;
3820b57cec5SDimitry Andric    __c.__end_      = nullptr;
3830b57cec5SDimitry Andric    __c.__end_cap() = nullptr;
384*e710425bSDimitry Andric  } else {
38581ad6265SDimitry Andric    auto __allocation = std::__allocate_at_least(__alloc(), __c.size());
38681ad6265SDimitry Andric    __first_          = __allocation.ptr;
3870b57cec5SDimitry Andric    __begin_ = __end_ = __first_;
38881ad6265SDimitry Andric    __end_cap()       = __first_ + __allocation.count;
3890b57cec5SDimitry Andric    typedef move_iterator<iterator> _Ip;
3900b57cec5SDimitry Andric    __construct_at_end(_Ip(__c.begin()), _Ip(__c.end()));
3910b57cec5SDimitry Andric  }
3920b57cec5SDimitry Andric}
3930b57cec5SDimitry Andric
3940b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
395*e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 __split_buffer<_Tp, _Allocator>&
3960b57cec5SDimitry Andric__split_buffer<_Tp, _Allocator>::operator=(__split_buffer&& __c)
3970b57cec5SDimitry Andric    _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value &&
3980b57cec5SDimitry Andric                is_nothrow_move_assignable<allocator_type>::value) ||
399*e710425bSDimitry Andric               !__alloc_traits::propagate_on_container_move_assignment::value) {
4000b57cec5SDimitry Andric  clear();
4010b57cec5SDimitry Andric  shrink_to_fit();
4020b57cec5SDimitry Andric  __first_    = __c.__first_;
4030b57cec5SDimitry Andric  __begin_    = __c.__begin_;
4040b57cec5SDimitry Andric  __end_      = __c.__end_;
4050b57cec5SDimitry Andric  __end_cap() = __c.__end_cap();
406*e710425bSDimitry Andric  __move_assign_alloc(__c, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>());
4070b57cec5SDimitry Andric  __c.__first_ = __c.__begin_ = __c.__end_ = __c.__end_cap() = nullptr;
4080b57cec5SDimitry Andric  return *this;
4090b57cec5SDimitry Andric}
4100b57cec5SDimitry Andric
4110b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
412*e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::swap(__split_buffer& __x)
413*e710425bSDimitry Andric    _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable<__alloc_rr>::value) {
414c9157d92SDimitry Andric  std::swap(__first_, __x.__first_);
415c9157d92SDimitry Andric  std::swap(__begin_, __x.__begin_);
416c9157d92SDimitry Andric  std::swap(__end_, __x.__end_);
417c9157d92SDimitry Andric  std::swap(__end_cap(), __x.__end_cap());
418c9157d92SDimitry Andric  std::__swap_allocator(__alloc(), __x.__alloc());
4190b57cec5SDimitry Andric}
4200b57cec5SDimitry Andric
4210b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
422*e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::reserve(size_type __n) {
423*e710425bSDimitry Andric  if (__n < capacity()) {
4240b57cec5SDimitry Andric    __split_buffer<value_type, __alloc_rr&> __t(__n, 0, __alloc());
425*e710425bSDimitry Andric    __t.__construct_at_end(move_iterator<pointer>(__begin_), move_iterator<pointer>(__end_));
426c9157d92SDimitry Andric    std::swap(__first_, __t.__first_);
427c9157d92SDimitry Andric    std::swap(__begin_, __t.__begin_);
428c9157d92SDimitry Andric    std::swap(__end_, __t.__end_);
429c9157d92SDimitry Andric    std::swap(__end_cap(), __t.__end_cap());
4300b57cec5SDimitry Andric  }
4310b57cec5SDimitry Andric}
4320b57cec5SDimitry Andric
4330b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
434*e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT {
435*e710425bSDimitry Andric  if (capacity() > size()) {
436fe013be4SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
437*e710425bSDimitry Andric    try {
438fe013be4SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
4390b57cec5SDimitry Andric      __split_buffer<value_type, __alloc_rr&> __t(size(), 0, __alloc());
440*e710425bSDimitry Andric      __t.__construct_at_end(move_iterator<pointer>(__begin_), move_iterator<pointer>(__end_));
4410b57cec5SDimitry Andric      __t.__end_ = __t.__begin_ + (__end_ - __begin_);
442c9157d92SDimitry Andric      std::swap(__first_, __t.__first_);
443c9157d92SDimitry Andric      std::swap(__begin_, __t.__begin_);
444c9157d92SDimitry Andric      std::swap(__end_, __t.__end_);
445c9157d92SDimitry Andric      std::swap(__end_cap(), __t.__end_cap());
446fe013be4SDimitry Andric#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
447*e710425bSDimitry Andric    } catch (...) {
4480b57cec5SDimitry Andric    }
449fe013be4SDimitry Andric#endif // _LIBCPP_HAS_NO_EXCEPTIONS
4500b57cec5SDimitry Andric  }
4510b57cec5SDimitry Andric}
4520b57cec5SDimitry Andric
4530b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
454*e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::push_front(const_reference __x) {
455*e710425bSDimitry Andric  if (__begin_ == __first_) {
456*e710425bSDimitry Andric    if (__end_ < __end_cap()) {
4570b57cec5SDimitry Andric      difference_type __d = __end_cap() - __end_;
4580b57cec5SDimitry Andric      __d                 = (__d + 1) / 2;
459c9157d92SDimitry Andric      __begin_            = std::move_backward(__begin_, __end_, __end_ + __d);
4600b57cec5SDimitry Andric      __end_ += __d;
461*e710425bSDimitry Andric    } else {
462bdd1243dSDimitry Andric      size_type __c = std::max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
4630b57cec5SDimitry Andric      __split_buffer<value_type, __alloc_rr&> __t(__c, (__c + 3) / 4, __alloc());
464*e710425bSDimitry Andric      __t.__construct_at_end(move_iterator<pointer>(__begin_), move_iterator<pointer>(__end_));
465c9157d92SDimitry Andric      std::swap(__first_, __t.__first_);
466c9157d92SDimitry Andric      std::swap(__begin_, __t.__begin_);
467c9157d92SDimitry Andric      std::swap(__end_, __t.__end_);
468c9157d92SDimitry Andric      std::swap(__end_cap(), __t.__end_cap());
4690b57cec5SDimitry Andric    }
4700b57cec5SDimitry Andric  }
471c9157d92SDimitry Andric  __alloc_traits::construct(__alloc(), std::__to_address(__begin_ - 1), __x);
4720b57cec5SDimitry Andric  --__begin_;
4730b57cec5SDimitry Andric}
4740b57cec5SDimitry Andric
4750b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
476*e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::push_front(value_type&& __x) {
477*e710425bSDimitry Andric  if (__begin_ == __first_) {
478*e710425bSDimitry Andric    if (__end_ < __end_cap()) {
4790b57cec5SDimitry Andric      difference_type __d = __end_cap() - __end_;
4800b57cec5SDimitry Andric      __d                 = (__d + 1) / 2;
481c9157d92SDimitry Andric      __begin_            = std::move_backward(__begin_, __end_, __end_ + __d);
4820b57cec5SDimitry Andric      __end_ += __d;
483*e710425bSDimitry Andric    } else {
484bdd1243dSDimitry Andric      size_type __c = std::max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
4850b57cec5SDimitry Andric      __split_buffer<value_type, __alloc_rr&> __t(__c, (__c + 3) / 4, __alloc());
486*e710425bSDimitry Andric      __t.__construct_at_end(move_iterator<pointer>(__begin_), move_iterator<pointer>(__end_));
487c9157d92SDimitry Andric      std::swap(__first_, __t.__first_);
488c9157d92SDimitry Andric      std::swap(__begin_, __t.__begin_);
489c9157d92SDimitry Andric      std::swap(__end_, __t.__end_);
490c9157d92SDimitry Andric      std::swap(__end_cap(), __t.__end_cap());
4910b57cec5SDimitry Andric    }
4920b57cec5SDimitry Andric  }
493*e710425bSDimitry Andric  __alloc_traits::construct(__alloc(), std::__to_address(__begin_ - 1), std::move(__x));
4940b57cec5SDimitry Andric  --__begin_;
4950b57cec5SDimitry Andric}
4960b57cec5SDimitry Andric
4970b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
498*e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI void
499*e710425bSDimitry Andric__split_buffer<_Tp, _Allocator>::push_back(const_reference __x) {
500*e710425bSDimitry Andric  if (__end_ == __end_cap()) {
501*e710425bSDimitry Andric    if (__begin_ > __first_) {
5020b57cec5SDimitry Andric      difference_type __d = __begin_ - __first_;
5030b57cec5SDimitry Andric      __d                 = (__d + 1) / 2;
504c9157d92SDimitry Andric      __end_              = std::move(__begin_, __end_, __begin_ - __d);
5050b57cec5SDimitry Andric      __begin_ -= __d;
506*e710425bSDimitry Andric    } else {
507bdd1243dSDimitry Andric      size_type __c = std::max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
5080b57cec5SDimitry Andric      __split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc());
509*e710425bSDimitry Andric      __t.__construct_at_end(move_iterator<pointer>(__begin_), move_iterator<pointer>(__end_));
510c9157d92SDimitry Andric      std::swap(__first_, __t.__first_);
511c9157d92SDimitry Andric      std::swap(__begin_, __t.__begin_);
512c9157d92SDimitry Andric      std::swap(__end_, __t.__end_);
513c9157d92SDimitry Andric      std::swap(__end_cap(), __t.__end_cap());
5140b57cec5SDimitry Andric    }
5150b57cec5SDimitry Andric  }
516c9157d92SDimitry Andric  __alloc_traits::construct(__alloc(), std::__to_address(__end_), __x);
5170b57cec5SDimitry Andric  ++__end_;
5180b57cec5SDimitry Andric}
5190b57cec5SDimitry Andric
5200b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
521*e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::push_back(value_type&& __x) {
522*e710425bSDimitry Andric  if (__end_ == __end_cap()) {
523*e710425bSDimitry Andric    if (__begin_ > __first_) {
5240b57cec5SDimitry Andric      difference_type __d = __begin_ - __first_;
5250b57cec5SDimitry Andric      __d                 = (__d + 1) / 2;
526c9157d92SDimitry Andric      __end_              = std::move(__begin_, __end_, __begin_ - __d);
5270b57cec5SDimitry Andric      __begin_ -= __d;
528*e710425bSDimitry Andric    } else {
529bdd1243dSDimitry Andric      size_type __c = std::max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
5300b57cec5SDimitry Andric      __split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc());
531*e710425bSDimitry Andric      __t.__construct_at_end(move_iterator<pointer>(__begin_), move_iterator<pointer>(__end_));
532c9157d92SDimitry Andric      std::swap(__first_, __t.__first_);
533c9157d92SDimitry Andric      std::swap(__begin_, __t.__begin_);
534c9157d92SDimitry Andric      std::swap(__end_, __t.__end_);
535c9157d92SDimitry Andric      std::swap(__end_cap(), __t.__end_cap());
5360b57cec5SDimitry Andric    }
5370b57cec5SDimitry Andric  }
538*e710425bSDimitry Andric  __alloc_traits::construct(__alloc(), std::__to_address(__end_), std::move(__x));
5390b57cec5SDimitry Andric  ++__end_;
5400b57cec5SDimitry Andric}
5410b57cec5SDimitry Andric
5420b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
5430b57cec5SDimitry Andrictemplate <class... _Args>
544*e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::emplace_back(_Args&&... __args) {
545*e710425bSDimitry Andric  if (__end_ == __end_cap()) {
546*e710425bSDimitry Andric    if (__begin_ > __first_) {
5470b57cec5SDimitry Andric      difference_type __d = __begin_ - __first_;
5480b57cec5SDimitry Andric      __d                 = (__d + 1) / 2;
549c9157d92SDimitry Andric      __end_              = std::move(__begin_, __end_, __begin_ - __d);
5500b57cec5SDimitry Andric      __begin_ -= __d;
551*e710425bSDimitry Andric    } else {
552bdd1243dSDimitry Andric      size_type __c = std::max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
5530b57cec5SDimitry Andric      __split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc());
554*e710425bSDimitry Andric      __t.__construct_at_end(move_iterator<pointer>(__begin_), move_iterator<pointer>(__end_));
555c9157d92SDimitry Andric      std::swap(__first_, __t.__first_);
556c9157d92SDimitry Andric      std::swap(__begin_, __t.__begin_);
557c9157d92SDimitry Andric      std::swap(__end_, __t.__end_);
558c9157d92SDimitry Andric      std::swap(__end_cap(), __t.__end_cap());
5590b57cec5SDimitry Andric    }
5600b57cec5SDimitry Andric  }
561*e710425bSDimitry Andric  __alloc_traits::construct(__alloc(), std::__to_address(__end_), std::forward<_Args>(__args)...);
5620b57cec5SDimitry Andric  ++__end_;
5630b57cec5SDimitry Andric}
5640b57cec5SDimitry Andric
5650b57cec5SDimitry Andrictemplate <class _Tp, class _Allocator>
566*e710425bSDimitry Andric_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI void
567*e710425bSDimitry Andricswap(__split_buffer<_Tp, _Allocator>& __x, __split_buffer<_Tp, _Allocator>& __y) _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
5680b57cec5SDimitry Andric  __x.swap(__y);
5690b57cec5SDimitry Andric}
5700b57cec5SDimitry Andric
5710b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
5720b57cec5SDimitry Andric
5730b57cec5SDimitry Andric_LIBCPP_POP_MACROS
5740b57cec5SDimitry Andric
57581ad6265SDimitry Andric#endif // _LIBCPP___SPLIT_BUFFER
576