Project

General

Profile

Statistics
| Revision:

root / lab4 / .minix-src / include / c++ / __split_buffer

History | View | Annotate | Download (21.7 KB)

1
// -*- C++ -*-
2
#ifndef _LIBCPP_SPLIT_BUFFER
3
#define _LIBCPP_SPLIT_BUFFER
4

    
5
#include <__config>
6
#include <type_traits>
7
#include <algorithm>
8

    
9
#include <__undef_min_max>
10

    
11
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
12
#pragma GCC system_header
13
#endif
14

    
15
_LIBCPP_BEGIN_NAMESPACE_STD
16

    
17
template <bool>
18
class __split_buffer_common
19
{
20
protected:
21
    void __throw_length_error() const;
22
    void __throw_out_of_range() const;
23
};
24

    
25
template <class _Tp, class _Allocator = allocator<_Tp> >
26
struct __split_buffer
27
    : private __split_buffer_common<true>
28
{
29
private:
30
    __split_buffer(const __split_buffer&);
31
    __split_buffer& operator=(const __split_buffer&);
32
public:
33
    typedef _Tp                                             value_type;
34
    typedef _Allocator                                      allocator_type;
35
    typedef typename remove_reference<allocator_type>::type __alloc_rr;
36
    typedef allocator_traits<__alloc_rr>                    __alloc_traits;
37
    typedef value_type&                                     reference;
38
    typedef const value_type&                               const_reference;
39
    typedef typename __alloc_traits::size_type              size_type;
40
    typedef typename __alloc_traits::difference_type        difference_type;
41
    typedef typename __alloc_traits::pointer                pointer;
42
    typedef typename __alloc_traits::const_pointer          const_pointer;
43
    typedef pointer                                         iterator;
44
    typedef const_pointer                                   const_iterator;
45

    
46
    pointer                                         __first_;
47
    pointer                                         __begin_;
48
    pointer                                         __end_;
49
    __compressed_pair<pointer, allocator_type> __end_cap_;
50

    
51
    typedef typename add_lvalue_reference<allocator_type>::type __alloc_ref;
52
    typedef typename add_lvalue_reference<allocator_type>::type __alloc_const_ref;
53

    
54
    _LIBCPP_INLINE_VISIBILITY __alloc_rr&           __alloc() _NOEXCEPT         {return __end_cap_.second();}
55
    _LIBCPP_INLINE_VISIBILITY const __alloc_rr&     __alloc() const _NOEXCEPT   {return __end_cap_.second();}
56
    _LIBCPP_INLINE_VISIBILITY pointer&              __end_cap() _NOEXCEPT       {return __end_cap_.first();}
57
    _LIBCPP_INLINE_VISIBILITY const pointer&        __end_cap() const _NOEXCEPT {return __end_cap_.first();}
58

    
59
    __split_buffer()
60
        _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value);
61
    explicit __split_buffer(__alloc_rr& __a);
62
    explicit __split_buffer(const __alloc_rr& __a);
63
    __split_buffer(size_type __cap, size_type __start, __alloc_rr& __a);
64
    ~__split_buffer();
65

    
66
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
67
    __split_buffer(__split_buffer&& __c)
68
        _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value);
69
    __split_buffer(__split_buffer&& __c, const __alloc_rr& __a);
70
    __split_buffer& operator=(__split_buffer&& __c)
71
        _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value &&
72
                is_nothrow_move_assignable<allocator_type>::value) ||
73
               !__alloc_traits::propagate_on_container_move_assignment::value);
74
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
75

    
76
    _LIBCPP_INLINE_VISIBILITY       iterator begin() _NOEXCEPT       {return __begin_;}
77
    _LIBCPP_INLINE_VISIBILITY const_iterator begin() const _NOEXCEPT {return __begin_;}
78
    _LIBCPP_INLINE_VISIBILITY       iterator end() _NOEXCEPT         {return __end_;}
79
    _LIBCPP_INLINE_VISIBILITY const_iterator end() const _NOEXCEPT   {return __end_;}
80

    
81
    _LIBCPP_INLINE_VISIBILITY
82
    void clear() _NOEXCEPT
83
        {__destruct_at_end(__begin_);}
84
    _LIBCPP_INLINE_VISIBILITY size_type size() const {return static_cast<size_type>(__end_ - __begin_);}
85
    _LIBCPP_INLINE_VISIBILITY bool empty()     const {return __end_ == __begin_;}
