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