__split_buffer revision 253146
1227825Stheraven// -*- C++ -*-
2227825Stheraven#ifndef _LIBCPP_SPLIT_BUFFER
3227825Stheraven#define _LIBCPP_SPLIT_BUFFER
4227825Stheraven
5227825Stheraven#include <__config>
6227825Stheraven#include <type_traits>
7227825Stheraven#include <algorithm>
8227825Stheraven
9232924Stheraven#include <__undef_min_max>
10232924Stheraven
11227825Stheraven#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
12227825Stheraven#pragma GCC system_header
13227825Stheraven#endif
14227825Stheraven
15227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD
16227825Stheraven
17227825Stheraventemplate <bool>
18227825Stheravenclass __split_buffer_common
19227825Stheraven{
20227825Stheravenprotected:
21227825Stheraven    void __throw_length_error() const;
22227825Stheraven    void __throw_out_of_range() const;
23227825Stheraven};
24227825Stheraven
25227825Stheraventemplate <class _Tp, class _Allocator = allocator<_Tp> >
26227825Stheravenstruct __split_buffer
27227825Stheraven    : private __split_buffer_common<true>
28227825Stheraven{
29227825Stheravenprivate:
30227825Stheraven    __split_buffer(const __split_buffer&);
31227825Stheraven    __split_buffer& operator=(const __split_buffer&);
32227825Stheravenpublic:
33227825Stheraven    typedef _Tp                                             value_type;
34227825Stheraven    typedef _Allocator                                      allocator_type;
35227825Stheraven    typedef typename remove_reference<allocator_type>::type __alloc_rr;
36227825Stheraven    typedef allocator_traits<__alloc_rr>                    __alloc_traits;
37227825Stheraven    typedef value_type&                                     reference;
38227825Stheraven    typedef const value_type&                               const_reference;
39227825Stheraven    typedef typename __alloc_traits::size_type              size_type;
40227825Stheraven    typedef typename __alloc_traits::difference_type        difference_type;
41227825Stheraven    typedef typename __alloc_traits::pointer                pointer;
42227825Stheraven    typedef typename __alloc_traits::const_pointer          const_pointer;
43227825Stheraven    typedef pointer                                         iterator;
44227825Stheraven    typedef const_pointer                                   const_iterator;
45227825Stheraven
46227825Stheraven    pointer                                         __first_;
47227825Stheraven    pointer                                         __begin_;
48227825Stheraven    pointer                                         __end_;
49227825Stheraven    __compressed_pair<pointer, allocator_type> __end_cap_;
50227825Stheraven
51227825Stheraven    typedef typename add_lvalue_reference<allocator_type>::type __alloc_ref;
52227825Stheraven    typedef typename add_lvalue_reference<allocator_type>::type __alloc_const_ref;
53227825Stheraven
54227825Stheraven    _LIBCPP_INLINE_VISIBILITY __alloc_rr&           __alloc() _NOEXCEPT         {return __end_cap_.second();}
55227825Stheraven    _LIBCPP_INLINE_VISIBILITY const __alloc_rr&     __alloc() const _NOEXCEPT   {return __end_cap_.second();}
56227825Stheraven    _LIBCPP_INLINE_VISIBILITY pointer&              __end_cap() _NOEXCEPT       {return __end_cap_.first();}
57227825Stheraven    _LIBCPP_INLINE_VISIBILITY const pointer&        __end_cap() const _NOEXCEPT {return __end_cap_.first();}
58227825Stheraven
59227825Stheraven    __split_buffer()
60227825Stheraven        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
61227825Stheraven    explicit __split_buffer(__alloc_rr& __a);
62227825Stheraven    explicit __split_buffer(const __alloc_rr& __a);
63227825Stheraven    __split_buffer(size_type __cap, size_type __start, __alloc_rr& __a);
64227825Stheraven    ~__split_buffer();
65227825Stheraven
66227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
67227825Stheraven    __split_buffer(__split_buffer&& __c)
68227825Stheraven        _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
69227825Stheraven    __split_buffer(__split_buffer&& __c, const __alloc_rr& __a);
70227825Stheraven    __split_buffer& operator=(__split_buffer&& __c)
71227825Stheraven        _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value &&
72227825Stheraven                is_nothrow_move_assignable<allocator_type>::value) ||
73227825Stheraven               !__alloc_traits::propagate_on_container_move_assignment::value);
74227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
75227825Stheraven
76227825Stheraven    _LIBCPP_INLINE_VISIBILITY       iterator begin() _NOEXCEPT       {return __begin_;}
77227825Stheraven    _LIBCPP_INLINE_VISIBILITY const_iterator begin() const _NOEXCEPT {return __begin_;}
78227825Stheraven    _LIBCPP_INLINE_VISIBILITY       iterator end() _NOEXCEPT         {return __end_;}
79227825Stheraven    _LIBCPP_INLINE_VISIBILITY const_iterator end() const _NOEXCEPT   {return __end_;}
80227825Stheraven
81227825Stheraven    _LIBCPP_INLINE_VISIBILITY
82227825Stheraven    void clear() _NOEXCEPT
83227825Stheraven        {__destruct_at_end(__begin_);}
84227825Stheraven    _LIBCPP_INLINE_VISIBILITY size_type size() const {return static_cast<size_type>(__end_ - __begin_);}
85227825Stheraven    _LIBCPP_INLINE_VISIBILITY bool empty()     const {return __end_ == __begin_;}
86227825Stheraven    _LIBCPP_INLINE_VISIBILITY size_type capacity() const {return static_cast<size_type>(__end_cap() - __first_);}
87227825Stheraven    _LIBCPP_INLINE_VISIBILITY size_type __front_spare() const {return static_cast<size_type>(__begin_ - __first_);}
88227825Stheraven    _LIBCPP_INLINE_VISIBILITY size_type __back_spare() const {return static_cast<size_type>(__end_cap() - __end_);}
89227825Stheraven
90227825Stheraven    _LIBCPP_INLINE_VISIBILITY       reference front()       {return *__begin_;}
91227825Stheraven    _LIBCPP_INLINE_VISIBILITY const_reference front() const {return *__begin_;}
92227825Stheraven    _LIBCPP_INLINE_VISIBILITY       reference back()        {return *(__end_ - 1);}
93227825Stheraven    _LIBCPP_INLINE_VISIBILITY const_reference back() const  {return *(__end_ - 1);}
94227825Stheraven
95227825Stheraven    void reserve(size_type __n);
96227825Stheraven    void shrink_to_fit() _NOEXCEPT;
97227825Stheraven    void push_front(const_reference __x);
98232924Stheraven    _LIBCPP_INLINE_VISIBILITY void push_back(const_reference __x);
99227825Stheraven#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
100227825Stheraven    void push_front(value_type&& __x);
101227825Stheraven    void push_back(value_type&& __x);
102227825Stheraven#if !defined(_LIBCPP_HAS_NO_VARIADICS)
103227825Stheraven    template <class... _Args>
104227825Stheraven        void emplace_back(_Args&&... __args);
105227825Stheraven#endif  // !defined(_LIBCPP_HAS_NO_VARIADICS)
106227825Stheraven#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
107227825Stheraven
108227825Stheraven    _LIBCPP_INLINE_VISIBILITY void pop_front() {__destruct_at_begin(__begin_+1);}
109227825Stheraven    _LIBCPP_INLINE_VISIBILITY void pop_back() {__destruct_at_end(__end_-1);}
110227825Stheraven
111227825Stheraven    void __construct_at_end(size_type __n);
112227825Stheraven    void __construct_at_end(size_type __n, const_reference __x);
113227825Stheraven    template <class _InputIter>
114227825Stheraven        typename enable_if
115227825Stheraven        <
116227825Stheraven            __is_input_iterator<_InputIter>::value &&
117227825Stheraven           !__is_forward_iterator<_InputIter>::value,
118227825Stheraven            void
119227825Stheraven        >::type
120227825Stheraven        __construct_at_end(_InputIter __first, _InputIter __last);
121227825Stheraven    template <class _ForwardIterator>
122227825Stheraven        typename enable_if
123227825Stheraven        <
124227825Stheraven            __is_forward_iterator<_ForwardIterator>::value,
125227825Stheraven            void
126227825Stheraven        >::type
127227825Stheraven        __construct_at_end(_ForwardIterator __first, _ForwardIterator __last);
128227825Stheraven
129227825Stheraven    _LIBCPP_INLINE_VISIBILITY void __destruct_at_begin(pointer __new_begin)
130227825Stheraven        {__destruct_at_begin(__new_begin, is_trivially_destructible<value_type>());}
131227825Stheraven        void __destruct_at_begin(pointer __new_begin, false_type);
132227825Stheraven        void __destruct_at_begin(pointer __new_begin, true_type);
133227825Stheraven
134227825Stheraven    _LIBCPP_INLINE_VISIBILITY
135227825Stheraven    void __destruct_at_end(pointer __new_last) _NOEXCEPT
136232924Stheraven        {__destruct_at_end(__new_last, false_type());}
137232924Stheraven    _LIBCPP_INLINE_VISIBILITY
138227825Stheraven        void __destruct_at_end(pointer __new_last, false_type) _NOEXCEPT;
139232924Stheraven    _LIBCPP_INLINE_VISIBILITY
140227825Stheraven        void __destruct_at_end(pointer __new_last, true_type) _NOEXCEPT;
141227825Stheraven
142227825Stheraven    void swap(__split_buffer& __x)
143227825Stheraven        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value||
144227825Stheraven                   __is_nothrow_swappable<__alloc_rr>::value);
145227825Stheraven
146227825Stheraven    bool __invariants() const;
147227825Stheraven
148227825Stheravenprivate:
149227825Stheraven    _LIBCPP_INLINE_VISIBILITY
150227825Stheraven    void __move_assign_alloc(__split_buffer& __c, true_type)
151227825Stheraven        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
152227825Stheraven        {
153227825Stheraven            __alloc() = _VSTD::move(__c.__alloc());
154227825Stheraven        }
155227825Stheraven
156227825Stheraven    _LIBCPP_INLINE_VISIBILITY
157232924Stheraven    void __move_assign_alloc(__split_buffer&, false_type) _NOEXCEPT
158227825Stheraven        {}
159227825Stheraven
160227825Stheraven    _LIBCPP_INLINE_VISIBILITY
161227825Stheraven    static void __swap_alloc(__alloc_rr& __x, __alloc_rr& __y)
162227825Stheraven        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value||
163227825Stheraven                   __is_nothrow_swappable<__alloc_rr>::value)
164227825Stheraven        {__swap_alloc(__x, __y, integral_constant<bool,
165227825Stheraven                      __alloc_traits::propagate_on_container_swap::value>());}
166227825Stheraven
167227825Stheraven    _LIBCPP_INLINE_VISIBILITY
168227825Stheraven    static void __swap_alloc(__alloc_rr& __x, __alloc_rr& __y, true_type)
169227825Stheraven        _NOEXCEPT_(__is_nothrow_swappable<__alloc_rr>::value)
170227825Stheraven        {
171227825Stheraven            using _VSTD::swap;
172227825Stheraven            swap(__x, __y);
173227825Stheraven        }
174227825Stheraven
175227825Stheraven    _LIBCPP_INLINE_VISIBILITY
176232924Stheraven    static void __swap_alloc(__alloc_rr&, __alloc_rr&, false_type) _NOEXCEPT
177227825Stheraven        {}
178227825Stheraven};
179227825Stheraven
180227825Stheraventemplate <class _Tp, class _Allocator>
181227825Stheravenbool
182227825Stheraven__split_buffer<_Tp, _Allocator>::__invariants() const
183227825Stheraven{
184227825Stheraven    if (__first_ == nullptr)
185227825Stheraven    {
186227825Stheraven        if (__begin_ != nullptr)
187227825Stheraven            return false;
188227825Stheraven        if (__end_ != nullptr)
189227825Stheraven            return false;
190227825Stheraven        if (__end_cap() != nullptr)
191227825Stheraven            return false;
192227825Stheraven    }
193227825Stheraven    else
194227825Stheraven    {
195227825Stheraven        if (__begin_ < __first_)
196227825Stheraven            return false;
197227825Stheraven        if (__end_ < __begin_)
198227825Stheraven            return false;
199227825Stheraven        if (__end_cap() < __end_)
200227825Stheraven            return false;
201227825Stheraven    }
202227825Stheraven    return true;
203227825Stheraven}
204227825Stheraven
205227825Stheraven//  Default constructs __n objects starting at __end_
206227825Stheraven//  throws if construction throws
207227825Stheraven//  Precondition:  __n > 0
208227825Stheraven//  Precondition:  size() + __n <= capacity()
209227825Stheraven//  Postcondition:  size() == size() + __n
210227825Stheraventemplate <class _Tp, class _Allocator>
211227825Stheravenvoid
212227825Stheraven__split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n)
213227825Stheraven{
214227825Stheraven    __alloc_rr& __a = this->__alloc();
215227825Stheraven    do
216227825Stheraven    {
217227825Stheraven        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_));
218227825Stheraven        ++this->__end_;
219227825Stheraven        --__n;
220227825Stheraven    } while (__n > 0);
221227825Stheraven}
222227825Stheraven
223227825Stheraven//  Copy constructs __n objects starting at __end_ from __x
224227825Stheraven//  throws if construction throws
225227825Stheraven//  Precondition:  __n > 0
226227825Stheraven//  Precondition:  size() + __n <= capacity()
227227825Stheraven//  Postcondition:  size() == old size() + __n
228227825Stheraven//  Postcondition:  [i] == __x for all i in [size() - __n, __n)
229227825Stheraventemplate <class _Tp, class _Allocator>
230227825Stheravenvoid
231227825Stheraven__split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x)
232227825Stheraven{
233227825Stheraven    __alloc_rr& __a = this->__alloc();
234227825Stheraven    do
235227825Stheraven    {
236227825Stheraven        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), __x);
237227825Stheraven        ++this->__end_;
238227825Stheraven        --__n;
239227825Stheraven    } while (__n > 0);
240227825Stheraven}
241227825Stheraven
242227825Stheraventemplate <class _Tp, class _Allocator>
243227825Stheraventemplate <class _InputIter>
244227825Stheraventypename enable_if
245227825Stheraven<
246227825Stheraven     __is_input_iterator<_InputIter>::value &&
247227825Stheraven    !__is_forward_iterator<_InputIter>::value,
248227825Stheraven    void
249227825Stheraven>::type
250227825Stheraven__split_buffer<_Tp, _Allocator>::__construct_at_end(_InputIter __first, _InputIter __last)
251227825Stheraven{
252227825Stheraven    __alloc_rr& __a = this->__alloc();
253227825Stheraven    for (; __first != __last; ++__first)
254227825Stheraven    {
255227825Stheraven        if (__end_ == __end_cap())
256227825Stheraven        {
257227825Stheraven            size_type __old_cap = __end_cap() - __first_;
258227825Stheraven            size_type __new_cap = _VSTD::max<size_type>(2 * __old_cap, 8);
259227825Stheraven            __split_buffer __buf(__new_cap, 0, __a);
260227825Stheraven            for (pointer __p = __begin_; __p != __end_; ++__p, ++__buf.__end_)
261227825Stheraven                __alloc_traits::construct(__buf.__alloc(),
262227825Stheraven                        _VSTD::__to_raw_pointer(__buf.__end_), _VSTD::move(*__p));
263227825Stheraven            swap(__buf);
264227825Stheraven        }
265227825Stheraven        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), *__first);
266227825Stheraven        ++this->__end_;
267227825Stheraven    }
268227825Stheraven}
269227825Stheraven
270227825Stheraventemplate <class _Tp, class _Allocator>
271227825Stheraventemplate <class _ForwardIterator>
272227825Stheraventypename enable_if
273227825Stheraven<
274227825Stheraven    __is_forward_iterator<_ForwardIterator>::value,
275227825Stheraven    void
276227825Stheraven>::type
277227825Stheraven__split_buffer<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last)
278227825Stheraven{
279227825Stheraven    __alloc_rr& __a = this->__alloc();
280227825Stheraven    for (; __first != __last; ++__first)
281227825Stheraven    {
282227825Stheraven        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), *__first);
283227825Stheraven        ++this->__end_;
284227825Stheraven    }
285227825Stheraven}
286227825Stheraven
287227825Stheraventemplate <class _Tp, class _Allocator>
288227825Stheraven_LIBCPP_INLINE_VISIBILITY inline
289227825Stheravenvoid
290227825Stheraven__split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, false_type)
291227825Stheraven{
292232924Stheraven    while (__begin_ != __new_begin)
293253146Stheraven        __alloc_traits::destroy(__alloc(), __to_raw_pointer(__begin_++));
294227825Stheraven}
295227825Stheraven
296227825Stheraventemplate <class _Tp, class _Allocator>
297227825Stheraven_LIBCPP_INLINE_VISIBILITY inline
298227825Stheravenvoid
299227825Stheraven__split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, true_type)
300227825Stheraven{
301227825Stheraven    __begin_ = __new_begin;
302227825Stheraven}
303227825Stheraven
304227825Stheraventemplate <class _Tp, class _Allocator>
305227825Stheraven_LIBCPP_INLINE_VISIBILITY inline
306227825Stheravenvoid
307227825Stheraven__split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, false_type) _NOEXCEPT
308227825Stheraven{
309232924Stheraven    while (__new_last != __end_)
310253146Stheraven        __alloc_traits::destroy(__alloc(), __to_raw_pointer(--__end_));
311227825Stheraven}
312227825Stheraven
313227825Stheraventemplate <class _Tp, class _Allocator>
314227825Stheraven_LIBCPP_INLINE_VISIBILITY inline
315227825Stheravenvoid
316227825Stheraven__split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, true_type) _NOEXCEPT
317227825Stheraven{
318227825Stheraven    __end_ = __new_last;
319227825Stheraven}
320227825Stheraven
321227825Stheraventemplate <class _Tp, class _Allocator>
322227825Stheraven__split_buffer<_Tp, _Allocator>::__split_buffer(size_type __cap, size_type __start, __alloc_rr& __a)
323253146Stheraven    : __end_cap_(nullptr, __a)
324227825Stheraven{
325227825Stheraven    __first_ = __cap != 0 ? __alloc_traits::allocate(__alloc(), __cap) : nullptr;
326227825Stheraven    __begin_ = __end_ = __first_ + __start;
327227825Stheraven    __end_cap() = __first_ + __cap;
328227825Stheraven}
329227825Stheraven
330227825Stheraventemplate <class _Tp, class _Allocator>
331227825Stheraven_LIBCPP_INLINE_VISIBILITY inline
332227825Stheraven__split_buffer<_Tp, _Allocator>::__split_buffer()
333227825Stheraven    _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
334253146Stheraven    : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr)
335227825Stheraven{
336227825Stheraven}
337227825Stheraven
338227825Stheraventemplate <class _Tp, class _Allocator>
339227825Stheraven_LIBCPP_INLINE_VISIBILITY inline
340227825Stheraven__split_buffer<_Tp, _Allocator>::__split_buffer(__alloc_rr& __a)
341253146Stheraven    : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a)
342227825Stheraven{
343227825Stheraven}
344227825Stheraven
345227825Stheraventemplate <class _Tp, class _Allocator>
346227825Stheraven_LIBCPP_INLINE_VISIBILITY inline
347227825Stheraven__split_buffer<_Tp, _Allocator>::__split_buffer(const __alloc_rr& __a)
348253146Stheraven    : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a)
349227825Stheraven{
350227825Stheraven}
351227825Stheraven
352227825Stheraventemplate <class _Tp, class _Allocator>
353227825Stheraven__split_buffer<_Tp, _Allocator>::~__split_buffer()
354227825Stheraven{
355227825Stheraven    clear();
356227825Stheraven    if (__first_)
357227825Stheraven        __alloc_traits::deallocate(__alloc(), __first_, capacity());
358227825Stheraven}
359227825Stheraven
360227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
361227825Stheraven
362227825Stheraventemplate <class _Tp, class _Allocator>
363227825Stheraven__split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c)
364227825Stheraven    _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
365227825Stheraven    : __first_(_VSTD::move(__c.__first_)),
366227825Stheraven      __begin_(_VSTD::move(__c.__begin_)),
367227825Stheraven      __end_(_VSTD::move(__c.__end_)),
368227825Stheraven      __end_cap_(_VSTD::move(__c.__end_cap_))
369227825Stheraven{
370227825Stheraven    __c.__first_ = nullptr;
371227825Stheraven    __c.__begin_ = nullptr;
372227825Stheraven    __c.__end_ = nullptr;
373227825Stheraven    __c.__end_cap() = nullptr;
374227825Stheraven}
375227825Stheraven
376227825Stheraventemplate <class _Tp, class _Allocator>
377227825Stheraven__split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c, const __alloc_rr& __a)
378227825Stheraven    : __end_cap_(__a)
379227825Stheraven{
380227825Stheraven    if (__a == __c.__alloc())
381227825Stheraven    {
382227825Stheraven        __first_ = __c.__first_;
383227825Stheraven        __begin_ = __c.__begin_;
384227825Stheraven        __end_ = __c.__end_;
385227825Stheraven        __end_cap() = __c.__end_cap();
386227825Stheraven        __c.__first_ = nullptr;
387227825Stheraven        __c.__begin_ = nullptr;
388227825Stheraven        __c.__end_ = nullptr;
389227825Stheraven        __c.__end_cap() = nullptr;
390227825Stheraven    }
391227825Stheraven    else
392227825Stheraven    {
393227825Stheraven        size_type __cap = __c.size();
394227825Stheraven        __first_ = __alloc_traits::allocate(__alloc(), __cap);
395227825Stheraven        __begin_ = __end_ = __first_;
396227825Stheraven        __end_cap() = __first_ + __cap;
397232924Stheraven        typedef move_iterator<iterator> _Ip;
398232924Stheraven        __construct_at_end(_Ip(__c.begin()), _Ip(__c.end()));
399227825Stheraven    }
400227825Stheraven}
401227825Stheraven
402227825Stheraventemplate <class _Tp, class _Allocator>
403227825Stheraven__split_buffer<_Tp, _Allocator>&
404227825Stheraven__split_buffer<_Tp, _Allocator>::operator=(__split_buffer&& __c)
405227825Stheraven    _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value &&
406227825Stheraven                is_nothrow_move_assignable<allocator_type>::value) ||
407227825Stheraven               !__alloc_traits::propagate_on_container_move_assignment::value)
408227825Stheraven{
409227825Stheraven    clear();
410227825Stheraven    shrink_to_fit();
411227825Stheraven    __first_ = __c.__first_;
412227825Stheraven    __begin_ = __c.__begin_;
413227825Stheraven    __end_ = __c.__end_;
414227825Stheraven    __end_cap() = __c.__end_cap();
415227825Stheraven    __move_assign_alloc(__c,
416227825Stheraven        integral_constant<bool,
417227825Stheraven                          __alloc_traits::propagate_on_container_move_assignment::value>());
418227825Stheraven    __c.__first_ = __c.__begin_ = __c.__end_ = __c.__end_cap() = nullptr;
419227825Stheraven    return *this;
420227825Stheraven}
421227825Stheraven
422227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
423227825Stheraven
424227825Stheraventemplate <class _Tp, class _Allocator>
425227825Stheravenvoid
426227825Stheraven__split_buffer<_Tp, _Allocator>::swap(__split_buffer& __x)
427227825Stheraven        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value||
428227825Stheraven                   __is_nothrow_swappable<__alloc_rr>::value)
429227825Stheraven{
430227825Stheraven    _VSTD::swap(__first_, __x.__first_);
431227825Stheraven    _VSTD::swap(__begin_, __x.__begin_);
432227825Stheraven    _VSTD::swap(__end_, __x.__end_);
433227825Stheraven    _VSTD::swap(__end_cap(), __x.__end_cap());
434227825Stheraven    __swap_alloc(__alloc(), __x.__alloc());
435227825Stheraven}
436227825Stheraven
437227825Stheraventemplate <class _Tp, class _Allocator>
438227825Stheravenvoid
439227825Stheraven__split_buffer<_Tp, _Allocator>::reserve(size_type __n)
440227825Stheraven{
441227825Stheraven    if (__n < capacity())
442227825Stheraven    {
443227825Stheraven        __split_buffer<value_type, __alloc_rr&> __t(__n, 0, __alloc());
444227825Stheraven        __t.__construct_at_end(move_iterator<pointer>(__begin_),
445227825Stheraven                               move_iterator<pointer>(__end_));
446227825Stheraven        _VSTD::swap(__first_, __t.__first_);
447227825Stheraven        _VSTD::swap(__begin_, __t.__begin_);
448227825Stheraven        _VSTD::swap(__end_, __t.__end_);
449227825Stheraven        _VSTD::swap(__end_cap(), __t.__end_cap());
450227825Stheraven    }
451227825Stheraven}
452227825Stheraven
453227825Stheraventemplate <class _Tp, class _Allocator>
454227825Stheravenvoid
455227825Stheraven__split_buffer<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
456227825Stheraven{
457227825Stheraven    if (capacity() > size())
458227825Stheraven    {
459227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
460227825Stheraven        try
461227825Stheraven        {
462227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
463227825Stheraven            __split_buffer<value_type, __alloc_rr&> __t(size(), 0, __alloc());
464227825Stheraven            __t.__construct_at_end(move_iterator<pointer>(__begin_),
465227825Stheraven                                   move_iterator<pointer>(__end_));
466227825Stheraven            __t.__end_ = __t.__begin_ + (__end_ - __begin_);
467227825Stheraven            _VSTD::swap(__first_, __t.__first_);
468227825Stheraven            _VSTD::swap(__begin_, __t.__begin_);
469227825Stheraven            _VSTD::swap(__end_, __t.__end_);
470227825Stheraven            _VSTD::swap(__end_cap(), __t.__end_cap());
471227825Stheraven#ifndef _LIBCPP_NO_EXCEPTIONS
472227825Stheraven        }
473227825Stheraven        catch (...)
474227825Stheraven        {
475227825Stheraven        }
476227825Stheraven#endif  // _LIBCPP_NO_EXCEPTIONS
477227825Stheraven    }
478227825Stheraven}
479227825Stheraven
480227825Stheraventemplate <class _Tp, class _Allocator>
481227825Stheravenvoid
482227825Stheraven__split_buffer<_Tp, _Allocator>::push_front(const_reference __x)
483227825Stheraven{
484227825Stheraven    if (__begin_ == __first_)
485227825Stheraven    {
486227825Stheraven        if (__end_ < __end_cap())
487227825Stheraven        {
488227825Stheraven            difference_type __d = __end_cap() - __end_;
489227825Stheraven            __d = (__d + 1) / 2;
490227825Stheraven            __begin_ = _VSTD::move_backward(__begin_, __end_, __end_ + __d);
491227825Stheraven            __end_ += __d;
492227825Stheraven        }
493227825Stheraven        else
494227825Stheraven        {
495232924Stheraven            size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
496227825Stheraven            __split_buffer<value_type, __alloc_rr&> __t(__c, (__c + 3) / 4, __alloc());
497227825Stheraven            __t.__construct_at_end(move_iterator<pointer>(__begin_),
498227825Stheraven                                   move_iterator<pointer>(__end_));
499227825Stheraven            _VSTD::swap(__first_, __t.__first_);
500227825Stheraven            _VSTD::swap(__begin_, __t.__begin_);
501227825Stheraven            _VSTD::swap(__end_, __t.__end_);
502227825Stheraven            _VSTD::swap(__end_cap(), __t.__end_cap());
503227825Stheraven        }
504227825Stheraven    }
505227825Stheraven    __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__begin_-1), __x);
506227825Stheraven    --__begin_;
507227825Stheraven}
508227825Stheraven
509227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
510227825Stheraven
511227825Stheraventemplate <class _Tp, class _Allocator>
512227825Stheravenvoid
513227825Stheraven__split_buffer<_Tp, _Allocator>::push_front(value_type&& __x)
514227825Stheraven{
515227825Stheraven    if (__begin_ == __first_)
516227825Stheraven    {
517227825Stheraven        if (__end_ < __end_cap())
518227825Stheraven        {
519227825Stheraven            difference_type __d = __end_cap() - __end_;
520227825Stheraven            __d = (__d + 1) / 2;
521227825Stheraven            __begin_ = _VSTD::move_backward(__begin_, __end_, __end_ + __d);
522227825Stheraven            __end_ += __d;
523227825Stheraven        }
524227825Stheraven        else
525227825Stheraven        {
526232924Stheraven            size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
527227825Stheraven            __split_buffer<value_type, __alloc_rr&> __t(__c, (__c + 3) / 4, __alloc());
528227825Stheraven            __t.__construct_at_end(move_iterator<pointer>(__begin_),
529227825Stheraven                                   move_iterator<pointer>(__end_));
530227825Stheraven            _VSTD::swap(__first_, __t.__first_);
531227825Stheraven            _VSTD::swap(__begin_, __t.__begin_);
532227825Stheraven            _VSTD::swap(__end_, __t.__end_);
533227825Stheraven            _VSTD::swap(__end_cap(), __t.__end_cap());
534227825Stheraven        }
535227825Stheraven    }
536227825Stheraven    __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__begin_-1),
537227825Stheraven            _VSTD::move(__x));
538227825Stheraven    --__begin_;
539227825Stheraven}
540227825Stheraven
541227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
542227825Stheraven
543227825Stheraventemplate <class _Tp, class _Allocator>
544227825Stheraven_LIBCPP_INLINE_VISIBILITY inline
545227825Stheravenvoid
546227825Stheraven__split_buffer<_Tp, _Allocator>::push_back(const_reference __x)
547227825Stheraven{
548227825Stheraven    if (__end_ == __end_cap())
549227825Stheraven    {
550227825Stheraven        if (__begin_ > __first_)
551227825Stheraven        {
552227825Stheraven            difference_type __d = __begin_ - __first_;
553227825Stheraven            __d = (__d + 1) / 2;
554227825Stheraven            __end_ = _VSTD::move(__begin_, __end_, __begin_ - __d);
555227825Stheraven            __begin_ -= __d;
556227825Stheraven        }
557227825Stheraven        else
558227825Stheraven        {
559232924Stheraven            size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
560227825Stheraven            __split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc());
561227825Stheraven            __t.__construct_at_end(move_iterator<pointer>(__begin_),
562227825Stheraven                                   move_iterator<pointer>(__end_));
563227825Stheraven            _VSTD::swap(__first_, __t.__first_);
564227825Stheraven            _VSTD::swap(__begin_, __t.__begin_);
565227825Stheraven            _VSTD::swap(__end_, __t.__end_);
566227825Stheraven            _VSTD::swap(__end_cap(), __t.__end_cap());
567227825Stheraven        }
568227825Stheraven    }
569227825Stheraven    __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_), __x);
570227825Stheraven    ++__end_;
571227825Stheraven}
572227825Stheraven
573227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
574227825Stheraven
575227825Stheraventemplate <class _Tp, class _Allocator>
576227825Stheravenvoid
577227825Stheraven__split_buffer<_Tp, _Allocator>::push_back(value_type&& __x)
578227825Stheraven{
579227825Stheraven    if (__end_ == __end_cap())
580227825Stheraven    {
581227825Stheraven        if (__begin_ > __first_)
582227825Stheraven        {
583227825Stheraven            difference_type __d = __begin_ - __first_;
584227825Stheraven            __d = (__d + 1) / 2;
585227825Stheraven            __end_ = _VSTD::move(__begin_, __end_, __begin_ - __d);
586227825Stheraven            __begin_ -= __d;
587227825Stheraven        }
588227825Stheraven        else
589227825Stheraven        {
590232924Stheraven            size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
591227825Stheraven            __split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc());
592227825Stheraven            __t.__construct_at_end(move_iterator<pointer>(__begin_),
593227825Stheraven                                   move_iterator<pointer>(__end_));
594227825Stheraven            _VSTD::swap(__first_, __t.__first_);
595227825Stheraven            _VSTD::swap(__begin_, __t.__begin_);
596227825Stheraven            _VSTD::swap(__end_, __t.__end_);
597227825Stheraven            _VSTD::swap(__end_cap(), __t.__end_cap());
598227825Stheraven        }
599227825Stheraven    }
600227825Stheraven    __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_),
601227825Stheraven            _VSTD::move(__x));
602227825Stheraven    ++__end_;
603227825Stheraven}
604227825Stheraven
605227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS
606227825Stheraven
607227825Stheraventemplate <class _Tp, class _Allocator>
608227825Stheraventemplate <class... _Args>
609227825Stheravenvoid
610227825Stheraven__split_buffer<_Tp, _Allocator>::emplace_back(_Args&&... __args)
611227825Stheraven{
612227825Stheraven    if (__end_ == __end_cap())
613227825Stheraven    {
614227825Stheraven        if (__begin_ > __first_)
615227825Stheraven        {
616227825Stheraven            difference_type __d = __begin_ - __first_;
617227825Stheraven            __d = (__d + 1) / 2;
618227825Stheraven            __end_ = _VSTD::move(__begin_, __end_, __begin_ - __d);
619227825Stheraven            __begin_ -= __d;
620227825Stheraven        }
621227825Stheraven        else
622227825Stheraven        {
623232924Stheraven            size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
624227825Stheraven            __split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc());
625227825Stheraven            __t.__construct_at_end(move_iterator<pointer>(__begin_),
626227825Stheraven                                   move_iterator<pointer>(__end_));
627227825Stheraven            _VSTD::swap(__first_, __t.__first_);
628227825Stheraven            _VSTD::swap(__begin_, __t.__begin_);
629227825Stheraven            _VSTD::swap(__end_, __t.__end_);
630227825Stheraven            _VSTD::swap(__end_cap(), __t.__end_cap());
631227825Stheraven        }
632227825Stheraven    }
633227825Stheraven    __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_),
634227825Stheraven                              _VSTD::forward<_Args>(__args)...);
635227825Stheraven    ++__end_;
636227825Stheraven}
637227825Stheraven
638227825Stheraven#endif  // _LIBCPP_HAS_NO_VARIADICS
639227825Stheraven
640227825Stheraven#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
641227825Stheraven
642227825Stheraventemplate <class _Tp, class _Allocator>
643227825Stheraven_LIBCPP_INLINE_VISIBILITY inline
644227825Stheravenvoid
645227825Stheravenswap(__split_buffer<_Tp, _Allocator>& __x, __split_buffer<_Tp, _Allocator>& __y)
646227825Stheraven        _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
647227825Stheraven{
648227825Stheraven    __x.swap(__y);
649227825Stheraven}
650227825Stheraven
651227825Stheraven
652227825Stheraven_LIBCPP_END_NAMESPACE_STD
653227825Stheraven
654227825Stheraven#endif  // _LIBCPP_SPLIT_BUFFER
655