86
    _LIBCPP_INLINE_VISIBILITY size_type capacity() const {return static_cast<size_type>(__end_cap() - __first_);}
87
    _LIBCPP_INLINE_VISIBILITY size_type __front_spare() const {return static_cast<size_type>(__begin_ - __first_);}
88
    _LIBCPP_INLINE_VISIBILITY size_type __back_spare() const {return static_cast<size_type>(__end_cap() - __end_);}
89

    
90
    _LIBCPP_INLINE_VISIBILITY       reference front()       {return *__begin_;}
91
    _LIBCPP_INLINE_VISIBILITY const_reference front() const {return *__begin_;}
92
    _LIBCPP_INLINE_VISIBILITY       reference back()        {return *(__end_ - 1);}
93
    _LIBCPP_INLINE_VISIBILITY const_reference back() const  {return *(__end_ - 1);}
94

    
95
    void reserve(size_type __n);
96
    void shrink_to_fit() _NOEXCEPT;
97
    void push_front(const_reference __x);
98
    _LIBCPP_INLINE_VISIBILITY void push_back(const_reference __x);
99
#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
100
    void push_front(value_type&& __x);
101
    void push_back(value_type&& __x);
102
#if !defined(_LIBCPP_HAS_NO_VARIADICS)
103
    template <class... _Args>
104
        void emplace_back(_Args&&... __args);
105
#endif  // !defined(_LIBCPP_HAS_NO_VARIADICS)
106
#endif  // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
107

    
108
    _LIBCPP_INLINE_VISIBILITY void pop_front() {__destruct_at_begin(__begin_+1);}
109
    _LIBCPP_INLINE_VISIBILITY void pop_back() {__destruct_at_end(__end_-1);}
110

    
111
    void __construct_at_end(size_type __n);
112
    void __construct_at_end(size_type __n, const_reference __x);
113
    template <class _InputIter>
114
        typename enable_if
115
        <
116
            __is_input_iterator<_InputIter>::value &&
117
           !__is_forward_iterator<_InputIter>::value,
118
            void
119
        >::type
120
        __construct_at_end(_InputIter __first, _InputIter __last);
121
    template <class _ForwardIterator>
122
        typename enable_if
123
        <
124
            __is_forward_iterator<_ForwardIterator>::value,
125
            void
126
        >::type
127
        __construct_at_end(_ForwardIterator __first, _ForwardIterator __last);
128

    
129
    _LIBCPP_INLINE_VISIBILITY void __destruct_at_begin(pointer __new_begin)
130
        {__destruct_at_begin(__new_begin, is_trivially_destructible<value_type>());}
131
        void __destruct_at_begin(pointer __new_begin, false_type);
132
        void __destruct_at_begin(pointer __new_begin, true_type);
133

    
134
    _LIBCPP_INLINE_VISIBILITY
135
    void __destruct_at_end(pointer __new_last) _NOEXCEPT
136
        {__destruct_at_end(__new_last, false_type());}
137
    _LIBCPP_INLINE_VISIBILITY
138
        void __destruct_at_end(pointer __new_last, false_type) _NOEXCEPT;
139
    _LIBCPP_INLINE_VISIBILITY
140
        void __destruct_at_end(pointer __new_last, true_type) _NOEXCEPT;
141

    
142
    void swap(__split_buffer& __x)
143
        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value||
144
                   __is_nothrow_swappable<__alloc_rr>::value);
145

    
146
    bool __invariants() const;
147

    
148
private:
149
    _LIBCPP_INLINE_VISIBILITY
150
    void __move_assign_alloc(__split_buffer& __c, true_type)
151
        _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
152
        {
153
            __alloc() = _VSTD::move(__c.__alloc());
154
        }
155

    
156
    _LIBCPP_INLINE_VISIBILITY
157
    void __move_assign_alloc(__split_buffer&, false_type) _NOEXCEPT
158
        {}
159
};
160

    
161
template <class _Tp, class _Allocator>
162
bool
163
__split_buffer<_Tp, _Allocator>::__invariants() const
164
{
165
    if (__first_ == nullptr)
166
    {
167
        if (__begin_ != nullptr)
168
            return false;
169
        if (__end_ != nullptr)
170
            return false;
171
        if (__end_cap() != nullptr)
172
            return false;
173
    }
174
    else
175
    {
176
        if (__begin_ < __first_)
177
            return false;
178
        if (__end_ < __begin_)
179
            return false;
180
        if (__end_cap() < __end_)
181
            return false;
182
    }
183
    return true;
184
}
185

    
186
//  Default constructs __n objects starting at __end_
187
//  throws if construction throws
188
//  Precondition:  __n > 0
189
//  Precondition:  size() + __n <= capacity()
190
//  Postcondition:  size() == size() + __n
191
template <class _Tp, class _Allocator>
192
void
193
__split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n)
194
{
195
    __alloc_rr& __a = this->__alloc();
196
    do
197
    {
198
        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_));
