Install msysDVLPR-1.0.0-alpha-1
[msysgit.git] / include / g++-3 / stl_deque.h
blob24a8bfb1bc8fd6aa8bcff225ac9621d1491c73ba
1 /*
3 * Copyright (c) 1994
4 * Hewlett-Packard Company
6 * Permission to use, copy, modify, distribute and sell this software
7 * and its documentation for any purpose is hereby granted without fee,
8 * provided that the above copyright notice appear in all copies and
9 * that both that copyright notice and this permission notice appear
10 * in supporting documentation. Hewlett-Packard Company makes no
11 * representations about the suitability of this software for any
12 * purpose. It is provided "as is" without express or implied warranty.
15 * Copyright (c) 1997
16 * Silicon Graphics Computer Systems, Inc.
18 * Permission to use, copy, modify, distribute and sell this software
19 * and its documentation for any purpose is hereby granted without fee,
20 * provided that the above copyright notice appear in all copies and
21 * that both that copyright notice and this permission notice appear
22 * in supporting documentation. Silicon Graphics makes no
23 * representations about the suitability of this software for any
24 * purpose. It is provided "as is" without express or implied warranty.
27 /* NOTE: This is an internal header file, included by other STL headers.
28 * You should not attempt to use it directly.
31 #ifndef __SGI_STL_INTERNAL_DEQUE_H
32 #define __SGI_STL_INTERNAL_DEQUE_H
34 /* Class invariants:
35 * For any nonsingular iterator i:
36 * i.node is the address of an element in the map array. The
37 * contents of i.node is a pointer to the beginning of a node.
38 * i.first == *(i.node)
39 * i.last == i.first + node_size
40 * i.cur is a pointer in the range [i.first, i.last). NOTE:
41 * the implication of this is that i.cur is always a dereferenceable
42 * pointer, even if i is a past-the-end iterator.
43 * Start and Finish are always nonsingular iterators. NOTE: this means
44 * that an empty deque must have one node, and that a deque
45 * with N elements, where N is the buffer size, must have two nodes.
46 * For every node other than start.node and finish.node, every element
47 * in the node is an initialized object. If start.node == finish.node,
48 * then [start.cur, finish.cur) are initialized objects, and
49 * the elements outside that range are uninitialized storage. Otherwise,
50 * [start.cur, start.last) and [finish.first, finish.cur) are initialized
51 * objects, and [start.first, start.cur) and [finish.cur, finish.last)
52 * are uninitialized storage.
53 * [map, map + map_size) is a valid, non-empty range.
54 * [start.node, finish.node] is a valid range contained within
55 * [map, map + map_size).
56 * A pointer in the range [map, map + map_size) points to an allocated node
57 * if and only if the pointer is in the range [start.node, finish.node].
62 * In previous versions of deque, node_size was fixed by the
63 * implementation. In this version, however, users can select
64 * the node size. Deque has three template parameters; the third,
65 * a number of type size_t, is the number of elements per node.
66 * If the third template parameter is 0 (which is the default),
67 * then deque will use a default node size.
69 * The only reason for using an alternate node size is if your application
70 * requires a different performance tradeoff than the default. If,
71 * for example, your program contains many deques each of which contains
72 * only a few elements, then you might want to save memory (possibly
73 * by sacrificing some speed) by using smaller nodes.
75 * Unfortunately, some compilers have trouble with non-type template
76 * parameters; stl_config.h defines __STL_NON_TYPE_TMPL_PARAM_BUG if
77 * that is the case. If your compiler is one of them, then you will
78 * not be able to use alternate node sizes; you will have to use the
79 * default value.
82 __STL_BEGIN_NAMESPACE
84 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
85 #pragma set woff 1174
86 #pragma set woff 1375
87 #endif
89 // Note: this function is simply a kludge to work around several compilers'
90 // bugs in handling constant expressions.
91 inline size_t
92 __deque_buf_size(size_t __n, size_t __size)
94 return __n != 0 ? __n : (__size < 512 ? size_t(512 / __size) : size_t(1));
97 #ifndef __STL_NON_TYPE_TMPL_PARAM_BUG
98 template <class _Tp, class _Ref, class _Ptr, size_t __bufsiz>
99 struct _Deque_iterator {
100 typedef _Deque_iterator<_Tp,_Tp&,_Tp*,__bufsiz> iterator;
101 typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*,__bufsiz> const_iterator;
102 static size_t
103 _S_buffer_size() { return __deque_buf_size(__bufsiz, sizeof(_Tp)); }
104 #else /* __STL_NON_TYPE_TMPL_PARAM_BUG */
105 template <class _Tp, class _Ref, class _Ptr>
106 struct _Deque_iterator {
107 typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator;
108 typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
109 static size_t
110 _S_buffer_size() { return __deque_buf_size(0, sizeof(_Tp)); }
111 #endif
113 typedef random_access_iterator_tag iterator_category;
114 typedef _Tp value_type;
115 typedef _Ptr pointer;
116 typedef _Ref reference;
117 typedef size_t size_type;
118 typedef ptrdiff_t difference_type;
119 typedef _Tp** _Map_pointer;
121 typedef _Deque_iterator _Self;
123 _Tp* _M_cur;
124 _Tp* _M_first;
125 _Tp* _M_last;
126 _Map_pointer _M_node;
128 _Deque_iterator(_Tp* __x, _Map_pointer __y)
129 : _M_cur(__x), _M_first(*__y),
130 _M_last(*__y + _S_buffer_size()), _M_node(__y) {}
131 _Deque_iterator() : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) {}
132 _Deque_iterator(const iterator& __x)
133 : _M_cur(__x._M_cur), _M_first(__x._M_first),
134 _M_last(__x._M_last), _M_node(__x._M_node) {}
136 reference operator*() const { return *_M_cur; }
137 #ifndef __SGI_STL_NO_ARROW_OPERATOR
138 pointer operator->() const { return _M_cur; }
139 #endif /* __SGI_STL_NO_ARROW_OPERATOR */
141 difference_type operator-(const _Self& __x) const {
142 return difference_type(_S_buffer_size()) * (_M_node - __x._M_node - 1) +
143 (_M_cur - _M_first) + (__x._M_last - __x._M_cur);
146 _Self& operator++() {
147 ++_M_cur;
148 if (_M_cur == _M_last) {
149 _M_set_node(_M_node + 1);
150 _M_cur = _M_first;
152 return *this;
154 _Self operator++(int) {
155 _Self __tmp = *this;
156 ++*this;
157 return __tmp;
160 _Self& operator--() {
161 if (_M_cur == _M_first) {
162 _M_set_node(_M_node - 1);
163 _M_cur = _M_last;
165 --_M_cur;
166 return *this;
168 _Self operator--(int) {
169 _Self __tmp = *this;
170 --*this;
171 return __tmp;
174 _Self& operator+=(difference_type __n)
176 difference_type __offset = __n + (_M_cur - _M_first);
177 if (__offset >= 0 && __offset < difference_type(_S_buffer_size()))
178 _M_cur += __n;
179 else {
180 difference_type __node_offset =
181 __offset > 0 ? __offset / difference_type(_S_buffer_size())
182 : -difference_type((-__offset - 1) / _S_buffer_size()) - 1;
183 _M_set_node(_M_node + __node_offset);
184 _M_cur = _M_first +
185 (__offset - __node_offset * difference_type(_S_buffer_size()));
187 return *this;
190 _Self operator+(difference_type __n) const
192 _Self __tmp = *this;
193 return __tmp += __n;
196 _Self& operator-=(difference_type __n) { return *this += -__n; }
198 _Self operator-(difference_type __n) const {
199 _Self __tmp = *this;
200 return __tmp -= __n;
203 reference operator[](difference_type __n) const { return *(*this + __n); }
205 bool operator==(const _Self& __x) const { return _M_cur == __x._M_cur; }
206 bool operator!=(const _Self& __x) const { return !(*this == __x); }
207 bool operator<(const _Self& __x) const {
208 return (_M_node == __x._M_node) ?
209 (_M_cur < __x._M_cur) : (_M_node < __x._M_node);
212 void _M_set_node(_Map_pointer __new_node) {
213 _M_node = __new_node;
214 _M_first = *__new_node;
215 _M_last = _M_first + difference_type(_S_buffer_size());
219 #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION
221 #ifndef __STL_NON_TYPE_TMPL_PARAM_BUG
223 template <class _Tp, class _Ref, class _Ptr, size_t __bufsiz>
224 inline random_access_iterator_tag
225 iterator_category(const _Deque_iterator<_Tp,_Ref,_Ptr,__bufsiz>&) {
226 return random_access_iterator_tag();
229 template <class _Tp, class _Ref, class _Ptr, size_t __bufsiz>
230 inline _Tp*
231 value_type(const _Deque_iterator<_Tp,_Ref,_Ptr,__bufsiz>&) {
232 return 0;
235 template <class _Tp, class _Ref, class _Ptr, size_t __bufsiz>
236 inline ptrdiff_t*
237 distance_type(const _Deque_iterator<_Tp,_Ref,_Ptr,__bufsiz>&) {
238 return 0;
241 #else /* __STL_NON_TYPE_TMPL_PARAM_BUG */
243 template <class _Tp, class _Ref, class _Ptr>
244 inline random_access_iterator_tag
245 iterator_category(const _Deque_iterator<_Tp,_Ref,_Ptr>&)
247 return random_access_iterator_tag();
250 template <class _Tp, class _Ref, class _Ptr>
251 inline _Tp*
252 value_type(const _Deque_iterator<_Tp,_Ref,_Ptr>&) { return 0; }
254 template <class _Tp, class _Ref, class _Ptr>
255 inline ptrdiff_t*
256 distance_type(const _Deque_iterator<_Tp,_Ref,_Ptr>&) {
257 return 0;
260 #endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */
262 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
264 // Deque base class. It has two purposes. First, its constructor
265 // and destructor allocate (but don't initialize) storage. This makes
266 // exception safety easier. Second, the base class encapsulates all of
267 // the differences between SGI-style allocators and standard-conforming
268 // allocators.
270 #ifdef __STL_USE_STD_ALLOCATORS
272 // Base class for ordinary allocators.
273 template <class _Tp, class _Alloc, size_t __bufsiz, bool __is_static>
274 class _Deque_alloc_base {
275 public:
276 typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type;
277 allocator_type get_allocator() const { return node_allocator; }
279 _Deque_alloc_base(const allocator_type& __a)
280 : node_allocator(__a), map_allocator(__a), _M_map(0), _M_map_size(0)
283 protected:
284 typedef typename _Alloc_traits<_Tp*, _Alloc>::allocator_type
285 map_allocator_type;
287 allocator_type node_allocator;
288 map_allocator_type map_allocator;
290 _Tp* _M_allocate_node() {
291 return node_allocator.allocate(__deque_buf_size(__bufsiz,sizeof(_Tp)));
293 void _M_deallocate_node(_Tp* __p) {
294 node_allocator.deallocate(__p, __deque_buf_size(__bufsiz,sizeof(_Tp)));
296 _Tp** _M_allocate_map(size_t __n)
297 { return map_allocator.allocate(__n); }
298 void _M_deallocate_map(_Tp** __p, size_t __n)
299 { map_allocator.deallocate(__p, __n); }
301 _Tp** _M_map;
302 size_t _M_map_size;
305 // Specialization for instanceless allocators.
306 template <class _Tp, class _Alloc, size_t __bufsiz>
307 class _Deque_alloc_base<_Tp, _Alloc, __bufsiz, true>
309 public:
310 typedef typename _Alloc_traits<_Tp,_Alloc>::allocator_type allocator_type;
311 allocator_type get_allocator() const { return allocator_type(); }
313 _Deque_alloc_base(const allocator_type&) : _M_map(0), _M_map_size(0) {}
315 protected:
316 typedef typename _Alloc_traits<_Tp, _Alloc>::_Alloc_type _Node_alloc_type;
317 typedef typename _Alloc_traits<_Tp*, _Alloc>::_Alloc_type _Map_alloc_type;
319 _Tp* _M_allocate_node()
320 { return _Node_alloc_type::allocate(__deque_buf_size(__bufsiz,
321 sizeof(_Tp))); }
322 void _M_deallocate_node(_Tp* __p)
323 { _Node_alloc_type::deallocate(__p, __deque_buf_size(__bufsiz,
324 sizeof(_Tp))); }
325 _Tp** _M_allocate_map(size_t __n)
326 { return _Map_alloc_type::allocate(__n); }
327 void _M_deallocate_map(_Tp** __p, size_t __n)
328 { _Map_alloc_type::deallocate(__p, __n); }
330 _Tp** _M_map;
331 size_t _M_map_size;
334 template <class _Tp, class _Alloc, size_t __bufsiz>
335 class _Deque_base
336 : public _Deque_alloc_base<_Tp,_Alloc,__bufsiz,
337 _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
339 public:
340 typedef _Deque_alloc_base<_Tp,_Alloc,__bufsiz,
341 _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
342 _Base;
343 typedef typename _Base::allocator_type allocator_type;
344 typedef _Deque_iterator<_Tp,_Tp&,_Tp*,__bufsiz> iterator;
345 typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*, __bufsiz> const_iterator;
347 _Deque_base(const allocator_type& __a, size_t __num_elements)
348 : _Base(__a), _M_start(), _M_finish()
349 { _M_initialize_map(__num_elements); }
350 _Deque_base(const allocator_type& __a)
351 : _Base(__a), _M_start(), _M_finish() {}
352 ~_Deque_base();
354 protected:
355 void _M_initialize_map(size_t);
356 void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish);
357 void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish);
358 enum { _S_initial_map_size = 8 };
360 protected:
361 iterator _M_start;
362 iterator _M_finish;
365 #else /* __STL_USE_STD_ALLOCATORS */
367 template <class _Tp, class _Alloc, size_t __bufsiz>
368 class _Deque_base {
369 public:
370 #ifndef __STL_NON_TYPE_TMPL_PARAM_BUG
371 typedef _Deque_iterator<_Tp,_Tp&,_Tp*,__bufsiz> iterator;
372 typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*, __bufsiz> const_iterator;
373 #else /* __STL_NON_TYPE_TMPL_PARAM_BUG */
374 typedef _Deque_iterator<_Tp,_Tp&,_Tp*> iterator;
375 typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
376 #endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */
378 typedef _Alloc allocator_type;
379 allocator_type get_allocator() const { return allocator_type(); }
381 _Deque_base(const allocator_type&, size_t __num_elements)
382 : _M_map(0), _M_map_size(0), _M_start(), _M_finish() {
383 _M_initialize_map(__num_elements);
385 _Deque_base(const allocator_type&)
386 : _M_map(0), _M_map_size(0), _M_start(), _M_finish() {}
387 ~_Deque_base();
389 protected:
390 void _M_initialize_map(size_t);
391 void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish);
392 void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish);
393 enum { _S_initial_map_size = 8 };
395 protected:
396 _Tp** _M_map;
397 size_t _M_map_size;
398 iterator _M_start;
399 iterator _M_finish;
401 typedef simple_alloc<_Tp, _Alloc> _Node_alloc_type;
402 typedef simple_alloc<_Tp*, _Alloc> _Map_alloc_type;
404 _Tp* _M_allocate_node()
405 { return _Node_alloc_type::allocate(__deque_buf_size(__bufsiz,
406 sizeof(_Tp))); }
407 void _M_deallocate_node(_Tp* __p)
408 { _Node_alloc_type::deallocate(__p, __deque_buf_size(__bufsiz,
409 sizeof(_Tp))); }
410 _Tp** _M_allocate_map(size_t __n)
411 { return _Map_alloc_type::allocate(__n); }
412 void _M_deallocate_map(_Tp** __p, size_t __n)
413 { _Map_alloc_type::deallocate(__p, __n); }
416 #endif /* __STL_USE_STD_ALLOCATORS */
418 // Non-inline member functions from _Deque_base.
420 template <class _Tp, class _Alloc, size_t __bufsiz>
421 _Deque_base<_Tp,_Alloc,__bufsiz>::~_Deque_base() {
422 if (_M_map) {
423 _M_destroy_nodes(_M_start._M_node, _M_finish._M_node + 1);
424 _M_deallocate_map(_M_map, _M_map_size);
428 template <class _Tp, class _Alloc, size_t __bufsiz>
429 void
430 _Deque_base<_Tp,_Alloc,__bufsiz>::_M_initialize_map(size_t __num_elements)
432 size_t __num_nodes =
433 __num_elements / __deque_buf_size(__bufsiz, sizeof(_Tp)) + 1;
435 _M_map_size = max((size_t) _S_initial_map_size, __num_nodes + 2);
436 _M_map = _M_allocate_map(_M_map_size);
438 _Tp** __nstart = _M_map + (_M_map_size - __num_nodes) / 2;
439 _Tp** __nfinish = __nstart + __num_nodes;
441 __STL_TRY {
442 _M_create_nodes(__nstart, __nfinish);
444 __STL_UNWIND((_M_deallocate_map(_M_map, _M_map_size),
445 _M_map = 0, _M_map_size = 0));
446 _M_start._M_set_node(__nstart);
447 _M_finish._M_set_node(__nfinish - 1);
448 _M_start._M_cur = _M_start._M_first;
449 _M_finish._M_cur = _M_finish._M_first +
450 __num_elements % __deque_buf_size(__bufsiz, sizeof(_Tp));
453 template <class _Tp, class _Alloc, size_t __bufsiz>
454 void
455 _Deque_base<_Tp,_Alloc,__bufsiz>::_M_create_nodes(_Tp** __nstart,
456 _Tp** __nfinish)
458 _Tp** __cur;
459 __STL_TRY {
460 for (__cur = __nstart; __cur < __nfinish; ++__cur)
461 *__cur = _M_allocate_node();
463 __STL_UNWIND(_M_destroy_nodes(__nstart, __cur));
466 template <class _Tp, class _Alloc, size_t __bufsiz>
467 void
468 _Deque_base<_Tp,_Alloc,__bufsiz>::_M_destroy_nodes(_Tp** __nstart,
469 _Tp** __nfinish)
471 for (_Tp** __n = __nstart; __n < __nfinish; ++__n)
472 _M_deallocate_node(*__n);
475 // See __deque_buf_size(). The only reason that the default value is 0
476 // is as a workaround for bugs in the way that some compilers handle
477 // constant expressions.
478 template <class _Tp, class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp),
479 size_t __bufsiz = 0>
480 class deque : protected _Deque_base<_Tp, _Alloc, __bufsiz> {
481 typedef _Deque_base<_Tp, _Alloc, __bufsiz> _Base;
482 public: // Basic types
483 typedef _Tp value_type;
484 typedef value_type* pointer;
485 typedef const value_type* const_pointer;
486 typedef value_type& reference;
487 typedef const value_type& const_reference;
488 typedef size_t size_type;
489 typedef ptrdiff_t difference_type;
491 typedef typename _Base::allocator_type allocator_type;
492 allocator_type get_allocator() const { return _Base::get_allocator(); }
494 public: // Iterators
495 typedef typename _Base::iterator iterator;
496 typedef typename _Base::const_iterator const_iterator;
498 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
499 typedef reverse_iterator<const_iterator> const_reverse_iterator;
500 typedef reverse_iterator<iterator> reverse_iterator;
501 #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
502 typedef reverse_iterator<const_iterator, value_type, const_reference,
503 difference_type>
504 const_reverse_iterator;
505 typedef reverse_iterator<iterator, value_type, reference, difference_type>
506 reverse_iterator;
507 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
509 protected: // Internal typedefs
510 typedef pointer* _Map_pointer;
511 static size_t _S_buffer_size()
512 { return __deque_buf_size(__bufsiz, sizeof(_Tp)); }
514 protected:
515 #ifdef __STL_USE_NAMESPACES
516 using _Base::_M_initialize_map;
517 using _Base::_M_create_nodes;
518 using _Base::_M_destroy_nodes;
519 using _Base::_M_allocate_node;
520 using _Base::_M_deallocate_node;
521 using _Base::_M_allocate_map;
522 using _Base::_M_deallocate_map;
524 using _Base::_M_map;
525 using _Base::_M_map_size;
526 using _Base::_M_start;
527 using _Base::_M_finish;
528 #endif /* __STL_USE_NAMESPACES */
530 public: // Basic accessors
531 iterator begin() { return _M_start; }
532 iterator end() { return _M_finish; }
533 const_iterator begin() const { return _M_start; }
534 const_iterator end() const { return _M_finish; }
536 reverse_iterator rbegin() { return reverse_iterator(_M_finish); }
537 reverse_iterator rend() { return reverse_iterator(_M_start); }
538 const_reverse_iterator rbegin() const
539 { return const_reverse_iterator(_M_finish); }
540 const_reverse_iterator rend() const
541 { return const_reverse_iterator(_M_start); }
543 reference operator[](size_type __n)
544 { return _M_start[difference_type(__n)]; }
545 const_reference operator[](size_type __n) const
546 { return _M_start[difference_type(__n)]; }
548 reference front() { return *_M_start; }
549 reference back() {
550 iterator __tmp = _M_finish;
551 --__tmp;
552 return *__tmp;
554 const_reference front() const { return *_M_start; }
555 const_reference back() const {
556 const_iterator __tmp = _M_finish;
557 --__tmp;
558 return *__tmp;
561 size_type size() const { return _M_finish - _M_start;; }
562 size_type max_size() const { return size_type(-1); }
563 bool empty() const { return _M_finish == _M_start; }
565 public: // Constructor, destructor.
566 explicit deque(const allocator_type& __a = allocator_type())
567 : _Base(__a, 0) {}
568 deque(const deque& __x) : _Base(__x.get_allocator(), __x.size())
569 { uninitialized_copy(__x.begin(), __x.end(), _M_start); }
570 deque(size_type __n, const value_type& __value,
571 const allocator_type& __a = allocator_type()) : _Base(__a, __n)
572 { _M_fill_initialize(__value); }
573 explicit deque(size_type __n) : _Base(allocator_type(), __n)
574 { _M_fill_initialize(value_type()); }
576 #ifdef __STL_MEMBER_TEMPLATES
578 // Check whether it's an integral type. If so, it's not an iterator.
579 template <class _InputIterator>
580 deque(_InputIterator __first, _InputIterator __last,
581 const allocator_type& __a = allocator_type()) : _Base(__a) {
582 typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
583 _M_initialize_dispatch(__first, __last, _Integral());
586 template <class _Integer>
587 void _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) {
588 _M_initialize_map(__n);
589 _M_fill_initialize(__x);
592 template <class _InputIter>
593 void _M_initialize_dispatch(_InputIter __first, _InputIter __last,
594 __false_type) {
595 _M_range_initialize(__first, __last, __ITERATOR_CATEGORY(__first));
598 #else /* __STL_MEMBER_TEMPLATES */
600 deque(const value_type* __first, const value_type* __last,
601 const allocator_type& __a = allocator_type())
602 : _Base(__a, __last - __first)
603 { uninitialized_copy(__first, __last, _M_start); }
604 deque(const_iterator __first, const_iterator __last,
605 const allocator_type& __a = allocator_type())
606 : _Base(__a, __last - __first)
607 { uninitialized_copy(__first, __last, _M_start); }
609 #endif /* __STL_MEMBER_TEMPLATES */
611 ~deque() { destroy(_M_start, _M_finish); }
613 deque& operator= (const deque& __x) {
614 const size_type __len = size();
615 if (&__x != this) {
616 if (__len >= __x.size())
617 erase(copy(__x.begin(), __x.end(), _M_start), _M_finish);
618 else {
619 const_iterator __mid = __x.begin() + difference_type(__len);
620 copy(__x.begin(), __mid, _M_start);
621 insert(_M_finish, __mid, __x.end());
624 return *this;
627 void swap(deque& __x) {
628 __STD::swap(_M_start, __x._M_start);
629 __STD::swap(_M_finish, __x._M_finish);
630 __STD::swap(_M_map, __x._M_map);
631 __STD::swap(_M_map_size, __x._M_map_size);
634 public:
635 // assign(), a generalized assignment member function. Two
636 // versions: one that takes a count, and one that takes a range.
637 // The range version is a member template, so we dispatch on whether
638 // or not the type is an integer.
640 void assign(size_type __n, const _Tp& __val) {
641 if (__n > size()) {
642 fill(begin(), end(), __val);
643 insert(end(), __n - size(), __val);
645 else {
646 erase(begin() + __n, end());
647 fill(begin(), end(), __val);
651 #ifdef __STL_MEMBER_TEMPLATES
653 template <class _InputIterator>
654 void assign(_InputIterator __first, _InputIterator __last) {
655 typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
656 _M_assign_dispatch(__first, __last, _Integral());
659 private: // helper functions for assign()
661 template <class _Integer>
662 void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
663 { assign((size_type) __n, (_Tp) __val); }
665 template <class _InputIterator>
666 void _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
667 __false_type) {
668 _M_assign_aux(__first, __last, __ITERATOR_CATEGORY(__first));
671 template <class _InputIterator>
672 void _M_assign_aux(_InputIterator __first, _InputIterator __last,
673 input_iterator_tag);
675 template <class _ForwardIterator>
676 void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
677 forward_iterator_tag) {
678 size_type __len = 0;
679 distance(__first, __last, __len);
680 if (__len > size()) {
681 _ForwardIterator __mid = __first;
682 advance(__mid, size());
683 copy(__first, __mid, begin());
684 insert(end(), __mid, __last);
686 else
687 erase(copy(__first, __last, begin()), end());
690 #endif /* __STL_MEMBER_TEMPLATES */
692 public: // push_* and pop_*
694 void push_back(const value_type& __t) {
695 if (_M_finish._M_cur != _M_finish._M_last - 1) {
696 construct(_M_finish._M_cur, __t);
697 ++_M_finish._M_cur;
699 else
700 _M_push_back_aux(__t);
703 void push_back() {
704 if (_M_finish._M_cur != _M_finish._M_last - 1) {
705 construct(_M_finish._M_cur);
706 ++_M_finish._M_cur;
708 else
709 _M_push_back_aux();
712 void push_front(const value_type& __t) {
713 if (_M_start._M_cur != _M_start._M_first) {
714 construct(_M_start._M_cur - 1, __t);
715 --_M_start._M_cur;
717 else
718 _M_push_front_aux(__t);
721 void push_front() {
722 if (_M_start._M_cur != _M_start._M_first) {
723 construct(_M_start._M_cur - 1);
724 --_M_start._M_cur;
726 else
727 _M_push_front_aux();
731 void pop_back() {
732 if (_M_finish._M_cur != _M_finish._M_first) {
733 --_M_finish._M_cur;
734 destroy(_M_finish._M_cur);
736 else
737 _M_pop_back_aux();
740 void pop_front() {
741 if (_M_start._M_cur != _M_start._M_last - 1) {
742 destroy(_M_start._M_cur);
743 ++_M_start._M_cur;
745 else
746 _M_pop_front_aux();
749 public: // Insert
751 iterator insert(iterator position, const value_type& __x) {
752 if (position._M_cur == _M_start._M_cur) {
753 push_front(__x);
754 return _M_start;
756 else if (position._M_cur == _M_finish._M_cur) {
757 push_back(__x);
758 iterator __tmp = _M_finish;
759 --__tmp;
760 return __tmp;
762 else {
763 return _M_insert_aux(position, __x);
767 iterator insert(iterator __position)
768 { return insert(__position, value_type()); }
770 void insert(iterator __pos, size_type __n, const value_type& __x);
772 #ifdef __STL_MEMBER_TEMPLATES
774 // Check whether it's an integral type. If so, it's not an iterator.
775 template <class _InputIterator>
776 void insert(iterator __pos, _InputIterator __first, _InputIterator __last) {
777 typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
778 _M_insert_dispatch(__pos, __first, __last, _Integral());
781 template <class _Integer>
782 void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x,
783 __true_type) {
784 insert(__pos, (size_type) __n, (value_type) __x);
787 template <class _InputIterator>
788 void _M_insert_dispatch(iterator __pos,
789 _InputIterator __first, _InputIterator __last,
790 __false_type) {
791 insert(__pos, __first, __last, __ITERATOR_CATEGORY(__first));
794 #else /* __STL_MEMBER_TEMPLATES */
796 void insert(iterator __pos,
797 const value_type* __first, const value_type* __last);
798 void insert(iterator __pos,
799 const_iterator __first, const_iterator __last);
801 #endif /* __STL_MEMBER_TEMPLATES */
803 void resize(size_type __new_size, const value_type& __x) {
804 const size_type __len = size();
805 if (__new_size < __len)
806 erase(_M_start + __new_size, _M_finish);
807 else
808 insert(_M_finish, __new_size - __len, __x);
811 void resize(size_type new_size) { resize(new_size, value_type()); }
813 public: // Erase
814 iterator erase(iterator __pos) {
815 iterator __next = __pos;
816 ++__next;
817 difference_type __index = __pos - _M_start;
818 if (static_cast<size_type>(__index) < (size() >> 1)) {
819 copy_backward(_M_start, __pos, __next);
820 pop_front();
822 else {
823 copy(__next, _M_finish, __pos);
824 pop_back();
826 return _M_start + __index;
829 iterator erase(iterator __first, iterator __last);
830 void clear();
832 protected: // Internal construction/destruction
834 void _M_fill_initialize(const value_type& __value);
836 #ifdef __STL_MEMBER_TEMPLATES
838 template <class _InputIterator>
839 void _M_range_initialize(_InputIterator __first, _InputIterator __last,
840 input_iterator_tag);
842 template <class _ForwardIterator>
843 void _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
844 forward_iterator_tag);
846 #endif /* __STL_MEMBER_TEMPLATES */
848 protected: // Internal push_* and pop_*
850 void _M_push_back_aux(const value_type&);
851 void _M_push_back_aux();
852 void _M_push_front_aux(const value_type&);
853 void _M_push_front_aux();
854 void _M_pop_back_aux();
855 void _M_pop_front_aux();
857 protected: // Internal insert functions
859 #ifdef __STL_MEMBER_TEMPLATES
861 template <class _InputIterator>
862 void insert(iterator __pos, _InputIterator __first, _InputIterator __last,
863 input_iterator_tag);
865 template <class _ForwardIterator>
866 void insert(iterator __pos,
867 _ForwardIterator __first, _ForwardIterator __last,
868 forward_iterator_tag);
870 #endif /* __STL_MEMBER_TEMPLATES */
872 iterator _M_insert_aux(iterator __pos, const value_type& __x);
873 iterator _M_insert_aux(iterator __pos);
874 void _M_insert_aux(iterator __pos, size_type __n, const value_type& __x);
876 #ifdef __STL_MEMBER_TEMPLATES
878 template <class _ForwardIterator>
879 void _M_insert_aux(iterator __pos,
880 _ForwardIterator __first, _ForwardIterator __last,
881 size_type __n);
883 #else /* __STL_MEMBER_TEMPLATES */
885 void _M_insert_aux(iterator __pos,
886 const value_type* __first, const value_type* __last,
887 size_type __n);
889 void _M_insert_aux(iterator __pos,
890 const_iterator __first, const_iterator __last,
891 size_type __n);
893 #endif /* __STL_MEMBER_TEMPLATES */
895 iterator _M_reserve_elements_at_front(size_type __n) {
896 size_type __vacancies = _M_start._M_cur - _M_start._M_first;
897 if (__n > __vacancies)
898 _M_new_elements_at_front(__n - __vacancies);
899 return _M_start - difference_type(__n);
902 iterator _M_reserve_elements_at_back(size_type __n) {
903 size_type __vacancies = (_M_finish._M_last - _M_finish._M_cur) - 1;
904 if (__n > __vacancies)
905 _M_new_elements_at_back(__n - __vacancies);
906 return _M_finish + difference_type(__n);
909 void _M_new_elements_at_front(size_type __new_elements);
910 void _M_new_elements_at_back(size_type __new_elements);
912 protected: // Allocation of _M_map and nodes
914 // Makes sure the _M_map has space for new nodes. Does not actually
915 // add the nodes. Can invalidate _M_map pointers. (And consequently,
916 // deque iterators.)
918 void _M_reserve_map_at_back (size_type __nodes_to_add = 1) {
919 if (__nodes_to_add + 1 > _M_map_size - (_M_finish._M_node - _M_map))
920 _M_reallocate_map(__nodes_to_add, false);
923 void _M_reserve_map_at_front (size_type __nodes_to_add = 1) {
924 if (__nodes_to_add > size_type(_M_start._M_node - _M_map))
925 _M_reallocate_map(__nodes_to_add, true);
928 void _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front);
930 #ifdef __STL_NON_TYPE_TMPL_PARAM_BUG
931 public:
932 bool operator==(const deque<_Tp,_Alloc,0>& __x) const {
933 return size() == __x.size() && equal(begin(), end(), __x.begin());
935 bool operator!=(const deque<_Tp,_Alloc,0>& __x) const {
936 return size() != __x.size() || !equal(begin(), end(), __x.begin());
938 bool operator<(const deque<_Tp,_Alloc,0>& __x) const {
939 return lexicographical_compare(begin(), end(), __x.begin(), __x.end());
941 #endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */
944 // Non-inline member functions
946 #ifdef __STL_MEMBER_TEMPLATES
948 template <class _Tp, class _Alloc, size_t __bufsize>
949 template <class _InputIter>
950 void deque<_Tp, _Alloc, __bufsize>
951 ::_M_assign_aux(_InputIter __first, _InputIter __last, input_iterator_tag)
953 iterator __cur = begin();
954 for ( ; __first != __last && __cur != end(); ++__cur, ++__first)
955 *__cur = *__first;
956 if (__first == __last)
957 erase(__cur, end());
958 else
959 insert(end(), __first, __last);
962 #endif /* __STL_MEMBER_TEMPLATES */
964 template <class _Tp, class _Alloc, size_t __bufsize>
965 void
966 deque<_Tp, _Alloc, __bufsize>::insert(iterator __pos,
967 size_type __n, const value_type& __x)
969 if (__pos._M_cur == _M_start._M_cur) {
970 iterator __new_start = _M_reserve_elements_at_front(__n);
971 uninitialized_fill(__new_start, _M_start, __x);
972 _M_start = __new_start;
974 else if (__pos._M_cur == _M_finish._M_cur) {
975 iterator __new_finish = _M_reserve_elements_at_back(__n);
976 uninitialized_fill(_M_finish, __new_finish, __x);
977 _M_finish = __new_finish;
979 else
980 _M_insert_aux(__pos, __n, __x);
983 #ifndef __STL_MEMBER_TEMPLATES
985 template <class _Tp, class _Alloc, size_t __bufsize>
986 void deque<_Tp, _Alloc, __bufsize>::insert(iterator __pos,
987 const value_type* __first,
988 const value_type* __last) {
989 size_type __n = __last - __first;
990 if (__pos._M_cur == _M_start._M_cur) {
991 iterator __new_start = _M_reserve_elements_at_front(__n);
992 __STL_TRY {
993 uninitialized_copy(__first, __last, __new_start);
994 _M_start = __new_start;
996 __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
998 else if (__pos._M_cur == _M_finish._M_cur) {
999 iterator __new_finish = _M_reserve_elements_at_back(__n);
1000 __STL_TRY {
1001 uninitialized_copy(__first, __last, _M_finish);
1002 _M_finish = __new_finish;
1004 __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1,
1005 __new_finish._M_node + 1));
1007 else
1008 _M_insert_aux(__pos, __first, __last, __n);
1011 template <class _Tp, class _Alloc, size_t __bufsize>
1012 void deque<_Tp,_Alloc,__bufsize>::insert(iterator __pos,
1013 const_iterator __first,
1014 const_iterator __last)
1016 size_type __n = __last - __first;
1017 if (__pos._M_cur == _M_start._M_cur) {
1018 iterator __new_start = _M_reserve_elements_at_front(__n);
1019 __STL_TRY {
1020 uninitialized_copy(__first, __last, __new_start);
1021 _M_start = __new_start;
1023 __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
1025 else if (__pos._M_cur == _M_finish._M_cur) {
1026 iterator __new_finish = _M_reserve_elements_at_back(__n);
1027 __STL_TRY {
1028 uninitialized_copy(__first, __last, _M_finish);
1029 _M_finish = __new_finish;
1031 __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1,
1032 __new_finish._M_node + 1));
1034 else
1035 _M_insert_aux(__pos, __first, __last, __n);
1038 #endif /* __STL_MEMBER_TEMPLATES */
1040 template <class _Tp, class _Alloc, size_t __bufsize>
1041 deque<_Tp,_Alloc,__bufsize>::iterator
1042 deque<_Tp,_Alloc,__bufsize>::erase(iterator __first, iterator __last)
1044 if (__first == _M_start && __last == _M_finish) {
1045 clear();
1046 return _M_finish;
1048 else {
1049 difference_type __n = __last - __first;
1050 difference_type __elems_before = __first - _M_start;
1051 if (static_cast<size_type>(__elems_before) < (size() - __n) / 2) {
1052 copy_backward(_M_start, __first, __last);
1053 iterator __new_start = _M_start + __n;
1054 destroy(_M_start, __new_start);
1055 _M_destroy_nodes(__new_start._M_node, _M_start._M_node);
1056 _M_start = __new_start;
1058 else {
1059 copy(__last, _M_finish, __first);
1060 iterator __new_finish = _M_finish - __n;
1061 destroy(__new_finish, _M_finish);
1062 _M_destroy_nodes(__new_finish._M_node + 1, _M_finish._M_node + 1);
1063 _M_finish = __new_finish;
1065 return _M_start + __elems_before;
1069 template <class _Tp, class _Alloc, size_t __bufsize>
1070 void deque<_Tp,_Alloc,__bufsize>::clear()
1072 for (_Map_pointer __node = _M_start._M_node + 1;
1073 __node < _M_finish._M_node;
1074 ++__node) {
1075 destroy(*__node, *__node + _S_buffer_size());
1076 _M_deallocate_node(*__node);
1079 if (_M_start._M_node != _M_finish._M_node) {
1080 destroy(_M_start._M_cur, _M_start._M_last);
1081 destroy(_M_finish._M_first, _M_finish._M_cur);
1082 _M_deallocate_node(_M_finish._M_first);
1084 else
1085 destroy(_M_start._M_cur, _M_finish._M_cur);
1087 _M_finish = _M_start;
1090 // Precondition: _M_start and _M_finish have already been initialized,
1091 // but none of the deque's elements have yet been constructed.
1092 template <class _Tp, class _Alloc, size_t __bufsize>
1093 void
1094 deque<_Tp,_Alloc,__bufsize>::_M_fill_initialize(const value_type& __value) {
1095 _Map_pointer __cur;
1096 __STL_TRY {
1097 for (__cur = _M_start._M_node; __cur < _M_finish._M_node; ++__cur)
1098 uninitialized_fill(*__cur, *__cur + _S_buffer_size(), __value);
1099 uninitialized_fill(_M_finish._M_first, _M_finish._M_cur, __value);
1101 __STL_UNWIND(destroy(_M_start, iterator(*__cur, __cur)));
1104 #ifdef __STL_MEMBER_TEMPLATES
1106 template <class _Tp, class _Alloc, size_t __bufsize>
1107 template <class _InputIterator>
1108 void
1109 deque<_Tp,_Alloc,__bufsize>::_M_range_initialize(_InputIterator __first,
1110 _InputIterator __last,
1111 input_iterator_tag)
1113 _M_initialize_map(0);
1114 for ( ; __first != __last; ++__first)
1115 push_back(*__first);
1118 template <class _Tp, class _Alloc, size_t __bufsize>
1119 template <class _ForwardIterator>
1120 void
1121 deque<_Tp,_Alloc,__bufsize>::_M_range_initialize(_ForwardIterator __first,
1122 _ForwardIterator __last,
1123 forward_iterator_tag)
1125 size_type __n = 0;
1126 distance(__first, __last, __n);
1127 _M_initialize_map(__n);
1129 _Map_pointer __cur_node;
1130 __STL_TRY {
1131 for (__cur_node = _M_start._M_node;
1132 __cur_node < _M_finish._M_node;
1133 ++__cur_node) {
1134 _ForwardIterator __mid = __first;
1135 advance(__mid, _S_buffer_size());
1136 uninitialized_copy(__first, __mid, *__cur_node);
1137 __first = __mid;
1139 uninitialized_copy(__first, __last, _M_finish._M_first);
1141 __STL_UNWIND(destroy(_M_start, iterator(*__cur_node, __cur_node)));
1144 #endif /* __STL_MEMBER_TEMPLATES */
1146 // Called only if _M_finish._M_cur == _M_finish._M_last - 1.
1147 template <class _Tp, class _Alloc, size_t __bufsize>
1148 void
1149 deque<_Tp,_Alloc,__bufsize>::_M_push_back_aux(const value_type& __t)
1151 value_type __t_copy = __t;
1152 _M_reserve_map_at_back();
1153 *(_M_finish._M_node + 1) = _M_allocate_node();
1154 __STL_TRY {
1155 construct(_M_finish._M_cur, __t_copy);
1156 _M_finish._M_set_node(_M_finish._M_node + 1);
1157 _M_finish._M_cur = _M_finish._M_first;
1159 __STL_UNWIND(_M_deallocate_node(*(_M_finish._M_node + 1)));
1162 // Called only if _M_finish._M_cur == _M_finish._M_last - 1.
1163 template <class _Tp, class _Alloc, size_t __bufsize>
1164 void
1165 deque<_Tp,_Alloc,__bufsize>::_M_push_back_aux()
1167 _M_reserve_map_at_back();
1168 *(_M_finish._M_node + 1) = _M_allocate_node();
1169 __STL_TRY {
1170 construct(_M_finish._M_cur);
1171 _M_finish._M_set_node(_M_finish._M_node + 1);
1172 _M_finish._M_cur = _M_finish._M_first;
1174 __STL_UNWIND(_M_deallocate_node(*(_M_finish._M_node + 1)));
1177 // Called only if _M_start._M_cur == _M_start._M_first.
1178 template <class _Tp, class _Alloc, size_t __bufsize>
1179 void
1180 deque<_Tp,_Alloc,__bufsize>::_M_push_front_aux(const value_type& __t)
1182 value_type __t_copy = __t;
1183 _M_reserve_map_at_front();
1184 *(_M_start._M_node - 1) = _M_allocate_node();
1185 __STL_TRY {
1186 _M_start._M_set_node(_M_start._M_node - 1);
1187 _M_start._M_cur = _M_start._M_last - 1;
1188 construct(_M_start._M_cur, __t_copy);
1190 __STL_UNWIND((++_M_start, _M_deallocate_node(*(_M_start._M_node - 1))));
1193 // Called only if _M_start._M_cur == _M_start._M_first.
1194 template <class _Tp, class _Alloc, size_t __bufsize>
1195 void
1196 deque<_Tp,_Alloc,__bufsize>::_M_push_front_aux()
1198 _M_reserve_map_at_front();
1199 *(_M_start._M_node - 1) = _M_allocate_node();
1200 __STL_TRY {
1201 _M_start._M_set_node(_M_start._M_node - 1);
1202 _M_start._M_cur = _M_start._M_last - 1;
1203 construct(_M_start._M_cur);
1205 __STL_UNWIND((++_M_start, _M_deallocate_node(*(_M_start._M_node - 1))));
1208 // Called only if _M_finish._M_cur == _M_finish._M_first.
1209 template <class _Tp, class _Alloc, size_t __bufsize>
1210 void
1211 deque<_Tp,_Alloc,__bufsize>::_M_pop_back_aux()
1213 _M_deallocate_node(_M_finish._M_first);
1214 _M_finish._M_set_node(_M_finish._M_node - 1);
1215 _M_finish._M_cur = _M_finish._M_last - 1;
1216 destroy(_M_finish._M_cur);
1219 // Called only if _M_start._M_cur == _M_start._M_last - 1. Note that
1220 // if the deque has at least one element (a precondition for this member
1221 // function), and if _M_start._M_cur == _M_start._M_last, then the deque
1222 // must have at least two nodes.
1223 template <class _Tp, class _Alloc, size_t __bufsize>
1224 void
1225 deque<_Tp,_Alloc,__bufsize>::_M_pop_front_aux()
1227 destroy(_M_start._M_cur);
1228 _M_deallocate_node(_M_start._M_first);
1229 _M_start._M_set_node(_M_start._M_node + 1);
1230 _M_start._M_cur = _M_start._M_first;
1233 #ifdef __STL_MEMBER_TEMPLATES
1235 template <class _Tp, class _Alloc, size_t __bufsize>
1236 template <class _InputIterator>
1237 void
1238 deque<_Tp,_Alloc,__bufsize>::insert(iterator __pos,
1239 _InputIterator __first,
1240 _InputIterator __last,
1241 input_iterator_tag)
1243 copy(__first, __last, inserter(*this, __pos));
1246 template <class _Tp, class _Alloc, size_t __bufsize>
1247 template <class _ForwardIterator>
1248 void
1249 deque<_Tp,_Alloc,__bufsize>::insert(iterator __pos,
1250 _ForwardIterator __first,
1251 _ForwardIterator __last,
1252 forward_iterator_tag) {
1253 size_type __n = 0;
1254 distance(__first, __last, __n);
1255 if (__pos._M_cur == _M_start._M_cur) {
1256 iterator __new_start = _M_reserve_elements_at_front(__n);
1257 __STL_TRY {
1258 uninitialized_copy(__first, __last, __new_start);
1259 _M_start = __new_start;
1261 __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
1263 else if (__pos._M_cur == _M_finish._M_cur) {
1264 iterator __new_finish = _M_reserve_elements_at_back(__n);
1265 __STL_TRY {
1266 uninitialized_copy(__first, __last, _M_finish);
1267 _M_finish = __new_finish;
1269 __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1,
1270 __new_finish._M_node + 1));
1272 else
1273 _M_insert_aux(__pos, __first, __last, __n);
1276 #endif /* __STL_MEMBER_TEMPLATES */
1278 template <class _Tp, class _Alloc, size_t __bufsize>
1279 typename deque<_Tp, _Alloc, __bufsize>::iterator
1280 deque<_Tp,_Alloc,__bufsize>::_M_insert_aux(iterator __pos,
1281 const value_type& __x)
1283 difference_type __index = __pos - _M_start;
1284 value_type __x_copy = __x;
1285 if (static_cast<size_type>(__index) < size() / 2) {
1286 push_front(front());
1287 iterator __front1 = _M_start;
1288 ++__front1;
1289 iterator __front2 = __front1;
1290 ++__front2;
1291 __pos = _M_start + __index;
1292 iterator __pos1 = __pos;
1293 ++__pos1;
1294 copy(__front2, __pos1, __front1);
1296 else {
1297 push_back(back());
1298 iterator __back1 = _M_finish;
1299 --__back1;
1300 iterator __back2 = __back1;
1301 --__back2;
1302 __pos = _M_start + __index;
1303 copy_backward(__pos, __back2, __back1);
1305 *__pos = __x_copy;
1306 return __pos;
1309 template <class _Tp, class _Alloc, size_t __bufsize>
1310 typename deque<_Tp,_Alloc,__bufsize>::iterator
1311 deque<_Tp,_Alloc,__bufsize>::_M_insert_aux(iterator __pos)
1313 difference_type __index = __pos - _M_start;
1314 if (static_cast<size_type>(__index) < size() / 2) {
1315 push_front(front());
1316 iterator __front1 = _M_start;
1317 ++__front1;
1318 iterator __front2 = __front1;
1319 ++__front2;
1320 __pos = _M_start + __index;
1321 iterator __pos1 = __pos;
1322 ++__pos1;
1323 copy(__front2, __pos1, __front1);
1325 else {
1326 push_back(back());
1327 iterator __back1 = _M_finish;
1328 --__back1;
1329 iterator __back2 = __back1;
1330 --__back2;
1331 __pos = _M_start + __index;
1332 copy_backward(__pos, __back2, __back1);
1334 *__pos = value_type();
1335 return __pos;
1338 template <class _Tp, class _Alloc, size_t __bufsize>
1339 void
1340 deque<_Tp,_Alloc,__bufsize>::_M_insert_aux(iterator __pos,
1341 size_type __n,
1342 const value_type& __x)
1344 const difference_type __elems_before = __pos - _M_start;
1345 size_type __length = size();
1346 value_type __x_copy = __x;
1347 if (static_cast<size_type>(__elems_before) < __length / 2) {
1348 iterator __new_start = _M_reserve_elements_at_front(__n);
1349 iterator __old_start = _M_start;
1350 __pos = _M_start + __elems_before;
1351 __STL_TRY {
1352 if (__elems_before >= difference_type(__n)) {
1353 iterator __start_n = _M_start + difference_type(__n);
1354 uninitialized_copy(_M_start, __start_n, __new_start);
1355 _M_start = __new_start;
1356 copy(__start_n, __pos, __old_start);
1357 fill(__pos - difference_type(__n), __pos, __x_copy);
1359 else {
1360 __uninitialized_copy_fill(_M_start, __pos, __new_start,
1361 _M_start, __x_copy);
1362 _M_start = __new_start;
1363 fill(__old_start, __pos, __x_copy);
1366 __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
1368 else {
1369 iterator __new_finish = _M_reserve_elements_at_back(__n);
1370 iterator __old_finish = _M_finish;
1371 const difference_type __elems_after =
1372 difference_type(__length) - __elems_before;
1373 __pos = _M_finish - __elems_after;
1374 __STL_TRY {
1375 if (__elems_after > difference_type(__n)) {
1376 iterator __finish_n = _M_finish - difference_type(__n);
1377 uninitialized_copy(__finish_n, _M_finish, _M_finish);
1378 _M_finish = __new_finish;
1379 copy_backward(__pos, __finish_n, __old_finish);
1380 fill(__pos, __pos + difference_type(__n), __x_copy);
1382 else {
1383 __uninitialized_fill_copy(_M_finish, __pos + difference_type(__n),
1384 __x_copy, __pos, _M_finish);
1385 _M_finish = __new_finish;
1386 fill(__pos, __old_finish, __x_copy);
1389 __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1,
1390 __new_finish._M_node + 1));
1394 #ifdef __STL_MEMBER_TEMPLATES
1396 template <class _Tp, class _Alloc, size_t __bufsize>
1397 template <class _ForwardIterator>
1398 void
1399 deque<_Tp,_Alloc,__bufsize>::_M_insert_aux(iterator __pos,
1400 _ForwardIterator __first,
1401 _ForwardIterator __last,
1402 size_type __n)
1404 const difference_type __elemsbefore = __pos - _M_start;
1405 size_type __length = size();
1406 if (static_cast<size_type>(__elemsbefore) < __length / 2) {
1407 iterator __new_start = _M_reserve_elements_at_front(__n);
1408 iterator __old_start = _M_start;
1409 __pos = _M_start + __elemsbefore;
1410 __STL_TRY {
1411 if (__elemsbefore >= difference_type(__n)) {
1412 iterator __start_n = _M_start + difference_type(__n);
1413 uninitialized_copy(_M_start, __start_n, __new_start);
1414 _M_start = __new_start;
1415 copy(__start_n, __pos, __old_start);
1416 copy(__first, __last, __pos - difference_type(__n));
1418 else {
1419 _ForwardIterator __mid = __first;
1420 advance(__mid, difference_type(__n) - __elemsbefore);
1421 __uninitialized_copy_copy(_M_start, __pos, __first, __mid,
1422 __new_start);
1423 _M_start = __new_start;
1424 copy(__mid, __last, __old_start);
1427 __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
1429 else {
1430 iterator __new_finish = _M_reserve_elements_at_back(__n);
1431 iterator __old_finish = _M_finish;
1432 const difference_type __elemsafter =
1433 difference_type(__length) - __elemsbefore;
1434 __pos = _M_finish - __elemsafter;
1435 __STL_TRY {
1436 if (__elemsafter > difference_type(__n)) {
1437 iterator __finish_n = _M_finish - difference_type(__n);
1438 uninitialized_copy(__finish_n, _M_finish, _M_finish);
1439 _M_finish = __new_finish;
1440 copy_backward(__pos, __finish_n, __old_finish);
1441 copy(__first, __last, __pos);
1443 else {
1444 _ForwardIterator __mid = __first;
1445 advance(__mid, __elemsafter);
1446 __uninitialized_copy_copy(__mid, __last, __pos, _M_finish, _M_finish);
1447 _M_finish = __new_finish;
1448 copy(__first, __mid, __pos);
1451 __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1,
1452 __new_finish._M_node + 1));
1456 #else /* __STL_MEMBER_TEMPLATES */
1458 template <class _Tp, class _Alloc, size_t __bufsize>
1459 void
1460 deque<_Tp,_Alloc,__bufsize>::_M_insert_aux(iterator __pos,
1461 const value_type* __first,
1462 const value_type* __last,
1463 size_type __n)
1465 const difference_type __elemsbefore = __pos - _M_start;
1466 size_type __length = size();
1467 if (__elemsbefore < __length / 2) {
1468 iterator __new_start = _M_reserve_elements_at_front(__n);
1469 iterator __old_start = _M_start;
1470 __pos = _M_start + __elemsbefore;
1471 __STL_TRY {
1472 if (__elemsbefore >= difference_type(__n)) {
1473 iterator __start_n = _M_start + difference_type(__n);
1474 uninitialized_copy(_M_start, __start_n, __new_start);
1475 _M_start = __new_start;
1476 copy(__start_n, __pos, __old_start);
1477 copy(__first, __last, __pos - difference_type(__n));
1479 else {
1480 const value_type* __mid =
1481 __first + (difference_type(__n) - __elemsbefore);
1482 __uninitialized_copy_copy(_M_start, __pos, __first, __mid,
1483 __new_start);
1484 _M_start = __new_start;
1485 copy(__mid, __last, __old_start);
1488 __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
1490 else {
1491 iterator __new_finish = _M_reserve_elements_at_back(__n);
1492 iterator __old_finish = _M_finish;
1493 const difference_type __elemsafter =
1494 difference_type(__length) - __elemsbefore;
1495 __pos = _M_finish - __elemsafter;
1496 __STL_TRY {
1497 if (__elemsafter > difference_type(__n)) {
1498 iterator __finish_n = _M_finish - difference_type(__n);
1499 uninitialized_copy(__finish_n, _M_finish, _M_finish);
1500 _M_finish = __new_finish;
1501 copy_backward(__pos, __finish_n, __old_finish);
1502 copy(__first, __last, __pos);
1504 else {
1505 const value_type* __mid = __first + __elemsafter;
1506 __uninitialized_copy_copy(__mid, __last, __pos, _M_finish, _M_finish);
1507 _M_finish = __new_finish;
1508 copy(__first, __mid, __pos);
1511 __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1,
1512 __new_finish._M_node + 1));
1516 template <class _Tp, class _Alloc, size_t __bufsize>
1517 void
1518 deque<_Tp,_Alloc,__bufsize>::_M_insert_aux(iterator __pos,
1519 const_iterator __first,
1520 const_iterator __last,
1521 size_type __n)
1523 const difference_type __elemsbefore = __pos - _M_start;
1524 size_type __length = size();
1525 if (__elemsbefore < __length / 2) {
1526 iterator __new_start = _M_reserve_elements_at_front(__n);
1527 iterator __old_start = _M_start;
1528 __pos = _M_start + __elemsbefore;
1529 __STL_TRY {
1530 if (__elemsbefore >= __n) {
1531 iterator __start_n = _M_start + __n;
1532 uninitialized_copy(_M_start, __start_n, __new_start);
1533 _M_start = __new_start;
1534 copy(__start_n, __pos, __old_start);
1535 copy(__first, __last, __pos - difference_type(__n));
1537 else {
1538 const_iterator __mid = __first + (__n - __elemsbefore);
1539 __uninitialized_copy_copy(_M_start, __pos, __first, __mid,
1540 __new_start);
1541 _M_start = __new_start;
1542 copy(__mid, __last, __old_start);
1545 __STL_UNWIND(_M_destroy_nodes(__new_start._M_node, _M_start._M_node));
1547 else {
1548 iterator __new_finish = _M_reserve_elements_at_back(__n);
1549 iterator __old_finish = _M_finish;
1550 const difference_type __elemsafter = __length - __elemsbefore;
1551 __pos = _M_finish - __elemsafter;
1552 __STL_TRY {
1553 if (__elemsafter > __n) {
1554 iterator __finish_n = _M_finish - difference_type(__n);
1555 uninitialized_copy(__finish_n, _M_finish, _M_finish);
1556 _M_finish = __new_finish;
1557 copy_backward(__pos, __finish_n, __old_finish);
1558 copy(__first, __last, __pos);
1560 else {
1561 const_iterator __mid = __first + __elemsafter;
1562 __uninitialized_copy_copy(__mid, __last, __pos, _M_finish, _M_finish);
1563 _M_finish = __new_finish;
1564 copy(__first, __mid, __pos);
1567 __STL_UNWIND(_M_destroy_nodes(_M_finish._M_node + 1,
1568 __new_finish._M_node + 1));
1572 #endif /* __STL_MEMBER_TEMPLATES */
1574 template <class _Tp, class _Alloc, size_t __bufsize>
1575 void
1576 deque<_Tp,_Alloc,__bufsize>::_M_new_elements_at_front(size_type __new_elems)
1578 size_type __new_nodes
1579 = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size();
1580 _M_reserve_map_at_front(__new_nodes);
1581 size_type __i;
1582 __STL_TRY {
1583 for (__i = 1; __i <= __new_nodes; ++__i)
1584 *(_M_start._M_node - __i) = _M_allocate_node();
1586 # ifdef __STL_USE_EXCEPTIONS
1587 catch(...) {
1588 for (size_type __j = 1; __j < __i; ++__j)
1589 _M_deallocate_node(*(_M_start._M_node - __j));
1590 throw;
1592 # endif /* __STL_USE_EXCEPTIONS */
1595 template <class _Tp, class _Alloc, size_t __bufsize>
1596 void
1597 deque<_Tp,_Alloc,__bufsize>::_M_new_elements_at_back(size_type __new_elems)
1599 size_type __new_nodes
1600 = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size();
1601 _M_reserve_map_at_back(__new_nodes);
1602 size_type __i;
1603 __STL_TRY {
1604 for (__i = 1; __i <= __new_nodes; ++__i)
1605 *(_M_finish._M_node + __i) = _M_allocate_node();
1607 # ifdef __STL_USE_EXCEPTIONS
1608 catch(...) {
1609 for (size_type __j = 1; __j < __i; ++__j)
1610 _M_deallocate_node(*(_M_finish._M_node + __j));
1611 throw;
1613 # endif /* __STL_USE_EXCEPTIONS */
1616 template <class _Tp, class _Alloc, size_t __bufsize>
1617 void
1618 deque<_Tp,_Alloc,__bufsize>::_M_reallocate_map(size_type __nodes_to_add,
1619 bool __add_at_front)
1621 size_type __old_num_nodes = _M_finish._M_node - _M_start._M_node + 1;
1622 size_type __new_num_nodes = __old_num_nodes + __nodes_to_add;
1624 _Map_pointer __new_nstart;
1625 if (_M_map_size > 2 * __new_num_nodes) {
1626 __new_nstart = _M_map + (_M_map_size - __new_num_nodes) / 2
1627 + (__add_at_front ? __nodes_to_add : 0);
1628 if (__new_nstart < _M_start._M_node)
1629 copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart);
1630 else
1631 copy_backward(_M_start._M_node, _M_finish._M_node + 1,
1632 __new_nstart + __old_num_nodes);
1634 else {
1635 size_type __new_map_size =
1636 _M_map_size + max(_M_map_size, __nodes_to_add) + 2;
1638 _Map_pointer __new_map = _M_allocate_map(__new_map_size);
1639 __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2
1640 + (__add_at_front ? __nodes_to_add : 0);
1641 copy(_M_start._M_node, _M_finish._M_node + 1, __new_nstart);
1642 _M_deallocate_map(_M_map, _M_map_size);
1644 _M_map = __new_map;
1645 _M_map_size = __new_map_size;
1648 _M_start._M_set_node(__new_nstart);
1649 _M_finish._M_set_node(__new_nstart + __old_num_nodes - 1);
1653 // Nonmember functions.
1655 #ifndef __STL_NON_TYPE_TMPL_PARAM_BUG
1657 template <class _Tp, class _Alloc, size_t __bufsiz>
1658 bool operator==(const deque<_Tp, _Alloc, __bufsiz>& __x,
1659 const deque<_Tp, _Alloc, __bufsiz>& __y)
1661 return __x.size() == __y.size() &&
1662 equal(__x.begin(), __x.end(), __y.begin());
1665 template <class _Tp, class _Alloc, size_t __bufsiz>
1666 bool operator<(const deque<_Tp, _Alloc, __bufsiz>& __x,
1667 const deque<_Tp, _Alloc, __bufsiz>& __y)
1669 return lexicographical_compare(__x.begin(), __x.end(),
1670 __y.begin(), __y.end());
1673 #endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */
1675 #if defined(__STL_FUNCTION_TMPL_PARTIAL_ORDER) && \
1676 !defined(__STL_NON_TYPE_TMPL_PARAM_BUG)
1678 template <class _Tp, class _Alloc, size_t __bufsiz>
1679 inline void
1680 swap(deque<_Tp,_Alloc,__bufsiz>& __x, deque<_Tp,_Alloc,__bufsiz>& __y)
1682 __x.swap(__y);
1685 #endif
1687 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
1688 #pragma reset woff 1174
1689 #pragma reset woff 1375
1690 #endif
1692 __STL_END_NAMESPACE
1694 #endif /* __SGI_STL_INTERNAL_DEQUE_H */
1696 // Local Variables:
1697 // mode:C++
1698 // End: