xref: /llvm-project/libcxx/include/__cxx03/__split_buffer (revision ce7771902dc50d900de639d499a60486b83f70e0)
1e78f53d1SNikolas Klauser// -*- C++ -*-
2e78f53d1SNikolas Klauser//===----------------------------------------------------------------------===//
3e78f53d1SNikolas Klauser//
4e78f53d1SNikolas Klauser// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5e78f53d1SNikolas Klauser// See https://llvm.org/LICENSE.txt for license information.
6e78f53d1SNikolas Klauser// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7e78f53d1SNikolas Klauser//
8e78f53d1SNikolas Klauser//===----------------------------------------------------------------------===//
9e78f53d1SNikolas Klauser
10*ce777190SNikolas Klauser#ifndef _LIBCPP___CXX03___SPLIT_BUFFER
11*ce777190SNikolas Klauser#define _LIBCPP___CXX03___SPLIT_BUFFER
12e78f53d1SNikolas Klauser
1373fbae83SNikolas Klauser#include <__cxx03/__algorithm/max.h>
1473fbae83SNikolas Klauser#include <__cxx03/__algorithm/move.h>
1573fbae83SNikolas Klauser#include <__cxx03/__algorithm/move_backward.h>
1673fbae83SNikolas Klauser#include <__cxx03/__config>
1773fbae83SNikolas Klauser#include <__cxx03/__iterator/distance.h>
1873fbae83SNikolas Klauser#include <__cxx03/__iterator/iterator_traits.h>
1973fbae83SNikolas Klauser#include <__cxx03/__iterator/move_iterator.h>
2073fbae83SNikolas Klauser#include <__cxx03/__memory/allocate_at_least.h>
2173fbae83SNikolas Klauser#include <__cxx03/__memory/allocator.h>
2273fbae83SNikolas Klauser#include <__cxx03/__memory/allocator_traits.h>
2373fbae83SNikolas Klauser#include <__cxx03/__memory/compressed_pair.h>
2473fbae83SNikolas Klauser#include <__cxx03/__memory/pointer_traits.h>
2573fbae83SNikolas Klauser#include <__cxx03/__memory/swap_allocator.h>
2673fbae83SNikolas Klauser#include <__cxx03/__type_traits/add_lvalue_reference.h>
2773fbae83SNikolas Klauser#include <__cxx03/__type_traits/conditional.h>
2873fbae83SNikolas Klauser#include <__cxx03/__type_traits/enable_if.h>
2973fbae83SNikolas Klauser#include <__cxx03/__type_traits/integral_constant.h>
3073fbae83SNikolas Klauser#include <__cxx03/__type_traits/is_nothrow_assignable.h>
3173fbae83SNikolas Klauser#include <__cxx03/__type_traits/is_nothrow_constructible.h>
3273fbae83SNikolas Klauser#include <__cxx03/__type_traits/is_swappable.h>
3373fbae83SNikolas Klauser#include <__cxx03/__type_traits/is_trivially_destructible.h>
3473fbae83SNikolas Klauser#include <__cxx03/__type_traits/is_trivially_relocatable.h>
3573fbae83SNikolas Klauser#include <__cxx03/__type_traits/remove_reference.h>
3673fbae83SNikolas Klauser#include <__cxx03/__utility/forward.h>
3773fbae83SNikolas Klauser#include <__cxx03/__utility/move.h>
3873fbae83SNikolas Klauser#include <__cxx03/cstddef>
39e78f53d1SNikolas Klauser
40e78f53d1SNikolas Klauser#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
41e78f53d1SNikolas Klauser#  pragma GCC system_header
42e78f53d1SNikolas Klauser#endif
43e78f53d1SNikolas Klauser
44e78f53d1SNikolas Klauser_LIBCPP_PUSH_MACROS
4573fbae83SNikolas Klauser#include <__cxx03/__undef_macros>
46e78f53d1SNikolas Klauser
47e78f53d1SNikolas Klauser_LIBCPP_BEGIN_NAMESPACE_STD
48e78f53d1SNikolas Klauser
49e78f53d1SNikolas Klauser// __split_buffer allocates a contiguous chunk of memory and stores objects in the range [__begin_, __end_).
50e78f53d1SNikolas Klauser// It has uninitialized memory in the ranges  [__first_, __begin_) and [__end_, __end_cap_.first()). That allows
51e78f53d1SNikolas Klauser// it to grow both in the front and back without having to move the data.
52e78f53d1SNikolas Klauser
53e78f53d1SNikolas Klausertemplate <class _Tp, class _Allocator = allocator<_Tp> >
54e78f53d1SNikolas Klauserstruct __split_buffer {
55e78f53d1SNikolas Klauserpublic:
56e78f53d1SNikolas Klauser  using value_type      = _Tp;
57e78f53d1SNikolas Klauser  using allocator_type  = _Allocator;
58e78f53d1SNikolas Klauser  using __alloc_rr      = __libcpp_remove_reference_t<allocator_type>;
59e78f53d1SNikolas Klauser  using __alloc_traits  = allocator_traits<__alloc_rr>;
60e78f53d1SNikolas Klauser  using reference       = value_type&;
61e78f53d1SNikolas Klauser  using const_reference = const value_type&;
62e78f53d1SNikolas Klauser  using size_type       = typename __alloc_traits::size_type;
63e78f53d1SNikolas Klauser  using difference_type = typename __alloc_traits::difference_type;
64e78f53d1SNikolas Klauser  using pointer         = typename __alloc_traits::pointer;
65e78f53d1SNikolas Klauser  using const_pointer   = typename __alloc_traits::const_pointer;
66e78f53d1SNikolas Klauser  using iterator        = pointer;
67e78f53d1SNikolas Klauser  using const_iterator  = const_pointer;
68e78f53d1SNikolas Klauser
69e78f53d1SNikolas Klauser  // A __split_buffer contains the following members which may be trivially relocatable:
70e78f53d1SNikolas Klauser  // - pointer: may be trivially relocatable, so it's checked
71e78f53d1SNikolas Klauser  // - allocator_type: may be trivially relocatable, so it's checked
72e78f53d1SNikolas Klauser  // __split_buffer doesn't have any self-references, so it's trivially relocatable if its members are.
73e78f53d1SNikolas Klauser  using __trivially_relocatable = __conditional_t<
74e78f53d1SNikolas Klauser      __libcpp_is_trivially_relocatable<pointer>::value && __libcpp_is_trivially_relocatable<allocator_type>::value,
75e78f53d1SNikolas Klauser      __split_buffer,
76e78f53d1SNikolas Klauser      void>;
77e78f53d1SNikolas Klauser
78e78f53d1SNikolas Klauser  pointer __first_;
79e78f53d1SNikolas Klauser  pointer __begin_;
80e78f53d1SNikolas Klauser  pointer __end_;
81e78f53d1SNikolas Klauser  __compressed_pair<pointer, allocator_type> __end_cap_;
82e78f53d1SNikolas Klauser
83e78f53d1SNikolas Klauser  using __alloc_ref       = __add_lvalue_reference_t<allocator_type>;
84e78f53d1SNikolas Klauser  using __alloc_const_ref = __add_lvalue_reference_t<allocator_type>;
85e78f53d1SNikolas Klauser
86e78f53d1SNikolas Klauser  __split_buffer(const __split_buffer&)            = delete;
87e78f53d1SNikolas Klauser  __split_buffer& operator=(const __split_buffer&) = delete;
88e78f53d1SNikolas Klauser
89e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer()
90e78f53d1SNikolas Klauser      _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
91e78f53d1SNikolas Klauser      : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __default_init_tag()) {}
92e78f53d1SNikolas Klauser
93e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit __split_buffer(__alloc_rr& __a)
94e78f53d1SNikolas Klauser      : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a) {}
95e78f53d1SNikolas Klauser
96e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI explicit __split_buffer(const __alloc_rr& __a)
97e78f53d1SNikolas Klauser      : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a) {}
98e78f53d1SNikolas Klauser
99e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI
100e78f53d1SNikolas Klauser  __split_buffer(size_type __cap, size_type __start, __alloc_rr& __a);
101e78f53d1SNikolas Klauser
102e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer(__split_buffer&& __c)
103e78f53d1SNikolas Klauser      _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
104e78f53d1SNikolas Klauser
105e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer(__split_buffer&& __c, const __alloc_rr& __a);
106e78f53d1SNikolas Klauser
107e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __split_buffer& operator=(__split_buffer&& __c)
108e78f53d1SNikolas Klauser      _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value &&
109e78f53d1SNikolas Klauser                  is_nothrow_move_assignable<allocator_type>::value) ||
110e78f53d1SNikolas Klauser                 !__alloc_traits::propagate_on_container_move_assignment::value);
111e78f53d1SNikolas Klauser
112e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~__split_buffer();
113e78f53d1SNikolas Klauser
114e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI __alloc_rr& __alloc() _NOEXCEPT { return __end_cap_.second(); }
115e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const __alloc_rr& __alloc() const _NOEXCEPT {
116e78f53d1SNikolas Klauser    return __end_cap_.second();
117e78f53d1SNikolas Klauser  }
118e78f53d1SNikolas Klauser
119e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI pointer& __end_cap() _NOEXCEPT { return __end_cap_.first(); }
120e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const pointer& __end_cap() const _NOEXCEPT {
121e78f53d1SNikolas Klauser    return __end_cap_.first();
122e78f53d1SNikolas Klauser  }
123e78f53d1SNikolas Klauser
124e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator begin() _NOEXCEPT { return __begin_; }
125e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator begin() const _NOEXCEPT { return __begin_; }
126e78f53d1SNikolas Klauser
127e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI iterator end() _NOEXCEPT { return __end_; }
128e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_iterator end() const _NOEXCEPT { return __end_; }
129e78f53d1SNikolas Klauser
130e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void clear() _NOEXCEPT { __destruct_at_end(__begin_); }
131e78f53d1SNikolas Klauser
132e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type size() const {
133e78f53d1SNikolas Klauser    return static_cast<size_type>(__end_ - __begin_);
134e78f53d1SNikolas Klauser  }
135e78f53d1SNikolas Klauser
136e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool empty() const { return __end_ == __begin_; }
137e78f53d1SNikolas Klauser
138e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type capacity() const {
139e78f53d1SNikolas Klauser    return static_cast<size_type>(__end_cap() - __first_);
140e78f53d1SNikolas Klauser  }
141e78f53d1SNikolas Klauser
142e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __front_spare() const {
143e78f53d1SNikolas Klauser    return static_cast<size_type>(__begin_ - __first_);
144e78f53d1SNikolas Klauser  }
145e78f53d1SNikolas Klauser
146e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI size_type __back_spare() const {
147e78f53d1SNikolas Klauser    return static_cast<size_type>(__end_cap() - __end_);
148e78f53d1SNikolas Klauser  }
149e78f53d1SNikolas Klauser
150e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference front() { return *__begin_; }
151e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference front() const { return *__begin_; }
152e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI reference back() { return *(__end_ - 1); }
153e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI const_reference back() const { return *(__end_ - 1); }
154e78f53d1SNikolas Klauser
155e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void reserve(size_type __n);
156e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void shrink_to_fit() _NOEXCEPT;
157e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_front(const_reference __x);
158e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_back(const_reference __x);
159e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_front(value_type&& __x);
160e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void push_back(value_type&& __x);
161e78f53d1SNikolas Klauser
162e78f53d1SNikolas Klauser  template <class... _Args>
163e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void emplace_back(_Args&&... __args);
164e78f53d1SNikolas Klauser
165e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void pop_front() { __destruct_at_begin(__begin_ + 1); }
166e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void pop_back() { __destruct_at_end(__end_ - 1); }
167e78f53d1SNikolas Klauser
168e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end(size_type __n);
169e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end(size_type __n, const_reference __x);
170e78f53d1SNikolas Klauser
171e78f53d1SNikolas Klauser  template <class _InputIter, __enable_if_t<__has_exactly_input_iterator_category<_InputIter>::value, int> = 0>
172e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __construct_at_end(_InputIter __first, _InputIter __last);
173e78f53d1SNikolas Klauser
174e78f53d1SNikolas Klauser  template <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> = 0>
175e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
176e78f53d1SNikolas Klauser  __construct_at_end(_ForwardIterator __first, _ForwardIterator __last);
177e78f53d1SNikolas Klauser
178e78f53d1SNikolas Klauser  template <class _Iterator, class _Sentinel>
179e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
180e78f53d1SNikolas Klauser  __construct_at_end_with_sentinel(_Iterator __first, _Sentinel __last);
181e78f53d1SNikolas Klauser
182e78f53d1SNikolas Klauser  template <class _Iterator>
183e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void
184e78f53d1SNikolas Klauser  __construct_at_end_with_size(_Iterator __first, size_type __n);
185e78f53d1SNikolas Klauser
186e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_begin(pointer __new_begin) {
187e78f53d1SNikolas Klauser    __destruct_at_begin(__new_begin, is_trivially_destructible<value_type>());
188e78f53d1SNikolas Klauser  }
189e78f53d1SNikolas Klauser
190e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_begin(pointer __new_begin, false_type);
191e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_begin(pointer __new_begin, true_type);
192e78f53d1SNikolas Klauser
193e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_end(pointer __new_last) _NOEXCEPT {
194e78f53d1SNikolas Klauser    __destruct_at_end(__new_last, false_type());
195e78f53d1SNikolas Klauser  }
196e78f53d1SNikolas Klauser
197e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_end(pointer __new_last, false_type) _NOEXCEPT;
198e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __destruct_at_end(pointer __new_last, true_type) _NOEXCEPT;
199e78f53d1SNikolas Klauser
200e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void swap(__split_buffer& __x)
201e78f53d1SNikolas Klauser      _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__alloc_rr>);
202e78f53d1SNikolas Klauser
203e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI bool __invariants() const;
204e78f53d1SNikolas Klauser
205e78f53d1SNikolas Klauserprivate:
206e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__split_buffer& __c, true_type)
207e78f53d1SNikolas Klauser      _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) {
208e78f53d1SNikolas Klauser    __alloc() = std::move(__c.__alloc());
209e78f53d1SNikolas Klauser  }
210e78f53d1SNikolas Klauser
211e78f53d1SNikolas Klauser  _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI void __move_assign_alloc(__split_buffer&, false_type) _NOEXCEPT {}
212e78f53d1SNikolas Klauser
213e78f53d1SNikolas Klauser  struct _ConstructTransaction {
214e78f53d1SNikolas Klauser    _LIBCPP_CONSTEXPR_SINCE_CXX20
215e78f53d1SNikolas Klauser    _LIBCPP_HIDE_FROM_ABI explicit _ConstructTransaction(pointer* __p, size_type __n) _NOEXCEPT
216e78f53d1SNikolas Klauser        : __pos_(*__p),
217e78f53d1SNikolas Klauser          __end_(*__p + __n),
218e78f53d1SNikolas Klauser          __dest_(__p) {}
219e78f53d1SNikolas Klauser
220e78f53d1SNikolas Klauser    _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_HIDE_FROM_ABI ~_ConstructTransaction() { *__dest_ = __pos_; }
221e78f53d1SNikolas Klauser
222e78f53d1SNikolas Klauser    pointer __pos_;
223e78f53d1SNikolas Klauser    const pointer __end_;
224e78f53d1SNikolas Klauser
225e78f53d1SNikolas Klauser  private:
226e78f53d1SNikolas Klauser    pointer* __dest_;
227e78f53d1SNikolas Klauser  };
228e78f53d1SNikolas Klauser};
229e78f53d1SNikolas Klauser
230e78f53d1SNikolas Klausertemplate <class _Tp, class _Allocator>
231e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 bool __split_buffer<_Tp, _Allocator>::__invariants() const {
232e78f53d1SNikolas Klauser  if (__first_ == nullptr) {
233e78f53d1SNikolas Klauser    if (__begin_ != nullptr)
234e78f53d1SNikolas Klauser      return false;
235e78f53d1SNikolas Klauser    if (__end_ != nullptr)
236e78f53d1SNikolas Klauser      return false;
237e78f53d1SNikolas Klauser    if (__end_cap() != nullptr)
238e78f53d1SNikolas Klauser      return false;
239e78f53d1SNikolas Klauser  } else {
240e78f53d1SNikolas Klauser    if (__begin_ < __first_)
241e78f53d1SNikolas Klauser      return false;
242e78f53d1SNikolas Klauser    if (__end_ < __begin_)
243e78f53d1SNikolas Klauser      return false;
244e78f53d1SNikolas Klauser    if (__end_cap() < __end_)
245e78f53d1SNikolas Klauser      return false;
246e78f53d1SNikolas Klauser  }
247e78f53d1SNikolas Klauser  return true;
248e78f53d1SNikolas Klauser}
249e78f53d1SNikolas Klauser
250e78f53d1SNikolas Klauser//  Default constructs __n objects starting at __end_
251e78f53d1SNikolas Klauser//  throws if construction throws
252e78f53d1SNikolas Klauser//  Precondition:  __n > 0
253e78f53d1SNikolas Klauser//  Precondition:  size() + __n <= capacity()
254e78f53d1SNikolas Klauser//  Postcondition:  size() == size() + __n
255e78f53d1SNikolas Klausertemplate <class _Tp, class _Allocator>
256e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n) {
257e78f53d1SNikolas Klauser  _ConstructTransaction __tx(&this->__end_, __n);
258e78f53d1SNikolas Klauser  for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) {
259e78f53d1SNikolas Klauser    __alloc_traits::construct(this->__alloc(), std::__to_address(__tx.__pos_));
260e78f53d1SNikolas Klauser  }
261e78f53d1SNikolas Klauser}
262e78f53d1SNikolas Klauser
263e78f53d1SNikolas Klauser//  Copy constructs __n objects starting at __end_ from __x
264e78f53d1SNikolas Klauser//  throws if construction throws
265e78f53d1SNikolas Klauser//  Precondition:  __n > 0
266e78f53d1SNikolas Klauser//  Precondition:  size() + __n <= capacity()
267e78f53d1SNikolas Klauser//  Postcondition:  size() == old size() + __n
268e78f53d1SNikolas Klauser//  Postcondition:  [i] == __x for all i in [size() - __n, __n)
269e78f53d1SNikolas Klausertemplate <class _Tp, class _Allocator>
270e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 void
271e78f53d1SNikolas Klauser__split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x) {
272e78f53d1SNikolas Klauser  _ConstructTransaction __tx(&this->__end_, __n);
273e78f53d1SNikolas Klauser  for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) {
274e78f53d1SNikolas Klauser    __alloc_traits::construct(this->__alloc(), std::__to_address(__tx.__pos_), __x);
275e78f53d1SNikolas Klauser  }
276e78f53d1SNikolas Klauser}
277e78f53d1SNikolas Klauser
278e78f53d1SNikolas Klausertemplate <class _Tp, class _Allocator>
279e78f53d1SNikolas Klausertemplate <class _InputIter, __enable_if_t<__has_exactly_input_iterator_category<_InputIter>::value, int> >
280e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 void
281e78f53d1SNikolas Klauser__split_buffer<_Tp, _Allocator>::__construct_at_end(_InputIter __first, _InputIter __last) {
282e78f53d1SNikolas Klauser  __construct_at_end_with_sentinel(__first, __last);
283e78f53d1SNikolas Klauser}
284e78f53d1SNikolas Klauser
285e78f53d1SNikolas Klausertemplate <class _Tp, class _Allocator>
286e78f53d1SNikolas Klausertemplate <class _Iterator, class _Sentinel>
287e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 void
288e78f53d1SNikolas Klauser__split_buffer<_Tp, _Allocator>::__construct_at_end_with_sentinel(_Iterator __first, _Sentinel __last) {
289e78f53d1SNikolas Klauser  __alloc_rr& __a = this->__alloc();
290e78f53d1SNikolas Klauser  for (; __first != __last; ++__first) {
291e78f53d1SNikolas Klauser    if (__end_ == __end_cap()) {
292e78f53d1SNikolas Klauser      size_type __old_cap = __end_cap() - __first_;
293e78f53d1SNikolas Klauser      size_type __new_cap = std::max<size_type>(2 * __old_cap, 8);
294e78f53d1SNikolas Klauser      __split_buffer __buf(__new_cap, 0, __a);
295e78f53d1SNikolas Klauser      for (pointer __p = __begin_; __p != __end_; ++__p, (void)++__buf.__end_)
296e78f53d1SNikolas Klauser        __alloc_traits::construct(__buf.__alloc(), std::__to_address(__buf.__end_), std::move(*__p));
297e78f53d1SNikolas Klauser      swap(__buf);
298e78f53d1SNikolas Klauser    }
299e78f53d1SNikolas Klauser    __alloc_traits::construct(__a, std::__to_address(this->__end_), *__first);
300e78f53d1SNikolas Klauser    ++this->__end_;
301e78f53d1SNikolas Klauser  }
302e78f53d1SNikolas Klauser}
303e78f53d1SNikolas Klausertemplate <class _Tp, class _Allocator>
304e78f53d1SNikolas Klausertemplate <class _ForwardIterator, __enable_if_t<__has_forward_iterator_category<_ForwardIterator>::value, int> >
305e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 void
306e78f53d1SNikolas Klauser__split_buffer<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last) {
307e78f53d1SNikolas Klauser  __construct_at_end_with_size(__first, std::distance(__first, __last));
308e78f53d1SNikolas Klauser}
309e78f53d1SNikolas Klauser
310e78f53d1SNikolas Klausertemplate <class _Tp, class _Allocator>
311e78f53d1SNikolas Klausertemplate <class _ForwardIterator>
312e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 void
313e78f53d1SNikolas Klauser__split_buffer<_Tp, _Allocator>::__construct_at_end_with_size(_ForwardIterator __first, size_type __n) {
314e78f53d1SNikolas Klauser  _ConstructTransaction __tx(&this->__end_, __n);
315e78f53d1SNikolas Klauser  for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, (void)++__first) {
316e78f53d1SNikolas Klauser    __alloc_traits::construct(this->__alloc(), std::__to_address(__tx.__pos_), *__first);
317e78f53d1SNikolas Klauser  }
318e78f53d1SNikolas Klauser}
319e78f53d1SNikolas Klauser
320e78f53d1SNikolas Klausertemplate <class _Tp, class _Allocator>
321e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 inline void
322e78f53d1SNikolas Klauser__split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, false_type) {
323e78f53d1SNikolas Klauser  while (__begin_ != __new_begin)
324e78f53d1SNikolas Klauser    __alloc_traits::destroy(__alloc(), std::__to_address(__begin_++));
325e78f53d1SNikolas Klauser}
326e78f53d1SNikolas Klauser
327e78f53d1SNikolas Klausertemplate <class _Tp, class _Allocator>
328e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 inline void
329e78f53d1SNikolas Klauser__split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, true_type) {
330e78f53d1SNikolas Klauser  __begin_ = __new_begin;
331e78f53d1SNikolas Klauser}
332e78f53d1SNikolas Klauser
333e78f53d1SNikolas Klausertemplate <class _Tp, class _Allocator>
334e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI void
335e78f53d1SNikolas Klauser__split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, false_type) _NOEXCEPT {
336e78f53d1SNikolas Klauser  while (__new_last != __end_)
337e78f53d1SNikolas Klauser    __alloc_traits::destroy(__alloc(), std::__to_address(--__end_));
338e78f53d1SNikolas Klauser}
339e78f53d1SNikolas Klauser
340e78f53d1SNikolas Klausertemplate <class _Tp, class _Allocator>
341e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI void
342e78f53d1SNikolas Klauser__split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, true_type) _NOEXCEPT {
343e78f53d1SNikolas Klauser  __end_ = __new_last;
344e78f53d1SNikolas Klauser}
345e78f53d1SNikolas Klauser
346e78f53d1SNikolas Klausertemplate <class _Tp, class _Allocator>
347e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20
348e78f53d1SNikolas Klauser__split_buffer<_Tp, _Allocator>::__split_buffer(size_type __cap, size_type __start, __alloc_rr& __a)
349e78f53d1SNikolas Klauser    : __end_cap_(nullptr, __a) {
350e78f53d1SNikolas Klauser  if (__cap == 0) {
351e78f53d1SNikolas Klauser    __first_ = nullptr;
352e78f53d1SNikolas Klauser  } else {
353e78f53d1SNikolas Klauser    auto __allocation = std::__allocate_at_least(__alloc(), __cap);
354e78f53d1SNikolas Klauser    __first_          = __allocation.ptr;
355e78f53d1SNikolas Klauser    __cap             = __allocation.count;
356e78f53d1SNikolas Klauser  }
357e78f53d1SNikolas Klauser  __begin_ = __end_ = __first_ + __start;
358e78f53d1SNikolas Klauser  __end_cap()       = __first_ + __cap;
359e78f53d1SNikolas Klauser}
360e78f53d1SNikolas Klauser
361e78f53d1SNikolas Klausertemplate <class _Tp, class _Allocator>
362e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 __split_buffer<_Tp, _Allocator>::~__split_buffer() {
363e78f53d1SNikolas Klauser  clear();
364e78f53d1SNikolas Klauser  if (__first_)
365e78f53d1SNikolas Klauser    __alloc_traits::deallocate(__alloc(), __first_, capacity());
366e78f53d1SNikolas Klauser}
367e78f53d1SNikolas Klauser
368e78f53d1SNikolas Klausertemplate <class _Tp, class _Allocator>
369e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 __split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c)
370e78f53d1SNikolas Klauser    _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
371e78f53d1SNikolas Klauser    : __first_(std::move(__c.__first_)),
372e78f53d1SNikolas Klauser      __begin_(std::move(__c.__begin_)),
373e78f53d1SNikolas Klauser      __end_(std::move(__c.__end_)),
374e78f53d1SNikolas Klauser      __end_cap_(std::move(__c.__end_cap_)) {
375e78f53d1SNikolas Klauser  __c.__first_    = nullptr;
376e78f53d1SNikolas Klauser  __c.__begin_    = nullptr;
377e78f53d1SNikolas Klauser  __c.__end_      = nullptr;
378e78f53d1SNikolas Klauser  __c.__end_cap() = nullptr;
379e78f53d1SNikolas Klauser}
380e78f53d1SNikolas Klauser
381e78f53d1SNikolas Klausertemplate <class _Tp, class _Allocator>
382e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20
383e78f53d1SNikolas Klauser__split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c, const __alloc_rr& __a)
384e78f53d1SNikolas Klauser    : __end_cap_(nullptr, __a) {
385e78f53d1SNikolas Klauser  if (__a == __c.__alloc()) {
386e78f53d1SNikolas Klauser    __first_        = __c.__first_;
387e78f53d1SNikolas Klauser    __begin_        = __c.__begin_;
388e78f53d1SNikolas Klauser    __end_          = __c.__end_;
389e78f53d1SNikolas Klauser    __end_cap()     = __c.__end_cap();
390e78f53d1SNikolas Klauser    __c.__first_    = nullptr;
391e78f53d1SNikolas Klauser    __c.__begin_    = nullptr;
392e78f53d1SNikolas Klauser    __c.__end_      = nullptr;
393e78f53d1SNikolas Klauser    __c.__end_cap() = nullptr;
394e78f53d1SNikolas Klauser  } else {
395e78f53d1SNikolas Klauser    auto __allocation = std::__allocate_at_least(__alloc(), __c.size());
396e78f53d1SNikolas Klauser    __first_          = __allocation.ptr;
397e78f53d1SNikolas Klauser    __begin_ = __end_ = __first_;
398e78f53d1SNikolas Klauser    __end_cap()       = __first_ + __allocation.count;
399e78f53d1SNikolas Klauser    typedef move_iterator<iterator> _Ip;
400e78f53d1SNikolas Klauser    __construct_at_end(_Ip(__c.begin()), _Ip(__c.end()));
401e78f53d1SNikolas Klauser  }
402e78f53d1SNikolas Klauser}
403e78f53d1SNikolas Klauser
404e78f53d1SNikolas Klausertemplate <class _Tp, class _Allocator>
405e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 __split_buffer<_Tp, _Allocator>&
406e78f53d1SNikolas Klauser__split_buffer<_Tp, _Allocator>::operator=(__split_buffer&& __c)
407e78f53d1SNikolas Klauser    _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value &&
408e78f53d1SNikolas Klauser                is_nothrow_move_assignable<allocator_type>::value) ||
409e78f53d1SNikolas Klauser               !__alloc_traits::propagate_on_container_move_assignment::value) {
410e78f53d1SNikolas Klauser  clear();
411e78f53d1SNikolas Klauser  shrink_to_fit();
412e78f53d1SNikolas Klauser  __first_    = __c.__first_;
413e78f53d1SNikolas Klauser  __begin_    = __c.__begin_;
414e78f53d1SNikolas Klauser  __end_      = __c.__end_;
415e78f53d1SNikolas Klauser  __end_cap() = __c.__end_cap();
416e78f53d1SNikolas Klauser  __move_assign_alloc(__c, integral_constant<bool, __alloc_traits::propagate_on_container_move_assignment::value>());
417e78f53d1SNikolas Klauser  __c.__first_ = __c.__begin_ = __c.__end_ = __c.__end_cap() = nullptr;
418e78f53d1SNikolas Klauser  return *this;
419e78f53d1SNikolas Klauser}
420e78f53d1SNikolas Klauser
421e78f53d1SNikolas Klausertemplate <class _Tp, class _Allocator>
422e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::swap(__split_buffer& __x)
423e78f53d1SNikolas Klauser    _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable_v<__alloc_rr>) {
424e78f53d1SNikolas Klauser  std::swap(__first_, __x.__first_);
425e78f53d1SNikolas Klauser  std::swap(__begin_, __x.__begin_);
426e78f53d1SNikolas Klauser  std::swap(__end_, __x.__end_);
427e78f53d1SNikolas Klauser  std::swap(__end_cap(), __x.__end_cap());
428e78f53d1SNikolas Klauser  std::__swap_allocator(__alloc(), __x.__alloc());
429e78f53d1SNikolas Klauser}
430e78f53d1SNikolas Klauser
431e78f53d1SNikolas Klausertemplate <class _Tp, class _Allocator>
432e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::reserve(size_type __n) {
433e78f53d1SNikolas Klauser  if (__n < capacity()) {
434e78f53d1SNikolas Klauser    __split_buffer<value_type, __alloc_rr&> __t(__n, 0, __alloc());
435e78f53d1SNikolas Klauser    __t.__construct_at_end(move_iterator<pointer>(__begin_), move_iterator<pointer>(__end_));
436e78f53d1SNikolas Klauser    std::swap(__first_, __t.__first_);
437e78f53d1SNikolas Klauser    std::swap(__begin_, __t.__begin_);
438e78f53d1SNikolas Klauser    std::swap(__end_, __t.__end_);
439e78f53d1SNikolas Klauser    std::swap(__end_cap(), __t.__end_cap());
440e78f53d1SNikolas Klauser  }
441e78f53d1SNikolas Klauser}
442e78f53d1SNikolas Klauser
443e78f53d1SNikolas Klausertemplate <class _Tp, class _Allocator>
444e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT {
445e78f53d1SNikolas Klauser  if (capacity() > size()) {
446e78f53d1SNikolas Klauser#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
447e78f53d1SNikolas Klauser    try {
448e78f53d1SNikolas Klauser#endif // _LIBCPP_HAS_NO_EXCEPTIONS
449e78f53d1SNikolas Klauser      __split_buffer<value_type, __alloc_rr&> __t(size(), 0, __alloc());
450e78f53d1SNikolas Klauser      __t.__construct_at_end(move_iterator<pointer>(__begin_), move_iterator<pointer>(__end_));
451e78f53d1SNikolas Klauser      __t.__end_ = __t.__begin_ + (__end_ - __begin_);
452e78f53d1SNikolas Klauser      std::swap(__first_, __t.__first_);
453e78f53d1SNikolas Klauser      std::swap(__begin_, __t.__begin_);
454e78f53d1SNikolas Klauser      std::swap(__end_, __t.__end_);
455e78f53d1SNikolas Klauser      std::swap(__end_cap(), __t.__end_cap());
456e78f53d1SNikolas Klauser#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
457e78f53d1SNikolas Klauser    } catch (...) {
458e78f53d1SNikolas Klauser    }
459e78f53d1SNikolas Klauser#endif // _LIBCPP_HAS_NO_EXCEPTIONS
460e78f53d1SNikolas Klauser  }
461e78f53d1SNikolas Klauser}
462e78f53d1SNikolas Klauser
463e78f53d1SNikolas Klausertemplate <class _Tp, class _Allocator>
464e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::push_front(const_reference __x) {
465e78f53d1SNikolas Klauser  if (__begin_ == __first_) {
466e78f53d1SNikolas Klauser    if (__end_ < __end_cap()) {
467e78f53d1SNikolas Klauser      difference_type __d = __end_cap() - __end_;
468e78f53d1SNikolas Klauser      __d                 = (__d + 1) / 2;
469e78f53d1SNikolas Klauser      __begin_            = std::move_backward(__begin_, __end_, __end_ + __d);
470e78f53d1SNikolas Klauser      __end_ += __d;
471e78f53d1SNikolas Klauser    } else {
472e78f53d1SNikolas Klauser      size_type __c = std::max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
473e78f53d1SNikolas Klauser      __split_buffer<value_type, __alloc_rr&> __t(__c, (__c + 3) / 4, __alloc());
474e78f53d1SNikolas Klauser      __t.__construct_at_end(move_iterator<pointer>(__begin_), move_iterator<pointer>(__end_));
475e78f53d1SNikolas Klauser      std::swap(__first_, __t.__first_);
476e78f53d1SNikolas Klauser      std::swap(__begin_, __t.__begin_);
477e78f53d1SNikolas Klauser      std::swap(__end_, __t.__end_);
478e78f53d1SNikolas Klauser      std::swap(__end_cap(), __t.__end_cap());
479e78f53d1SNikolas Klauser    }
480e78f53d1SNikolas Klauser  }
481e78f53d1SNikolas Klauser  __alloc_traits::construct(__alloc(), std::__to_address(__begin_ - 1), __x);
482e78f53d1SNikolas Klauser  --__begin_;
483e78f53d1SNikolas Klauser}
484e78f53d1SNikolas Klauser
485e78f53d1SNikolas Klausertemplate <class _Tp, class _Allocator>
486e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::push_front(value_type&& __x) {
487e78f53d1SNikolas Klauser  if (__begin_ == __first_) {
488e78f53d1SNikolas Klauser    if (__end_ < __end_cap()) {
489e78f53d1SNikolas Klauser      difference_type __d = __end_cap() - __end_;
490e78f53d1SNikolas Klauser      __d                 = (__d + 1) / 2;
491e78f53d1SNikolas Klauser      __begin_            = std::move_backward(__begin_, __end_, __end_ + __d);
492e78f53d1SNikolas Klauser      __end_ += __d;
493e78f53d1SNikolas Klauser    } else {
494e78f53d1SNikolas Klauser      size_type __c = std::max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
495e78f53d1SNikolas Klauser      __split_buffer<value_type, __alloc_rr&> __t(__c, (__c + 3) / 4, __alloc());
496e78f53d1SNikolas Klauser      __t.__construct_at_end(move_iterator<pointer>(__begin_), move_iterator<pointer>(__end_));
497e78f53d1SNikolas Klauser      std::swap(__first_, __t.__first_);
498e78f53d1SNikolas Klauser      std::swap(__begin_, __t.__begin_);
499e78f53d1SNikolas Klauser      std::swap(__end_, __t.__end_);
500e78f53d1SNikolas Klauser      std::swap(__end_cap(), __t.__end_cap());
501e78f53d1SNikolas Klauser    }
502e78f53d1SNikolas Klauser  }
503e78f53d1SNikolas Klauser  __alloc_traits::construct(__alloc(), std::__to_address(__begin_ - 1), std::move(__x));
504e78f53d1SNikolas Klauser  --__begin_;
505e78f53d1SNikolas Klauser}
506e78f53d1SNikolas Klauser
507e78f53d1SNikolas Klausertemplate <class _Tp, class _Allocator>
508e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI void
509e78f53d1SNikolas Klauser__split_buffer<_Tp, _Allocator>::push_back(const_reference __x) {
510e78f53d1SNikolas Klauser  if (__end_ == __end_cap()) {
511e78f53d1SNikolas Klauser    if (__begin_ > __first_) {
512e78f53d1SNikolas Klauser      difference_type __d = __begin_ - __first_;
513e78f53d1SNikolas Klauser      __d                 = (__d + 1) / 2;
514e78f53d1SNikolas Klauser      __end_              = std::move(__begin_, __end_, __begin_ - __d);
515e78f53d1SNikolas Klauser      __begin_ -= __d;
516e78f53d1SNikolas Klauser    } else {
517e78f53d1SNikolas Klauser      size_type __c = std::max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
518e78f53d1SNikolas Klauser      __split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc());
519e78f53d1SNikolas Klauser      __t.__construct_at_end(move_iterator<pointer>(__begin_), move_iterator<pointer>(__end_));
520e78f53d1SNikolas Klauser      std::swap(__first_, __t.__first_);
521e78f53d1SNikolas Klauser      std::swap(__begin_, __t.__begin_);
522e78f53d1SNikolas Klauser      std::swap(__end_, __t.__end_);
523e78f53d1SNikolas Klauser      std::swap(__end_cap(), __t.__end_cap());
524e78f53d1SNikolas Klauser    }
525e78f53d1SNikolas Klauser  }
526e78f53d1SNikolas Klauser  __alloc_traits::construct(__alloc(), std::__to_address(__end_), __x);
527e78f53d1SNikolas Klauser  ++__end_;
528e78f53d1SNikolas Klauser}
529e78f53d1SNikolas Klauser
530e78f53d1SNikolas Klausertemplate <class _Tp, class _Allocator>
531e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::push_back(value_type&& __x) {
532e78f53d1SNikolas Klauser  if (__end_ == __end_cap()) {
533e78f53d1SNikolas Klauser    if (__begin_ > __first_) {
534e78f53d1SNikolas Klauser      difference_type __d = __begin_ - __first_;
535e78f53d1SNikolas Klauser      __d                 = (__d + 1) / 2;
536e78f53d1SNikolas Klauser      __end_              = std::move(__begin_, __end_, __begin_ - __d);
537e78f53d1SNikolas Klauser      __begin_ -= __d;
538e78f53d1SNikolas Klauser    } else {
539e78f53d1SNikolas Klauser      size_type __c = std::max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
540e78f53d1SNikolas Klauser      __split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc());
541e78f53d1SNikolas Klauser      __t.__construct_at_end(move_iterator<pointer>(__begin_), move_iterator<pointer>(__end_));
542e78f53d1SNikolas Klauser      std::swap(__first_, __t.__first_);
543e78f53d1SNikolas Klauser      std::swap(__begin_, __t.__begin_);
544e78f53d1SNikolas Klauser      std::swap(__end_, __t.__end_);
545e78f53d1SNikolas Klauser      std::swap(__end_cap(), __t.__end_cap());
546e78f53d1SNikolas Klauser    }
547e78f53d1SNikolas Klauser  }
548e78f53d1SNikolas Klauser  __alloc_traits::construct(__alloc(), std::__to_address(__end_), std::move(__x));
549e78f53d1SNikolas Klauser  ++__end_;
550e78f53d1SNikolas Klauser}
551e78f53d1SNikolas Klauser
552e78f53d1SNikolas Klausertemplate <class _Tp, class _Allocator>
553e78f53d1SNikolas Klausertemplate <class... _Args>
554e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 void __split_buffer<_Tp, _Allocator>::emplace_back(_Args&&... __args) {
555e78f53d1SNikolas Klauser  if (__end_ == __end_cap()) {
556e78f53d1SNikolas Klauser    if (__begin_ > __first_) {
557e78f53d1SNikolas Klauser      difference_type __d = __begin_ - __first_;
558e78f53d1SNikolas Klauser      __d                 = (__d + 1) / 2;
559e78f53d1SNikolas Klauser      __end_              = std::move(__begin_, __end_, __begin_ - __d);
560e78f53d1SNikolas Klauser      __begin_ -= __d;
561e78f53d1SNikolas Klauser    } else {
562e78f53d1SNikolas Klauser      size_type __c = std::max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
563e78f53d1SNikolas Klauser      __split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc());
564e78f53d1SNikolas Klauser      __t.__construct_at_end(move_iterator<pointer>(__begin_), move_iterator<pointer>(__end_));
565e78f53d1SNikolas Klauser      std::swap(__first_, __t.__first_);
566e78f53d1SNikolas Klauser      std::swap(__begin_, __t.__begin_);
567e78f53d1SNikolas Klauser      std::swap(__end_, __t.__end_);
568e78f53d1SNikolas Klauser      std::swap(__end_cap(), __t.__end_cap());
569e78f53d1SNikolas Klauser    }
570e78f53d1SNikolas Klauser  }
571e78f53d1SNikolas Klauser  __alloc_traits::construct(__alloc(), std::__to_address(__end_), std::forward<_Args>(__args)...);
572e78f53d1SNikolas Klauser  ++__end_;
573e78f53d1SNikolas Klauser}
574e78f53d1SNikolas Klauser
575e78f53d1SNikolas Klausertemplate <class _Tp, class _Allocator>
576e78f53d1SNikolas Klauser_LIBCPP_CONSTEXPR_SINCE_CXX20 inline _LIBCPP_HIDE_FROM_ABI void
577e78f53d1SNikolas Klauserswap(__split_buffer<_Tp, _Allocator>& __x, __split_buffer<_Tp, _Allocator>& __y) _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) {
578e78f53d1SNikolas Klauser  __x.swap(__y);
579e78f53d1SNikolas Klauser}
580e78f53d1SNikolas Klauser
581e78f53d1SNikolas Klauser_LIBCPP_END_NAMESPACE_STD
582e78f53d1SNikolas Klauser
583e78f53d1SNikolas Klauser_LIBCPP_POP_MACROS
584e78f53d1SNikolas Klauser
585*ce777190SNikolas Klauser#endif // _LIBCPP___CXX03___SPLIT_BUFFER
586