199
        ++this->__end_;
200
        --__n;
201
    } while (__n > 0);
202
}
203

    
204
//  Copy constructs __n objects starting at __end_ from __x
205
//  throws if construction throws
206
//  Precondition:  __n > 0
207
//  Precondition:  size() + __n <= capacity()
208
//  Postcondition:  size() == old size() + __n
209
//  Postcondition:  [i] == __x for all i in [size() - __n, __n)
210
template <class _Tp, class _Allocator>
211
void
212
__split_buffer<_Tp, _Allocator>::__construct_at_end(size_type __n, const_reference __x)
213
{
214
    __alloc_rr& __a = this->__alloc();
215
    do
216
    {
217
        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), __x);
218
        ++this->__end_;
219
        --__n;
220
    } while (__n > 0);
221
}
222

    
223
template <class _Tp, class _Allocator>
224
template <class _InputIter>
225
typename enable_if
226
<
227
     __is_input_iterator<_InputIter>::value &&
228
    !__is_forward_iterator<_InputIter>::value,
229
    void
230
>::type
231
__split_buffer<_Tp, _Allocator>::__construct_at_end(_InputIter __first, _InputIter __last)
232
{
233
    __alloc_rr& __a = this->__alloc();
234
    for (; __first != __last; ++__first)
235
    {
236
        if (__end_ == __end_cap())
237
        {
238
            size_type __old_cap = __end_cap() - __first_;
239
            size_type __new_cap = _VSTD::max<size_type>(2 * __old_cap, 8);
240
            __split_buffer __buf(__new_cap, 0, __a);
241
            for (pointer __p = __begin_; __p != __end_; ++__p, ++__buf.__end_)
242
                __alloc_traits::construct(__buf.__alloc(),
243
                        _VSTD::__to_raw_pointer(__buf.__end_), _VSTD::move(*__p));
244
            swap(__buf);
245
        }
246
        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), *__first);
247
        ++this->__end_;
248
    }
249
}
250

    
251
template <class _Tp, class _Allocator>
252
template <class _ForwardIterator>
253
typename enable_if
254
<
255
    __is_forward_iterator<_ForwardIterator>::value,
256
    void
257
>::type
258
__split_buffer<_Tp, _Allocator>::__construct_at_end(_ForwardIterator __first, _ForwardIterator __last)
259
{
260
    __alloc_rr& __a = this->__alloc();
261
    for (; __first != __last; ++__first)
262
    {
263
        __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_), *__first);
264
        ++this->__end_;
265
    }
266
}
267

    
268
template <class _Tp, class _Allocator>
269
inline _LIBCPP_INLINE_VISIBILITY
270
void
271
__split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, false_type)
272
{
273
    while (__begin_ != __new_begin)
274
        __alloc_traits::destroy(__alloc(), __to_raw_pointer(__begin_++));
275
}
276

    
277
template <class _Tp, class _Allocator>
278
inline _LIBCPP_INLINE_VISIBILITY
279
void
280
__split_buffer<_Tp, _Allocator>::__destruct_at_begin(pointer __new_begin, true_type)
281
{
282
    __begin_ = __new_begin;
283
}
284

    
285
template <class _Tp, class _Allocator>
286
inline _LIBCPP_INLINE_VISIBILITY
287
void
288
__split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, false_type) _NOEXCEPT
289
{
290
    while (__new_last != __end_)
291
        __alloc_traits::destroy(__alloc(), __to_raw_pointer(--__end_));
292
}
293

    
294
template <class _Tp, class _Allocator>
295
inline _LIBCPP_INLINE_VISIBILITY
296
void
297
__split_buffer<_Tp, _Allocator>::__destruct_at_end(pointer __new_last, true_type) _NOEXCEPT
298
{
299
    __end_ = __new_last;
300
}
301

    
302
template <class _Tp, class _Allocator>
303
__split_buffer<_Tp, _Allocator>::__split_buffer(size_type __cap, size_type __start, __alloc_rr& __a)
304
    : __end_cap_(nullptr, __a)
