/elec/propeller-clock

To get this branch, use:
bzr branch http://bzr.ed.am/elec/propeller-clock
57 by edam
added ulibc
1
/*	Copyright (C) 2004 Garrett A. Kajmowicz
2
3
	This file is part of the uClibc++ Library.
4
5
	This library is free software; you can redistribute it and/or
6
	modify it under the terms of the GNU Lesser General Public
7
	License as published by the Free Software Foundation; either
8
	version 2.1 of the License, or (at your option) any later version.
9
10
	This library is distributed in the hope that it will be useful,
11
	but WITHOUT ANY WARRANTY; without even the implied warranty of
12
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
	Lesser General Public License for more details.
14
15
	You should have received a copy of the GNU Lesser General Public
16
	License along with this library; if not, write to the Free Software
17
	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
*/
19
20
#include <memory>
21
#include <iterator>
22
#include <algorithm>
23
24
#ifndef __STD_HEADER_LIST
25
#define __STD_HEADER_LIST 1
26
27
#pragma GCC visibility push(default)
28
29
namespace std{
30
31
	template <class T, class Allocator = allocator<T> > class _UCXXEXPORT list {
32
	public:
33
		typedef typename Allocator::reference		reference;
34
		typedef typename Allocator::const_reference	const_reference;
35
		typedef typename Allocator::size_type		size_type;
36
		typedef typename Allocator::difference_type	difference_type;
37
		typedef T					value_type;
38
		typedef Allocator				allocator_type;
39
		typedef typename Allocator::pointer		pointer;
40
		typedef typename Allocator::const_pointer	const_pointer;
41
42
	protected:
43
		class node;
44
		class iter_list;
45
46
		node * list_start;
47
		node * list_end;
48
		size_type elements;
49
		Allocator a;
50
51
	public:
52
53
		typedef iter_list				iterator;
54
		typedef iter_list				const_iterator;
55
		typedef std::reverse_iterator<iterator>		reverse_iterator;
56
		typedef std::reverse_iterator<const_iterator>	const_reverse_iterator;
57
58
		explicit list(const Allocator& = Allocator());
59
		explicit list(size_type n, const T& value = T(), const Allocator& = Allocator());
60
		template <class InputIterator> list(InputIterator first, InputIterator last, 
61
			const Allocator& al= Allocator());
62
		list(const list<T,Allocator>& x);
63
		~list();
64
65
		list<T,Allocator>& operator=(const list<T,Allocator>& x){
66
			if(&x == this){
67
				return *this;
68
			}
69
			clear();
70
			iterator i = x.begin();
71
			while(i != x.end()){
72
				push_back(*i);
73
				++i;
74
			}
75
			return *this;
76
		}
77
78
		template <class InputIterator> void assign(InputIterator first, InputIterator last);
79
		template <class Size, class U> void assign(Size n, const U& u = U());
80
		allocator_type get_allocator() const;
81
82
		iterator		begin();
83
		const_iterator		begin() const;
84
		iterator		end();
85
		const_iterator		end() const;
86
		reverse_iterator	rbegin();
87
		const_reverse_iterator	rbegin() const;
88
		reverse_iterator	rend();
89
		const_reverse_iterator	rend() const;
90
91
		bool      empty() const;
92
		size_type size() const;
93
		size_type max_size() const;
94
		void      resize(size_type sz, T c = T());
95
96
		reference       front();
97
		const_reference front() const;
98
		reference       back();
99
		const_reference back() const;
100
101
		void push_front(const T& x);
102
		void pop_front();
103
		void push_back(const T& x);
104
		void pop_back();
105
		iterator insert(iterator position, const T& x = T());
106
		void     insert(iterator position, size_type n, const T& x);
107
		template <class InputIterator> void insert(iterator position, InputIterator first, InputIterator last);
108
		iterator erase(iterator position);
109
		iterator erase(iterator position, iterator last);
110
		void     swap(list<T,Allocator>&);
111
		void     clear();
112
113
		void splice(iterator position, list<T,Allocator>& x);
114
		void splice(iterator position, list<T,Allocator>& x, iterator i);
115
		void splice(iterator position, list<T,Allocator>& x, iterator first, iterator last);
116
		void remove(const T& value);
117
		template <class Predicate> void remove_if(Predicate pred);
118
		void unique();
119
		template <class BinaryPredicate> void unique(BinaryPredicate binary_pred);
120
		void merge(list<T,Allocator>& x);
121
		template <class Compare> void merge(list<T,Allocator>& x, Compare comp);
122
		void sort();
123
		template <class Compare> void sort(Compare comp);
124
		void reverse();
125
	protected:
126
		void swap_nodes(node * x, node * y);
127
	};
128
129
130
	//Implementations of List
131
132
	//List node
133
	template <class T, class Allocator> class _UCXXEXPORT list<T, Allocator>::node{
134
	public:
135
		node * previous;
136
		node * next;
137
		T * val;
138
139
		node(): previous(0), next(0), val(0){ }
140
		node(const T & t ): previous(0), next(0), val(0) {
141
			val = new T(t);
142
			//FIXME use allocator somehow but only call constructor once
143
		}
144
		node(const T & t, node * p, node * n): previous(p), next(n), val(0) {
145
			val = new T(t);
146
		}
147
		~node(){ }
148
	};
149
150
	//List iterator
151
	template <class T, class Allocator> class _UCXXEXPORT list<T, Allocator>::iter_list
152
		: public std::iterator<
153
			bidirectional_iterator_tag, 
154
			T, 
155
			typename Allocator::difference_type, 
156
			typename Allocator::pointer, 
157
			typename Allocator::reference
158
		>
159
	{
160
	private:
161
		node * current;
162
	public:
163
		iter_list():current(0) { }
164
		iter_list( typename list<T, Allocator>::node * n): current(n) { }
165
		iter_list(const list<T, Allocator>::iter_list & l): current(l.current) { }
166
		~iter_list(){ }
167
168
		iter_list & operator=(const list<T, Allocator>::iter_list & right ){
169
			current = right.current;
170
			return *this;
171
		}
172
173
		T & operator*(){
174
			return *(current->val);
175
		}
176
		T * operator->(){
177
			return current->val;
178
		}
179
		const T & operator*() const{
180
			return *current->val;
181
		}
182
		const T * operator->() const{
183
			return current->val;
184
		}
185
186
		bool operator==(const list<T, Allocator>::iter_list & right) const {
187
			return (current == right.current);
188
		}
189
190
		bool operator!=(const list<T, Allocator>::iter_list & right) const {
191
			return (current != right.current);
192
		}
193
194
		iter_list & operator++(){
195
			current = current->next;
196
			return *this;
197
		}
198
199
		iter_list operator++(int){
200
			iter_list temp(current);
201
			current = current->next;
202
			return temp;
203
		}		
204
		iter_list & operator--(){
205
			current = current->previous;
206
			return *this;
207
		}
208
209
		iter_list operator--(int){
210
			iter_list temp(current);
211
			current = current->previous;
212
			return temp;
213
		}
214
		node * link_struct(){
215
			return current;
216
		}
217
		iter_list & operator+=(unsigned int n){
218
			for(unsigned int i = 0; i < n; ++i){
219
				current = current->next;
220
			}
221
			return *this;
222
		}
223
		iter_list & operator-=(unsigned int n){
224
			for(unsigned int i = 0; i < n; ++i){
225
				current = current->previous;
226
			}
227
			return *this;
228
		}
229
	};
230
231
232
	template<class T, class Allocator> list<T, Allocator>::list(const Allocator& al)
233
		:list_start(0), list_end(0), elements(0), a(al)
234
	{
235
		//End node
236
		list_start = new node();
237
		list_end = list_start;
238
		return;
239
	}
240
241
	template<class T, class Allocator> list<T, Allocator>::list
242
		(typename Allocator::size_type n, const T& value, const Allocator& al)
243
		:list_start(0), list_end(0), elements(0), a(al)
244
	{
245
		//End node
246
		list_start = new node();
247
		list_end = list_start;
248
249
		for(typename Allocator::size_type i = 0; i < n ; ++i){
250
			push_back(value);
251
		}
252
	}
253
254
	template<class T, class Allocator> template <class InputIterator>
255
		list<T, Allocator>::list
256
		(InputIterator first, InputIterator last, const Allocator& al)
257
		: list_start(0), list_end(0), elements(0), a(al)
258
	{
259
		list_start = new node();
260
		list_end = list_start;
261
		while(first != last){
262
			push_back(*first);
263
			++first;
264
		}
265
	}
266
267
	template<class T, class Allocator> list<T, Allocator>::list(const list<T,Allocator>& x)
268
		: list_start(0), list_end(0), elements(0), a(x.a)
269
	{
270
		list_start = new node();
271
		list_end = list_start;
272
273
		iterator i = x.begin();
274
		while(i != x.end()){
275
			push_back( *i);
276
			++i;
277
		}
278
	}
279
280
	template<class T, class Allocator> list<T, Allocator>::~list(){
281
		while(elements > 0){
282
			pop_front();
283
		}
284
		delete list_start->val;
285
#if UCLIBCXX_DEBUG
286
		list_start->val = 0;
287
#endif
288
		delete list_start;
289
#if UCLIBCXX_DEBUG
290
		list_start = 0;
291
		list_end = 0;
292
#endif
293
	}
294
295
296
	template<class T, class Allocator> void list<T, Allocator>::swap_nodes(node * x, node * y){
297
		T * v = x->val;
298
		x->val = y->val;
299
		y->val = v;
300
	}
301
302
	template<class T, class Allocator> typename list<T, Allocator>::iterator 
303
		list<T, Allocator>::begin()
304
	{
305
		return iterator(list_start);
306
	}
307
308
	
309
	template<class T, class Allocator> typename list<T, Allocator>::const_iterator
310
		list<T, Allocator>::begin() const
311
	{
312
		return const_iterator(list_start);
313
	}
314
315
	
316
	template<class T, class Allocator> typename list<T, Allocator>::iterator
317
		list<T, Allocator>::end()
318
	{
319
		return iterator(list_end);
320
	}
321
322
	template<class T, class Allocator> typename list<T, Allocator>::const_iterator
323
		list<T, Allocator>::end() const
324
	{
325
		return const_iterator(list_end);
326
	}
327
328
	template<class T, class Allocator> typename list<T, Allocator>::reverse_iterator
329
		list<T, Allocator>::rbegin()
330
	{
331
		return reverse_iterator(end());
332
	}
333
334
	template<class T, class Allocator> typename list<T, Allocator>::const_reverse_iterator
335
		list<T, Allocator>::rbegin() const
336
	{
337
		return const_reverse_iterator(end());
338
	}
339
340
	template<class T, class Allocator> typename list<T, Allocator>::reverse_iterator
341
		list<T, Allocator>::rend()
342
	{
343
		return reverse_iterator(begin());
344
	}
345
346
	template<class T, class Allocator> typename list<T, Allocator>::const_reverse_iterator
347
		list<T, Allocator>::rend() const
348
	{
349
		return const_reverse_iterator(begin());
350
	}
351
352
	template<class T, class Allocator> bool list<T, Allocator>::empty() const{
353
		return (elements == 0);
354
	}
355
	template<class T, class Allocator> typename list<T, Allocator>::size_type list<T, Allocator>::size() const{
356
		return elements;
357
	}
358
	template<class T, class Allocator> typename list<T, Allocator>::size_type list<T, Allocator>::max_size() const{
359
		return ((size_type)(-1)) / (sizeof(T) + sizeof(node));
360
	}
361
	template<class T, class Allocator> void list<T, Allocator>::resize(typename Allocator::size_type sz, T c){
362
//		if(sz > elements){
363
			for(typename Allocator::size_type i = elements; i < sz; ++i){
364
				push_back(c);
365
			}
366
//		}
367
//		if(sz < elements){
368
			for(typename Allocator::size_type i = elements; i > sz; --i){
369
				pop_back();
370
			}
371
//		}
372
	}
373
374
	template<class T, class Allocator> typename list<T, Allocator>::reference list<T, Allocator>::front(){
375
		return *(list_start->val);
376
	}
377
	template<class T, class Allocator> typename list<T, Allocator>::const_reference list<T, Allocator>::front() const{
378
		return *(list_start->val);
379
	}
380
	template<class T, class Allocator> typename list<T, Allocator>::reference list<T, Allocator>::back(){
381
		return *(list_end->previous->val);
382
	}
383
	template<class T, class Allocator> typename list<T, Allocator>::const_reference list<T, Allocator>::back() const{
384
		return *(list_end->previous->val);
385
	}
386
387
388
	template<class T, class Allocator> void list<T, Allocator>::push_front(const T& x){
389
		node * temp = new node(x);
390
		list_start->previous = temp;
391
		temp->previous = 0;
392
		temp->next = list_start;
393
		list_start = temp;
394
		++elements;
395
	}
396
397
	template<class T, class Allocator> void list<T, Allocator>::pop_front(){
398
		if(elements > 0){
399
			list_start = list_start->next;
400
			delete list_start->previous->val;
401
#if UCLIBCXX_DEBUG
402
			list_start->previous->val = 0;
403
			list_start->previous->next = 0;
404
			list_start->previous->previous = 0;
405
#endif
406
			delete list_start->previous;
407
			list_start->previous = 0;
408
			--elements;
409
		}
410
	}
411
412
	template<class T, class Allocator> void list<T, Allocator>::push_back(const T& x){
413
		if(elements == 0){
414
			//The list is completely empty
415
			list_start = new node(x);
416
			list_end->previous = list_start;
417
			list_start->previous = 0;
418
			list_start->next = list_end;
419
			elements = 1;
420
		}else{
421
			node * temp = new node(x);
422
			temp->previous = list_end->previous;
423
			temp->next = list_end;
424
			list_end->previous->next = temp;
425
			list_end->previous = temp;
426
			++elements;
427
		}
428
	}
429
430
	template<class T, class Allocator> void list<T, Allocator>::pop_back(){
431
		if(elements > 0){
432
			node * temp = list_end->previous;
433
			if(temp == list_start){
434
				list_end->previous = 0;
435
				list_start = list_end;
436
			}else{
437
				temp->previous->next = temp->next;
438
				list_end->previous = temp->previous;
439
			}
440
			delete temp->val;
441
#if UCLIBCXX_DEBUG
442
			temp->val = 0;
443
			temp->next = 0;
444
			temp->previous = 0;
445
#endif
446
			delete temp;
447
#if UCLIBCXX_DEBUG
448
			temp = 0;
449
#endif
450
			--elements;
451
		}
452
	}
453
454
455
	template<class T, class Allocator> typename list<T, Allocator>::iterator 
456
		list<T, Allocator>::insert(iterator position, const T& x)
457
	{
458
		node * temp = new node(x);
459
460
		temp->previous = position.link_struct()->previous;
461
		temp->next = position.link_struct();
462
463
		if(temp->previous == 0){
464
			list_start = temp;
465
		}else{
466
			position.link_struct()->previous->next = temp;
467
		}
468
469
		position.link_struct()->previous = temp;
470
471
		++elements;
472
		--position;
473
		return position;
474
	}
475
476
	template<class T, class Allocator> void list<T, Allocator>::insert(iterator position, size_type n, const T& x){
477
		for(typename list<T, Allocator>::size_type i = 0; i < n; ++i){
478
			position = insert(position, x);
479
		}
480
	}
481
482
	template<class T, class Allocator> template <class InputIterator> void
483
		list<T, Allocator>::insert(iterator position, InputIterator first, InputIterator last)
484
	{
485
		while(first !=last){
486
			insert(position, *first);
487
			++first;
488
		}
489
	}
490
	template<class T, class Allocator> typename list<T, Allocator>::iterator
491
		list<T, Allocator>::erase(iterator position)
492
	{
493
		if(position != end() ){
494
			node * temp = position.link_struct();
495
			if(temp == list_start){
496
				++position;
497
				temp->next->previous = 0;
498
				list_start = temp->next;
499
			}else{
500
				--position;
501
				temp->next->previous = temp->previous;
502
				temp->previous->next = temp->next;
503
				++position;
504
			}
505
			delete temp->val;
506
#if UCLIBCXX_DEBUG
507
			temp->next = 0;
508
			temp->previous = 0;
509
			temp->val = 0;
510
#endif
511
			delete temp;
512
#if UCLIBCXX_DEBUG
513
			temp = 0;
514
#endif
515
			--elements;
516
		}
517
		return position;
518
	}
519
	template<class T, class Allocator> typename list<T, Allocator>::iterator
520
		list<T, Allocator>::erase(iterator position, iterator last)
521
	{
522
		iterator temp = position;
523
		while(position !=last){
524
			position = erase(position);
525
		}
526
		return position;
527
	}
528
	template<class T, class Allocator> void list<T, Allocator>::swap(list<T,Allocator>& l){
529
		node * temp;
530
		size_type tempel;
531
532
		temp = list_start;
533
		list_start = l.list_start;
534
		l.list_start = temp;
535
536
		temp = list_end;
537
		list_end = l.list_end;
538
		l.list_end = temp;
539
540
		tempel = elements;
541
		elements = l.elements;
542
		l.elements = tempel;
543
	}
544
	template<class T, class Allocator> void list<T, Allocator>::clear(){
545
		while(elements > 0){
546
			pop_front();
547
		}
548
	}
549
550
	template<class T, class Allocator>
551
		void list<T, Allocator>::splice(iterator position, list<T,Allocator>& x)
552
	{
553
554
		//Can't add non-existant elements
555
		if(x.elements == 0){
556
			return;
557
		}
558
559
		elements += x.elements;
560
		x.elements = 0;
561
562
563
		//Chaining to the begining
564
		if(position == begin()){
565
			x.list_end->previous->next = list_start;
566
			list_start->previous = x.list_end->previous;
567
568
			list_start = x.list_start;
569
570
			x.list_start = x.list_end;
571
			x.list_end->previous = 0;
572
573
			return;
574
		}
575
576
		//Link everything we need
577
		x.list_start->previous = position.link_struct()->previous;
578
		position.link_struct()->previous->next = x.list_start;
579
	
580
		position.link_struct()->previous = x.list_end->previous;
581
		x.list_end->previous->next = position.link_struct();
582
583
		//Clean up the other list
584
		
585
		x.list_start = x.list_end;
586
		x.list_end->previous=0;
587
588
	}
589
590
	template<class T, class Allocator>
591
                void list<T, Allocator>::splice(iterator position, list<T,Allocator>& x, iterator i)
592
	{
593
		//Invalid conditions
594
		if( x.elements == 0 || i == position || position.link_struct() == i.link_struct()->next ){
595
			return;
596
		}
597
598
599
		//Do we need to adjust the begining pointer?
600
		if(i == x.begin()){
601
			x.list_start = x.list_start->next;
602
			x.list_start->previous = 0;
603
		}
604
605
606
		//Insert at begining special case
607
		if(position == begin()){
608
609
			i.link_struct()->previous->next = i.link_struct()->next;
610
			i.link_struct()->next->previous = i.link_struct()->previous;
611
612
			i.link_struct()->previous = 0;
613
			i.link_struct()->next = position.link_struct();
614
			position.link_struct()->previous = i.link_struct();
615
616
			list_start = i.link_struct();
617
618
			--x.elements;
619
			++elements;
620
			return;
621
		}
622
623
		if( i.link_struct()->previous != 0){
624
			i.link_struct()->previous->next = i.link_struct()->next;
625
			i.link_struct()->next->previous = i.link_struct()->previous;
626
		}else{
627
			i.link_struct()->next->previous = 0;
628
			x.list_start = i.link_struct()->next;
629
		}
630
		
631
		i.link_struct()->previous = position.link_struct()->previous;
632
		position.link_struct()->previous->next = i.link_struct();
633
634
		i.link_struct()->next = position.link_struct();
635
		position.link_struct()->previous = i.link_struct();
636
637
		--x.elements;
638
		++elements;
639
	}
640
641
	template<class T, class Allocator>
642
		void list<T, Allocator>::splice(iterator position, list<T,Allocator>& x,
643
			iterator first, iterator last)
644
	{
645
		if(x.elements == 0){
646
			return;
647
		}
648
649
		iterator temp;
650
		while(first != last){
651
			temp = first;
652
			++first;
653
			splice(position, x, temp);
654
		}
655
	}
656
657
658
	template<class T, class Allocator> void list<T, Allocator>::remove(const T& value){
659
		iterator temp = begin();
660
		while( temp != end() ){
661
			if(*temp == value){
662
				temp = erase(temp);
663
			}else{
664
				++temp;
665
			}
666
		}
667
	}
668
669
670
	template<class T, class Allocator> template <class Predicate> void list<T, Allocator>::remove_if(Predicate pred){
671
		iterator temp = begin();
672
		while( temp != end() ){
673
			if( pred(*temp) ){
674
				temp = erase(temp);
675
			}else{
676
				++temp;
677
			}
678
		}
679
	}
680
681
682
	template<class T, class Allocator> void list<T, Allocator>::unique(){
683
		equal_to<typename iterator_traits<iterator>::value_type> p;
684
		unique(p);
685
	}
686
687
	template<class T, class Allocator> template <class BinaryPredicate>
688
		void list<T, Allocator>::unique(BinaryPredicate binary_pred)
689
	{
690
		iterator temp1 = begin();
691
		iterator temp2;
692
		++temp1;
693
		while( temp1 != end() ){
694
			temp2 = temp1;
695
			--temp2;
696
			if( binary_pred(*temp1, *temp2) ){
697
				erase(temp1);
698
				temp1 = temp2;
699
			}
700
			++temp1;
701
		}
702
	}
703
704
	template<class T, class Allocator> void list<T, Allocator>::merge(list<T,Allocator>& x){
705
		less<typename iterator_traits<typename list<T, Allocator>::iterator>::value_type> c;
706
		merge(x, c);
707
	}
708
709
	template<class T, class Allocator> template <class Compare> 
710
		void list<T, Allocator>::merge(list<T,Allocator>& x, Compare comp)
711
	{
712
		iterator source = x.begin();
713
		iterator temp;
714
		iterator dest  = begin();
715
716
		while(source != x.end()){
717
			while( dest != end() && comp (*dest, *source) ){
718
				++dest;
719
			}
720
			++elements;
721
			--x.elements;
722
723
			temp = source;
724
			++temp;
725
726
			if(dest == begin()){
727
				dest.link_struct()->previous = source.link_struct();
728
				source.link_struct()->next = dest.link_struct();
729
				source.link_struct()->previous = 0;
730
				list_start = source.link_struct();
731
			}else{
732
				source.link_struct()->previous = dest.link_struct()->previous;
733
				dest.link_struct()->previous->next = source.link_struct();
734
				source.link_struct()->next = dest.link_struct();
735
				dest.link_struct()->previous = source.link_struct();
736
			}
737
			source = temp;
738
		}
739
740
		//Fix up x;
741
		x.list_start = x.list_end;
742
		x.list_start->previous = 0;
743
	}
744
745
	template<class T, class Allocator> void list<T, Allocator>::sort(){
746
		less<typename iterator_traits<typename list<T, Allocator>::iterator>::value_type> c;
747
		sort(c);
748
	}
749
750
	template<class T, class Allocator> template <class Compare>
751
		void list<T, Allocator>::sort(Compare comp)
752
	{
753
		typename list<T, Allocator>::iterator i, j, k;
754
755
		//FIXME - bubble sort
756
757
		if(elements == 0){
758
			return;
759
		}
760
761
		i = end();
762
		--i;
763
		while(i != begin()){
764
			j = begin();
765
			k = j;
766
			++k;
767
			while(j != i){
768
				if( comp(*k, *j) ){
769
					swap_nodes(k.link_struct(), j.link_struct());
770
				}
771
				++j;
772
				++k;
773
			}
774
			--i;
775
		}
776
	}
777
778
779
	template<class T, class Allocator> void list<T, Allocator>::reverse(){
780
		if(elements == 0){
781
			return;
782
		}
783
784
		node * current;
785
		node * following;
786
		node * temp;
787
788
		//Need to move the list_end element to the begining
789
790
		temp = list_end;
791
		list_end = temp->previous;
792
		list_end->next = 0;
793
794
		list_start->previous = temp;
795
		temp->previous = 0;
796
		temp->next = list_start;
797
		list_start = temp;
798
799
		current = list_start;
800
801
		while( current != list_end ){
802
			following = current->next;
803
804
			//Swap the values pointed to/at with the current node
805
			temp = current->next;
806
			current->next = current->previous;
807
			current->previous = temp;
808
809
			current = following;
810
		}
811
812
		//Swap pointers on the end node
813
		temp = list_end->next;
814
		list_end->next = list_end->previous;
815
		list_end->previous = temp;
816
817
818
		//Swap the fixed pointers
819
		temp = list_start;
820
		list_start = list_end;
821
		list_end = temp;
822
823
	}
824
825
	template <class T, class Allocator>
826
	bool operator==(const list<T,Allocator>& x, const list<T,Allocator>& y){
827
		if(x.size() != y.size()){
828
			return false;
829
		}
830
		typename list<T,Allocator>::const_iterator i = x.begin();
831
		typename list<T,Allocator>::const_iterator j = y.begin();
832
833
		while(i != x.end()){
834
			if( *i != *j){
835
				return false;
836
			}
837
			++i;
838
			++j;
839
		}
840
		return true;
841
	}
842
843
	template <class T, class Allocator>
844
	bool operator< (const list<T,Allocator>& x, const list<T,Allocator>& y){
845
		typename list<T,Allocator>::const_iterator i = x.begin();
846
		typename list<T,Allocator>::const_iterator j = y.begin();
847
		while(i != x.end() && j != y.end()){
848
			if( *i < *j){
849
				return true;
850
			}
851
			if(*j < *i){
852
				return false;
853
			}
854
			++i;
855
			++j;
856
		}
857
		return (i == x.end() && j != y.end());
858
	}
859
860
	template <class T, class Allocator>
861
	bool operator!=(const list<T,Allocator>& x, const list<T,Allocator>& y){
862
		return !(x == y);
863
	}
864
865
	template <class T, class Allocator>
866
	bool operator> (const list<T,Allocator>& x, const list<T,Allocator>& y){
867
		typename list<T,Allocator>::const_iterator i = x.begin();
868
		typename list<T,Allocator>::const_iterator j = y.begin();
869
		while(i != x.end() && j != y.end()){
870
			if( *i > *j){
871
				return true;
872
			}
873
			if( *j > *i){
874
				return false;
875
			}
876
			++i;
877
			++j;
878
		}
879
		return (i != x.end() && j == y.end());
880
	}
881
882
	template <class T, class Allocator>
883
	bool operator>=(const list<T,Allocator>& x, const list<T,Allocator>& y){
884
		typename list<T,Allocator>::const_iterator i = x.begin();
885
		typename list<T,Allocator>::const_iterator j = y.begin();
886
		while(i != x.end() && j != y.end()){
887
			if( *i >= *j){
888
				return true;
889
			}
890
			if(*j >= *i){
891
				return false;
892
			}
893
			++i;
894
			++j;
895
		}
896
		return (i != x.end() && j == y.end());
897
	}
898
899
	template <class T, class Allocator>
900
	bool operator<=(const list<T,Allocator>& x, const list<T,Allocator>& y){
901
		typename list<T,Allocator>::const_iterator i = x.begin();
902
		typename list<T,Allocator>::const_iterator j = y.begin();
903
		while(i != x.end() && j != y.end()){
904
			if( *i <= *j){
905
				return true;
906
			}
907
			if(*j <= *i){
908
				return false;
909
			}
910
			++i;
911
			++j;
912
		}
913
		return (i == x.end());
914
	}
915
916
	template <class T, class Allocator>
917
	void swap(list<T,Allocator>& x, list<T,Allocator>& y){
918
		x.swap(y);
919
	}
920
921
}
922
923
#pragma GCC visibility pop
924
925
#endif
926
927