17a984708SDavid Chisnall// -*- C++ -*- 27a984708SDavid Chisnall#ifndef _LIBCPP_SPLIT_BUFFER 37a984708SDavid Chisnall#define _LIBCPP_SPLIT_BUFFER 47a984708SDavid Chisnall 57a984708SDavid Chisnall#include <__config> 67a984708SDavid Chisnall#include <type_traits> 77a984708SDavid Chisnall#include <algorithm> 87a984708SDavid Chisnall 97a984708SDavid Chisnall#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 107a984708SDavid Chisnall#pragma GCC system_header 117a984708SDavid Chisnall#endif 127a984708SDavid Chisnall 13*f9448bf3SDimitry Andric_LIBCPP_PUSH_MACROS 14*f9448bf3SDimitry Andric#include <__undef_macros> 15*f9448bf3SDimitry Andric 16*f9448bf3SDimitry Andric 177a984708SDavid Chisnall_LIBCPP_BEGIN_NAMESPACE_STD 187a984708SDavid Chisnall 197a984708SDavid Chisnalltemplate <bool> 207a984708SDavid Chisnallclass __split_buffer_common 217a984708SDavid Chisnall{ 227a984708SDavid Chisnallprotected: 237a984708SDavid Chisnall void __throw_length_error() const; 247a984708SDavid Chisnall void __throw_out_of_range() const; 257a984708SDavid Chisnall}; 267a984708SDavid Chisnall 277a984708SDavid Chisnalltemplate <class _Tp, class _Allocator = allocator<_Tp> > 287a984708SDavid Chisnallstruct __split_buffer 297a984708SDavid Chisnall : private __split_buffer_common<true> 307a984708SDavid Chisnall{ 317a984708SDavid Chisnallprivate: 327a984708SDavid Chisnall __split_buffer(const __split_buffer&); 337a984708SDavid Chisnall __split_buffer& operator=(const __split_buffer&); 347a984708SDavid Chisnallpublic: 357a984708SDavid Chisnall typedef _Tp value_type; 367a984708SDavid Chisnall typedef _Allocator allocator_type; 377a984708SDavid Chisnall typedef typename remove_reference<allocator_type>::type __alloc_rr; 387a984708SDavid Chisnall typedef allocator_traits<__alloc_rr> __alloc_traits; 397a984708SDavid Chisnall typedef value_type& reference; 407a984708SDavid Chisnall typedef const value_type& const_reference; 417a984708SDavid Chisnall typedef typename __alloc_traits::size_type size_type; 427a984708SDavid Chisnall typedef typename __alloc_traits::difference_type difference_type; 437a984708SDavid Chisnall typedef typename __alloc_traits::pointer pointer; 447a984708SDavid Chisnall typedef typename __alloc_traits::const_pointer const_pointer; 457a984708SDavid Chisnall typedef pointer iterator; 467a984708SDavid Chisnall typedef const_pointer const_iterator; 477a984708SDavid Chisnall 487a984708SDavid Chisnall pointer __first_; 497a984708SDavid Chisnall pointer __begin_; 507a984708SDavid Chisnall pointer __end_; 517a984708SDavid Chisnall __compressed_pair<pointer, allocator_type> __end_cap_; 527a984708SDavid Chisnall 537a984708SDavid Chisnall typedef typename add_lvalue_reference<allocator_type>::type __alloc_ref; 547a984708SDavid Chisnall typedef typename add_lvalue_reference<allocator_type>::type __alloc_const_ref; 557a984708SDavid Chisnall 567a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY __alloc_rr& __alloc() _NOEXCEPT {return __end_cap_.second();} 577a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY const __alloc_rr& __alloc() const _NOEXCEPT {return __end_cap_.second();} 587a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY pointer& __end_cap() _NOEXCEPT {return __end_cap_.first();} 597a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY const pointer& __end_cap() const _NOEXCEPT {return __end_cap_.first();} 607a984708SDavid Chisnall 619729cf09SDimitry Andric _LIBCPP_INLINE_VISIBILITY 627a984708SDavid Chisnall __split_buffer() 637a984708SDavid Chisnall _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value); 649729cf09SDimitry Andric _LIBCPP_INLINE_VISIBILITY 657a984708SDavid Chisnall explicit __split_buffer(__alloc_rr& __a); 669729cf09SDimitry Andric _LIBCPP_INLINE_VISIBILITY 677a984708SDavid Chisnall explicit __split_buffer(const __alloc_rr& __a); 687a984708SDavid Chisnall __split_buffer(size_type __cap, size_type __start, __alloc_rr& __a); 697a984708SDavid Chisnall ~__split_buffer(); 707a984708SDavid Chisnall 71540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 727a984708SDavid Chisnall __split_buffer(__split_buffer&& __c) 737a984708SDavid Chisnall _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value); 747a984708SDavid Chisnall __split_buffer(__split_buffer&& __c, const __alloc_rr& __a); 757a984708SDavid Chisnall __split_buffer& operator=(__split_buffer&& __c) 767a984708SDavid Chisnall _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value && 777a984708SDavid Chisnall is_nothrow_move_assignable<allocator_type>::value) || 787a984708SDavid Chisnall !__alloc_traits::propagate_on_container_move_assignment::value); 79540d2a8bSDimitry Andric#endif // _LIBCPP_CXX03_LANG 807a984708SDavid Chisnall 817a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY iterator begin() _NOEXCEPT {return __begin_;} 827a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY const_iterator begin() const _NOEXCEPT {return __begin_;} 837a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY iterator end() _NOEXCEPT {return __end_;} 847a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY const_iterator end() const _NOEXCEPT {return __end_;} 857a984708SDavid Chisnall 867a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 877a984708SDavid Chisnall void clear() _NOEXCEPT 887a984708SDavid Chisnall {__destruct_at_end(__begin_);} 897a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY size_type size() const {return static_cast<size_type>(__end_ - __begin_);} 907a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY bool empty() const {return __end_ == __begin_;} 917a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY size_type capacity() const {return static_cast<size_type>(__end_cap() - __first_);} 927a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY size_type __front_spare() const {return static_cast<size_type>(__begin_ - __first_);} 937a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY size_type __back_spare() const {return static_cast<size_type>(__end_cap() - __end_);} 947a984708SDavid Chisnall 957a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY reference front() {return *__begin_;} 967a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY const_reference front() const {return *__begin_;} 977a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY reference back() {return *(__end_ - 1);} 987a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY const_reference back() const {return *(__end_ - 1);} 997a984708SDavid Chisnall 1007a984708SDavid Chisnall void reserve(size_type __n); 1017a984708SDavid Chisnall void shrink_to_fit() _NOEXCEPT; 1027a984708SDavid Chisnall void push_front(const_reference __x); 10394e3ee44SDavid Chisnall _LIBCPP_INLINE_VISIBILITY void push_back(const_reference __x); 104540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 1057a984708SDavid Chisnall void push_front(value_type&& __x); 1067a984708SDavid Chisnall void push_back(value_type&& __x); 1077a984708SDavid Chisnall template <class... _Args> 1087a984708SDavid Chisnall void emplace_back(_Args&&... __args); 109540d2a8bSDimitry Andric#endif // !defined(_LIBCPP_CXX03_LANG) 1107a984708SDavid Chisnall 1117a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY void pop_front() {__destruct_at_begin(__begin_+1);} 1127a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY void pop_back() {__destruct_at_end(__end_-1);} 1137a984708SDavid Chisnall 1147a984708SDavid Chisnall void __construct_at_end(size_type __n); 1157a984708SDavid Chisnall void __construct_at_end(size_type __n, const_reference __x); 1167a984708SDavid Chisnall template <class _InputIter> 1177a984708SDavid Chisnall typename enable_if 1187a984708SDavid Chisnall < 1197a984708SDavid Chisnall __is_input_iterator<_InputIter>::value && 1207a984708SDavid Chisnall !__is_forward_iterator<_InputIter>::value, 1217a984708SDavid Chisnall void 1227a984708SDavid Chisnall >::type 1237a984708SDavid Chisnall __construct_at_end(_InputIter __first, _InputIter __last); 1247a984708SDavid Chisnall template <class _ForwardIterator> 1257a984708SDavid Chisnall typename enable_if 1267a984708SDavid Chisnall < 1277a984708SDavid Chisnall __is_forward_iterator<_ForwardIterator>::value, 1287a984708SDavid Chisnall void 1297a984708SDavid Chisnall >::type 1307a984708SDavid Chisnall __construct_at_end(_ForwardIterator __first, _ForwardIterator __last); 1317a984708SDavid Chisnall 1327a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY void __destruct_at_begin(pointer __new_begin) 1337a984708SDavid Chisnall {__destruct_at_begin(__new_begin, is_trivially_destructible<value_type>());} 1349729cf09SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1357a984708SDavid Chisnall void __destruct_at_begin(pointer __new_begin, false_type); 1369729cf09SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1377a984708SDavid Chisnall void __destruct_at_begin(pointer __new_begin, true_type); 1387a984708SDavid Chisnall 1397a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1407a984708SDavid Chisnall void __destruct_at_end(pointer __new_last) _NOEXCEPT 14194e3ee44SDavid Chisnall {__destruct_at_end(__new_last, false_type());} 14294e3ee44SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1437a984708SDavid Chisnall void __destruct_at_end(pointer __new_last, false_type) _NOEXCEPT; 14494e3ee44SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1457a984708SDavid Chisnall void __destruct_at_end(pointer __new_last, true_type) _NOEXCEPT; 1467a984708SDavid Chisnall 1477a984708SDavid Chisnall void swap(__split_buffer& __x) 1487a984708SDavid Chisnall _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value|| 1497a984708SDavid Chisnall __is_nothrow_swappable<__alloc_rr>::value); 1507a984708SDavid Chisnall 1517a984708SDavid Chisnall bool __invariants() const; 1527a984708SDavid Chisnall 1537a984708SDavid Chisnallprivate: 1547a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 1557a984708SDavid Chisnall void __move_assign_alloc(__split_buffer& __c, true_type) 1567a984708SDavid Chisnall _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value) 1577a984708SDavid Chisnall { 1587a984708SDavid Chisnall __alloc() = _VSTD::move(__c.__alloc()); 1597a984708SDavid Chisnall } 1607a984708SDavid Chisnall 1617a984708SDavid Chisnall _LIBCPP_INLINE_VISIBILITY 16294e3ee44SDavid Chisnall void __move_assign_alloc(__split_buffer&, false_type) _NOEXCEPT 1637a984708SDavid Chisnall {} 1647a984708SDavid Chisnall}; 1657a984708SDavid Chisnall 1667a984708SDavid Chisnalltemplate <class _Tp, class _Allocator> 1677a984708SDavid Chisnallbool 1687a984708SDavid Chisnall__split_buffer<_Tp, _Allocator>::__invariants() const 1697a984708SDavid Chisnall{ 1707a984708SDavid Chisnall if (__first_ == nullptr) 1717a984708SDavid Chisnall { 1727a984708SDavid Chisnall if (__begin_ != nullptr) 1737a984708SDavid Chisnall return false; 1747a984708SDavid Chisnall if (__end_ != nullptr) 1757a984708SDavid Chisnall return false; 1767a984708SDavid Chisnall if (__end_cap() != nullptr) 1777a984708SDavid Chisnall return false; 1787a984708SDavid Chisnall } 1797a984708SDavid Chisnall else 1807a984708SDavid Chisnall { 1817a984708SDavid Chisnall if (__begin_ < __first_) 1827a984708SDavid Chisnall return false; 1837a984708SDavid Chisnall if (__end_ < __begin_) 1847a984708SDavid Chisnall return false; 1857a984708SDavid Chisnall if (__end_cap() < __end_) 1867a984708SDavid Chisnall return false; 1877a984708SDavid Chisnall } 1887a984708SDavid Chisnall return true; 1897a984708SDavid Chisnall} 1907a984708SDavid Chisnall 1917a984708SDavid Chisnall// Default constructs __n objects starting at __end_ 1927a984708SDavid Chisnall// throws if construction throws 1937a984708SDavid Chisnall// Precondition: __n > 0 1947a984708SDavid Chisnall// Precondition: size() + __n <= capacity() 1957a984708SDavid Chisnall// Postcondition: size() == size() + __n 1967a984708SDavid Chisnalltemplate <class _Tp, class _Allocator> 1977a984708SDavid Chisnallvoid 1987a984708SDavid Chisnall__split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n) 1997a984708SDavid Chisnall{ 2007a984708SDavid Chisnall __alloc_rr& __a = this->__alloc(); 2017a984708SDavid Chisnall do 2027a984708SDavid Chisnall { 2037a984708SDavid Chisnall __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_)); 2047a984708SDavid Chisnall ++this->__end_; 2057a984708SDavid Chisnall --__n; 2067a984708SDavid Chisnall } while (__n > 0); 2077a984708SDavid Chisnall} 2087a984708SDavid Chisnall 2097a984708SDavid Chisnall// Copy constructs __n objects starting at __end_ from __x 2107a984708SDavid Chisnall// throws if construction throws 2117a984708SDavid Chisnall// Precondition: __n > 0 2127a984708SDavid Chisnall// Precondition: size() + __n <= capacity() 2137a984708SDavid Chisnall// Postcondition: size() == old size() + __n 2147a984708SDavid Chisnall// Postcondition: [i] == __x for all i in [size() - __n, __n) 2157a984708SDavid Chisnalltemplate <class _Tp, class _Allocator> 2167a984708SDavid Chisnallvoid 2177a984708SDavid Chisnall__split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x) 2187a984708SDavid Chisnall{ 2197a984708SDavid Chisnall __alloc_rr& __a = this->__alloc(); 2207a984708SDavid Chisnall do 2217a984708SDavid Chisnall { 2227a984708SDavid Chisnall __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), __x); 2237a984708SDavid Chisnall ++this->__end_; 2247a984708SDavid Chisnall --__n; 2257a984708SDavid Chisnall } while (__n > 0); 2267a984708SDavid Chisnall} 2277a984708SDavid Chisnall 2287a984708SDavid Chisnalltemplate <class _Tp, class _Allocator> 2297a984708SDavid Chisnalltemplate <class _InputIter> 2307a984708SDavid Chisnalltypename enable_if 2317a984708SDavid Chisnall< 2327a984708SDavid Chisnall __is_input_iterator<_InputIter>::value && 2337a984708SDavid Chisnall !__is_forward_iterator<_InputIter>::value, 2347a984708SDavid Chisnall void 2357a984708SDavid Chisnall>::type 2367a984708SDavid Chisnall__split_buffer<_Tp, _Allocator>::__construct_at_end(_InputIter __first, _InputIter __last) 2377a984708SDavid Chisnall{ 2387a984708SDavid Chisnall __alloc_rr& __a = this->__alloc(); 2397a984708SDavid Chisnall for (; __first != __last; ++__first) 2407a984708SDavid Chisnall { 2417a984708SDavid Chisnall if (__end_ == __end_cap()) 2427a984708SDavid Chisnall { 2437a984708SDavid Chisnall size_type __old_cap = __end_cap() - __first_; 2447a984708SDavid Chisnall size_type __new_cap = _VSTD::max<size_type>(2 * __old_cap, 8); 2457a984708SDavid Chisnall __split_buffer __buf(__new_cap, 0, __a); 2467a984708SDavid Chisnall for (pointer __p = __begin_; __p != __end_; ++__p, ++__buf.__end_) 2477a984708SDavid Chisnall __alloc_traits::construct(__buf.__alloc(), 2487a984708SDavid Chisnall _VSTD::__to_raw_pointer(__buf.__end_), _VSTD::move(*__p)); 2497a984708SDavid Chisnall swap(__buf); 2507a984708SDavid Chisnall } 2517a984708SDavid Chisnall __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), *__first); 2527a984708SDavid Chisnall ++this->__end_; 2537a984708SDavid Chisnall } 2547a984708SDavid Chisnall} 2557a984708SDavid Chisnall 2567a984708SDavid Chisnalltemplate <class _Tp, class _Allocator> 2577a984708SDavid Chisnalltemplate <class _ForwardIterator> 2587a984708SDavid Chisnalltypename enable_if 2597a984708SDavid Chisnall< 2607a984708SDavid Chisnall __is_forward_iterator<_ForwardIterator>::value, 2617a984708SDavid Chisnall void 2627a984708SDavid Chisnall>::type 2637a984708SDavid Chisnall__split_buffer<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last) 2647a984708SDavid Chisnall{ 2657a984708SDavid Chisnall __alloc_rr& __a = this->__alloc(); 2667a984708SDavid Chisnall for (; __first != __last; ++__first) 2677a984708SDavid Chisnall { 2687a984708SDavid Chisnall __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), *__first); 2697a984708SDavid Chisnall ++this->__end_; 2707a984708SDavid Chisnall } 2717a984708SDavid Chisnall} 2727a984708SDavid Chisnall 2737a984708SDavid Chisnalltemplate <class _Tp, class _Allocator> 2749729cf09SDimitry Andricinline 2757a984708SDavid Chisnallvoid 2767a984708SDavid Chisnall__split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, false_type) 2777a984708SDavid Chisnall{ 27894e3ee44SDavid Chisnall while (__begin_ != __new_begin) 2794bab9fd9SDavid Chisnall __alloc_traits::destroy(__alloc(), __to_raw_pointer(__begin_++)); 2807a984708SDavid Chisnall} 2817a984708SDavid Chisnall 2827a984708SDavid Chisnalltemplate <class _Tp, class _Allocator> 2839729cf09SDimitry Andricinline 2847a984708SDavid Chisnallvoid 2857a984708SDavid Chisnall__split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, true_type) 2867a984708SDavid Chisnall{ 2877a984708SDavid Chisnall __begin_ = __new_begin; 2887a984708SDavid Chisnall} 2897a984708SDavid Chisnall 2907a984708SDavid Chisnalltemplate <class _Tp, class _Allocator> 2914f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 2927a984708SDavid Chisnallvoid 2937a984708SDavid Chisnall__split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, false_type) _NOEXCEPT 2947a984708SDavid Chisnall{ 29594e3ee44SDavid Chisnall while (__new_last != __end_) 2964bab9fd9SDavid Chisnall __alloc_traits::destroy(__alloc(), __to_raw_pointer(--__end_)); 2977a984708SDavid Chisnall} 2987a984708SDavid Chisnall 2997a984708SDavid Chisnalltemplate <class _Tp, class _Allocator> 3004f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 3017a984708SDavid Chisnallvoid 3027a984708SDavid Chisnall__split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, true_type) _NOEXCEPT 3037a984708SDavid Chisnall{ 3047a984708SDavid Chisnall __end_ = __new_last; 3057a984708SDavid Chisnall} 3067a984708SDavid Chisnall 3077a984708SDavid Chisnalltemplate <class _Tp, class _Allocator> 3087a984708SDavid Chisnall__split_buffer<_Tp, _Allocator>::__split_buffer(size_type __cap, size_type __start, __alloc_rr& __a) 3094bab9fd9SDavid Chisnall : __end_cap_(nullptr, __a) 3107a984708SDavid Chisnall{ 3117a984708SDavid Chisnall __first_ = __cap != 0 ? __alloc_traits::allocate(__alloc(), __cap) : nullptr; 3127a984708SDavid Chisnall __begin_ = __end_ = __first_ + __start; 3137a984708SDavid Chisnall __end_cap() = __first_ + __cap; 3147a984708SDavid Chisnall} 3157a984708SDavid Chisnall 3167a984708SDavid Chisnalltemplate <class _Tp, class _Allocator> 3179729cf09SDimitry Andricinline 3187a984708SDavid Chisnall__split_buffer<_Tp, _Allocator>::__split_buffer() 3197a984708SDavid Chisnall _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value) 3204bab9fd9SDavid Chisnall : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr) 3217a984708SDavid Chisnall{ 3227a984708SDavid Chisnall} 3237a984708SDavid Chisnall 3247a984708SDavid Chisnalltemplate <class _Tp, class _Allocator> 3259729cf09SDimitry Andricinline 3267a984708SDavid Chisnall__split_buffer<_Tp, _Allocator>::__split_buffer(__alloc_rr& __a) 3274bab9fd9SDavid Chisnall : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a) 3287a984708SDavid Chisnall{ 3297a984708SDavid Chisnall} 3307a984708SDavid Chisnall 3317a984708SDavid Chisnalltemplate <class _Tp, class _Allocator> 3329729cf09SDimitry Andricinline 3337a984708SDavid Chisnall__split_buffer<_Tp, _Allocator>::__split_buffer(const __alloc_rr& __a) 3344bab9fd9SDavid Chisnall : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a) 3357a984708SDavid Chisnall{ 3367a984708SDavid Chisnall} 3377a984708SDavid Chisnall 3387a984708SDavid Chisnalltemplate <class _Tp, class _Allocator> 3397a984708SDavid Chisnall__split_buffer<_Tp, _Allocator>::~__split_buffer() 3407a984708SDavid Chisnall{ 3417a984708SDavid Chisnall clear(); 3427a984708SDavid Chisnall if (__first_) 3437a984708SDavid Chisnall __alloc_traits::deallocate(__alloc(), __first_, capacity()); 3447a984708SDavid Chisnall} 3457a984708SDavid Chisnall 346540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 3477a984708SDavid Chisnall 3487a984708SDavid Chisnalltemplate <class _Tp, class _Allocator> 3497a984708SDavid Chisnall__split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c) 3507a984708SDavid Chisnall _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value) 3517a984708SDavid Chisnall : __first_(_VSTD::move(__c.__first_)), 3527a984708SDavid Chisnall __begin_(_VSTD::move(__c.__begin_)), 3537a984708SDavid Chisnall __end_(_VSTD::move(__c.__end_)), 3547a984708SDavid Chisnall __end_cap_(_VSTD::move(__c.__end_cap_)) 3557a984708SDavid Chisnall{ 3567a984708SDavid Chisnall __c.__first_ = nullptr; 3577a984708SDavid Chisnall __c.__begin_ = nullptr; 3587a984708SDavid Chisnall __c.__end_ = nullptr; 3597a984708SDavid Chisnall __c.__end_cap() = nullptr; 3607a984708SDavid Chisnall} 3617a984708SDavid Chisnall 3627a984708SDavid Chisnalltemplate <class _Tp, class _Allocator> 3637a984708SDavid Chisnall__split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c, const __alloc_rr& __a) 364540d2a8bSDimitry Andric : __end_cap_(__second_tag(), __a) 3657a984708SDavid Chisnall{ 3667a984708SDavid Chisnall if (__a == __c.__alloc()) 3677a984708SDavid Chisnall { 3687a984708SDavid Chisnall __first_ = __c.__first_; 3697a984708SDavid Chisnall __begin_ = __c.__begin_; 3707a984708SDavid Chisnall __end_ = __c.__end_; 3717a984708SDavid Chisnall __end_cap() = __c.__end_cap(); 3727a984708SDavid Chisnall __c.__first_ = nullptr; 3737a984708SDavid Chisnall __c.__begin_ = nullptr; 3747a984708SDavid Chisnall __c.__end_ = nullptr; 3757a984708SDavid Chisnall __c.__end_cap() = nullptr; 3767a984708SDavid Chisnall } 3777a984708SDavid Chisnall else 3787a984708SDavid Chisnall { 3797a984708SDavid Chisnall size_type __cap = __c.size(); 3807a984708SDavid Chisnall __first_ = __alloc_traits::allocate(__alloc(), __cap); 3817a984708SDavid Chisnall __begin_ = __end_ = __first_; 3827a984708SDavid Chisnall __end_cap() = __first_ + __cap; 38394e3ee44SDavid Chisnall typedef move_iterator<iterator> _Ip; 38494e3ee44SDavid Chisnall __construct_at_end(_Ip(__c.begin()), _Ip(__c.end())); 3857a984708SDavid Chisnall } 3867a984708SDavid Chisnall} 3877a984708SDavid Chisnall 3887a984708SDavid Chisnalltemplate <class _Tp, class _Allocator> 3897a984708SDavid Chisnall__split_buffer<_Tp, _Allocator>& 3907a984708SDavid Chisnall__split_buffer<_Tp, _Allocator>::operator=(__split_buffer&& __c) 3917a984708SDavid Chisnall _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value && 3927a984708SDavid Chisnall is_nothrow_move_assignable<allocator_type>::value) || 3937a984708SDavid Chisnall !__alloc_traits::propagate_on_container_move_assignment::value) 3947a984708SDavid Chisnall{ 3957a984708SDavid Chisnall clear(); 3967a984708SDavid Chisnall shrink_to_fit(); 3977a984708SDavid Chisnall __first_ = __c.__first_; 3987a984708SDavid Chisnall __begin_ = __c.__begin_; 3997a984708SDavid Chisnall __end_ = __c.__end_; 4007a984708SDavid Chisnall __end_cap() = __c.__end_cap(); 4017a984708SDavid Chisnall __move_assign_alloc(__c, 4027a984708SDavid Chisnall integral_constant<bool, 4037a984708SDavid Chisnall __alloc_traits::propagate_on_container_move_assignment::value>()); 4047a984708SDavid Chisnall __c.__first_ = __c.__begin_ = __c.__end_ = __c.__end_cap() = nullptr; 4057a984708SDavid Chisnall return *this; 4067a984708SDavid Chisnall} 4077a984708SDavid Chisnall 408540d2a8bSDimitry Andric#endif // _LIBCPP_CXX03_LANG 4097a984708SDavid Chisnall 4107a984708SDavid Chisnalltemplate <class _Tp, class _Allocator> 4117a984708SDavid Chisnallvoid 4127a984708SDavid Chisnall__split_buffer<_Tp, _Allocator>::swap(__split_buffer& __x) 4137a984708SDavid Chisnall _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value|| 4147a984708SDavid Chisnall __is_nothrow_swappable<__alloc_rr>::value) 4157a984708SDavid Chisnall{ 4167a984708SDavid Chisnall _VSTD::swap(__first_, __x.__first_); 4177a984708SDavid Chisnall _VSTD::swap(__begin_, __x.__begin_); 4187a984708SDavid Chisnall _VSTD::swap(__end_, __x.__end_); 4197a984708SDavid Chisnall _VSTD::swap(__end_cap(), __x.__end_cap()); 420854fa44bSDimitry Andric __swap_allocator(__alloc(), __x.__alloc()); 4217a984708SDavid Chisnall} 4227a984708SDavid Chisnall 4237a984708SDavid Chisnalltemplate <class _Tp, class _Allocator> 4247a984708SDavid Chisnallvoid 4257a984708SDavid Chisnall__split_buffer<_Tp, _Allocator>::reserve(size_type __n) 4267a984708SDavid Chisnall{ 4277a984708SDavid Chisnall if (__n < capacity()) 4287a984708SDavid Chisnall { 4297a984708SDavid Chisnall __split_buffer<value_type, __alloc_rr&> __t(__n, 0, __alloc()); 4307a984708SDavid Chisnall __t.__construct_at_end(move_iterator<pointer>(__begin_), 4317a984708SDavid Chisnall move_iterator<pointer>(__end_)); 4327a984708SDavid Chisnall _VSTD::swap(__first_, __t.__first_); 4337a984708SDavid Chisnall _VSTD::swap(__begin_, __t.__begin_); 4347a984708SDavid Chisnall _VSTD::swap(__end_, __t.__end_); 4357a984708SDavid Chisnall _VSTD::swap(__end_cap(), __t.__end_cap()); 4367a984708SDavid Chisnall } 4377a984708SDavid Chisnall} 4387a984708SDavid Chisnall 4397a984708SDavid Chisnalltemplate <class _Tp, class _Allocator> 4407a984708SDavid Chisnallvoid 4417a984708SDavid Chisnall__split_buffer<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT 4427a984708SDavid Chisnall{ 4437a984708SDavid Chisnall if (capacity() > size()) 4447a984708SDavid Chisnall { 4457a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS 4467a984708SDavid Chisnall try 4477a984708SDavid Chisnall { 4487a984708SDavid Chisnall#endif // _LIBCPP_NO_EXCEPTIONS 4497a984708SDavid Chisnall __split_buffer<value_type, __alloc_rr&> __t(size(), 0, __alloc()); 4507a984708SDavid Chisnall __t.__construct_at_end(move_iterator<pointer>(__begin_), 4517a984708SDavid Chisnall move_iterator<pointer>(__end_)); 4527a984708SDavid Chisnall __t.__end_ = __t.__begin_ + (__end_ - __begin_); 4537a984708SDavid Chisnall _VSTD::swap(__first_, __t.__first_); 4547a984708SDavid Chisnall _VSTD::swap(__begin_, __t.__begin_); 4557a984708SDavid Chisnall _VSTD::swap(__end_, __t.__end_); 4567a984708SDavid Chisnall _VSTD::swap(__end_cap(), __t.__end_cap()); 4577a984708SDavid Chisnall#ifndef _LIBCPP_NO_EXCEPTIONS 4587a984708SDavid Chisnall } 4597a984708SDavid Chisnall catch (...) 4607a984708SDavid Chisnall { 4617a984708SDavid Chisnall } 4627a984708SDavid Chisnall#endif // _LIBCPP_NO_EXCEPTIONS 4637a984708SDavid Chisnall } 4647a984708SDavid Chisnall} 4657a984708SDavid Chisnall 4667a984708SDavid Chisnalltemplate <class _Tp, class _Allocator> 4677a984708SDavid Chisnallvoid 4687a984708SDavid Chisnall__split_buffer<_Tp, _Allocator>::push_front(const_reference __x) 4697a984708SDavid Chisnall{ 4707a984708SDavid Chisnall if (__begin_ == __first_) 4717a984708SDavid Chisnall { 4727a984708SDavid Chisnall if (__end_ < __end_cap()) 4737a984708SDavid Chisnall { 4747a984708SDavid Chisnall difference_type __d = __end_cap() - __end_; 4757a984708SDavid Chisnall __d = (__d + 1) / 2; 4767a984708SDavid Chisnall __begin_ = _VSTD::move_backward(__begin_, __end_, __end_ + __d); 4777a984708SDavid Chisnall __end_ += __d; 4787a984708SDavid Chisnall } 4797a984708SDavid Chisnall else 4807a984708SDavid Chisnall { 48194e3ee44SDavid Chisnall size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1); 4827a984708SDavid Chisnall __split_buffer<value_type, __alloc_rr&> __t(__c, (__c + 3) / 4, __alloc()); 4837a984708SDavid Chisnall __t.__construct_at_end(move_iterator<pointer>(__begin_), 4847a984708SDavid Chisnall move_iterator<pointer>(__end_)); 4857a984708SDavid Chisnall _VSTD::swap(__first_, __t.__first_); 4867a984708SDavid Chisnall _VSTD::swap(__begin_, __t.__begin_); 4877a984708SDavid Chisnall _VSTD::swap(__end_, __t.__end_); 4887a984708SDavid Chisnall _VSTD::swap(__end_cap(), __t.__end_cap()); 4897a984708SDavid Chisnall } 4907a984708SDavid Chisnall } 4917a984708SDavid Chisnall __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__begin_-1), __x); 4927a984708SDavid Chisnall --__begin_; 4937a984708SDavid Chisnall} 4947a984708SDavid Chisnall 495540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 4967a984708SDavid Chisnall 4977a984708SDavid Chisnalltemplate <class _Tp, class _Allocator> 4987a984708SDavid Chisnallvoid 4997a984708SDavid Chisnall__split_buffer<_Tp, _Allocator>::push_front(value_type&& __x) 5007a984708SDavid Chisnall{ 5017a984708SDavid Chisnall if (__begin_ == __first_) 5027a984708SDavid Chisnall { 5037a984708SDavid Chisnall if (__end_ < __end_cap()) 5047a984708SDavid Chisnall { 5057a984708SDavid Chisnall difference_type __d = __end_cap() - __end_; 5067a984708SDavid Chisnall __d = (__d + 1) / 2; 5077a984708SDavid Chisnall __begin_ = _VSTD::move_backward(__begin_, __end_, __end_ + __d); 5087a984708SDavid Chisnall __end_ += __d; 5097a984708SDavid Chisnall } 5107a984708SDavid Chisnall else 5117a984708SDavid Chisnall { 51294e3ee44SDavid Chisnall size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1); 5137a984708SDavid Chisnall __split_buffer<value_type, __alloc_rr&> __t(__c, (__c + 3) / 4, __alloc()); 5147a984708SDavid Chisnall __t.__construct_at_end(move_iterator<pointer>(__begin_), 5157a984708SDavid Chisnall move_iterator<pointer>(__end_)); 5167a984708SDavid Chisnall _VSTD::swap(__first_, __t.__first_); 5177a984708SDavid Chisnall _VSTD::swap(__begin_, __t.__begin_); 5187a984708SDavid Chisnall _VSTD::swap(__end_, __t.__end_); 5197a984708SDavid Chisnall _VSTD::swap(__end_cap(), __t.__end_cap()); 5207a984708SDavid Chisnall } 5217a984708SDavid Chisnall } 5227a984708SDavid Chisnall __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__begin_-1), 5237a984708SDavid Chisnall _VSTD::move(__x)); 5247a984708SDavid Chisnall --__begin_; 5257a984708SDavid Chisnall} 5267a984708SDavid Chisnall 527540d2a8bSDimitry Andric#endif // _LIBCPP_CXX03_LANG 5287a984708SDavid Chisnall 5297a984708SDavid Chisnalltemplate <class _Tp, class _Allocator> 5304f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 5317a984708SDavid Chisnallvoid 5327a984708SDavid Chisnall__split_buffer<_Tp, _Allocator>::push_back(const_reference __x) 5337a984708SDavid Chisnall{ 5347a984708SDavid Chisnall if (__end_ == __end_cap()) 5357a984708SDavid Chisnall { 5367a984708SDavid Chisnall if (__begin_ > __first_) 5377a984708SDavid Chisnall { 5387a984708SDavid Chisnall difference_type __d = __begin_ - __first_; 5397a984708SDavid Chisnall __d = (__d + 1) / 2; 5407a984708SDavid Chisnall __end_ = _VSTD::move(__begin_, __end_, __begin_ - __d); 5417a984708SDavid Chisnall __begin_ -= __d; 5427a984708SDavid Chisnall } 5437a984708SDavid Chisnall else 5447a984708SDavid Chisnall { 54594e3ee44SDavid Chisnall size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1); 5467a984708SDavid Chisnall __split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc()); 5477a984708SDavid Chisnall __t.__construct_at_end(move_iterator<pointer>(__begin_), 5487a984708SDavid Chisnall move_iterator<pointer>(__end_)); 5497a984708SDavid Chisnall _VSTD::swap(__first_, __t.__first_); 5507a984708SDavid Chisnall _VSTD::swap(__begin_, __t.__begin_); 5517a984708SDavid Chisnall _VSTD::swap(__end_, __t.__end_); 5527a984708SDavid Chisnall _VSTD::swap(__end_cap(), __t.__end_cap()); 5537a984708SDavid Chisnall } 5547a984708SDavid Chisnall } 5557a984708SDavid Chisnall __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_), __x); 5567a984708SDavid Chisnall ++__end_; 5577a984708SDavid Chisnall} 5587a984708SDavid Chisnall 559540d2a8bSDimitry Andric#ifndef _LIBCPP_CXX03_LANG 5607a984708SDavid Chisnall 5617a984708SDavid Chisnalltemplate <class _Tp, class _Allocator> 5627a984708SDavid Chisnallvoid 5637a984708SDavid Chisnall__split_buffer<_Tp, _Allocator>::push_back(value_type&& __x) 5647a984708SDavid Chisnall{ 5657a984708SDavid Chisnall if (__end_ == __end_cap()) 5667a984708SDavid Chisnall { 5677a984708SDavid Chisnall if (__begin_ > __first_) 5687a984708SDavid Chisnall { 5697a984708SDavid Chisnall difference_type __d = __begin_ - __first_; 5707a984708SDavid Chisnall __d = (__d + 1) / 2; 5717a984708SDavid Chisnall __end_ = _VSTD::move(__begin_, __end_, __begin_ - __d); 5727a984708SDavid Chisnall __begin_ -= __d; 5737a984708SDavid Chisnall } 5747a984708SDavid Chisnall else 5757a984708SDavid Chisnall { 57694e3ee44SDavid Chisnall size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1); 5777a984708SDavid Chisnall __split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc()); 5787a984708SDavid Chisnall __t.__construct_at_end(move_iterator<pointer>(__begin_), 5797a984708SDavid Chisnall move_iterator<pointer>(__end_)); 5807a984708SDavid Chisnall _VSTD::swap(__first_, __t.__first_); 5817a984708SDavid Chisnall _VSTD::swap(__begin_, __t.__begin_); 5827a984708SDavid Chisnall _VSTD::swap(__end_, __t.__end_); 5837a984708SDavid Chisnall _VSTD::swap(__end_cap(), __t.__end_cap()); 5847a984708SDavid Chisnall } 5857a984708SDavid Chisnall } 5867a984708SDavid Chisnall __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_), 5877a984708SDavid Chisnall _VSTD::move(__x)); 5887a984708SDavid Chisnall ++__end_; 5897a984708SDavid Chisnall} 5907a984708SDavid Chisnall 5917a984708SDavid Chisnalltemplate <class _Tp, class _Allocator> 5927a984708SDavid Chisnalltemplate <class... _Args> 5937a984708SDavid Chisnallvoid 5947a984708SDavid Chisnall__split_buffer<_Tp, _Allocator>::emplace_back(_Args&&... __args) 5957a984708SDavid Chisnall{ 5967a984708SDavid Chisnall if (__end_ == __end_cap()) 5977a984708SDavid Chisnall { 5987a984708SDavid Chisnall if (__begin_ > __first_) 5997a984708SDavid Chisnall { 6007a984708SDavid Chisnall difference_type __d = __begin_ - __first_; 6017a984708SDavid Chisnall __d = (__d + 1) / 2; 6027a984708SDavid Chisnall __end_ = _VSTD::move(__begin_, __end_, __begin_ - __d); 6037a984708SDavid Chisnall __begin_ -= __d; 6047a984708SDavid Chisnall } 6057a984708SDavid Chisnall else 6067a984708SDavid Chisnall { 60794e3ee44SDavid Chisnall size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1); 6087a984708SDavid Chisnall __split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc()); 6097a984708SDavid Chisnall __t.__construct_at_end(move_iterator<pointer>(__begin_), 6107a984708SDavid Chisnall move_iterator<pointer>(__end_)); 6117a984708SDavid Chisnall _VSTD::swap(__first_, __t.__first_); 6127a984708SDavid Chisnall _VSTD::swap(__begin_, __t.__begin_); 6137a984708SDavid Chisnall _VSTD::swap(__end_, __t.__end_); 6147a984708SDavid Chisnall _VSTD::swap(__end_cap(), __t.__end_cap()); 6157a984708SDavid Chisnall } 6167a984708SDavid Chisnall } 6177a984708SDavid Chisnall __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_), 6187a984708SDavid Chisnall _VSTD::forward<_Args>(__args)...); 6197a984708SDavid Chisnall ++__end_; 6207a984708SDavid Chisnall} 6217a984708SDavid Chisnall 622540d2a8bSDimitry Andric#endif // _LIBCPP_CXX03_LANG 6237a984708SDavid Chisnall 6247a984708SDavid Chisnalltemplate <class _Tp, class _Allocator> 6254f7ab58eSDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 6267a984708SDavid Chisnallvoid 6277a984708SDavid Chisnallswap(__split_buffer<_Tp, _Allocator>& __x, __split_buffer<_Tp, _Allocator>& __y) 6287a984708SDavid Chisnall _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) 6297a984708SDavid Chisnall{ 6307a984708SDavid Chisnall __x.swap(__y); 6317a984708SDavid Chisnall} 6327a984708SDavid Chisnall 6337a984708SDavid Chisnall_LIBCPP_END_NAMESPACE_STD 6347a984708SDavid Chisnall 635*f9448bf3SDimitry Andric_LIBCPP_POP_MACROS 636*f9448bf3SDimitry Andric 6377a984708SDavid Chisnall#endif // _LIBCPP_SPLIT_BUFFER 638