305
{
306
    __first_ = __cap != 0 ? __alloc_traits::allocate(__alloc(), __cap) : nullptr;
307
    __begin_ = __end_ = __first_ + __start;
308
    __end_cap() = __first_ + __cap;
309
}
310

    
311
template <class _Tp, class _Allocator>
312
inline _LIBCPP_INLINE_VISIBILITY
313
__split_buffer<_Tp, _Allocator>::__split_buffer()
314
    _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
315
    : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr)
316
{
317
}
318

    
319
template <class _Tp, class _Allocator>
320
inline _LIBCPP_INLINE_VISIBILITY
321
__split_buffer<_Tp, _Allocator>::__split_buffer(__alloc_rr& __a)
322
    : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a)
323
{
324
}
325

    
326
template <class _Tp, class _Allocator>
327
inline _LIBCPP_INLINE_VISIBILITY
328
__split_buffer<_Tp, _Allocator>::__split_buffer(const __alloc_rr& __a)
329
    : __first_(nullptr), __begin_(nullptr), __end_(nullptr), __end_cap_(nullptr, __a)
330
{
331
}
332

    
333
template <class _Tp, class _Allocator>
334
__split_buffer<_Tp, _Allocator>::~__split_buffer()
335
{
336
    clear();
337
    if (__first_)
338
        __alloc_traits::deallocate(__alloc(), __first_, capacity());
339
}
340

    
341
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
342

    
343
template <class _Tp, class _Allocator>
344
__split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c)
345
    _NOEXCEPT_(is_nothrow_move_constructible<allocator_type>::value)
346
    : __first_(_VSTD::move(__c.__first_)),
347
      __begin_(_VSTD::move(__c.__begin_)),
348
      __end_(_VSTD::move(__c.__end_)),
349
      __end_cap_(_VSTD::move(__c.__end_cap_))
350
{
351
    __c.__first_ = nullptr;
352
    __c.__begin_ = nullptr;
353
    __c.__end_ = nullptr;
354
    __c.__end_cap() = nullptr;
355
}
356

    
357
template <class _Tp, class _Allocator>
358
__split_buffer<_Tp, _Allocator>::__split_buffer(__split_buffer&& __c, const __alloc_rr& __a)
359
    : __end_cap_(__a)
360
{
361
    if (__a == __c.__alloc())
362
    {
363
        __first_ = __c.__first_;
364
        __begin_ = __c.__begin_;
365
        __end_ = __c.__end_;
366
        __end_cap() = __c.__end_cap();
367
        __c.__first_ = nullptr;
368
        __c.__begin_ = nullptr;
369
        __c.__end_ = nullptr;
370
        __c.__end_cap() = nullptr;
371
    }
372
    else
373
    {
374
        size_type __cap = __c.size();
375
        __first_ = __alloc_traits::allocate(__alloc(), __cap);
376
        __begin_ = __end_ = __first_;
377
        __end_cap() = __first_ + __cap;
378
        typedef move_iterator<iterator> _Ip;
379
        __construct_at_end(_Ip(__c.begin()), _Ip(__c.end()));
380
    }
381
}
382

    
383
template <class _Tp, class _Allocator>
384
__split_buffer<_Tp, _Allocator>&
385
__split_buffer<_Tp, _Allocator>::operator=(__split_buffer&& __c)
386
    _NOEXCEPT_((__alloc_traits::propagate_on_container_move_assignment::value &&
387
                is_nothrow_move_assignable<allocator_type>::value) ||
388
               !__alloc_traits::propagate_on_container_move_assignment::value)
389
{
390
    clear();
391
    shrink_to_fit();
392
    __first_ = __c.__first_;
393
    __begin_ = __c.__begin_;
394
    __end_ = __c.__end_;
395
    __end_cap() = __c.__end_cap();
396
    __move_assign_alloc(__c,
397
        integral_constant<bool,
398
                          __alloc_traits::propagate_on_container_move_assignment::value>());
399
    __c.__first_ = __c.__begin_ = __c.__end_ = __c.__end_cap() = nullptr;
400
    return *this;
401
}
402

    
403
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
404

    
405
template <class _Tp, class _Allocator>
406
void
407
__split_buffer<_Tp, _Allocator>::swap(__split_buffer& __x)
408
        _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value||
