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