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