409
                   __is_nothrow_swappable<__alloc_rr>::value)
410
{
411
    _VSTD::swap(__first_, __x.__first_);
412
    _VSTD::swap(__begin_, __x.__begin_);
413
    _VSTD::swap(__end_, __x.__end_);
414
    _VSTD::swap(__end_cap(), __x.__end_cap());
415
    __swap_allocator(__alloc(), __x.__alloc());
416
}
417

    
418
template <class _Tp, class _Allocator>
419
void
420
__split_buffer<_Tp, _Allocator>::reserve(size_type __n)
421
{
422
    if (__n < capacity())
423
    {
424
        __split_buffer<value_type, __alloc_rr&> __t(__n, 0, __alloc());
425
        __t.__construct_at_end(move_iterator<pointer>(__begin_),
426
                               move_iterator<pointer>(__end_));
427
        _VSTD::swap(__first_, __t.__first_);
428
        _VSTD::swap(__begin_, __t.__begin_);
429
        _VSTD::swap(__end_, __t.__end_);
430
        _VSTD::swap(__end_cap(), __t.__end_cap());
431
    }
432
}
433

    
434
template <class _Tp, class _Allocator>
435
void
436
__split_buffer<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
437
{
438
    if (capacity() > size())
439
    {
440
#ifndef _LIBCPP_NO_EXCEPTIONS
441
        try
442
        {
443
#endif  // _LIBCPP_NO_EXCEPTIONS
444
            __split_buffer<value_type, __alloc_rr&> __t(size(), 0, __alloc());
445
            __t.__construct_at_end(move_iterator<pointer>(__begin_),
446
                                   move_iterator<pointer>(__end_));
447
            __t.__end_ = __t.__begin_ + (__end_ - __begin_);
448
            _VSTD::swap(__first_, __t.__first_);
449
            _VSTD::swap(__begin_, __t.__begin_);
450
            _VSTD::swap(__end_, __t.__end_);
451
            _VSTD::swap(__end_cap(), __t.__end_cap());
452
#ifndef _LIBCPP_NO_EXCEPTIONS
453
        }
454
        catch (...)
455
        {
456
        }
457
#endif  // _LIBCPP_NO_EXCEPTIONS
458
    }
459
}
460

    
461
template <class _Tp, class _Allocator>
462
void
463
__split_buffer<_Tp, _Allocator>::push_front(const_reference __x)
464
{
465
    if (__begin_ == __first_)
466
    {
467
        if (__end_ < __end_cap())
468
        {
469
            difference_type __d = __end_cap() - __end_;
470
            __d = (__d + 1) / 2;
471
            __begin_ = _VSTD::move_backward(__begin_, __end_, __end_ + __d);
472
            __end_ += __d;
473
        }
474
        else
475
        {
476
            size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
477
            __split_buffer<value_type, __alloc_rr&> __t(__c, (__c + 3) / 4, __alloc());
478
            __t.__construct_at_end(move_iterator<pointer>(__begin_),
479
                                   move_iterator<pointer>(__end_));
480
            _VSTD::swap(__first_, __t.__first_);
481
            _VSTD::swap(__begin_, __t.__begin_);
482
            _VSTD::swap(__end_, __t.__end_);
483
            _VSTD::swap(__end_cap(), __t.__end_cap());
484
        }
485
    }
486
    __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__begin_-1), __x);
487
    --__begin_;
488
}
489

    
490
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
491

    
492
template <class _Tp, class _Allocator>
493
void
494
__split_buffer<_Tp, _Allocator>::push_front(value_type&& __x)
495
{
496
    if (__begin_ == __first_)
497
    {
498
        if (__end_ < __end_cap())
499
        {
500
            difference_type __d = __end_cap() - __end_;
501
            __d = (__d + 1) / 2;
502
            __begin_ = _VSTD::move_backward(__begin_, __end_, __end_ + __d);
503
            __end_ += __d;
504
        }
505
        else
506
        {
507
            size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
508
            __split_buffer<value_type, __alloc_rr&> __t(__c, (__c + 3) / 4, __alloc());
509
            __t.__construct_at_end(move_iterator<pointer>(__begin_),
510
                                   move_iterator<pointer>(__end_));
511
            _VSTD::swap(__first_, __t.__first_);
512
            _VSTD::swap(__begin_, __t.__begin_);
513
            _VSTD::swap(__end_, __t.__end_);
514
            _VSTD::swap(__end_cap(), __t.__end_cap());
515
        }
516
    }
517
    __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__begin_-1),
