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 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, is_trivially_destructible<value_type>());} 137 void __destruct_at_end(pointer __new_last, false_type) _NOEXCEPT; 138 void __destruct_at_end(pointer __new_last, true_type) _NOEXCEPT; 139 140 void swap(__split_buffer& __x) 141 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value|| 142 __is_nothrow_swappable<__alloc_rr>::value); 143 144 bool __invariants() const; 145 146private: 147 _LIBCPP_INLINE_VISIBILITY 148 void __move_assign_alloc(__split_buffer& __c, true_type) 149 _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) 150 { 151 __alloc() = _VSTD::move(__c.__alloc()); 152 } 153 154 _LIBCPP_INLINE_VISIBILITY 155 void __move_assign_alloc(__split_buffer&, false_type) _NOEXCEPT 156 {} 157 158 _LIBCPP_INLINE_VISIBILITY 159 static void __swap_alloc(__alloc_rr& __x, __alloc_rr& __y) 160 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value|| 161 __is_nothrow_swappable<__alloc_rr>::value) 162 {__swap_alloc(__x, __y, integral_constant<bool, 163 __alloc_traits::propagate_on_container_swap::value>());} 164 165 _LIBCPP_INLINE_VISIBILITY 166 static void __swap_alloc(__alloc_rr& __x, __alloc_rr& __y, true_type) 167 _NOEXCEPT_(__is_nothrow_swappable<__alloc_rr>::value) 168 { 169 using _VSTD::swap; 170 swap(__x, __y); 171 } 172 173 _LIBCPP_INLINE_VISIBILITY 174 static void __swap_alloc(__alloc_rr&, __alloc_rr&, false_type) _NOEXCEPT 175 {} 176}; 177 178template <class _Tp, class _Allocator> 179bool 180__split_buffer<_Tp, _Allocator>::__invariants() const 181{ 182 if (__first_ == nullptr) 183 { 184 if (__begin_ != nullptr) 185 return false; 186 if (__end_ != nullptr) 187 return false; 188 if (__end_cap() != nullptr) 189 return false; 190 } 191 else 192 { 193 if (__begin_ < __first_) 194 return false; 195 if (__end_ < __begin_) 196 return false; 197 if (__end_cap() < __end_) 198 return false; 199 } 200 return true; 201} 202 203// Default constructs __n objects starting at __end_ 204// throws if construction throws 205// Precondition: __n > 0 206// Precondition: size() + __n <= capacity() 207// Postcondition: size() == size() + __n 208template <class _Tp, class _Allocator> 209void 210__split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n) 211{ 212 __alloc_rr& __a = this->__alloc(); 213 do 214 { 215 __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_)); 216 ++this->__end_; 217 --__n; 218 } while (__n > 0); 219} 220 221// Copy constructs __n objects starting at __end_ from __x 222// throws if construction throws 223// Precondition: __n > 0 224// Precondition: size() + __n <= capacity() 225// Postcondition: size() == old size() + __n 226// Postcondition: [i] == __x for all i in [size() - __n, __n) 227template <class _Tp, class _Allocator> 228void 229__split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x) 230{ 231 __alloc_rr& __a = this->__alloc(); 232 do 233 { 234 __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), __x); 235 ++this->__end_; 236 --__n; 237 } while (__n > 0); 238} 239 240template <class _Tp, class _Allocator> 241template <class _InputIter> 242typename enable_if 243< 244 __is_input_iterator<_InputIter>::value && 245 !__is_forward_iterator<_InputIter>::value, 246 void 247>::type 248__split_buffer<_Tp, _Allocator>::__construct_at_end(_InputIter __first, _InputIter __last) 249{ 250 __alloc_rr& __a = this->__alloc(); 251 for (; __first != __last; ++__first) 252 { 253 if (__end_ == __end_cap()) 254 { 255 size_type __old_cap = __end_cap() - __first_; 256 size_type __new_cap = _VSTD::max<size_type>(2 * __old_cap, 8); 257 __split_buffer __buf(__new_cap, 0, __a); 258 for (pointer __p = __begin_; __p != __end_; ++__p, ++__buf.__end_) 259 __alloc_traits::construct(__buf.__alloc(), 260 _VSTD::__to_raw_pointer(__buf.__end_), _VSTD::move(*__p)); 261 swap(__buf); 262 } 263 __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), *__first); 264 ++this->__end_; 265 } 266} 267 268template <class _Tp, class _Allocator> 269template <class _ForwardIterator> 270typename enable_if 271< 272 __is_forward_iterator<_ForwardIterator>::value, 273 void 274>::type 275__split_buffer<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last) 276{ 277 __alloc_rr& __a = this->__alloc(); 278 for (; __first != __last; ++__first) 279 { 280 __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), *__first); 281 ++this->__end_; 282 } 283} 284 285template <class _Tp, class _Allocator> 286_LIBCPP_INLINE_VISIBILITY inline 287void 288__split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, false_type) 289{ 290 while (__begin_ < __new_begin) 291 __alloc_traits::destroy(__alloc(), __begin_++); 292} 293 294template <class _Tp, class _Allocator> 295_LIBCPP_INLINE_VISIBILITY inline 296void 297__split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, true_type) 298{ 299 __begin_ = __new_begin; 300} 301 302template <class _Tp, class _Allocator> 303_LIBCPP_INLINE_VISIBILITY inline 304void 305__split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, false_type) _NOEXCEPT 306{ 307 while (__new_last < __end_) 308 __alloc_traits::destroy(__alloc(), --__end_); 309} 310 311template <class _Tp, class _Allocator> 312_LIBCPP_INLINE_VISIBILITY inline 313void 314__split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, true_type) _NOEXCEPT 315{ 316 __end_ = __new_last; 317} 318 319template <class _Tp, class _Allocator> 320__split_buffer<_Tp, _Allocator>::__split_buffer(size_type __cap, size_type __start, __alloc_rr& __a) 321 : __end_cap_(0, __a) 322{ 323 __first_ = __cap != 0 ? __alloc_traits::allocate(__alloc(), __cap) : nullptr; 324 __begin_ = __end_ = __first_ + __start; 325 __end_cap() = __first_ + __cap; 326} 327 328template <class _Tp, class _Allocator> 329_LIBCPP_INLINE_VISIBILITY inline 330__split_buffer<_Tp, _Allocator>::__split_buffer() 331 _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) 332 : __first_(0), __begin_(0), __end_(0), __end_cap_(0) 333{ 334} 335 336template <class _Tp, class _Allocator> 337_LIBCPP_INLINE_VISIBILITY inline 338__split_buffer<_Tp, _Allocator>::__split_buffer(__alloc_rr& __a) 339 : __first_(0), __begin_(0), __end_(0), __end_cap_(0, __a) 340{ 341} 342 343template <class _Tp, class _Allocator> 344_LIBCPP_INLINE_VISIBILITY inline 345__split_buffer<_Tp, _Allocator>::__split_buffer(const __alloc_rr& __a) 346 : __first_(0), __begin_(0), __end_(0), __end_cap_(0, __a) 347{ 348} 349 350template <class _Tp, class _Allocator> 351__split_buffer<_Tp, _Allocator>::~__split_buffer() 352{ 353 clear(); 354 if (__first_) 355 __alloc_traits::deallocate(__alloc(), __first_, capacity()); 356} 357 358#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 359 360template <class _Tp, class _Allocator> 361__split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c) 362 _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value) 363 : __first_(_VSTD::move(__c.__first_)), 364 __begin_(_VSTD::move(__c.__begin_)), 365 __end_(_VSTD::move(__c.__end_)), 366 __end_cap_(_VSTD::move(__c.__end_cap_)) 367{ 368 __c.__first_ = nullptr; 369 __c.__begin_ = nullptr; 370 __c.__end_ = nullptr; 371 __c.__end_cap() = nullptr; 372} 373 374template <class _Tp, class _Allocator> 375__split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c, const __alloc_rr& __a) 376 : __end_cap_(__a) 377{ 378 if (__a == __c.__alloc()) 379 { 380 __first_ = __c.__first_; 381 __begin_ = __c.__begin_; 382 __end_ = __c.__end_; 383 __end_cap() = __c.__end_cap(); 384 __c.__first_ = nullptr; 385 __c.__begin_ = nullptr; 386 __c.__end_ = nullptr; 387 __c.__end_cap() = nullptr; 388 } 389 else 390 { 391 size_type __cap = __c.size(); 392 __first_ = __alloc_traits::allocate(__alloc(), __cap); 393 __begin_ = __end_ = __first_; 394 __end_cap() = __first_ + __cap; 395 typedef move_iterator<iterator> _Ip; 396 __construct_at_end(_Ip(__c.begin()), _Ip(__c.end())); 397 } 398} 399 400template <class _Tp, class _Allocator> 401__split_buffer<_Tp, _Allocator>& 402__split_buffer<_Tp, _Allocator>::operator=(__split_buffer&& __c) 403 _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value && 404 is_nothrow_move_assignable<allocator_type>::value) || 405 !__alloc_traits::propagate_on_container_move_assignment::value) 406{ 407 clear(); 408 shrink_to_fit(); 409 __first_ = __c.__first_; 410 __begin_ = __c.__begin_; 411 __end_ = __c.__end_; 412 __end_cap() = __c.__end_cap(); 413 __move_assign_alloc(__c, 414 integral_constant<bool, 415 __alloc_traits::propagate_on_container_move_assignment::value>()); 416 __c.__first_ = __c.__begin_ = __c.__end_ = __c.__end_cap() = nullptr; 417 return *this; 418} 419 420#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 421 422template <class _Tp, class _Allocator> 423void 424__split_buffer<_Tp, _Allocator>::swap(__split_buffer& __x) 425 _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value|| 426 __is_nothrow_swappable<__alloc_rr>::value) 427{ 428 _VSTD::swap(__first_, __x.__first_); 429 _VSTD::swap(__begin_, __x.__begin_); 430 _VSTD::swap(__end_, __x.__end_); 431 _VSTD::swap(__end_cap(), __x.__end_cap()); 432 __swap_alloc(__alloc(), __x.__alloc()); 433} 434 435template <class _Tp, class _Allocator> 436void 437__split_buffer<_Tp, _Allocator>::reserve(size_type __n) 438{ 439 if (__n < capacity()) 440 { 441 __split_buffer<value_type, __alloc_rr&> __t(__n, 0, __alloc()); 442 __t.__construct_at_end(move_iterator<pointer>(__begin_), 443 move_iterator<pointer>(__end_)); 444 _VSTD::swap(__first_, __t.__first_); 445 _VSTD::swap(__begin_, __t.__begin_); 446 _VSTD::swap(__end_, __t.__end_); 447 _VSTD::swap(__end_cap(), __t.__end_cap()); 448 } 449} 450 451template <class _Tp, class _Allocator> 452void 453__split_buffer<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT 454{ 455 if (capacity() > size()) 456 { 457#ifndef _LIBCPP_NO_EXCEPTIONS 458 try 459 { 460#endif // _LIBCPP_NO_EXCEPTIONS 461 __split_buffer<value_type, __alloc_rr&> __t(size(), 0, __alloc()); 462 __t.__construct_at_end(move_iterator<pointer>(__begin_), 463 move_iterator<pointer>(__end_)); 464 __t.__end_ = __t.__begin_ + (__end_ - __begin_); 465 _VSTD::swap(__first_, __t.__first_); 466 _VSTD::swap(__begin_, __t.__begin_); 467 _VSTD::swap(__end_, __t.__end_); 468 _VSTD::swap(__end_cap(), __t.__end_cap()); 469#ifndef _LIBCPP_NO_EXCEPTIONS 470 } 471 catch (...) 472 { 473 } 474#endif // _LIBCPP_NO_EXCEPTIONS 475 } 476} 477 478template <class _Tp, class _Allocator> 479void 480__split_buffer<_Tp, _Allocator>::push_front(const_reference __x) 481{ 482 if (__begin_ == __first_) 483 { 484 if (__end_ < __end_cap()) 485 { 486 difference_type __d = __end_cap() - __end_; 487 __d = (__d + 1) / 2; 488 __begin_ = _VSTD::move_backward(__begin_, __end_, __end_ + __d); 489 __end_ += __d; 490 } 491 else 492 { 493 size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1); 494 __split_buffer<value_type, __alloc_rr&> __t(__c, (__c + 3) / 4, __alloc()); 495 __t.__construct_at_end(move_iterator<pointer>(__begin_), 496 move_iterator<pointer>(__end_)); 497 _VSTD::swap(__first_, __t.__first_); 498 _VSTD::swap(__begin_, __t.__begin_); 499 _VSTD::swap(__end_, __t.__end_); 500 _VSTD::swap(__end_cap(), __t.__end_cap()); 501 } 502 } 503 __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__begin_-1), __x); 504 --__begin_; 505} 506 507#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 508 509template <class _Tp, class _Allocator> 510void 511__split_buffer<_Tp, _Allocator>::push_front(value_type&& __x) 512{ 513 if (__begin_ == __first_) 514 { 515 if (__end_ < __end_cap()) 516 { 517 difference_type __d = __end_cap() - __end_; 518 __d = (__d + 1) / 2; 519 __begin_ = _VSTD::move_backward(__begin_, __end_, __end_ + __d); 520 __end_ += __d; 521 } 522 else 523 { 524 size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1); 525 __split_buffer<value_type, __alloc_rr&> __t(__c, (__c + 3) / 4, __alloc()); 526 __t.__construct_at_end(move_iterator<pointer>(__begin_), 527 move_iterator<pointer>(__end_)); 528 _VSTD::swap(__first_, __t.__first_); 529 _VSTD::swap(__begin_, __t.__begin_); 530 _VSTD::swap(__end_, __t.__end_); 531 _VSTD::swap(__end_cap(), __t.__end_cap()); 532 } 533 } 534 __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__begin_-1), 535 _VSTD::move(__x)); 536 --__begin_; 537} 538 539#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 540 541template <class _Tp, class _Allocator> 542_LIBCPP_INLINE_VISIBILITY inline 543void 544__split_buffer<_Tp, _Allocator>::push_back(const_reference __x) 545{ 546 if (__end_ == __end_cap()) 547 { 548 if (__begin_ > __first_) 549 { 550 difference_type __d = __begin_ - __first_; 551 __d = (__d + 1) / 2; 552 __end_ = _VSTD::move(__begin_, __end_, __begin_ - __d); 553 __begin_ -= __d; 554 } 555 else 556 { 557 size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1); 558 __split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc()); 559 __t.__construct_at_end(move_iterator<pointer>(__begin_), 560 move_iterator<pointer>(__end_)); 561 _VSTD::swap(__first_, __t.__first_); 562 _VSTD::swap(__begin_, __t.__begin_); 563 _VSTD::swap(__end_, __t.__end_); 564 _VSTD::swap(__end_cap(), __t.__end_cap()); 565 } 566 } 567 __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_), __x); 568 ++__end_; 569} 570 571#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 572 573template <class _Tp, class _Allocator> 574void 575__split_buffer<_Tp, _Allocator>::push_back(value_type&& __x) 576{ 577 if (__end_ == __end_cap()) 578 { 579 if (__begin_ > __first_) 580 { 581 difference_type __d = __begin_ - __first_; 582 __d = (__d + 1) / 2; 583 __end_ = _VSTD::move(__begin_, __end_, __begin_ - __d); 584 __begin_ -= __d; 585 } 586 else 587 { 588 size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1); 589 __split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc()); 590 __t.__construct_at_end(move_iterator<pointer>(__begin_), 591 move_iterator<pointer>(__end_)); 592 _VSTD::swap(__first_, __t.__first_); 593 _VSTD::swap(__begin_, __t.__begin_); 594 _VSTD::swap(__end_, __t.__end_); 595 _VSTD::swap(__end_cap(), __t.__end_cap()); 596 } 597 } 598 __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_), 599 _VSTD::move(__x)); 600 ++__end_; 601} 602 603#ifndef _LIBCPP_HAS_NO_VARIADICS 604 605template <class _Tp, class _Allocator> 606template <class... _Args> 607void 608__split_buffer<_Tp, _Allocator>::emplace_back(_Args&&... __args) 609{ 610 if (__end_ == __end_cap()) 611 { 612 if (__begin_ > __first_) 613 { 614 difference_type __d = __begin_ - __first_; 615 __d = (__d + 1) / 2; 616 __end_ = _VSTD::move(__begin_, __end_, __begin_ - __d); 617 __begin_ -= __d; 618 } 619 else 620 { 621 size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1); 622 __split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc()); 623 __t.__construct_at_end(move_iterator<pointer>(__begin_), 624 move_iterator<pointer>(__end_)); 625 _VSTD::swap(__first_, __t.__first_); 626 _VSTD::swap(__begin_, __t.__begin_); 627 _VSTD::swap(__end_, __t.__end_); 628 _VSTD::swap(__end_cap(), __t.__end_cap()); 629 } 630 } 631 __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_), 632 _VSTD::forward<_Args>(__args)...); 633 ++__end_; 634} 635 636#endif // _LIBCPP_HAS_NO_VARIADICS 637 638#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES 639 640template <class _Tp, class _Allocator> 641_LIBCPP_INLINE_VISIBILITY inline 642void 643swap(__split_buffer<_Tp, _Allocator>& __x, __split_buffer<_Tp, _Allocator>& __y) 644 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) 645{ 646 __x.swap(__y); 647} 648 649 650_LIBCPP_END_NAMESPACE_STD 651 652#endif // _LIBCPP_SPLIT_BUFFER 653