1
/* Copyright (C) 2004 Garrett A. Kajmowicz
2
This file is part of the uClibc++ Library.
3
This library is free software; you can redistribute it and/or
4
modify it under the terms of the GNU Lesser General Public
5
License as published by the Free Software Foundation; either
6
version 2.1 of the License, or (at your option) any later version.
8
This library is distributed in the hope that it will be useful,
9
but WITHOUT ANY WARRANTY; without even the implied warranty of
10
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
Lesser General Public License for more details.
13
You should have received a copy of the GNU Lesser General Public
14
License along with this library; if not, write to the Free Software
15
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24
#pragma GCC visibility push(default)
26
#ifndef __STD_HEADER_DEQUE
27
#define __STD_HEADER_DEQUE
31
template <class T, class Allocator = allocator<T> > class deque;
32
template <class T, class Allocator> bool operator==(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
33
template <class T, class Allocator> bool operator< (const deque<T,Allocator>& x, const deque<T,Allocator>& y);
34
template <class T, class Allocator> bool operator!=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
35
template <class T, class Allocator> bool operator> (const deque<T,Allocator>& x, const deque<T,Allocator>& y);
36
template <class T, class Allocator> bool operator>=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
37
template <class T, class Allocator> bool operator<=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
38
template <class T, class Allocator> void swap(deque<T,Allocator>& x, deque<T,Allocator>& y);
40
template <class T, class Allocator> class _UCXXEXPORT deque {
42
friend bool operator==<>(const deque<T, Allocator>& x, const deque<T, Allocator>& y);
43
friend class deque_iter;
44
friend class deque_citer;
48
typedef typename Allocator::reference reference;
49
typedef typename Allocator::const_reference const_reference;
50
typedef deque_iter iterator;
51
typedef deque_citer const_iterator;
52
typedef typename Allocator::size_type size_type;
53
typedef typename Allocator::difference_type difference_type;
55
typedef Allocator allocator_type;
56
typedef typename Allocator::pointer pointer;
57
typedef typename Allocator::const_pointer const_pointer;
58
typedef std::reverse_iterator<iterator> reverse_iterator;
59
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
61
explicit deque(const Allocator& al = Allocator());
62
explicit deque(size_type n, const T& value = T(), const Allocator& al = Allocator());
63
template <class InputIterator> deque(InputIterator first, InputIterator last, const Allocator& = Allocator());
64
deque(const deque<T,Allocator>& x);
67
deque<T,Allocator>& operator=(const deque<T,Allocator>& x);
68
template <class InputIterator> void assign(InputIterator first, InputIterator last);
69
template <class Size, class U> void assign(Size n, const U& u = U());
70
allocator_type get_allocator() const;
73
const_iterator begin() const;
75
const_iterator end() const;
76
reverse_iterator rbegin();
77
const_reverse_iterator rbegin() const;
78
reverse_iterator rend();
79
const_reverse_iterator rend() const;
81
size_type size() const;
82
size_type max_size() const;
83
void resize(size_type sz, T c = T());
86
reference operator[](size_type n);
87
const_reference operator[](size_type n) const;
88
reference at(size_type n);
89
const_reference at(size_type n) const;
91
const_reference front() const;
93
const_reference back() const;
95
void push_front(const T& x);
96
void push_back(const T& x);
97
iterator insert(iterator position, const T& x = T());
98
void insert(iterator position, size_type n, const T& x);
99
template <class InputIterator> void insert (iterator position, InputIterator first, InputIterator last);
103
iterator erase(iterator position);
104
iterator erase(iterator first, iterator last);
105
void swap(deque<T,Allocator>&);
109
void reserve(size_type n);
110
inline size_type array_element(size_type deque_element) const{
111
if(deque_element < (data_size - first_element)){
112
return first_element + deque_element;
114
return deque_element - (data_size - first_element);
116
inline size_type first_subtract(size_type sub_size) const{
117
if(sub_size > first_element){
118
return (data_size - first_element) - sub_size;
120
return first_element - sub_size;
124
size_type data_size; //Physical size of array
125
size_type elements; //Elements in array
126
size_type first_element; //Element number of array 0..n
127
size_type last_element; //Element number of array 0..n
133
template<class T, class Allocator> class _UCXXEXPORT deque<T, Allocator>::deque_iter
134
: public std::iterator<
135
random_access_iterator_tag,
137
typename Allocator::difference_type,
138
typename Allocator::pointer,
139
typename Allocator::reference
142
friend class deque<T, Allocator>;
144
deque<T, Allocator> * container;
145
typename Allocator::size_type element;
148
deque_iter() : container(0), element(0) { }
149
deque_iter(const deque_iter & d) : container (d.container), element(d.element) { }
150
deque_iter(deque<T, Allocator> * c, typename Allocator::size_type e)
151
: container(c), element(e)
156
deque_iter & operator=(const deque_iter & d){
157
container = d.container;
162
return container->data[container->array_element(element)];
165
return container->data + container->array_element(element);
167
const T & operator*() const{
168
return container->data[container->array_element(element)];
170
const T * operator->() const{
171
return container->data + container->array_element(element);
173
bool operator==(const deque_iter & d) const{
174
if(container == d.container && element == d.element){
179
bool operator==(const deque_citer & d) const{
180
if(container == d.container && element == d.element){
185
bool operator!=(const deque_iter & d) const{
186
if(container != d.container || element != d.element){
191
bool operator!=(const deque_citer & d) const{
192
if(container != d.container || element != d.element){
197
bool operator<(const deque_iter & d) const{
198
if(element < d.element){
203
bool operator<(const deque_citer & d) const{
204
if(element < d.element){
209
bool operator<=(const deque_iter & d) const{
210
if(element <= d.element){
215
bool operator<=(const deque_citer & d) const{
216
if(element <= d.element){
221
bool operator>(const deque_iter & d) const{
222
if(element > d.element){
227
bool operator>(const deque_citer & d) const{
228
if(element > d.element){
233
bool operator>=(const deque_iter & d) const{
234
if(element >= d.element){
239
bool operator>=(const deque_citer & d) const{
240
if(element >= d.element){
245
deque_iter & operator++(){
249
deque_iter operator++(int){
250
deque_iter temp(container, element);
254
deque_iter operator+(typename Allocator::size_type n){
255
deque_iter temp(container, element + n);
258
deque_iter & operator+=(typename Allocator::size_type n){
262
deque_iter & operator--(){
266
deque_iter operator--(int){
267
deque_iter temp(container, element);
271
deque_iter operator-(typename Allocator::size_type n){
272
deque_iter temp(container, element - n);
275
deque_iter & operator-=(typename Allocator::size_type n){
279
typename Allocator::size_type operator-(const deque_iter & d){
280
return element - d.element;
285
template<class T, class Allocator> class _UCXXEXPORT deque<T, Allocator>::deque_citer
286
: public std::iterator<
287
random_access_iterator_tag,
289
typename Allocator::difference_type,
290
typename Allocator::const_pointer,
291
typename Allocator::const_reference
294
friend class deque<T, Allocator>;
296
const deque<T, Allocator> * container;
297
typename Allocator::size_type element;
300
deque_citer() : container(0), element(0) { }
301
deque_citer(const deque_citer & d) : container (d.container), element(d.element) { }
302
deque_citer(const deque_iter & d) : container (d.container), element(d.element) { }
303
deque_citer(const deque<T, Allocator> * c, typename Allocator::size_type e)
304
: container(c), element(e)
309
deque_citer & operator=(const deque_iter & d){
310
container = d.container;
314
const T & operator*() const{
315
return container->data[container->array_element(element)];
317
const T * operator->() const{
318
return container->data + container->array_element(element);
320
bool operator==(const deque_citer & d) const{
321
if(container == d.container && element == d.element){
326
bool operator==(const deque_iter & d) const{
327
if(container == d.container && element == d.element){
332
bool operator!=(const deque_citer & d) const{
333
if(container != d.container || element != d.element){
338
bool operator!=(const deque_iter & d) const{
339
if(container != d.container || element != d.element){
344
bool operator<(const deque_citer & d) const{
345
if(element < d.element){
350
bool operator<(const deque_iter & d) const{
351
if(element < d.element){
356
bool operator<=(const deque_citer & d) const{
357
if(element <= d.element){
362
bool operator<=(const deque_iter & d) const{
363
if(element <= d.element){
368
bool operator>(const deque_citer & d) const{
369
if(element > d.element){
374
bool operator>(const deque_iter & d) const{
375
if(element > d.element){
380
bool operator>=(const deque_citer & d){
381
if(element >= d.element){
386
bool operator>=(const deque_iter & d){
387
if(element >= d.element){
392
deque_citer & operator++(){
396
deque_citer operator++(int){
397
deque_citer temp(container, element);
401
deque_citer operator+(typename Allocator::size_type n){
402
deque_citer temp(container, element + n);
405
deque_citer & operator+=(typename Allocator::size_type n){
409
deque_citer & operator--(){
413
deque_citer operator--(int){
414
deque_citer temp(container, element);
418
deque_citer operator-(typename Allocator::size_type n){
419
deque_citer temp(container, element - n);
422
deque_citer & operator-=(typename Allocator::size_type n){
426
typename Allocator::size_type operator-(const deque_citer & d){
427
return element - d.element;
432
template<class T, class Allocator> deque<T, Allocator>::deque(const Allocator& al)
434
data_size(0), elements(0), first_element(0), last_element(0), a(al)
436
data_size = __UCLIBCXX_STL_BUFFER_SIZE__;
437
data = a.allocate(data_size);
438
first_element = data_size /2;
439
last_element = first_element;
443
template<class T, class Allocator> deque<T, Allocator>::deque(
444
size_type n, const T& value, const Allocator& al)
446
elements(n), first_element(0), last_element(0), a(al)
448
data_size = elements + __UCLIBCXX_STL_BUFFER_SIZE__;
449
data = a.allocate(data_size);
450
first_element = (data_size - elements) / 2;
451
last_element = first_element;
453
for(n=first_element ; n < last_element; ++n ){
454
a.construct(data+n, value);
459
template<class T, class Allocator> template <class InputIterator>
460
deque<T, Allocator>::deque(InputIterator first, InputIterator last, const Allocator& al)
462
data_size(0), elements(0), first_element(0), last_element(0), a(al)
464
data_size = __UCLIBCXX_STL_BUFFER_SIZE__;
465
data = a.allocate(data_size);
466
first_element = data_size / 4; //Note sure how big, but let's add a little space...
467
last_element = first_element;
468
while(first != last){
475
template<class T, class Allocator> deque<T, Allocator>::deque(const deque<T,Allocator>& x)
477
elements(0), first_element(0), last_element(0), a(x.a)
479
data_size = x.elements + __UCLIBCXX_STL_BUFFER_SIZE__;
480
data = a.allocate(data_size);
481
first_element = (data_size - x.elements) / 2;
482
last_element = first_element;
483
for(size_type i=0; i < x.elements; ++i){
489
template<class T, class Allocator> deque<T, Allocator>::~deque(){
491
a.deallocate(data, data_size);
494
template<class T, class Allocator> deque<T,Allocator>& deque<T, Allocator>::
495
operator=(const deque<T,Allocator>& x)
501
for(size_t i = 0; i < elements; ++i){
502
data[array_element(i)] = x[i];
508
template<class T, class Allocator> template <class InputIterator> void
509
deque<T, Allocator>::assign(InputIterator first, InputIterator last)
519
template<class T, class Allocator> template <class Size, class U> void
520
deque<T, Allocator>::assign(Size n, const U& u)
526
for(size_type i = 0; i < n; ++i){
532
template<class T, class Allocator> typename deque<T, Allocator>::allocator_type
533
deque<T, Allocator>::get_allocator() const
538
template<class T, class Allocator> typename
539
deque<T, Allocator>::iterator deque<T, Allocator>::begin()
541
return deque_iter(this, 0);
545
template<class T, class Allocator> typename deque<T, Allocator>::const_iterator
546
deque<T, Allocator>::begin() const
548
return deque_citer(this, 0);
551
template<class T, class Allocator> typename
552
deque<T, Allocator>::iterator deque<T, Allocator>::end()
554
return deque_iter(this, elements);
557
template<class T, class Allocator> typename
558
deque<T, Allocator>::const_iterator deque<T, Allocator>::end() const
560
return deque_citer(this, elements);
563
template<class T, class Allocator> typename
564
deque<T, Allocator>::reverse_iterator deque<T, Allocator>::rbegin()
566
return reverse_iterator(end());
569
template<class T, class Allocator> typename
570
deque<T, Allocator>::const_reverse_iterator deque<T, Allocator>::rbegin() const
572
return const_reverse_iterator(end());
575
template<class T, class Allocator> typename
576
deque<T, Allocator>::reverse_iterator deque<T, Allocator>::rend()
578
return reverse_iterator(begin());
581
template<class T, class Allocator> typename
582
deque<T, Allocator>::const_reverse_iterator deque<T, Allocator>::rend() const
584
return const_reverse_iterator(begin());
587
template<class T, class Allocator> typename
588
deque<T, Allocator>::size_type deque<T, Allocator>::size() const
593
template<class T, class Allocator> typename
594
deque<T, Allocator>::size_type deque<T, Allocator>::max_size() const
596
return ((size_type)(-1)) / sizeof(T);
599
template<class T, class Allocator> void deque<T, Allocator>::resize(size_type sz, T c){
609
template<class T, class Allocator> bool deque<T, Allocator>::empty() const{
610
return (elements == 0);
613
template<class T, class Allocator> typename
614
deque<T, Allocator>::reference deque<T, Allocator>::operator[](size_type n)
616
return data[array_element(n)];
619
template<class T, class Allocator> typename
620
deque<T, Allocator>::const_reference deque<T, Allocator>::operator[](size_type n) const
622
return data[array_element(n)];
625
template<class T, class Allocator> typename
626
deque<T, Allocator>::reference deque<T, Allocator>::at(size_type n)
629
__throw_out_of_range("Out of deque range");
631
return data[array_element(n)];
634
template<class T, class Allocator> typename
635
deque<T, Allocator>::const_reference deque<T, Allocator>::at(size_type n) const
638
__throw_out_of_range("Out of deque range");
640
return data[array_element(n)];
643
template<class T, class Allocator> typename
644
deque<T, Allocator>::reference deque<T, Allocator>::front()
646
return data[first_element];
649
template<class T, class Allocator> typename
650
deque<T, Allocator>::const_reference deque<T, Allocator>::front() const
652
return data[first_element];
655
template<class T, class Allocator> typename
656
deque<T, Allocator>::reference deque<T, Allocator>::back()
658
return data[array_element(elements-1)];
661
template<class T, class Allocator> typename
662
deque<T, Allocator>::const_reference deque<T, Allocator>::back() const
664
return data[array_element(elements-1)];
667
template<class T, class Allocator> void deque<T, Allocator>::push_front(const T& x){
668
reserve(elements + 1);
669
first_element = first_subtract(1);
670
a.construct(data + first_element, x);
674
template<class T, class Allocator> void deque<T, Allocator>::push_back(const T& x){
675
reserve(elements + 1);
676
a.construct(data + last_element, x);
678
last_element = array_element(elements);
681
template<class T, class Allocator> typename
682
deque<T, Allocator>::iterator deque<T, Allocator>::insert(iterator position, const T& x)
685
if(position.element > (elements/2)){
686
//Push all elements back 1
688
for(size_type i = elements-1; i > position.element; --i){
692
//Push all elements forward 1
694
for(size_type i = 0; i < position.element; ++i){
698
at(position.element) = x;
699
return deque_iter(this, position.element);
702
template<class T, class Allocator> void deque<T, Allocator>::
703
insert(typename deque<T, Allocator>::iterator position, size_type n, const T& x)
705
reserve(elements + n);
706
for(size_t i =0; i < n; ++i){
707
position = insert(position, x);
711
template<class T, class Allocator> template <class InputIterator>
712
void deque<T, Allocator>::insert (iterator position, InputIterator first, InputIterator last)
714
while(first != last){
715
position = insert(position, *first);
720
template<class T, class Allocator> void deque<T, Allocator>::pop_front(){
722
__throw_out_of_range("deque pop_front");
724
a.destroy(data + first_element);
725
first_element = array_element(1);
729
template<class T, class Allocator> void deque<T, Allocator>::pop_back(){
730
last_element = array_element(elements - 1);
731
a.destroy(data + last_element);
735
template<class T, class Allocator> typename
736
deque<T, Allocator>::iterator deque<T, Allocator>::erase(typename deque<T, Allocator>::iterator position)
738
if(position.element > (elements /2)){
739
for(size_type i = position.element; i < elements - 1; ++i){
744
for(size_type i = position.element; i > 0; --i){
749
return deque_iter(this, position.element);
752
template<class T, class Allocator> typename deque<T, Allocator>::iterator
753
deque<T, Allocator>::
754
erase(typename deque<T, Allocator>::iterator first, typename deque<T, Allocator>::iterator last)
757
size_type num_move = last.element - first.element;
758
if( first.element > (elements - last.element) ){
759
for(size_type i = last.element; i < elements ; ++i){
760
at(i-num_move) = at(i);
762
for(size_type i = 0; i < num_move ; ++i){
766
for(size_type i = 0; i < first.element ; ++i){
767
at(last.element - i - 1) = at(first.element - i - 1);
769
for(size_type i = 0; i < num_move ; ++i){
773
return deque_iter(this, first.element);
776
template<class T, class Allocator> void deque<T, Allocator>::swap(deque<T,Allocator>& x)
779
typename deque<T,Allocator>::size_type temp_size;
787
temp_size = x.data_size;
788
x.data_size = data_size;
789
data_size = temp_size;
791
//Swap num array elements
792
temp_size = x.elements;
793
x.elements = elements;
794
elements = temp_size;
797
temp_size = x.first_element;
798
x.first_element = first_element;
799
first_element = temp_size;
802
temp_size = x.last_element;
803
x.last_element = last_element;
804
last_element = temp_size;
807
template<class T, class Allocator> void deque<T, Allocator>::clear()
809
while(elements > 0 ){
815
template<class T, class Allocator> void deque<T, Allocator>::reserve(typename deque<T, Allocator>::size_type n)
822
size_type first_temp;
824
size_temp = n + __UCLIBCXX_STL_BUFFER_SIZE__; //Reserve extra 'cause we can
825
data_temp = a.allocate(size_temp);
827
first_temp = (size_temp - elements) / 2;
828
for(size_type i = 0; i < elements; ++i){
829
a.construct(data_temp + first_temp + i, data[array_element(i)]);
830
a.destroy(data + array_element(i));
833
//Now shuffle pointers
834
a.deallocate(data, data_size);
836
data_size = size_temp;
837
first_element = first_temp;
838
last_element = first_element + elements;
842
template <class T, class Allocator> _UCXXEXPORT
844
operator==(const deque<T,Allocator>& x, const deque<T,Allocator>& y)
846
if(x.elements != y.elements){
849
for(typename deque<T,Allocator>::size_type i = 0; i < x.elements; ++i){
850
if(x[i] < y[i] || y[i] < x[i]){
857
template <class T, class Allocator> bool operator< (const deque<T,Allocator>& x, const deque<T,Allocator>& y);
858
template <class T, class Allocator> _UCXXEXPORT
860
operator!=(const deque<T,Allocator>& x, const deque<T,Allocator>& y)
867
template <class T, class Allocator> bool operator> (const deque<T,Allocator>& x, const deque<T,Allocator>& y);
868
template <class T, class Allocator> bool operator>=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
869
template <class T, class Allocator> bool operator<=(const deque<T,Allocator>& x, const deque<T,Allocator>& y);
870
template <class T, class Allocator> _UCXXEXPORT void swap(deque<T,Allocator>& x, deque<T,Allocator>& y){
878
#pragma GCC visibility pop