518
            _VSTD::move(__x));
519
    --__begin_;
520
}
521

    
522
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
523

    
524
template <class _Tp, class _Allocator>
525
inline _LIBCPP_INLINE_VISIBILITY
526
void
527
__split_buffer<_Tp, _Allocator>::push_back(const_reference __x)
528
{
529
    if (__end_ == __end_cap())
530
    {
531
        if (__begin_ > __first_)
532
        {
533
            difference_type __d = __begin_ - __first_;
534
            __d = (__d + 1) / 2;
535
            __end_ = _VSTD::move(__begin_, __end_, __begin_ - __d);
536
            __begin_ -= __d;
537
        }
538
        else
539
        {
540
            size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
541
            __split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc());
542
            __t.__construct_at_end(move_iterator<pointer>(__begin_),
543
                                   move_iterator<pointer>(__end_));
544
            _VSTD::swap(__first_, __t.__first_);
545
            _VSTD::swap(__begin_, __t.__begin_);
546
            _VSTD::swap(__end_, __t.__end_);
547
            _VSTD::swap(__end_cap(), __t.__end_cap());
548
        }
549
    }
550
    __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_), __x);
551
    ++__end_;
552
}
553

    
554
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
555

    
556
template <class _Tp, class _Allocator>
557
void
558
__split_buffer<_Tp, _Allocator>::push_back(value_type&& __x)
559
{
560
    if (__end_ == __end_cap())
561
    {
562
        if (__begin_ > __first_)
563
        {
564
            difference_type __d = __begin_ - __first_;
565
            __d = (__d + 1) / 2;
566
            __end_ = _VSTD::move(__begin_, __end_, __begin_ - __d);
567
            __begin_ -= __d;
568
        }
569
        else
570
        {
571
            size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
572
            __split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc());
573
            __t.__construct_at_end(move_iterator<pointer>(__begin_),
574
                                   move_iterator<pointer>(__end_));
575
            _VSTD::swap(__first_, __t.__first_);
576
            _VSTD::swap(__begin_, __t.__begin_);
577
            _VSTD::swap(__end_, __t.__end_);
578
            _VSTD::swap(__end_cap(), __t.__end_cap());
579
        }
580
    }
581
    __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_),
582
            _VSTD::move(__x));
583
    ++__end_;
584
}
585

    
586
#ifndef _LIBCPP_HAS_NO_VARIADICS
587

    
588
template <class _Tp, class _Allocator>
589
template <class... _Args>
590
void
591
__split_buffer<_Tp, _Allocator>::emplace_back(_Args&&... __args)
592
{
593
    if (__end_ == __end_cap())
594
    {
595
        if (__begin_ > __first_)
596
        {
597
            difference_type __d = __begin_ - __first_;
598
            __d = (__d + 1) / 2;
599
            __end_ = _VSTD::move(__begin_, __end_, __begin_ - __d);
600
            __begin_ -= __d;
601
        }
602
        else
603
        {
604
            size_type __c = max<size_type>(2 * static_cast<size_t>(__end_cap() - __first_), 1);
605
            __split_buffer<value_type, __alloc_rr&> __t(__c, __c / 4, __alloc());
606
            __t.__construct_at_end(move_iterator<pointer>(__begin_),
607
                                   move_iterator<pointer>(__end_));
608
            _VSTD::swap(__first_, __t.__first_);
609
            _VSTD::swap(__begin_, __t.__begin_);
610
            _VSTD::swap(__end_, __t.__end_);
611
            _VSTD::swap(__end_cap(), __t.__end_cap());
612
        }
613
    }
614
    __alloc_traits::construct(__alloc(), _VSTD::__to_raw_pointer(__end_),
615
                              _VSTD::forward<_Args>(__args)...);
616
    ++__end_;
617
}
618

    
619
#endif  // _LIBCPP_HAS_NO_VARIADICS
620

    
621
#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
622

    
623
template <class _Tp, class _Allocator>
624
inline _LIBCPP_INLINE_VISIBILITY
625
void
626
swap(__split_buffer<_Tp, _Allocator>& __x, __split_buffer<_Tp, _Allocator>& __y)
627
        _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
628
{
629
    __x.swap(__y);
630
}
631

    
632

    
633
_LIBCPP_END_NAMESPACE_STD
634

    
635
#endif  // _LIBCPP_SPLIT_BUFFER