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