1*4d6fc14bSjoerg// -*- C++ -*- 2*4d6fc14bSjoerg#ifndef _LIBCPP_SPLIT_BUFFER 3*4d6fc14bSjoerg#define _LIBCPP_SPLIT_BUFFER 4*4d6fc14bSjoerg 5*4d6fc14bSjoerg#include <__config> 6*4d6fc14bSjoerg#include <type_traits> 7*4d6fc14bSjoerg#include <algorithm> 8*4d6fc14bSjoerg 9*4d6fc14bSjoerg#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 10*4d6fc14bSjoerg#pragma GCC system_header 11*4d6fc14bSjoerg#endif 12*4d6fc14bSjoerg 13*4d6fc14bSjoerg_LIBCPP_PUSH_MACROS 14*4d6fc14bSjoerg#include <__undef_macros> 15*4d6fc14bSjoerg 16*4d6fc14bSjoerg 17*4d6fc14bSjoerg_LIBCPP_BEGIN_NAMESPACE_STD 18*4d6fc14bSjoerg 19*4d6fc14bSjoergtemplate <bool> 20*4d6fc14bSjoergclass __split_buffer_common 21*4d6fc14bSjoerg{ 22*4d6fc14bSjoergprotected: 23*4d6fc14bSjoerg _LIBCPP_NORETURN void __throw_length_error() const; 24*4d6fc14bSjoerg _LIBCPP_NORETURN void __throw_out_of_range() const; 25*4d6fc14bSjoerg}; 26*4d6fc14bSjoerg 27*4d6fc14bSjoergtemplate <class _Tp, class _Allocator = allocator<_Tp> > 28*4d6fc14bSjoergstruct __split_buffer 29*4d6fc14bSjoerg : private __split_buffer_common<true> 30*4d6fc14bSjoerg{ 31*4d6fc14bSjoergprivate: 32*4d6fc14bSjoerg __split_buffer(const __split_buffer&); 33*4d6fc14bSjoerg __split_buffer& operator=(const __split_buffer&); 34*4d6fc14bSjoergpublic: 35*4d6fc14bSjoerg typedef _Tp value_type; 36*4d6fc14bSjoerg typedef _Allocator allocator_type; 37*4d6fc14bSjoerg typedef typename remove_reference<allocator_type>::type __alloc_rr; 38*4d6fc14bSjoerg typedef allocator_traits<__alloc_rr> __alloc_traits; 39*4d6fc14bSjoerg typedef value_type& reference; 40*4d6fc14bSjoerg typedef const value_type& const_reference; 41*4d6fc14bSjoerg typedef typename __alloc_traits::size_type size_type; 42*4d6fc14bSjoerg typedef typename __alloc_traits::difference_type difference_type; 43*4d6fc14bSjoerg typedef typename __alloc_traits::pointer pointer; 44*4d6fc14bSjoerg typedef typename __alloc_traits::const_pointer const_pointer; 45*4d6fc14bSjoerg typedef pointer iterator; 46*4d6fc14bSjoerg typedef const_pointer const_iterator; 47*4d6fc14bSjoerg 48*4d6fc14bSjoerg pointer __first_; 49*4d6fc14bSjoerg pointer __begin_; 50*4d6fc14bSjoerg pointer __end_; 51*4d6fc14bSjoerg __compressed_pair<pointer, allocator_type> __end_cap_; 52*4d6fc14bSjoerg 53*4d6fc14bSjoerg typedef typename add_lvalue_reference<allocator_type>::type __alloc_ref; 54*4d6fc14bSjoerg typedef typename add_lvalue_reference<allocator_type>::type __alloc_const_ref; 55*4d6fc14bSjoerg 56*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY __alloc_rr& __alloc() _NOEXCEPT {return __end_cap_.second();} 57*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY const __alloc_rr& __alloc() const _NOEXCEPT {return __end_cap_.second();} 58*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY pointer& __end_cap() _NOEXCEPT {return __end_cap_.first();} 59*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY const pointer& __end_cap() const _NOEXCEPT {return __end_cap_.first();} 60*4d6fc14bSjoerg 61*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 62*4d6fc14bSjoerg __split_buffer() 63*4d6fc14bSjoerg _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value); 64*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 65*4d6fc14bSjoerg explicit __split_buffer(__alloc_rr& __a); 66*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 67*4d6fc14bSjoerg explicit __split_buffer(const __alloc_rr& __a); 68*4d6fc14bSjoerg __split_buffer(size_type __cap, size_type __start, __alloc_rr& __a); 69*4d6fc14bSjoerg ~__split_buffer(); 70*4d6fc14bSjoerg 71*4d6fc14bSjoerg __split_buffer(__split_buffer&& __c) 72*4d6fc14bSjoerg _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value); 73*4d6fc14bSjoerg __split_buffer(__split_buffer&& __c, const __alloc_rr& __a); 74*4d6fc14bSjoerg __split_buffer& operator=(__split_buffer&& __c) 75*4d6fc14bSjoerg _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value && 76*4d6fc14bSjoerg is_nothrow_move_assignable<allocator_type>::value) || 77*4d6fc14bSjoerg !__alloc_traits::propagate_on_container_move_assignment::value); 78*4d6fc14bSjoerg 79*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY iterator begin() _NOEXCEPT {return __begin_;} 80*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY const_iterator begin() const _NOEXCEPT {return __begin_;} 81*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY iterator end() _NOEXCEPT {return __end_;} 82*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY const_iterator end() const _NOEXCEPT {return __end_;} 83*4d6fc14bSjoerg 84*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 85*4d6fc14bSjoerg void clear() _NOEXCEPT 86*4d6fc14bSjoerg {__destruct_at_end(__begin_);} 87*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY size_type size() const {return static_cast<size_type>(__end_ - __begin_);} 88*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY bool empty() const {return __end_ == __begin_;} 89*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY size_type capacity() const {return static_cast<size_type>(__end_cap() - __first_);} 90*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY size_type __front_spare() const {return static_cast<size_type>(__begin_ - __first_);} 91*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY size_type __back_spare() const {return static_cast<size_type>(__end_cap() - __end_);} 92*4d6fc14bSjoerg 93*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY reference front() {return *__begin_;} 94*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY const_reference front() const {return *__begin_;} 95*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY reference back() {return *(__end_ - 1);} 96*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY const_reference back() const {return *(__end_ - 1);} 97*4d6fc14bSjoerg 98*4d6fc14bSjoerg void reserve(size_type __n); 99*4d6fc14bSjoerg void shrink_to_fit() _NOEXCEPT; 100*4d6fc14bSjoerg void push_front(const_reference __x); 101*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY void push_back(const_reference __x); 102*4d6fc14bSjoerg void push_front(value_type&& __x); 103*4d6fc14bSjoerg void push_back(value_type&& __x); 104*4d6fc14bSjoerg template <class... _Args> 105*4d6fc14bSjoerg void emplace_back(_Args&&... __args); 106*4d6fc14bSjoerg 107*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY void pop_front() {__destruct_at_begin(__begin_+1);} 108*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY void pop_back() {__destruct_at_end(__end_-1);} 109*4d6fc14bSjoerg 110*4d6fc14bSjoerg void __construct_at_end(size_type __n); 111*4d6fc14bSjoerg void __construct_at_end(size_type __n, const_reference __x); 112*4d6fc14bSjoerg template <class _InputIter> 113*4d6fc14bSjoerg typename enable_if 114*4d6fc14bSjoerg < 115*4d6fc14bSjoerg __is_cpp17_input_iterator<_InputIter>::value && 116*4d6fc14bSjoerg !__is_cpp17_forward_iterator<_InputIter>::value, 117*4d6fc14bSjoerg void 118*4d6fc14bSjoerg >::type 119*4d6fc14bSjoerg __construct_at_end(_InputIter __first, _InputIter __last); 120*4d6fc14bSjoerg template <class _ForwardIterator> 121*4d6fc14bSjoerg typename enable_if 122*4d6fc14bSjoerg < 123*4d6fc14bSjoerg __is_cpp17_forward_iterator<_ForwardIterator>::value, 124*4d6fc14bSjoerg void 125*4d6fc14bSjoerg >::type 126*4d6fc14bSjoerg __construct_at_end(_ForwardIterator __first, _ForwardIterator __last); 127*4d6fc14bSjoerg 128*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY void __destruct_at_begin(pointer __new_begin) 129*4d6fc14bSjoerg {__destruct_at_begin(__new_begin, is_trivially_destructible<value_type>());} 130*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 131*4d6fc14bSjoerg void __destruct_at_begin(pointer __new_begin, false_type); 132*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 133*4d6fc14bSjoerg void __destruct_at_begin(pointer __new_begin, true_type); 134*4d6fc14bSjoerg 135*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 136*4d6fc14bSjoerg void __destruct_at_end(pointer __new_last) _NOEXCEPT 137*4d6fc14bSjoerg {__destruct_at_end(__new_last, false_type());} 138*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 139*4d6fc14bSjoerg void __destruct_at_end(pointer __new_last, false_type) _NOEXCEPT; 140*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 141*4d6fc14bSjoerg void __destruct_at_end(pointer __new_last, true_type) _NOEXCEPT; 142*4d6fc14bSjoerg 143*4d6fc14bSjoerg void swap(__split_buffer& __x) 144*4d6fc14bSjoerg _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value|| 145*4d6fc14bSjoerg __is_nothrow_swappable<__alloc_rr>::value); 146*4d6fc14bSjoerg 147*4d6fc14bSjoerg bool __invariants() const; 148*4d6fc14bSjoerg 149*4d6fc14bSjoergprivate: 150*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 151*4d6fc14bSjoerg void __move_assign_alloc(__split_buffer& __c, true_type) 152*4d6fc14bSjoerg _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) 153*4d6fc14bSjoerg { 154*4d6fc14bSjoerg __alloc() = _VSTD::move(__c.__alloc()); 155*4d6fc14bSjoerg } 156*4d6fc14bSjoerg 157*4d6fc14bSjoerg _LIBCPP_INLINE_VISIBILITY 158*4d6fc14bSjoerg void __move_assign_alloc(__split_buffer&, false_type) _NOEXCEPT 159*4d6fc14bSjoerg {} 160*4d6fc14bSjoerg 161*4d6fc14bSjoerg struct _ConstructTransaction { 162*4d6fc14bSjoerg explicit _ConstructTransaction(pointer* __p, size_type __n) _NOEXCEPT 163*4d6fc14bSjoerg : __pos_(*__p), __end_(*__p + __n), __dest_(__p) { 164*4d6fc14bSjoerg } 165*4d6fc14bSjoerg ~_ConstructTransaction() { 166*4d6fc14bSjoerg *__dest_ = __pos_; 167*4d6fc14bSjoerg } 168*4d6fc14bSjoerg pointer __pos_; 169*4d6fc14bSjoerg const pointer __end_; 170*4d6fc14bSjoerg private: 171*4d6fc14bSjoerg pointer *__dest_; 172*4d6fc14bSjoerg }; 173*4d6fc14bSjoerg}; 174*4d6fc14bSjoerg 175*4d6fc14bSjoergtemplate <class _Tp, class _Allocator> 176*4d6fc14bSjoergbool 177*4d6fc14bSjoerg__split_buffer<_Tp, _Allocator>::__invariants() const 178*4d6fc14bSjoerg{ 179*4d6fc14bSjoerg if (__first_ == nullptr) 180*4d6fc14bSjoerg { 181*4d6fc14bSjoerg if (__begin_ != nullptr) 182*4d6fc14bSjoerg return false; 183*4d6fc14bSjoerg if (__end_ != nullptr) 184*4d6fc14bSjoerg return false; 185*4d6fc14bSjoerg if (__end_cap() != nullptr) 186*4d6fc14bSjoerg return false; 187*4d6fc14bSjoerg } 188*4d6fc14bSjoerg else 189*4d6fc14bSjoerg { 190*4d6fc14bSjoerg if (__begin_ < __first_) 191*4d6fc14bSjoerg return false; 192*4d6fc14bSjoerg if (__end_ < __begin_) 193*4d6fc14bSjoerg return false; 194*4d6fc14bSjoerg if (__end_cap() < __end_) 195*4d6fc14bSjoerg return false; 196*4d6fc14bSjoerg } 197*4d6fc14bSjoerg return true; 198*4d6fc14bSjoerg} 199*4d6fc14bSjoerg 200*4d6fc14bSjoerg// Default constructs __n objects starting at __end_ 201*4d6fc14bSjoerg// throws if construction throws 202*4d6fc14bSjoerg// Precondition: __n > 0 203*4d6fc14bSjoerg// Precondition: size() + __n <= capacity() 204*4d6fc14bSjoerg// Postcondition: size() == size() + __n 205*4d6fc14bSjoergtemplate <class _Tp, class _Allocator> 206*4d6fc14bSjoergvoid 207*4d6fc14bSjoerg__split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n) 208*4d6fc14bSjoerg{ 209*4d6fc14bSjoerg _ConstructTransaction __tx(&this->__end_, __n); 210*4d6fc14bSjoerg for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { 211*4d6fc14bSjoerg __alloc_traits::construct(this->__alloc(), _VSTD::__to_address(__tx.__pos_)); 212*4d6fc14bSjoerg } 213*4d6fc14bSjoerg} 214*4d6fc14bSjoerg 215*4d6fc14bSjoerg// Copy constructs __n objects starting at __end_ from __x 216*4d6fc14bSjoerg// throws if construction throws 217*4d6fc14bSjoerg// Precondition: __n > 0 218*4d6fc14bSjoerg// Precondition: size() + __n <= capacity() 219*4d6fc14bSjoerg// Postcondition: size() == old size() + __n 220*4d6fc14bSjoerg// Postcondition: [i] == __x for all i in [size() - __n, __n) 221*4d6fc14bSjoergtemplate <class _Tp, class _Allocator> 222*4d6fc14bSjoergvoid 223*4d6fc14bSjoerg__split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x) 224*4d6fc14bSjoerg{ 225*4d6fc14bSjoerg _ConstructTransaction __tx(&this->__end_, __n); 226*4d6fc14bSjoerg for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_) { 227*4d6fc14bSjoerg __alloc_traits::construct(this->__alloc(), 228*4d6fc14bSjoerg _VSTD::__to_address(__tx.__pos_), __x); 229*4d6fc14bSjoerg } 230*4d6fc14bSjoerg} 231*4d6fc14bSjoerg 232*4d6fc14bSjoergtemplate <class _Tp, class _Allocator> 233*4d6fc14bSjoergtemplate <class _InputIter> 234*4d6fc14bSjoergtypename enable_if 235*4d6fc14bSjoerg< 236*4d6fc14bSjoerg __is_cpp17_input_iterator<_InputIter>::value && 237*4d6fc14bSjoerg !__is_cpp17_forward_iterator<_InputIter>::value, 238*4d6fc14bSjoerg void 239*4d6fc14bSjoerg>::type 240*4d6fc14bSjoerg__split_buffer<_Tp, _Allocator>::__construct_at_end(_InputIter __first, _InputIter __last) 241*4d6fc14bSjoerg{ 242*4d6fc14bSjoerg __alloc_rr& __a = this->__alloc(); 243*4d6fc14bSjoerg for (; __first != __last; ++__first) 244*4d6fc14bSjoerg { 245*4d6fc14bSjoerg if (__end_ == __end_cap()) 246*4d6fc14bSjoerg { 247*4d6fc14bSjoerg size_type __old_cap = __end_cap() - __first_; 248*4d6fc14bSjoerg size_type __new_cap = _VSTD::max<size_type>(2 * __old_cap, 8); 249*4d6fc14bSjoerg __split_buffer __buf(__new_cap, 0, __a); 250*4d6fc14bSjoerg for (pointer __p = __begin_; __p != __end_; ++__p, ++__buf.__end_) 251*4d6fc14bSjoerg __alloc_traits::construct(__buf.__alloc(), 252*4d6fc14bSjoerg _VSTD::__to_address(__buf.__end_), _VSTD::move(*__p)); 253*4d6fc14bSjoerg swap(__buf); 254*4d6fc14bSjoerg } 255*4d6fc14bSjoerg __alloc_traits::construct(__a, _VSTD::__to_address(this->__end_), *__first); 256*4d6fc14bSjoerg ++this->__end_; 257*4d6fc14bSjoerg } 258*4d6fc14bSjoerg} 259*4d6fc14bSjoerg 260*4d6fc14bSjoergtemplate <class _Tp, class _Allocator> 261*4d6fc14bSjoergtemplate <class _ForwardIterator> 262*4d6fc14bSjoergtypename enable_if 263*4d6fc14bSjoerg< 264*4d6fc14bSjoerg __is_cpp17_forward_iterator<_ForwardIterator>::value, 265*4d6fc14bSjoerg void 266*4d6fc14bSjoerg>::type 267*4d6fc14bSjoerg__split_buffer<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last) 268*4d6fc14bSjoerg{ 269*4d6fc14bSjoerg _ConstructTransaction __tx(&this->__end_, _VSTD::distance(__first, __last)); 270*4d6fc14bSjoerg for (; __tx.__pos_ != __tx.__end_; ++__tx.__pos_, ++__first) { 271*4d6fc14bSjoerg __alloc_traits::construct(this->__alloc(), 272*4d6fc14bSjoerg _VSTD::__to_address(__tx.__pos_), *__first); 273*4d6fc14bSjoerg } 274*4d6fc14bSjoerg} 275*4d6fc14bSjoerg 276*4d6fc14bSjoergtemplate <class _Tp, class _Allocator> 277*4d6fc14bSjoerginline 278*4d6fc14bSjoergvoid 279*4d6fc14bSjoerg__split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, false_type) 280*4d6fc14bSjoerg{ 281*4d6fc14bSjoerg while (__begin_ != __new_begin) 282*4d6fc14bSjoerg __alloc_traits::destroy(__alloc(), _VSTD::__to_address(__begin_++)); 283*4d6fc14bSjoerg} 284*4d6fc14bSjoerg 285*4d6fc14bSjoergtemplate <class _Tp, class _Allocator> 286*4d6fc14bSjoerginline 287*4d6fc14bSjoergvoid 288*4d6fc14bSjoerg__split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, true_type) 289*4d6fc14bSjoerg{ 290*4d6fc14bSjoerg __begin_ = __new_begin; 291*4d6fc14bSjoerg} 292*4d6fc14bSjoerg 293*4d6fc14bSjoergtemplate <class _Tp, class _Allocator> 294*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 295*4d6fc14bSjoergvoid 296*4d6fc14bSjoerg__split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, false_type) _NOEXCEPT 297*4d6fc14bSjoerg{ 298*4d6fc14bSjoerg while (__new_last != __end_) 299*4d6fc14bSjoerg __alloc_traits::destroy(__alloc(), _VSTD::__to_address(--__end_)); 300*4d6fc14bSjoerg} 301*4d6fc14bSjoerg 302*4d6fc14bSjoergtemplate <class _Tp, class _Allocator> 303*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 304*4d6fc14bSjoergvoid 305*4d6fc14bSjoerg__split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, true_type) _NOEXCEPT 306*4d6fc14bSjoerg{ 307*4d6fc14bSjoerg __end_ = __new_last; 308*4d6fc14bSjoerg} 309*4d6fc14bSjoerg 310*4d6fc14bSjoergtemplate <class _Tp, class _Allocator> 311*4d6fc14bSjoerg__split_buffer<_Tp, _Allocator>::__split_buffer(size_type __cap, size_type __start, __alloc_rr& __a) 312*4d6fc14bSjoerg : __end_cap_(nullptr, __a) 313*4d6fc14bSjoerg{ 314*4d6fc14bSjoerg __first_ = __cap != 0 ? __alloc_traits::allocate(__alloc(), __cap) : nullptr; 315*4d6fc14bSjoerg __begin_ = __end_ = __first_ + __start; 316*4d6fc14bSjoerg __end_cap() = __first_ + __cap; 317*4d6fc14bSjoerg} 318*4d6fc14bSjoerg 319*4d6fc14bSjoergtemplate <class _Tp, class _Allocator> 320*4d6fc14bSjoerginline 321*4d6fc14bSjoerg__split_buffer<_Tp, _Allocator>::__split_buffer() 322*4d6fc14bSjoerg _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) 323*4d6fc14bSjoerg : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __default_init_tag()) 324*4d6fc14bSjoerg{ 325*4d6fc14bSjoerg} 326*4d6fc14bSjoerg 327*4d6fc14bSjoergtemplate <class _Tp, class _Allocator> 328*4d6fc14bSjoerginline 329*4d6fc14bSjoerg__split_buffer<_Tp, _Allocator>::__split_buffer(__alloc_rr& __a) 330*4d6fc14bSjoerg : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a) 331*4d6fc14bSjoerg{ 332*4d6fc14bSjoerg} 333*4d6fc14bSjoerg 334*4d6fc14bSjoergtemplate <class _Tp, class _Allocator> 335*4d6fc14bSjoerginline 336*4d6fc14bSjoerg__split_buffer<_Tp, _Allocator>::__split_buffer(const __alloc_rr& __a) 337*4d6fc14bSjoerg : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a) 338*4d6fc14bSjoerg{ 339*4d6fc14bSjoerg} 340*4d6fc14bSjoerg 341*4d6fc14bSjoergtemplate <class _Tp, class _Allocator> 342*4d6fc14bSjoerg__split_buffer<_Tp, _Allocator>::~__split_buffer() 343*4d6fc14bSjoerg{ 344*4d6fc14bSjoerg clear(); 345*4d6fc14bSjoerg if (__first_) 346*4d6fc14bSjoerg __alloc_traits::deallocate(__alloc(), __first_, capacity()); 347*4d6fc14bSjoerg} 348*4d6fc14bSjoerg 349*4d6fc14bSjoergtemplate <class _Tp, class _Allocator> 350*4d6fc14bSjoerg__split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c) 351*4d6fc14bSjoerg _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value) 352*4d6fc14bSjoerg : __first_(_VSTD::move(__c.__first_)), 353*4d6fc14bSjoerg __begin_(_VSTD::move(__c.__begin_)), 354*4d6fc14bSjoerg __end_(_VSTD::move(__c.__end_)), 355*4d6fc14bSjoerg __end_cap_(_VSTD::move(__c.__end_cap_)) 356*4d6fc14bSjoerg{ 357*4d6fc14bSjoerg __c.__first_ = nullptr; 358*4d6fc14bSjoerg __c.__begin_ = nullptr; 359*4d6fc14bSjoerg __c.__end_ = nullptr; 360*4d6fc14bSjoerg __c.__end_cap() = nullptr; 361*4d6fc14bSjoerg} 362*4d6fc14bSjoerg 363*4d6fc14bSjoergtemplate <class _Tp, class _Allocator> 364*4d6fc14bSjoerg__split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c, const __alloc_rr& __a) 365*4d6fc14bSjoerg : __end_cap_(nullptr, __a) 366*4d6fc14bSjoerg{ 367*4d6fc14bSjoerg if (__a == __c.__alloc()) 368*4d6fc14bSjoerg { 369*4d6fc14bSjoerg __first_ = __c.__first_; 370*4d6fc14bSjoerg __begin_ = __c.__begin_; 371*4d6fc14bSjoerg __end_ = __c.__end_; 372*4d6fc14bSjoerg __end_cap() = __c.__end_cap(); 373*4d6fc14bSjoerg __c.__first_ = nullptr; 374*4d6fc14bSjoerg __c.__begin_ = nullptr; 375*4d6fc14bSjoerg __c.__end_ = nullptr; 376*4d6fc14bSjoerg __c.__end_cap() = nullptr; 377*4d6fc14bSjoerg } 378*4d6fc14bSjoerg else 379*4d6fc14bSjoerg { 380*4d6fc14bSjoerg size_type __cap = __c.size(); 381*4d6fc14bSjoerg __first_ = __alloc_traits::allocate(__alloc(), __cap); 382*4d6fc14bSjoerg __begin_ = __end_ = __first_; 383*4d6fc14bSjoerg __end_cap() = __first_ + __cap; 384*4d6fc14bSjoerg typedef move_iterator<iterator> _Ip; 385*4d6fc14bSjoerg __construct_at_end(_Ip(__c.begin()), _Ip(__c.end())); 386*4d6fc14bSjoerg } 387*4d6fc14bSjoerg} 388*4d6fc14bSjoerg 389*4d6fc14bSjoergtemplate <class _Tp, class _Allocator> 390*4d6fc14bSjoerg__split_buffer<_Tp, _Allocator>& 391*4d6fc14bSjoerg__split_buffer<_Tp, _Allocator>::operator=(__split_buffer&& __c) 392*4d6fc14bSjoerg _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value && 393*4d6fc14bSjoerg is_nothrow_move_assignable<allocator_type>::value) || 394*4d6fc14bSjoerg !__alloc_traits::propagate_on_container_move_assignment::value) 395*4d6fc14bSjoerg{ 396*4d6fc14bSjoerg clear(); 397*4d6fc14bSjoerg shrink_to_fit(); 398*4d6fc14bSjoerg __first_ = __c.__first_; 399*4d6fc14bSjoerg __begin_ = __c.__begin_; 400*4d6fc14bSjoerg __end_ = __c.__end_; 401*4d6fc14bSjoerg __end_cap() = __c.__end_cap(); 402*4d6fc14bSjoerg __move_assign_alloc(__c, 403*4d6fc14bSjoerg integral_constant<bool, 404*4d6fc14bSjoerg __alloc_traits::propagate_on_container_move_assignment::value>()); 405*4d6fc14bSjoerg __c.__first_ = __c.__begin_ = __c.__end_ = __c.__end_cap() = nullptr; 406*4d6fc14bSjoerg return *this; 407*4d6fc14bSjoerg} 408*4d6fc14bSjoerg 409*4d6fc14bSjoergtemplate <class _Tp, class _Allocator> 410*4d6fc14bSjoergvoid 411*4d6fc14bSjoerg__split_buffer<_Tp, _Allocator>::swap(__split_buffer& __x) 412*4d6fc14bSjoerg _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value|| 413*4d6fc14bSjoerg __is_nothrow_swappable<__alloc_rr>::value) 414*4d6fc14bSjoerg{ 415*4d6fc14bSjoerg _VSTD::swap(__first_, __x.__first_); 416*4d6fc14bSjoerg _VSTD::swap(__begin_, __x.__begin_); 417*4d6fc14bSjoerg _VSTD::swap(__end_, __x.__end_); 418*4d6fc14bSjoerg _VSTD::swap(__end_cap(), __x.__end_cap()); 419*4d6fc14bSjoerg _VSTD::__swap_allocator(__alloc(), __x.__alloc()); 420*4d6fc14bSjoerg} 421*4d6fc14bSjoerg 422*4d6fc14bSjoergtemplate <class _Tp, class _Allocator> 423*4d6fc14bSjoergvoid 424*4d6fc14bSjoerg__split_buffer<_Tp, _Allocator>::reserve(size_type __n) 425*4d6fc14bSjoerg{ 426*4d6fc14bSjoerg if (__n < capacity()) 427*4d6fc14bSjoerg { 428*4d6fc14bSjoerg __split_buffer<value_type, __alloc_rr&> __t(__n, 0, __alloc()); 429*4d6fc14bSjoerg __t.__construct_at_end(move_iterator<pointer>(__begin_), 430*4d6fc14bSjoerg move_iterator<pointer>(__end_)); 431*4d6fc14bSjoerg _VSTD::swap(__first_, __t.__first_); 432*4d6fc14bSjoerg _VSTD::swap(__begin_, __t.__begin_); 433*4d6fc14bSjoerg _VSTD::swap(__end_, __t.__end_); 434*4d6fc14bSjoerg _VSTD::swap(__end_cap(), __t.__end_cap()); 435*4d6fc14bSjoerg } 436*4d6fc14bSjoerg} 437*4d6fc14bSjoerg 438*4d6fc14bSjoergtemplate <class _Tp, class _Allocator> 439*4d6fc14bSjoergvoid 440*4d6fc14bSjoerg__split_buffer<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT 441*4d6fc14bSjoerg{ 442*4d6fc14bSjoerg if (capacity() > size()) 443*4d6fc14bSjoerg { 444*4d6fc14bSjoerg#ifndef _LIBCPP_NO_EXCEPTIONS 445*4d6fc14bSjoerg try 446*4d6fc14bSjoerg { 447*4d6fc14bSjoerg#endif // _LIBCPP_NO_EXCEPTIONS 448*4d6fc14bSjoerg __split_buffer<value_type, __alloc_rr&> __t(size(), 0, __alloc()); 449*4d6fc14bSjoerg __t.__construct_at_end(move_iterator<pointer>(__begin_), 450*4d6fc14bSjoerg move_iterator<pointer>(__end_)); 451*4d6fc14bSjoerg __t.__end_ = __t.__begin_ + (__end_ - __begin_); 452*4d6fc14bSjoerg _VSTD::swap(__first_, __t.__first_); 453*4d6fc14bSjoerg _VSTD::swap(__begin_, __t.__begin_); 454*4d6fc14bSjoerg _VSTD::swap(__end_, __t.__end_); 455*4d6fc14bSjoerg _VSTD::swap(__end_cap(), __t.__end_cap()); 456*4d6fc14bSjoerg#ifndef _LIBCPP_NO_EXCEPTIONS 457*4d6fc14bSjoerg } 458*4d6fc14bSjoerg catch (...) 459*4d6fc14bSjoerg { 460*4d6fc14bSjoerg } 461*4d6fc14bSjoerg#endif // _LIBCPP_NO_EXCEPTIONS 462*4d6fc14bSjoerg } 463*4d6fc14bSjoerg} 464*4d6fc14bSjoerg 465*4d6fc14bSjoergtemplate <class _Tp, class _Allocator> 466*4d6fc14bSjoergvoid 467*4d6fc14bSjoerg__split_buffer<_Tp, _Allocator>::push_front(const_reference __x) 468*4d6fc14bSjoerg{ 469*4d6fc14bSjoerg if (__begin_ == __first_) 470*4d6fc14bSjoerg { 471*4d6fc14bSjoerg if (__end_ < __end_cap()) 472*4d6fc14bSjoerg { 473*4d6fc14bSjoerg difference_type __d = __end_cap() - __end_; 474*4d6fc14bSjoerg __d = (__d + 1) / 2; 475*4d6fc14bSjoerg __begin_ = _VSTD::move_backward(__begin_, __end_, __end_ + __d); 476*4d6fc14bSjoerg __end_ += __d; 477*4d6fc14bSjoerg } 478*4d6fc14bSjoerg else 479*4d6fc14bSjoerg { 480*4d6fc14bSjoerg size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1); 481*4d6fc14bSjoerg __split_buffer<value_type, __alloc_rr&> __t(__c, (__c + 3) / 4, __alloc()); 482*4d6fc14bSjoerg __t.__construct_at_end(move_iterator<pointer>(__begin_), 483*4d6fc14bSjoerg move_iterator<pointer>(__end_)); 484*4d6fc14bSjoerg _VSTD::swap(__first_, __t.__first_); 485*4d6fc14bSjoerg _VSTD::swap(__begin_, __t.__begin_); 486*4d6fc14bSjoerg _VSTD::swap(__end_, __t.__end_); 487*4d6fc14bSjoerg _VSTD::swap(__end_cap(), __t.__end_cap()); 488*4d6fc14bSjoerg } 489*4d6fc14bSjoerg } 490*4d6fc14bSjoerg __alloc_traits::construct(__alloc(), _VSTD::__to_address(__begin_-1), __x); 491*4d6fc14bSjoerg --__begin_; 492*4d6fc14bSjoerg} 493*4d6fc14bSjoerg 494*4d6fc14bSjoergtemplate <class _Tp, class _Allocator> 495*4d6fc14bSjoergvoid 496*4d6fc14bSjoerg__split_buffer<_Tp, _Allocator>::push_front(value_type&& __x) 497*4d6fc14bSjoerg{ 498*4d6fc14bSjoerg if (__begin_ == __first_) 499*4d6fc14bSjoerg { 500*4d6fc14bSjoerg if (__end_ < __end_cap()) 501*4d6fc14bSjoerg { 502*4d6fc14bSjoerg difference_type __d = __end_cap() - __end_; 503*4d6fc14bSjoerg __d = (__d + 1) / 2; 504*4d6fc14bSjoerg __begin_ = _VSTD::move_backward(__begin_, __end_, __end_ + __d); 505*4d6fc14bSjoerg __end_ += __d; 506*4d6fc14bSjoerg } 507*4d6fc14bSjoerg else 508*4d6fc14bSjoerg { 509*4d6fc14bSjoerg size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1); 510*4d6fc14bSjoerg __split_buffer<value_type, __alloc_rr&> __t(__c, (__c + 3) / 4, __alloc()); 511*4d6fc14bSjoerg __t.__construct_at_end(move_iterator<pointer>(__begin_), 512*4d6fc14bSjoerg move_iterator<pointer>(__end_)); 513*4d6fc14bSjoerg _VSTD::swap(__first_, __t.__first_); 514*4d6fc14bSjoerg _VSTD::swap(__begin_, __t.__begin_); 515*4d6fc14bSjoerg _VSTD::swap(__end_, __t.__end_); 516*4d6fc14bSjoerg _VSTD::swap(__end_cap(), __t.__end_cap()); 517*4d6fc14bSjoerg } 518*4d6fc14bSjoerg } 519*4d6fc14bSjoerg __alloc_traits::construct(__alloc(), _VSTD::__to_address(__begin_-1), 520*4d6fc14bSjoerg _VSTD::move(__x)); 521*4d6fc14bSjoerg --__begin_; 522*4d6fc14bSjoerg} 523*4d6fc14bSjoerg 524*4d6fc14bSjoergtemplate <class _Tp, class _Allocator> 525*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 526*4d6fc14bSjoergvoid 527*4d6fc14bSjoerg__split_buffer<_Tp, _Allocator>::push_back(const_reference __x) 528*4d6fc14bSjoerg{ 529*4d6fc14bSjoerg if (__end_ == __end_cap()) 530*4d6fc14bSjoerg { 531*4d6fc14bSjoerg if (__begin_ > __first_) 532*4d6fc14bSjoerg { 533*4d6fc14bSjoerg difference_type __d = __begin_ - __first_; 534*4d6fc14bSjoerg __d = (__d + 1) / 2; 535*4d6fc14bSjoerg __end_ = _VSTD::move(__begin_, __end_, __begin_ - __d); 536*4d6fc14bSjoerg __begin_ -= __d; 537*4d6fc14bSjoerg } 538*4d6fc14bSjoerg else 539*4d6fc14bSjoerg { 540*4d6fc14bSjoerg size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1); 541*4d6fc14bSjoerg __split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc()); 542*4d6fc14bSjoerg __t.__construct_at_end(move_iterator<pointer>(__begin_), 543*4d6fc14bSjoerg move_iterator<pointer>(__end_)); 544*4d6fc14bSjoerg _VSTD::swap(__first_, __t.__first_); 545*4d6fc14bSjoerg _VSTD::swap(__begin_, __t.__begin_); 546*4d6fc14bSjoerg _VSTD::swap(__end_, __t.__end_); 547*4d6fc14bSjoerg _VSTD::swap(__end_cap(), __t.__end_cap()); 548*4d6fc14bSjoerg } 549*4d6fc14bSjoerg } 550*4d6fc14bSjoerg __alloc_traits::construct(__alloc(), _VSTD::__to_address(__end_), __x); 551*4d6fc14bSjoerg ++__end_; 552*4d6fc14bSjoerg} 553*4d6fc14bSjoerg 554*4d6fc14bSjoergtemplate <class _Tp, class _Allocator> 555*4d6fc14bSjoergvoid 556*4d6fc14bSjoerg__split_buffer<_Tp, _Allocator>::push_back(value_type&& __x) 557*4d6fc14bSjoerg{ 558*4d6fc14bSjoerg if (__end_ == __end_cap()) 559*4d6fc14bSjoerg { 560*4d6fc14bSjoerg if (__begin_ > __first_) 561*4d6fc14bSjoerg { 562*4d6fc14bSjoerg difference_type __d = __begin_ - __first_; 563*4d6fc14bSjoerg __d = (__d + 1) / 2; 564*4d6fc14bSjoerg __end_ = _VSTD::move(__begin_, __end_, __begin_ - __d); 565*4d6fc14bSjoerg __begin_ -= __d; 566*4d6fc14bSjoerg } 567*4d6fc14bSjoerg else 568*4d6fc14bSjoerg { 569*4d6fc14bSjoerg size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1); 570*4d6fc14bSjoerg __split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc()); 571*4d6fc14bSjoerg __t.__construct_at_end(move_iterator<pointer>(__begin_), 572*4d6fc14bSjoerg move_iterator<pointer>(__end_)); 573*4d6fc14bSjoerg _VSTD::swap(__first_, __t.__first_); 574*4d6fc14bSjoerg _VSTD::swap(__begin_, __t.__begin_); 575*4d6fc14bSjoerg _VSTD::swap(__end_, __t.__end_); 576*4d6fc14bSjoerg _VSTD::swap(__end_cap(), __t.__end_cap()); 577*4d6fc14bSjoerg } 578*4d6fc14bSjoerg } 579*4d6fc14bSjoerg __alloc_traits::construct(__alloc(), _VSTD::__to_address(__end_), 580*4d6fc14bSjoerg _VSTD::move(__x)); 581*4d6fc14bSjoerg ++__end_; 582*4d6fc14bSjoerg} 583*4d6fc14bSjoerg 584*4d6fc14bSjoergtemplate <class _Tp, class _Allocator> 585*4d6fc14bSjoergtemplate <class... _Args> 586*4d6fc14bSjoergvoid 587*4d6fc14bSjoerg__split_buffer<_Tp, _Allocator>::emplace_back(_Args&&... __args) 588*4d6fc14bSjoerg{ 589*4d6fc14bSjoerg if (__end_ == __end_cap()) 590*4d6fc14bSjoerg { 591*4d6fc14bSjoerg if (__begin_ > __first_) 592*4d6fc14bSjoerg { 593*4d6fc14bSjoerg difference_type __d = __begin_ - __first_; 594*4d6fc14bSjoerg __d = (__d + 1) / 2; 595*4d6fc14bSjoerg __end_ = _VSTD::move(__begin_, __end_, __begin_ - __d); 596*4d6fc14bSjoerg __begin_ -= __d; 597*4d6fc14bSjoerg } 598*4d6fc14bSjoerg else 599*4d6fc14bSjoerg { 600*4d6fc14bSjoerg size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1); 601*4d6fc14bSjoerg __split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc()); 602*4d6fc14bSjoerg __t.__construct_at_end(move_iterator<pointer>(__begin_), 603*4d6fc14bSjoerg move_iterator<pointer>(__end_)); 604*4d6fc14bSjoerg _VSTD::swap(__first_, __t.__first_); 605*4d6fc14bSjoerg _VSTD::swap(__begin_, __t.__begin_); 606*4d6fc14bSjoerg _VSTD::swap(__end_, __t.__end_); 607*4d6fc14bSjoerg _VSTD::swap(__end_cap(), __t.__end_cap()); 608*4d6fc14bSjoerg } 609*4d6fc14bSjoerg } 610*4d6fc14bSjoerg __alloc_traits::construct(__alloc(), _VSTD::__to_address(__end_), 611*4d6fc14bSjoerg _VSTD::forward<_Args>(__args)...); 612*4d6fc14bSjoerg ++__end_; 613*4d6fc14bSjoerg} 614*4d6fc14bSjoerg 615*4d6fc14bSjoergtemplate <class _Tp, class _Allocator> 616*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 617*4d6fc14bSjoergvoid 618*4d6fc14bSjoergswap(__split_buffer<_Tp, _Allocator>& __x, __split_buffer<_Tp, _Allocator>& __y) 619*4d6fc14bSjoerg _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) 620*4d6fc14bSjoerg{ 621*4d6fc14bSjoerg __x.swap(__y); 622*4d6fc14bSjoerg} 623*4d6fc14bSjoerg 624*4d6fc14bSjoerg_LIBCPP_END_NAMESPACE_STD 625*4d6fc14bSjoerg 626*4d6fc14bSjoerg_LIBCPP_POP_MACROS 627*4d6fc14bSjoerg 628*4d6fc14bSjoerg#endif // _LIBCPP_SPLIT_BUFFER 629