11b86b14eSAlexander Kabaev // Deque implementation -*- C++ -*-
200db7afdSDavid E. O'Brien 
3f8a1b7d9SAlexander Kabaev // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
4f8a1b7d9SAlexander Kabaev // Free Software Foundation, Inc.
500db7afdSDavid E. O'Brien //
600db7afdSDavid E. O'Brien // This file is part of the GNU ISO C++ Library.  This library is free
700db7afdSDavid E. O'Brien // software; you can redistribute it and/or modify it under the
800db7afdSDavid E. O'Brien // terms of the GNU General Public License as published by the
900db7afdSDavid E. O'Brien // Free Software Foundation; either version 2, or (at your option)
1000db7afdSDavid E. O'Brien // any later version.
1100db7afdSDavid E. O'Brien 
1200db7afdSDavid E. O'Brien // This library is distributed in the hope that it will be useful,
1300db7afdSDavid E. O'Brien // but WITHOUT ANY WARRANTY; without even the implied warranty of
1400db7afdSDavid E. O'Brien // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1500db7afdSDavid E. O'Brien // GNU General Public License for more details.
1600db7afdSDavid E. O'Brien 
1700db7afdSDavid E. O'Brien // You should have received a copy of the GNU General Public License along
1800db7afdSDavid E. O'Brien // with this library; see the file COPYING.  If not, write to the Free
19f8a1b7d9SAlexander Kabaev // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
2000db7afdSDavid E. O'Brien // USA.
2100db7afdSDavid E. O'Brien 
2200db7afdSDavid E. O'Brien // As a special exception, you may use this file as part of a free software
2300db7afdSDavid E. O'Brien // library without restriction.  Specifically, if other files instantiate
2400db7afdSDavid E. O'Brien // templates or use macros or inline functions from this file, or you compile
2500db7afdSDavid E. O'Brien // this file and link it with other files to produce an executable, this
2600db7afdSDavid E. O'Brien // file does not by itself cause the resulting executable to be covered by
2700db7afdSDavid E. O'Brien // the GNU General Public License.  This exception does not however
2800db7afdSDavid E. O'Brien // invalidate any other reasons why the executable file might be covered by
2900db7afdSDavid E. O'Brien // the GNU General Public License.
3000db7afdSDavid E. O'Brien 
3100db7afdSDavid E. O'Brien /*
3200db7afdSDavid E. O'Brien  *
3300db7afdSDavid E. O'Brien  * Copyright (c) 1994
3400db7afdSDavid E. O'Brien  * Hewlett-Packard Company
3500db7afdSDavid E. O'Brien  *
3600db7afdSDavid E. O'Brien  * Permission to use, copy, modify, distribute and sell this software
3700db7afdSDavid E. O'Brien  * and its documentation for any purpose is hereby granted without fee,
3800db7afdSDavid E. O'Brien  * provided that the above copyright notice appear in all copies and
3900db7afdSDavid E. O'Brien  * that both that copyright notice and this permission notice appear
4000db7afdSDavid E. O'Brien  * in supporting documentation.  Hewlett-Packard Company makes no
4100db7afdSDavid E. O'Brien  * representations about the suitability of this software for any
4200db7afdSDavid E. O'Brien  * purpose.  It is provided "as is" without express or implied warranty.
4300db7afdSDavid E. O'Brien  *
4400db7afdSDavid E. O'Brien  *
4500db7afdSDavid E. O'Brien  * Copyright (c) 1997
4600db7afdSDavid E. O'Brien  * Silicon Graphics Computer Systems, Inc.
4700db7afdSDavid E. O'Brien  *
4800db7afdSDavid E. O'Brien  * Permission to use, copy, modify, distribute and sell this software
4900db7afdSDavid E. O'Brien  * and its documentation for any purpose is hereby granted without fee,
5000db7afdSDavid E. O'Brien  * provided that the above copyright notice appear in all copies and
5100db7afdSDavid E. O'Brien  * that both that copyright notice and this permission notice appear
5200db7afdSDavid E. O'Brien  * in supporting documentation.  Silicon Graphics makes no
5300db7afdSDavid E. O'Brien  * representations about the suitability of this software for any
5400db7afdSDavid E. O'Brien  * purpose.  It is provided "as is" without express or implied warranty.
5500db7afdSDavid E. O'Brien  */
5600db7afdSDavid E. O'Brien 
5700db7afdSDavid E. O'Brien /** @file stl_deque.h
5800db7afdSDavid E. O'Brien  *  This is an internal header file, included by other library headers.
5900db7afdSDavid E. O'Brien  *  You should not attempt to use it directly.
6000db7afdSDavid E. O'Brien  */
6100db7afdSDavid E. O'Brien 
62ffeaf689SAlexander Kabaev #ifndef _DEQUE_H
63ffeaf689SAlexander Kabaev #define _DEQUE_H 1
641b86b14eSAlexander Kabaev 
6500db7afdSDavid E. O'Brien #include <bits/concept_check.h>
6600db7afdSDavid E. O'Brien #include <bits/stl_iterator_base_types.h>
6700db7afdSDavid E. O'Brien #include <bits/stl_iterator_base_funcs.h>
6800db7afdSDavid E. O'Brien 
_GLIBCXX_BEGIN_NESTED_NAMESPACE(std,_GLIBCXX_STD)69f8a1b7d9SAlexander Kabaev _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD)
70f8a1b7d9SAlexander Kabaev 
7100db7afdSDavid E. O'Brien   /**
7200db7afdSDavid E. O'Brien    *  @if maint
7300db7afdSDavid E. O'Brien    *  @brief This function controls the size of memory nodes.
7400db7afdSDavid E. O'Brien    *  @param  size  The size of an element.
7500db7afdSDavid E. O'Brien    *  @return   The number (not byte size) of elements per node.
7600db7afdSDavid E. O'Brien    *
7700db7afdSDavid E. O'Brien    *  This function started off as a compiler kludge from SGI, but seems to
781b86b14eSAlexander Kabaev    *  be a useful wrapper around a repeated constant expression.  The '512' is
791b86b14eSAlexander Kabaev    *  tuneable (and no other code needs to change), but no investigation has
801b86b14eSAlexander Kabaev    *  been done since inheriting the SGI code.
8100db7afdSDavid E. O'Brien    *  @endif
8200db7afdSDavid E. O'Brien   */
8300db7afdSDavid E. O'Brien   inline size_t
8400db7afdSDavid E. O'Brien   __deque_buf_size(size_t __size)
8500db7afdSDavid E. O'Brien   { return __size < 512 ? size_t(512 / __size) : size_t(1); }
8600db7afdSDavid E. O'Brien 
8700db7afdSDavid E. O'Brien 
8800db7afdSDavid E. O'Brien   /**
891b86b14eSAlexander Kabaev    *  @brief A deque::iterator.
901b86b14eSAlexander Kabaev    *
91f8a1b7d9SAlexander Kabaev    *  Quite a bit of intelligence here.  Much of the functionality of
92f8a1b7d9SAlexander Kabaev    *  deque is actually passed off to this class.  A deque holds two
93f8a1b7d9SAlexander Kabaev    *  of these internally, marking its valid range.  Access to
94f8a1b7d9SAlexander Kabaev    *  elements is done as offsets of either of those two, relying on
95f8a1b7d9SAlexander Kabaev    *  operator overloading in this class.
9600db7afdSDavid E. O'Brien    *
9700db7afdSDavid E. O'Brien    *  @if maint
9800db7afdSDavid E. O'Brien    *  All the functions are op overloads except for _M_set_node.
9900db7afdSDavid E. O'Brien    *  @endif
10000db7afdSDavid E. O'Brien   */
1011b86b14eSAlexander Kabaev   template<typename _Tp, typename _Ref, typename _Ptr>
10200db7afdSDavid E. O'Brien     struct _Deque_iterator
10300db7afdSDavid E. O'Brien     {
10400db7afdSDavid E. O'Brien       typedef _Deque_iterator<_Tp, _Tp&, _Tp*>             iterator;
10500db7afdSDavid E. O'Brien       typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
106ffeaf689SAlexander Kabaev 
_S_buffer_size_Deque_iterator107ffeaf689SAlexander Kabaev       static size_t _S_buffer_size()
108ffeaf689SAlexander Kabaev       { return __deque_buf_size(sizeof(_Tp)); }
10900db7afdSDavid E. O'Brien 
110f8a1b7d9SAlexander Kabaev       typedef std::random_access_iterator_tag iterator_category;
11100db7afdSDavid E. O'Brien       typedef _Tp                             value_type;
11200db7afdSDavid E. O'Brien       typedef _Ptr                            pointer;
11300db7afdSDavid E. O'Brien       typedef _Ref                            reference;
11400db7afdSDavid E. O'Brien       typedef size_t                          size_type;
11500db7afdSDavid E. O'Brien       typedef ptrdiff_t                       difference_type;
11600db7afdSDavid E. O'Brien       typedef _Tp**                           _Map_pointer;
11700db7afdSDavid E. O'Brien       typedef _Deque_iterator                 _Self;
11800db7afdSDavid E. O'Brien 
11900db7afdSDavid E. O'Brien       _Tp* _M_cur;
12000db7afdSDavid E. O'Brien       _Tp* _M_first;
12100db7afdSDavid E. O'Brien       _Tp* _M_last;
12200db7afdSDavid E. O'Brien       _Map_pointer _M_node;
12300db7afdSDavid E. O'Brien 
_Deque_iterator_Deque_iterator12400db7afdSDavid E. O'Brien       _Deque_iterator(_Tp* __x, _Map_pointer __y)
12500db7afdSDavid E. O'Brien       : _M_cur(__x), _M_first(*__y),
12600db7afdSDavid E. O'Brien         _M_last(*__y + _S_buffer_size()), _M_node(__y) {}
127ffeaf689SAlexander Kabaev 
_Deque_iterator_Deque_iterator12800db7afdSDavid E. O'Brien       _Deque_iterator() : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) {}
129ffeaf689SAlexander Kabaev 
_Deque_iterator_Deque_iterator13000db7afdSDavid E. O'Brien       _Deque_iterator(const iterator& __x)
13100db7afdSDavid E. O'Brien       : _M_cur(__x._M_cur), _M_first(__x._M_first),
13200db7afdSDavid E. O'Brien         _M_last(__x._M_last), _M_node(__x._M_node) {}
13300db7afdSDavid E. O'Brien 
134ffeaf689SAlexander Kabaev       reference
135ffeaf689SAlexander Kabaev       operator*() const
136ffeaf689SAlexander Kabaev       { return *_M_cur; }
13700db7afdSDavid E. O'Brien 
138ffeaf689SAlexander Kabaev       pointer
139ffeaf689SAlexander Kabaev       operator->() const
140ffeaf689SAlexander Kabaev       { return _M_cur; }
141ffeaf689SAlexander Kabaev 
142ffeaf689SAlexander Kabaev       _Self&
143ffeaf689SAlexander Kabaev       operator++()
144ffeaf689SAlexander Kabaev       {
14500db7afdSDavid E. O'Brien 	++_M_cur;
146ffeaf689SAlexander Kabaev 	if (_M_cur == _M_last)
147ffeaf689SAlexander Kabaev 	  {
14800db7afdSDavid E. O'Brien 	    _M_set_node(_M_node + 1);
14900db7afdSDavid E. O'Brien 	    _M_cur = _M_first;
15000db7afdSDavid E. O'Brien 	  }
15100db7afdSDavid E. O'Brien 	return *this;
15200db7afdSDavid E. O'Brien       }
153ffeaf689SAlexander Kabaev 
154ffeaf689SAlexander Kabaev       _Self
155ffeaf689SAlexander Kabaev       operator++(int)
156ffeaf689SAlexander Kabaev       {
15700db7afdSDavid E. O'Brien 	_Self __tmp = *this;
15800db7afdSDavid E. O'Brien 	++*this;
15900db7afdSDavid E. O'Brien 	return __tmp;
16000db7afdSDavid E. O'Brien       }
16100db7afdSDavid E. O'Brien 
162ffeaf689SAlexander Kabaev       _Self&
163ffeaf689SAlexander Kabaev       operator--()
164ffeaf689SAlexander Kabaev       {
165ffeaf689SAlexander Kabaev 	if (_M_cur == _M_first)
166ffeaf689SAlexander Kabaev 	  {
16700db7afdSDavid E. O'Brien 	    _M_set_node(_M_node - 1);
16800db7afdSDavid E. O'Brien 	    _M_cur = _M_last;
16900db7afdSDavid E. O'Brien 	  }
17000db7afdSDavid E. O'Brien 	--_M_cur;
17100db7afdSDavid E. O'Brien 	return *this;
17200db7afdSDavid E. O'Brien       }
173ffeaf689SAlexander Kabaev 
174ffeaf689SAlexander Kabaev       _Self
175ffeaf689SAlexander Kabaev       operator--(int)
176ffeaf689SAlexander Kabaev       {
17700db7afdSDavid E. O'Brien 	_Self __tmp = *this;
17800db7afdSDavid E. O'Brien 	--*this;
17900db7afdSDavid E. O'Brien 	return __tmp;
18000db7afdSDavid E. O'Brien       }
18100db7afdSDavid E. O'Brien 
182ffeaf689SAlexander Kabaev       _Self&
183ffeaf689SAlexander Kabaev       operator+=(difference_type __n)
18400db7afdSDavid E. O'Brien       {
185ffeaf689SAlexander Kabaev 	const difference_type __offset = __n + (_M_cur - _M_first);
18600db7afdSDavid E. O'Brien 	if (__offset >= 0 && __offset < difference_type(_S_buffer_size()))
18700db7afdSDavid E. O'Brien 	  _M_cur += __n;
188ffeaf689SAlexander Kabaev 	else
189ffeaf689SAlexander Kabaev 	  {
190ffeaf689SAlexander Kabaev 	    const difference_type __node_offset =
19100db7afdSDavid E. O'Brien 	      __offset > 0 ? __offset / difference_type(_S_buffer_size())
192ffeaf689SAlexander Kabaev 	                   : -difference_type((-__offset - 1)
193ffeaf689SAlexander Kabaev 					      / _S_buffer_size()) - 1;
19400db7afdSDavid E. O'Brien 	    _M_set_node(_M_node + __node_offset);
195ffeaf689SAlexander Kabaev 	    _M_cur = _M_first + (__offset - __node_offset
196ffeaf689SAlexander Kabaev 				 * difference_type(_S_buffer_size()));
19700db7afdSDavid E. O'Brien 	  }
19800db7afdSDavid E. O'Brien 	return *this;
19900db7afdSDavid E. O'Brien       }
20000db7afdSDavid E. O'Brien 
201ffeaf689SAlexander Kabaev       _Self
202ffeaf689SAlexander Kabaev       operator+(difference_type __n) const
20300db7afdSDavid E. O'Brien       {
20400db7afdSDavid E. O'Brien 	_Self __tmp = *this;
20500db7afdSDavid E. O'Brien 	return __tmp += __n;
20600db7afdSDavid E. O'Brien       }
20700db7afdSDavid E. O'Brien 
208ffeaf689SAlexander Kabaev       _Self&
209ffeaf689SAlexander Kabaev       operator-=(difference_type __n)
210ffeaf689SAlexander Kabaev       { return *this += -__n; }
21100db7afdSDavid E. O'Brien 
212ffeaf689SAlexander Kabaev       _Self
213ffeaf689SAlexander Kabaev       operator-(difference_type __n) const
214ffeaf689SAlexander Kabaev       {
21500db7afdSDavid E. O'Brien 	_Self __tmp = *this;
21600db7afdSDavid E. O'Brien 	return __tmp -= __n;
21700db7afdSDavid E. O'Brien       }
21800db7afdSDavid E. O'Brien 
219ffeaf689SAlexander Kabaev       reference
220ffeaf689SAlexander Kabaev       operator[](difference_type __n) const
221ffeaf689SAlexander Kabaev       { return *(*this + __n); }
22200db7afdSDavid E. O'Brien 
22300db7afdSDavid E. O'Brien       /** @if maint
224f8a1b7d9SAlexander Kabaev        *  Prepares to traverse new_node.  Sets everything except
225f8a1b7d9SAlexander Kabaev        *  _M_cur, which should therefore be set by the caller
226f8a1b7d9SAlexander Kabaev        *  immediately afterwards, based on _M_first and _M_last.
22700db7afdSDavid E. O'Brien        *  @endif
22800db7afdSDavid E. O'Brien        */
2291b86b14eSAlexander Kabaev       void
_M_set_node_Deque_iterator2301b86b14eSAlexander Kabaev       _M_set_node(_Map_pointer __new_node)
2311b86b14eSAlexander Kabaev       {
23200db7afdSDavid E. O'Brien 	_M_node = __new_node;
23300db7afdSDavid E. O'Brien 	_M_first = *__new_node;
23400db7afdSDavid E. O'Brien 	_M_last = _M_first + difference_type(_S_buffer_size());
23500db7afdSDavid E. O'Brien       }
23600db7afdSDavid E. O'Brien     };
23700db7afdSDavid E. O'Brien 
238ca6500fcSAlexander Kabaev   // Note: we also provide overloads whose operands are of the same type in
2391b86b14eSAlexander Kabaev   // order to avoid ambiguous overload resolution when std::rel_ops operators
240ca6500fcSAlexander Kabaev   // are in scope (for additional details, see libstdc++/3628)
2411b86b14eSAlexander Kabaev   template<typename _Tp, typename _Ref, typename _Ptr>
242ca6500fcSAlexander Kabaev     inline bool
243ca6500fcSAlexander Kabaev     operator==(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
244ca6500fcSAlexander Kabaev 	       const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
245ffeaf689SAlexander Kabaev     { return __x._M_cur == __y._M_cur; }
246ca6500fcSAlexander Kabaev 
2471b86b14eSAlexander Kabaev   template<typename _Tp, typename _RefL, typename _PtrL,
2481b86b14eSAlexander Kabaev 	   typename _RefR, typename _PtrR>
249ca6500fcSAlexander Kabaev     inline bool
250ca6500fcSAlexander Kabaev     operator==(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
251ca6500fcSAlexander Kabaev 	       const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
252ffeaf689SAlexander Kabaev     { return __x._M_cur == __y._M_cur; }
253ca6500fcSAlexander Kabaev 
2541b86b14eSAlexander Kabaev   template<typename _Tp, typename _Ref, typename _Ptr>
255ca6500fcSAlexander Kabaev     inline bool
256ca6500fcSAlexander Kabaev     operator!=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
257ca6500fcSAlexander Kabaev 	       const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
258ffeaf689SAlexander Kabaev     { return !(__x == __y); }
259ca6500fcSAlexander Kabaev 
2601b86b14eSAlexander Kabaev   template<typename _Tp, typename _RefL, typename _PtrL,
2611b86b14eSAlexander Kabaev 	   typename _RefR, typename _PtrR>
262ca6500fcSAlexander Kabaev     inline bool
263ca6500fcSAlexander Kabaev     operator!=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
264ca6500fcSAlexander Kabaev 	       const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
265ffeaf689SAlexander Kabaev     { return !(__x == __y); }
266ca6500fcSAlexander Kabaev 
2671b86b14eSAlexander Kabaev   template<typename _Tp, typename _Ref, typename _Ptr>
268ca6500fcSAlexander Kabaev     inline bool
269ca6500fcSAlexander Kabaev     operator<(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
270ca6500fcSAlexander Kabaev 	      const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
271ffeaf689SAlexander Kabaev     { return (__x._M_node == __y._M_node) ? (__x._M_cur < __y._M_cur)
272ffeaf689SAlexander Kabaev                                           : (__x._M_node < __y._M_node); }
273ca6500fcSAlexander Kabaev 
2741b86b14eSAlexander Kabaev   template<typename _Tp, typename _RefL, typename _PtrL,
2751b86b14eSAlexander Kabaev 	   typename _RefR, typename _PtrR>
276ca6500fcSAlexander Kabaev     inline bool
277ca6500fcSAlexander Kabaev     operator<(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
278ca6500fcSAlexander Kabaev 	      const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
279ffeaf689SAlexander Kabaev     { return (__x._M_node == __y._M_node) ? (__x._M_cur < __y._M_cur)
280ffeaf689SAlexander Kabaev 	                                  : (__x._M_node < __y._M_node); }
281ca6500fcSAlexander Kabaev 
2821b86b14eSAlexander Kabaev   template<typename _Tp, typename _Ref, typename _Ptr>
283ca6500fcSAlexander Kabaev     inline bool
284ca6500fcSAlexander Kabaev     operator>(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
285ca6500fcSAlexander Kabaev 	      const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
286ffeaf689SAlexander Kabaev     { return __y < __x; }
287ca6500fcSAlexander Kabaev 
2881b86b14eSAlexander Kabaev   template<typename _Tp, typename _RefL, typename _PtrL,
2891b86b14eSAlexander Kabaev 	   typename _RefR, typename _PtrR>
290ca6500fcSAlexander Kabaev     inline bool
291ca6500fcSAlexander Kabaev     operator>(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
292ca6500fcSAlexander Kabaev 	      const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
293ffeaf689SAlexander Kabaev     { return __y < __x; }
294ca6500fcSAlexander Kabaev 
2951b86b14eSAlexander Kabaev   template<typename _Tp, typename _Ref, typename _Ptr>
296ca6500fcSAlexander Kabaev     inline bool
297ca6500fcSAlexander Kabaev     operator<=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
298ca6500fcSAlexander Kabaev 	       const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
299ffeaf689SAlexander Kabaev     { return !(__y < __x); }
300ca6500fcSAlexander Kabaev 
3011b86b14eSAlexander Kabaev   template<typename _Tp, typename _RefL, typename _PtrL,
3021b86b14eSAlexander Kabaev 	   typename _RefR, typename _PtrR>
303ca6500fcSAlexander Kabaev     inline bool
304ca6500fcSAlexander Kabaev     operator<=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
305ca6500fcSAlexander Kabaev 	       const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
306ffeaf689SAlexander Kabaev     { return !(__y < __x); }
307ca6500fcSAlexander Kabaev 
3081b86b14eSAlexander Kabaev   template<typename _Tp, typename _Ref, typename _Ptr>
309ca6500fcSAlexander Kabaev     inline bool
310ca6500fcSAlexander Kabaev     operator>=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
311ca6500fcSAlexander Kabaev 	       const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
312ffeaf689SAlexander Kabaev     { return !(__x < __y); }
313ca6500fcSAlexander Kabaev 
3141b86b14eSAlexander Kabaev   template<typename _Tp, typename _RefL, typename _PtrL,
3151b86b14eSAlexander Kabaev 	   typename _RefR, typename _PtrR>
316ca6500fcSAlexander Kabaev     inline bool
317ca6500fcSAlexander Kabaev     operator>=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
318ca6500fcSAlexander Kabaev 	       const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
319ffeaf689SAlexander Kabaev     { return !(__x < __y); }
320ca6500fcSAlexander Kabaev 
321ffeaf689SAlexander Kabaev   // _GLIBCXX_RESOLVE_LIB_DEFECTS
322ca6500fcSAlexander Kabaev   // According to the resolution of DR179 not only the various comparison
323ca6500fcSAlexander Kabaev   // operators but also operator- must accept mixed iterator/const_iterator
324ca6500fcSAlexander Kabaev   // parameters.
325f8a1b7d9SAlexander Kabaev   template<typename _Tp, typename _Ref, typename _Ptr>
326f8a1b7d9SAlexander Kabaev     inline typename _Deque_iterator<_Tp, _Ref, _Ptr>::difference_type
327f8a1b7d9SAlexander Kabaev     operator-(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
328f8a1b7d9SAlexander Kabaev 	      const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
329f8a1b7d9SAlexander Kabaev     {
330f8a1b7d9SAlexander Kabaev       return typename _Deque_iterator<_Tp, _Ref, _Ptr>::difference_type
331f8a1b7d9SAlexander Kabaev 	(_Deque_iterator<_Tp, _Ref, _Ptr>::_S_buffer_size())
332f8a1b7d9SAlexander Kabaev 	* (__x._M_node - __y._M_node - 1) + (__x._M_cur - __x._M_first)
333f8a1b7d9SAlexander Kabaev 	+ (__y._M_last - __y._M_cur);
334f8a1b7d9SAlexander Kabaev     }
335f8a1b7d9SAlexander Kabaev 
336ca6500fcSAlexander Kabaev   template<typename _Tp, typename _RefL, typename _PtrL,
337ca6500fcSAlexander Kabaev 	   typename _RefR, typename _PtrR>
338ca6500fcSAlexander Kabaev     inline typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type
339ca6500fcSAlexander Kabaev     operator-(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
340ca6500fcSAlexander Kabaev 	      const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
341ca6500fcSAlexander Kabaev     {
342ffeaf689SAlexander Kabaev       return typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type
343ffeaf689SAlexander Kabaev 	(_Deque_iterator<_Tp, _RefL, _PtrL>::_S_buffer_size())
344ffeaf689SAlexander Kabaev 	* (__x._M_node - __y._M_node - 1) + (__x._M_cur - __x._M_first)
345ffeaf689SAlexander Kabaev 	+ (__y._M_last - __y._M_cur);
346ca6500fcSAlexander Kabaev     }
347ca6500fcSAlexander Kabaev 
3481b86b14eSAlexander Kabaev   template<typename _Tp, typename _Ref, typename _Ptr>
34900db7afdSDavid E. O'Brien     inline _Deque_iterator<_Tp, _Ref, _Ptr>
35000db7afdSDavid E. O'Brien     operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x)
351ffeaf689SAlexander Kabaev     { return __x + __n; }
35200db7afdSDavid E. O'Brien 
353f8a1b7d9SAlexander Kabaev   template<typename _Tp>
354f8a1b7d9SAlexander Kabaev     void
355f8a1b7d9SAlexander Kabaev     fill(const _Deque_iterator<_Tp, _Tp&, _Tp*>& __first,
356f8a1b7d9SAlexander Kabaev 	 const _Deque_iterator<_Tp, _Tp&, _Tp*>& __last, const _Tp& __value);
357f8a1b7d9SAlexander Kabaev 
35800db7afdSDavid E. O'Brien   /**
35900db7afdSDavid E. O'Brien    *  @if maint
360ffeaf689SAlexander Kabaev    *  Deque base class.  This class provides the unified face for %deque's
361ffeaf689SAlexander Kabaev    *  allocation.  This class's constructor and destructor allocate and
362ffeaf689SAlexander Kabaev    *  deallocate (but do not initialize) storage.  This makes %exception
363ffeaf689SAlexander Kabaev    *  safety easier.
36400db7afdSDavid E. O'Brien    *
36500db7afdSDavid E. O'Brien    *  Nothing in this class ever constructs or destroys an actual Tp element.
3661b86b14eSAlexander Kabaev    *  (Deque handles that itself.)  Only/All memory management is performed
3671b86b14eSAlexander Kabaev    *  here.
36800db7afdSDavid E. O'Brien    *  @endif
36900db7afdSDavid E. O'Brien   */
3701b86b14eSAlexander Kabaev   template<typename _Tp, typename _Alloc>
37100db7afdSDavid E. O'Brien     class _Deque_base
37200db7afdSDavid E. O'Brien     {
37300db7afdSDavid E. O'Brien     public:
374ffeaf689SAlexander Kabaev       typedef _Alloc                  allocator_type;
375ffeaf689SAlexander Kabaev 
376ffeaf689SAlexander Kabaev       allocator_type
get_allocator()377ffeaf689SAlexander Kabaev       get_allocator() const
378f8a1b7d9SAlexander Kabaev       { return allocator_type(_M_get_Tp_allocator()); }
379ffeaf689SAlexander Kabaev 
38000db7afdSDavid E. O'Brien       typedef _Deque_iterator<_Tp, _Tp&, _Tp*>             iterator;
38100db7afdSDavid E. O'Brien       typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
38200db7afdSDavid E. O'Brien 
_Deque_base()383*dc3fe0ffSPedro F. Giffuni       _Deque_base()
384*dc3fe0ffSPedro F. Giffuni       : _M_impl()
385*dc3fe0ffSPedro F. Giffuni       { _M_initialize_map(0); }
386*dc3fe0ffSPedro F. Giffuni 
_Deque_base(const allocator_type & __a,size_t __num_elements)38700db7afdSDavid E. O'Brien       _Deque_base(const allocator_type& __a, size_t __num_elements)
388ffeaf689SAlexander Kabaev       : _M_impl(__a)
38900db7afdSDavid E. O'Brien       { _M_initialize_map(__num_elements); }
390ffeaf689SAlexander Kabaev 
_Deque_base(const allocator_type & __a)39100db7afdSDavid E. O'Brien       _Deque_base(const allocator_type& __a)
392ffeaf689SAlexander Kabaev       : _M_impl(__a)
393ffeaf689SAlexander Kabaev       { }
394ffeaf689SAlexander Kabaev 
39500db7afdSDavid E. O'Brien       ~_Deque_base();
39600db7afdSDavid E. O'Brien 
39700db7afdSDavid E. O'Brien     protected:
398ffeaf689SAlexander Kabaev       //This struct encapsulates the implementation of the std::deque
399ffeaf689SAlexander Kabaev       //standard container and at the same time makes use of the EBO
400ffeaf689SAlexander Kabaev       //for empty allocators.
401f8a1b7d9SAlexander Kabaev       typedef typename _Alloc::template rebind<_Tp*>::other _Map_alloc_type;
402f8a1b7d9SAlexander Kabaev 
403f8a1b7d9SAlexander Kabaev       typedef typename _Alloc::template rebind<_Tp>::other  _Tp_alloc_type;
404f8a1b7d9SAlexander Kabaev 
405ffeaf689SAlexander Kabaev       struct _Deque_impl
406f8a1b7d9SAlexander Kabaev       : public _Tp_alloc_type
407f8a1b7d9SAlexander Kabaev       {
408ffeaf689SAlexander Kabaev 	_Tp** _M_map;
409ffeaf689SAlexander Kabaev 	size_t _M_map_size;
410ffeaf689SAlexander Kabaev 	iterator _M_start;
411ffeaf689SAlexander Kabaev 	iterator _M_finish;
412ffeaf689SAlexander Kabaev 
_Deque_impl_Deque_impl413*dc3fe0ffSPedro F. Giffuni 	_Deque_impl()
414*dc3fe0ffSPedro F. Giffuni 	: _Tp_alloc_type(), _M_map(0), _M_map_size(0),
415*dc3fe0ffSPedro F. Giffuni 	  _M_start(), _M_finish()
416*dc3fe0ffSPedro F. Giffuni 	{ }
417*dc3fe0ffSPedro F. Giffuni 
_Deque_impl_Deque_impl418f8a1b7d9SAlexander Kabaev 	_Deque_impl(const _Tp_alloc_type& __a)
419f8a1b7d9SAlexander Kabaev 	: _Tp_alloc_type(__a), _M_map(0), _M_map_size(0),
420f8a1b7d9SAlexander Kabaev 	  _M_start(), _M_finish()
421ffeaf689SAlexander Kabaev 	{ }
422ffeaf689SAlexander Kabaev       };
423ffeaf689SAlexander Kabaev 
424f8a1b7d9SAlexander Kabaev       _Tp_alloc_type&
_M_get_Tp_allocator()425f8a1b7d9SAlexander Kabaev       _M_get_Tp_allocator()
426f8a1b7d9SAlexander Kabaev       { return *static_cast<_Tp_alloc_type*>(&this->_M_impl); }
427f8a1b7d9SAlexander Kabaev 
428f8a1b7d9SAlexander Kabaev       const _Tp_alloc_type&
_M_get_Tp_allocator()429f8a1b7d9SAlexander Kabaev       _M_get_Tp_allocator() const
430f8a1b7d9SAlexander Kabaev       { return *static_cast<const _Tp_alloc_type*>(&this->_M_impl); }
431f8a1b7d9SAlexander Kabaev 
432f8a1b7d9SAlexander Kabaev       _Map_alloc_type
_M_get_map_allocator()433f8a1b7d9SAlexander Kabaev       _M_get_map_allocator() const
434f8a1b7d9SAlexander Kabaev       { return _Map_alloc_type(_M_get_Tp_allocator()); }
435ffeaf689SAlexander Kabaev 
436ffeaf689SAlexander Kabaev       _Tp*
_M_allocate_node()437ffeaf689SAlexander Kabaev       _M_allocate_node()
438f8a1b7d9SAlexander Kabaev       {
439f8a1b7d9SAlexander Kabaev 	return _M_impl._Tp_alloc_type::allocate(__deque_buf_size(sizeof(_Tp)));
440f8a1b7d9SAlexander Kabaev       }
441ffeaf689SAlexander Kabaev 
442ffeaf689SAlexander Kabaev       void
_M_deallocate_node(_Tp * __p)443ffeaf689SAlexander Kabaev       _M_deallocate_node(_Tp* __p)
444f8a1b7d9SAlexander Kabaev       {
445f8a1b7d9SAlexander Kabaev 	_M_impl._Tp_alloc_type::deallocate(__p, __deque_buf_size(sizeof(_Tp)));
446f8a1b7d9SAlexander Kabaev       }
447ffeaf689SAlexander Kabaev 
448ffeaf689SAlexander Kabaev       _Tp**
_M_allocate_map(size_t __n)449ffeaf689SAlexander Kabaev       _M_allocate_map(size_t __n)
450ffeaf689SAlexander Kabaev       { return _M_get_map_allocator().allocate(__n); }
451ffeaf689SAlexander Kabaev 
452ffeaf689SAlexander Kabaev       void
_M_deallocate_map(_Tp ** __p,size_t __n)453ffeaf689SAlexander Kabaev       _M_deallocate_map(_Tp** __p, size_t __n)
454ffeaf689SAlexander Kabaev       { _M_get_map_allocator().deallocate(__p, __n); }
455ffeaf689SAlexander Kabaev 
456ffeaf689SAlexander Kabaev     protected:
45700db7afdSDavid E. O'Brien       void _M_initialize_map(size_t);
45800db7afdSDavid E. O'Brien       void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish);
45900db7afdSDavid E. O'Brien       void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish);
46000db7afdSDavid E. O'Brien       enum { _S_initial_map_size = 8 };
46100db7afdSDavid E. O'Brien 
462ffeaf689SAlexander Kabaev       _Deque_impl _M_impl;
46300db7afdSDavid E. O'Brien     };
46400db7afdSDavid E. O'Brien 
4651b86b14eSAlexander Kabaev   template<typename _Tp, typename _Alloc>
466f8a1b7d9SAlexander Kabaev     _Deque_base<_Tp, _Alloc>::
~_Deque_base()467f8a1b7d9SAlexander Kabaev     ~_Deque_base()
46800db7afdSDavid E. O'Brien     {
469ffeaf689SAlexander Kabaev       if (this->_M_impl._M_map)
4701b86b14eSAlexander Kabaev 	{
471f8a1b7d9SAlexander Kabaev 	  _M_destroy_nodes(this->_M_impl._M_start._M_node,
472f8a1b7d9SAlexander Kabaev 			   this->_M_impl._M_finish._M_node + 1);
473ffeaf689SAlexander Kabaev 	  _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size);
47400db7afdSDavid E. O'Brien 	}
47500db7afdSDavid E. O'Brien     }
47600db7afdSDavid E. O'Brien 
47700db7afdSDavid E. O'Brien   /**
47800db7afdSDavid E. O'Brien    *  @if maint
47900db7afdSDavid E. O'Brien    *  @brief Layout storage.
4801b86b14eSAlexander Kabaev    *  @param  num_elements  The count of T's for which to allocate space
4811b86b14eSAlexander Kabaev    *                        at first.
48200db7afdSDavid E. O'Brien    *  @return   Nothing.
48300db7afdSDavid E. O'Brien    *
48400db7afdSDavid E. O'Brien    *  The initial underlying memory layout is a bit complicated...
48500db7afdSDavid E. O'Brien    *  @endif
48600db7afdSDavid E. O'Brien   */
4871b86b14eSAlexander Kabaev   template<typename _Tp, typename _Alloc>
48800db7afdSDavid E. O'Brien     void
489f8a1b7d9SAlexander Kabaev     _Deque_base<_Tp, _Alloc>::
_M_initialize_map(size_t __num_elements)490f8a1b7d9SAlexander Kabaev     _M_initialize_map(size_t __num_elements)
49100db7afdSDavid E. O'Brien     {
492f8a1b7d9SAlexander Kabaev       const size_t __num_nodes = (__num_elements/ __deque_buf_size(sizeof(_Tp))
493f8a1b7d9SAlexander Kabaev 				  + 1);
49400db7afdSDavid E. O'Brien 
495ffeaf689SAlexander Kabaev       this->_M_impl._M_map_size = std::max((size_t) _S_initial_map_size,
496f8a1b7d9SAlexander Kabaev 					   size_t(__num_nodes + 2));
497ffeaf689SAlexander Kabaev       this->_M_impl._M_map = _M_allocate_map(this->_M_impl._M_map_size);
49800db7afdSDavid E. O'Brien 
4991b86b14eSAlexander Kabaev       // For "small" maps (needing less than _M_map_size nodes), allocation
500ffeaf689SAlexander Kabaev       // starts in the middle elements and grows outwards.  So nstart may be
501ffeaf689SAlexander Kabaev       // the beginning of _M_map, but for small maps it may be as far in as
502ffeaf689SAlexander Kabaev       // _M_map+3.
5031b86b14eSAlexander Kabaev 
504f8a1b7d9SAlexander Kabaev       _Tp** __nstart = (this->_M_impl._M_map
505f8a1b7d9SAlexander Kabaev 			+ (this->_M_impl._M_map_size - __num_nodes) / 2);
50600db7afdSDavid E. O'Brien       _Tp** __nfinish = __nstart + __num_nodes;
50700db7afdSDavid E. O'Brien 
50800db7afdSDavid E. O'Brien       try
50900db7afdSDavid E. O'Brien 	{ _M_create_nodes(__nstart, __nfinish); }
51000db7afdSDavid E. O'Brien       catch(...)
51100db7afdSDavid E. O'Brien 	{
512ffeaf689SAlexander Kabaev 	  _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size);
513ffeaf689SAlexander Kabaev 	  this->_M_impl._M_map = 0;
514ffeaf689SAlexander Kabaev 	  this->_M_impl._M_map_size = 0;
51500db7afdSDavid E. O'Brien 	  __throw_exception_again;
51600db7afdSDavid E. O'Brien 	}
51700db7afdSDavid E. O'Brien 
518ffeaf689SAlexander Kabaev       this->_M_impl._M_start._M_set_node(__nstart);
519ffeaf689SAlexander Kabaev       this->_M_impl._M_finish._M_set_node(__nfinish - 1);
520ffeaf689SAlexander Kabaev       this->_M_impl._M_start._M_cur = _M_impl._M_start._M_first;
521f8a1b7d9SAlexander Kabaev       this->_M_impl._M_finish._M_cur = (this->_M_impl._M_finish._M_first
522f8a1b7d9SAlexander Kabaev 					+ __num_elements
523f8a1b7d9SAlexander Kabaev 					% __deque_buf_size(sizeof(_Tp)));
52400db7afdSDavid E. O'Brien     }
52500db7afdSDavid E. O'Brien 
5261b86b14eSAlexander Kabaev   template<typename _Tp, typename _Alloc>
527ffeaf689SAlexander Kabaev     void
528f8a1b7d9SAlexander Kabaev     _Deque_base<_Tp, _Alloc>::
_M_create_nodes(_Tp ** __nstart,_Tp ** __nfinish)529f8a1b7d9SAlexander Kabaev     _M_create_nodes(_Tp** __nstart, _Tp** __nfinish)
53000db7afdSDavid E. O'Brien     {
53100db7afdSDavid E. O'Brien       _Tp** __cur;
5321b86b14eSAlexander Kabaev       try
5331b86b14eSAlexander Kabaev 	{
53400db7afdSDavid E. O'Brien 	  for (__cur = __nstart; __cur < __nfinish; ++__cur)
535ffeaf689SAlexander Kabaev 	    *__cur = this->_M_allocate_node();
53600db7afdSDavid E. O'Brien 	}
53700db7afdSDavid E. O'Brien       catch(...)
53800db7afdSDavid E. O'Brien 	{
53900db7afdSDavid E. O'Brien 	  _M_destroy_nodes(__nstart, __cur);
54000db7afdSDavid E. O'Brien 	  __throw_exception_again;
54100db7afdSDavid E. O'Brien 	}
54200db7afdSDavid E. O'Brien     }
54300db7afdSDavid E. O'Brien 
5441b86b14eSAlexander Kabaev   template<typename _Tp, typename _Alloc>
54500db7afdSDavid E. O'Brien     void
546f8a1b7d9SAlexander Kabaev     _Deque_base<_Tp, _Alloc>::
_M_destroy_nodes(_Tp ** __nstart,_Tp ** __nfinish)547f8a1b7d9SAlexander Kabaev     _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish)
54800db7afdSDavid E. O'Brien     {
54900db7afdSDavid E. O'Brien       for (_Tp** __n = __nstart; __n < __nfinish; ++__n)
55000db7afdSDavid E. O'Brien 	_M_deallocate_node(*__n);
55100db7afdSDavid E. O'Brien     }
55200db7afdSDavid E. O'Brien 
55300db7afdSDavid E. O'Brien   /**
5541b86b14eSAlexander Kabaev    *  @brief  A standard container using fixed-size memory allocation and
5551b86b14eSAlexander Kabaev    *  constant-time manipulation of elements at either end.
5561b86b14eSAlexander Kabaev    *
55700db7afdSDavid E. O'Brien    *  @ingroup Containers
55800db7afdSDavid E. O'Brien    *  @ingroup Sequences
55900db7afdSDavid E. O'Brien    *
56000db7afdSDavid E. O'Brien    *  Meets the requirements of a <a href="tables.html#65">container</a>, a
56100db7afdSDavid E. O'Brien    *  <a href="tables.html#66">reversible container</a>, and a
56200db7afdSDavid E. O'Brien    *  <a href="tables.html#67">sequence</a>, including the
56300db7afdSDavid E. O'Brien    *  <a href="tables.html#68">optional sequence requirements</a>.
56400db7afdSDavid E. O'Brien    *
5651b86b14eSAlexander Kabaev    *  In previous HP/SGI versions of deque, there was an extra template
5661b86b14eSAlexander Kabaev    *  parameter so users could control the node size.  This extension turned
5671b86b14eSAlexander Kabaev    *  out to violate the C++ standard (it can be detected using template
5681b86b14eSAlexander Kabaev    *  template parameters), and it was removed.
56900db7afdSDavid E. O'Brien    *
57000db7afdSDavid E. O'Brien    *  @if maint
57100db7afdSDavid E. O'Brien    *  Here's how a deque<Tp> manages memory.  Each deque has 4 members:
57200db7afdSDavid E. O'Brien    *
57300db7afdSDavid E. O'Brien    *  - Tp**        _M_map
57400db7afdSDavid E. O'Brien    *  - size_t      _M_map_size
57500db7afdSDavid E. O'Brien    *  - iterator    _M_start, _M_finish
57600db7afdSDavid E. O'Brien    *
577f8a1b7d9SAlexander Kabaev    *  map_size is at least 8.  %map is an array of map_size
578f8a1b7d9SAlexander Kabaev    *  pointers-to-"nodes".  (The name %map has nothing to do with the
579f8a1b7d9SAlexander Kabaev    *  std::map class, and "nodes" should not be confused with
580f8a1b7d9SAlexander Kabaev    *  std::list's usage of "node".)
58100db7afdSDavid E. O'Brien    *
582f8a1b7d9SAlexander Kabaev    *  A "node" has no specific type name as such, but it is referred
583f8a1b7d9SAlexander Kabaev    *  to as "node" in this file.  It is a simple array-of-Tp.  If Tp
584f8a1b7d9SAlexander Kabaev    *  is very large, there will be one Tp element per node (i.e., an
585f8a1b7d9SAlexander Kabaev    *  "array" of one).  For non-huge Tp's, node size is inversely
586f8a1b7d9SAlexander Kabaev    *  related to Tp size: the larger the Tp, the fewer Tp's will fit
587f8a1b7d9SAlexander Kabaev    *  in a node.  The goal here is to keep the total size of a node
588f8a1b7d9SAlexander Kabaev    *  relatively small and constant over different Tp's, to improve
589f8a1b7d9SAlexander Kabaev    *  allocator efficiency.
59000db7afdSDavid E. O'Brien    *
591f8a1b7d9SAlexander Kabaev    *  Not every pointer in the %map array will point to a node.  If
592f8a1b7d9SAlexander Kabaev    *  the initial number of elements in the deque is small, the
593f8a1b7d9SAlexander Kabaev    *  /middle/ %map pointers will be valid, and the ones at the edges
594f8a1b7d9SAlexander Kabaev    *  will be unused.  This same situation will arise as the %map
595f8a1b7d9SAlexander Kabaev    *  grows: available %map pointers, if any, will be on the ends.  As
596f8a1b7d9SAlexander Kabaev    *  new nodes are created, only a subset of the %map's pointers need
597f8a1b7d9SAlexander Kabaev    *  to be copied "outward".
59800db7afdSDavid E. O'Brien    *
59900db7afdSDavid E. O'Brien    *  Class invariants:
60000db7afdSDavid E. O'Brien    * - For any nonsingular iterator i:
60100db7afdSDavid E. O'Brien    *    - i.node points to a member of the %map array.  (Yes, you read that
60200db7afdSDavid E. O'Brien    *      correctly:  i.node does not actually point to a node.)  The member of
60300db7afdSDavid E. O'Brien    *      the %map array is what actually points to the node.
60400db7afdSDavid E. O'Brien    *    - i.first == *(i.node)    (This points to the node (first Tp element).)
60500db7afdSDavid E. O'Brien    *    - i.last  == i.first + node_size
60600db7afdSDavid E. O'Brien    *    - i.cur is a pointer in the range [i.first, i.last).  NOTE:
60700db7afdSDavid E. O'Brien    *      the implication of this is that i.cur is always a dereferenceable
60800db7afdSDavid E. O'Brien    *      pointer, even if i is a past-the-end iterator.
609f8a1b7d9SAlexander Kabaev    * - Start and Finish are always nonsingular iterators.  NOTE: this
610f8a1b7d9SAlexander Kabaev    * means that an empty deque must have one node, a deque with <N
611f8a1b7d9SAlexander Kabaev    * elements (where N is the node buffer size) must have one node, a
612f8a1b7d9SAlexander Kabaev    * deque with N through (2N-1) elements must have two nodes, etc.
613f8a1b7d9SAlexander Kabaev    * - For every node other than start.node and finish.node, every
614f8a1b7d9SAlexander Kabaev    * element in the node is an initialized object.  If start.node ==
615f8a1b7d9SAlexander Kabaev    * finish.node, then [start.cur, finish.cur) are initialized
616f8a1b7d9SAlexander Kabaev    * objects, and the elements outside that range are uninitialized
617f8a1b7d9SAlexander Kabaev    * storage.  Otherwise, [start.cur, start.last) and [finish.first,
618f8a1b7d9SAlexander Kabaev    * finish.cur) are initialized objects, and [start.first, start.cur)
619f8a1b7d9SAlexander Kabaev    * and [finish.cur, finish.last) are uninitialized storage.
62000db7afdSDavid E. O'Brien    * - [%map, %map + map_size) is a valid, non-empty range.
62100db7afdSDavid E. O'Brien    * - [start.node, finish.node] is a valid range contained within
62200db7afdSDavid E. O'Brien    *   [%map, %map + map_size).
6231b86b14eSAlexander Kabaev    * - A pointer in the range [%map, %map + map_size) points to an allocated
6241b86b14eSAlexander Kabaev    *   node if and only if the pointer is in the range
6251b86b14eSAlexander Kabaev    *   [start.node, finish.node].
62600db7afdSDavid E. O'Brien    *
6271b86b14eSAlexander Kabaev    *  Here's the magic:  nothing in deque is "aware" of the discontiguous
6281b86b14eSAlexander Kabaev    *  storage!
62900db7afdSDavid E. O'Brien    *
63000db7afdSDavid E. O'Brien    *  The memory setup and layout occurs in the parent, _Base, and the iterator
6311b86b14eSAlexander Kabaev    *  class is entirely responsible for "leaping" from one node to the next.
6321b86b14eSAlexander Kabaev    *  All the implementation routines for deque itself work only through the
6331b86b14eSAlexander Kabaev    *  start and finish iterators.  This keeps the routines simple and sane,
6341b86b14eSAlexander Kabaev    *  and we can use other standard algorithms as well.
63500db7afdSDavid E. O'Brien    *  @endif
63600db7afdSDavid E. O'Brien   */
637f8a1b7d9SAlexander Kabaev   template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
63800db7afdSDavid E. O'Brien     class deque : protected _Deque_base<_Tp, _Alloc>
63900db7afdSDavid E. O'Brien     {
64000db7afdSDavid E. O'Brien       // concept requirements
641f8a1b7d9SAlexander Kabaev       typedef typename _Alloc::value_type        _Alloc_value_type;
642ffeaf689SAlexander Kabaev       __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
643f8a1b7d9SAlexander Kabaev       __glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept)
64400db7afdSDavid E. O'Brien 
64500db7afdSDavid E. O'Brien       typedef _Deque_base<_Tp, _Alloc>           _Base;
646f8a1b7d9SAlexander Kabaev       typedef typename _Base::_Tp_alloc_type	 _Tp_alloc_type;
64700db7afdSDavid E. O'Brien 
64800db7afdSDavid E. O'Brien     public:
64900db7afdSDavid E. O'Brien       typedef _Tp                                        value_type;
650f8a1b7d9SAlexander Kabaev       typedef typename _Tp_alloc_type::pointer           pointer;
651f8a1b7d9SAlexander Kabaev       typedef typename _Tp_alloc_type::const_pointer     const_pointer;
652f8a1b7d9SAlexander Kabaev       typedef typename _Tp_alloc_type::reference         reference;
653f8a1b7d9SAlexander Kabaev       typedef typename _Tp_alloc_type::const_reference   const_reference;
6541b86b14eSAlexander Kabaev       typedef typename _Base::iterator                   iterator;
6551b86b14eSAlexander Kabaev       typedef typename _Base::const_iterator             const_iterator;
6561b86b14eSAlexander Kabaev       typedef std::reverse_iterator<const_iterator>      const_reverse_iterator;
6571b86b14eSAlexander Kabaev       typedef std::reverse_iterator<iterator>            reverse_iterator;
65800db7afdSDavid E. O'Brien       typedef size_t                             size_type;
65900db7afdSDavid E. O'Brien       typedef ptrdiff_t                          difference_type;
660f8a1b7d9SAlexander Kabaev       typedef _Alloc                             allocator_type;
66100db7afdSDavid E. O'Brien 
66200db7afdSDavid E. O'Brien     protected:
66300db7afdSDavid E. O'Brien       typedef pointer*                           _Map_pointer;
664ffeaf689SAlexander Kabaev 
_S_buffer_size()665ffeaf689SAlexander Kabaev       static size_t _S_buffer_size()
666ffeaf689SAlexander Kabaev       { return __deque_buf_size(sizeof(_Tp)); }
66700db7afdSDavid E. O'Brien 
66800db7afdSDavid E. O'Brien       // Functions controlling memory layout, and nothing else.
66900db7afdSDavid E. O'Brien       using _Base::_M_initialize_map;
67000db7afdSDavid E. O'Brien       using _Base::_M_create_nodes;
67100db7afdSDavid E. O'Brien       using _Base::_M_destroy_nodes;
67200db7afdSDavid E. O'Brien       using _Base::_M_allocate_node;
67300db7afdSDavid E. O'Brien       using _Base::_M_deallocate_node;
67400db7afdSDavid E. O'Brien       using _Base::_M_allocate_map;
67500db7afdSDavid E. O'Brien       using _Base::_M_deallocate_map;
676f8a1b7d9SAlexander Kabaev       using _Base::_M_get_Tp_allocator;
67700db7afdSDavid E. O'Brien 
67800db7afdSDavid E. O'Brien       /** @if maint
679ffeaf689SAlexander Kabaev        *  A total of four data members accumulated down the heirarchy.
680ffeaf689SAlexander Kabaev        *  May be accessed via _M_impl.*
68100db7afdSDavid E. O'Brien        *  @endif
68200db7afdSDavid E. O'Brien        */
683ffeaf689SAlexander Kabaev       using _Base::_M_impl;
68400db7afdSDavid E. O'Brien 
6851b86b14eSAlexander Kabaev     public:
6861b86b14eSAlexander Kabaev       // [23.2.1.1] construct/copy/destroy
6871b86b14eSAlexander Kabaev       // (assign() and get_allocator() are also listed in this section)
6881b86b14eSAlexander Kabaev       /**
6891b86b14eSAlexander Kabaev        *  @brief  Default constructor creates no elements.
6901b86b14eSAlexander Kabaev        */
deque()691*dc3fe0ffSPedro F. Giffuni       deque()
692*dc3fe0ffSPedro F. Giffuni       : _Base() { }
693*dc3fe0ffSPedro F. Giffuni 
6941b86b14eSAlexander Kabaev       explicit
deque(const allocator_type & __a)695*dc3fe0ffSPedro F. Giffuni       deque(const allocator_type& __a)
69600db7afdSDavid E. O'Brien       : _Base(__a, 0) {}
6971b86b14eSAlexander Kabaev 
6981b86b14eSAlexander Kabaev       /**
6991b86b14eSAlexander Kabaev        *  @brief  Create a %deque with copies of an exemplar element.
7001b86b14eSAlexander Kabaev        *  @param  n  The number of elements to initially create.
7011b86b14eSAlexander Kabaev        *  @param  value  An element to copy.
7021b86b14eSAlexander Kabaev        *
7031b86b14eSAlexander Kabaev        *  This constructor fills the %deque with @a n copies of @a value.
7041b86b14eSAlexander Kabaev        */
705f8a1b7d9SAlexander Kabaev       explicit
706f8a1b7d9SAlexander Kabaev       deque(size_type __n, const value_type& __value = value_type(),
7071b86b14eSAlexander Kabaev 	    const allocator_type& __a = allocator_type())
_Base(__a,__n)7081b86b14eSAlexander Kabaev       : _Base(__a, __n)
70900db7afdSDavid E. O'Brien       { _M_fill_initialize(__value); }
71000db7afdSDavid E. O'Brien 
7111b86b14eSAlexander Kabaev       /**
7121b86b14eSAlexander Kabaev        *  @brief  %Deque copy constructor.
7131b86b14eSAlexander Kabaev        *  @param  x  A %deque of identical element and allocator types.
7141b86b14eSAlexander Kabaev        *
7151b86b14eSAlexander Kabaev        *  The newly-created %deque uses a copy of the allocation object used
7161b86b14eSAlexander Kabaev        *  by @a x.
7171b86b14eSAlexander Kabaev        */
deque(const deque & __x)7181b86b14eSAlexander Kabaev       deque(const deque& __x)
719f8a1b7d9SAlexander Kabaev       : _Base(__x._M_get_Tp_allocator(), __x.size())
720f8a1b7d9SAlexander Kabaev       { std::__uninitialized_copy_a(__x.begin(), __x.end(),
721f8a1b7d9SAlexander Kabaev 				    this->_M_impl._M_start,
722f8a1b7d9SAlexander Kabaev 				    _M_get_Tp_allocator()); }
7231b86b14eSAlexander Kabaev 
7241b86b14eSAlexander Kabaev       /**
7251b86b14eSAlexander Kabaev        *  @brief  Builds a %deque from a range.
7261b86b14eSAlexander Kabaev        *  @param  first  An input iterator.
7271b86b14eSAlexander Kabaev        *  @param  last  An input iterator.
7281b86b14eSAlexander Kabaev        *
729ffeaf689SAlexander Kabaev        *  Create a %deque consisting of copies of the elements from [first,
730ffeaf689SAlexander Kabaev        *  last).
7311b86b14eSAlexander Kabaev        *
7321b86b14eSAlexander Kabaev        *  If the iterators are forward, bidirectional, or random-access, then
7331b86b14eSAlexander Kabaev        *  this will call the elements' copy constructor N times (where N is
7341b86b14eSAlexander Kabaev        *  distance(first,last)) and do no memory reallocation.  But if only
7351b86b14eSAlexander Kabaev        *  input iterators are used, then this will do at most 2N calls to the
7361b86b14eSAlexander Kabaev        *  copy constructor, and logN memory reallocations.
7371b86b14eSAlexander Kabaev        */
7381b86b14eSAlexander Kabaev       template<typename _InputIterator>
73900db7afdSDavid E. O'Brien         deque(_InputIterator __first, _InputIterator __last,
74000db7afdSDavid E. O'Brien 	      const allocator_type& __a = allocator_type())
_Base(__a)74100db7afdSDavid E. O'Brien 	: _Base(__a)
74200db7afdSDavid E. O'Brien         {
7431b86b14eSAlexander Kabaev 	  // Check whether it's an integral type.  If so, it's not an iterator.
744f8a1b7d9SAlexander Kabaev 	  typedef typename std::__is_integer<_InputIterator>::__type _Integral;
74500db7afdSDavid E. O'Brien 	  _M_initialize_dispatch(__first, __last, _Integral());
74600db7afdSDavid E. O'Brien 	}
74700db7afdSDavid E. O'Brien 
7481b86b14eSAlexander Kabaev       /**
7491b86b14eSAlexander Kabaev        *  The dtor only erases the elements, and note that if the elements
7501b86b14eSAlexander Kabaev        *  themselves are pointers, the pointed-to memory is not touched in any
7511b86b14eSAlexander Kabaev        *  way.  Managing the pointer is the user's responsibilty.
7521b86b14eSAlexander Kabaev        */
~deque()753ffeaf689SAlexander Kabaev       ~deque()
754f8a1b7d9SAlexander Kabaev       { _M_destroy_data(begin(), end(), _M_get_Tp_allocator()); }
7551b86b14eSAlexander Kabaev 
7561b86b14eSAlexander Kabaev       /**
7571b86b14eSAlexander Kabaev        *  @brief  %Deque assignment operator.
7581b86b14eSAlexander Kabaev        *  @param  x  A %deque of identical element and allocator types.
7591b86b14eSAlexander Kabaev        *
7601b86b14eSAlexander Kabaev        *  All the elements of @a x are copied, but unlike the copy constructor,
7611b86b14eSAlexander Kabaev        *  the allocator object is not copied.
7621b86b14eSAlexander Kabaev        */
7631b86b14eSAlexander Kabaev       deque&
7641b86b14eSAlexander Kabaev       operator=(const deque& __x);
7651b86b14eSAlexander Kabaev 
7661b86b14eSAlexander Kabaev       /**
7671b86b14eSAlexander Kabaev        *  @brief  Assigns a given value to a %deque.
7681b86b14eSAlexander Kabaev        *  @param  n  Number of elements to be assigned.
7691b86b14eSAlexander Kabaev        *  @param  val  Value to be assigned.
7701b86b14eSAlexander Kabaev        *
771f8a1b7d9SAlexander Kabaev        *  This function fills a %deque with @a n copies of the given
772f8a1b7d9SAlexander Kabaev        *  value.  Note that the assignment completely changes the
773f8a1b7d9SAlexander Kabaev        *  %deque and that the resulting %deque's size is the same as
774f8a1b7d9SAlexander Kabaev        *  the number of elements assigned.  Old data may be lost.
7751b86b14eSAlexander Kabaev        */
77600db7afdSDavid E. O'Brien       void
assign(size_type __n,const value_type & __val)777ffeaf689SAlexander Kabaev       assign(size_type __n, const value_type& __val)
778ffeaf689SAlexander Kabaev       { _M_fill_assign(__n, __val); }
77900db7afdSDavid E. O'Brien 
7801b86b14eSAlexander Kabaev       /**
7811b86b14eSAlexander Kabaev        *  @brief  Assigns a range to a %deque.
7821b86b14eSAlexander Kabaev        *  @param  first  An input iterator.
7831b86b14eSAlexander Kabaev        *  @param  last   An input iterator.
7841b86b14eSAlexander Kabaev        *
7851b86b14eSAlexander Kabaev        *  This function fills a %deque with copies of the elements in the
7861b86b14eSAlexander Kabaev        *  range [first,last).
7871b86b14eSAlexander Kabaev        *
7881b86b14eSAlexander Kabaev        *  Note that the assignment completely changes the %deque and that the
789ffeaf689SAlexander Kabaev        *  resulting %deque's size is the same as the number of elements
790ffeaf689SAlexander Kabaev        *  assigned.  Old data may be lost.
7911b86b14eSAlexander Kabaev        */
7921b86b14eSAlexander Kabaev       template<typename _InputIterator>
79300db7afdSDavid E. O'Brien         void
assign(_InputIterator __first,_InputIterator __last)79400db7afdSDavid E. O'Brien         assign(_InputIterator __first, _InputIterator __last)
79500db7afdSDavid E. O'Brien         {
796f8a1b7d9SAlexander Kabaev 	  typedef typename std::__is_integer<_InputIterator>::__type _Integral;
79700db7afdSDavid E. O'Brien 	  _M_assign_dispatch(__first, __last, _Integral());
79800db7afdSDavid E. O'Brien 	}
79900db7afdSDavid E. O'Brien 
8001b86b14eSAlexander Kabaev       /// Get a copy of the memory allocation object.
8011b86b14eSAlexander Kabaev       allocator_type
get_allocator()802ffeaf689SAlexander Kabaev       get_allocator() const
803ffeaf689SAlexander Kabaev       { return _Base::get_allocator(); }
80400db7afdSDavid E. O'Brien 
8051b86b14eSAlexander Kabaev       // iterators
8061b86b14eSAlexander Kabaev       /**
8071b86b14eSAlexander Kabaev        *  Returns a read/write iterator that points to the first element in the
8081b86b14eSAlexander Kabaev        *  %deque.  Iteration is done in ordinary element order.
8091b86b14eSAlexander Kabaev        */
8101b86b14eSAlexander Kabaev       iterator
begin()811ffeaf689SAlexander Kabaev       begin()
812ffeaf689SAlexander Kabaev       { return this->_M_impl._M_start; }
81300db7afdSDavid E. O'Brien 
8141b86b14eSAlexander Kabaev       /**
815ffeaf689SAlexander Kabaev        *  Returns a read-only (constant) iterator that points to the first
816ffeaf689SAlexander Kabaev        *  element in the %deque.  Iteration is done in ordinary element order.
8171b86b14eSAlexander Kabaev        */
8181b86b14eSAlexander Kabaev       const_iterator
begin()819ffeaf689SAlexander Kabaev       begin() const
820ffeaf689SAlexander Kabaev       { return this->_M_impl._M_start; }
8211b86b14eSAlexander Kabaev 
8221b86b14eSAlexander Kabaev       /**
823f8a1b7d9SAlexander Kabaev        *  Returns a read/write iterator that points one past the last
824f8a1b7d9SAlexander Kabaev        *  element in the %deque.  Iteration is done in ordinary
825f8a1b7d9SAlexander Kabaev        *  element order.
8261b86b14eSAlexander Kabaev        */
8271b86b14eSAlexander Kabaev       iterator
end()828ffeaf689SAlexander Kabaev       end()
829ffeaf689SAlexander Kabaev       { return this->_M_impl._M_finish; }
8301b86b14eSAlexander Kabaev 
8311b86b14eSAlexander Kabaev       /**
832f8a1b7d9SAlexander Kabaev        *  Returns a read-only (constant) iterator that points one past
833f8a1b7d9SAlexander Kabaev        *  the last element in the %deque.  Iteration is done in
834f8a1b7d9SAlexander Kabaev        *  ordinary element order.
8351b86b14eSAlexander Kabaev        */
8361b86b14eSAlexander Kabaev       const_iterator
end()837ffeaf689SAlexander Kabaev       end() const
838ffeaf689SAlexander Kabaev       { return this->_M_impl._M_finish; }
8391b86b14eSAlexander Kabaev 
8401b86b14eSAlexander Kabaev       /**
841f8a1b7d9SAlexander Kabaev        *  Returns a read/write reverse iterator that points to the
842f8a1b7d9SAlexander Kabaev        *  last element in the %deque.  Iteration is done in reverse
843f8a1b7d9SAlexander Kabaev        *  element order.
8441b86b14eSAlexander Kabaev        */
8451b86b14eSAlexander Kabaev       reverse_iterator
rbegin()846ffeaf689SAlexander Kabaev       rbegin()
847ffeaf689SAlexander Kabaev       { return reverse_iterator(this->_M_impl._M_finish); }
8481b86b14eSAlexander Kabaev 
8491b86b14eSAlexander Kabaev       /**
850f8a1b7d9SAlexander Kabaev        *  Returns a read-only (constant) reverse iterator that points
851f8a1b7d9SAlexander Kabaev        *  to the last element in the %deque.  Iteration is done in
852f8a1b7d9SAlexander Kabaev        *  reverse element order.
8531b86b14eSAlexander Kabaev        */
8541b86b14eSAlexander Kabaev       const_reverse_iterator
rbegin()855ffeaf689SAlexander Kabaev       rbegin() const
856ffeaf689SAlexander Kabaev       { return const_reverse_iterator(this->_M_impl._M_finish); }
8571b86b14eSAlexander Kabaev 
8581b86b14eSAlexander Kabaev       /**
859f8a1b7d9SAlexander Kabaev        *  Returns a read/write reverse iterator that points to one
860f8a1b7d9SAlexander Kabaev        *  before the first element in the %deque.  Iteration is done
861f8a1b7d9SAlexander Kabaev        *  in reverse element order.
8621b86b14eSAlexander Kabaev        */
8631b86b14eSAlexander Kabaev       reverse_iterator
rend()864f8a1b7d9SAlexander Kabaev       rend()
865f8a1b7d9SAlexander Kabaev       { return reverse_iterator(this->_M_impl._M_start); }
8661b86b14eSAlexander Kabaev 
8671b86b14eSAlexander Kabaev       /**
868f8a1b7d9SAlexander Kabaev        *  Returns a read-only (constant) reverse iterator that points
869f8a1b7d9SAlexander Kabaev        *  to one before the first element in the %deque.  Iteration is
870f8a1b7d9SAlexander Kabaev        *  done in reverse element order.
8711b86b14eSAlexander Kabaev        */
8721b86b14eSAlexander Kabaev       const_reverse_iterator
rend()873ffeaf689SAlexander Kabaev       rend() const
874ffeaf689SAlexander Kabaev       { return const_reverse_iterator(this->_M_impl._M_start); }
8751b86b14eSAlexander Kabaev 
8761b86b14eSAlexander Kabaev       // [23.2.1.2] capacity
8771b86b14eSAlexander Kabaev       /**  Returns the number of elements in the %deque.  */
8781b86b14eSAlexander Kabaev       size_type
size()879ffeaf689SAlexander Kabaev       size() const
880ffeaf689SAlexander Kabaev       { return this->_M_impl._M_finish - this->_M_impl._M_start; }
8811b86b14eSAlexander Kabaev 
8821b86b14eSAlexander Kabaev       /**  Returns the size() of the largest possible %deque.  */
8831b86b14eSAlexander Kabaev       size_type
max_size()884ffeaf689SAlexander Kabaev       max_size() const
885f8a1b7d9SAlexander Kabaev       { return _M_get_Tp_allocator().max_size(); }
8861b86b14eSAlexander Kabaev 
8871b86b14eSAlexander Kabaev       /**
8881b86b14eSAlexander Kabaev        *  @brief  Resizes the %deque to the specified number of elements.
8891b86b14eSAlexander Kabaev        *  @param  new_size  Number of elements the %deque should contain.
8901b86b14eSAlexander Kabaev        *  @param  x  Data with which new elements should be populated.
8911b86b14eSAlexander Kabaev        *
892f8a1b7d9SAlexander Kabaev        *  This function will %resize the %deque to the specified
893f8a1b7d9SAlexander Kabaev        *  number of elements.  If the number is smaller than the
894f8a1b7d9SAlexander Kabaev        *  %deque's current size the %deque is truncated, otherwise the
895f8a1b7d9SAlexander Kabaev        *  %deque is extended and new elements are populated with given
896f8a1b7d9SAlexander Kabaev        *  data.
8971b86b14eSAlexander Kabaev        */
89800db7afdSDavid E. O'Brien       void
899f8a1b7d9SAlexander Kabaev       resize(size_type __new_size, value_type __x = value_type())
90000db7afdSDavid E. O'Brien       {
9011b86b14eSAlexander Kabaev 	const size_type __len = size();
9021b86b14eSAlexander Kabaev 	if (__new_size < __len)
903f8a1b7d9SAlexander Kabaev 	  _M_erase_at_end(this->_M_impl._M_start + difference_type(__new_size));
90400db7afdSDavid E. O'Brien 	else
905ffeaf689SAlexander Kabaev 	  insert(this->_M_impl._M_finish, __new_size - __len, __x);
90600db7afdSDavid E. O'Brien       }
90700db7afdSDavid E. O'Brien 
9081b86b14eSAlexander Kabaev       /**
909f8a1b7d9SAlexander Kabaev        *  Returns true if the %deque is empty.  (Thus begin() would
910f8a1b7d9SAlexander Kabaev        *  equal end().)
9111b86b14eSAlexander Kabaev        */
912ffeaf689SAlexander Kabaev       bool
empty()913ffeaf689SAlexander Kabaev       empty() const
914ffeaf689SAlexander Kabaev       { return this->_M_impl._M_finish == this->_M_impl._M_start; }
9151b86b14eSAlexander Kabaev 
9161b86b14eSAlexander Kabaev       // element access
9171b86b14eSAlexander Kabaev       /**
9181b86b14eSAlexander Kabaev        *  @brief Subscript access to the data contained in the %deque.
919f8a1b7d9SAlexander Kabaev        *  @param n The index of the element for which data should be
920f8a1b7d9SAlexander Kabaev        *  accessed.
9211b86b14eSAlexander Kabaev        *  @return  Read/write reference to data.
9221b86b14eSAlexander Kabaev        *
9231b86b14eSAlexander Kabaev        *  This operator allows for easy, array-style, data access.
924f8a1b7d9SAlexander Kabaev        *  Note that data access with this operator is unchecked and
925f8a1b7d9SAlexander Kabaev        *  out_of_range lookups are not defined. (For checked lookups
926f8a1b7d9SAlexander Kabaev        *  see at().)
9271b86b14eSAlexander Kabaev        */
9281b86b14eSAlexander Kabaev       reference
929ffeaf689SAlexander Kabaev       operator[](size_type __n)
930ffeaf689SAlexander Kabaev       { return this->_M_impl._M_start[difference_type(__n)]; }
9311b86b14eSAlexander Kabaev 
9321b86b14eSAlexander Kabaev       /**
9331b86b14eSAlexander Kabaev        *  @brief Subscript access to the data contained in the %deque.
934f8a1b7d9SAlexander Kabaev        *  @param n The index of the element for which data should be
935f8a1b7d9SAlexander Kabaev        *  accessed.
9361b86b14eSAlexander Kabaev        *  @return  Read-only (constant) reference to data.
9371b86b14eSAlexander Kabaev        *
9381b86b14eSAlexander Kabaev        *  This operator allows for easy, array-style, data access.
939f8a1b7d9SAlexander Kabaev        *  Note that data access with this operator is unchecked and
940f8a1b7d9SAlexander Kabaev        *  out_of_range lookups are not defined. (For checked lookups
941f8a1b7d9SAlexander Kabaev        *  see at().)
9421b86b14eSAlexander Kabaev        */
9431b86b14eSAlexander Kabaev       const_reference
944ffeaf689SAlexander Kabaev       operator[](size_type __n) const
945ffeaf689SAlexander Kabaev       { return this->_M_impl._M_start[difference_type(__n)]; }
9461b86b14eSAlexander Kabaev 
9471b86b14eSAlexander Kabaev     protected:
9481b86b14eSAlexander Kabaev       /// @if maint Safety check used only from at().  @endif
9491b86b14eSAlexander Kabaev       void
_M_range_check(size_type __n)9501b86b14eSAlexander Kabaev       _M_range_check(size_type __n) const
95100db7afdSDavid E. O'Brien       {
9521b86b14eSAlexander Kabaev 	if (__n >= this->size())
953ffeaf689SAlexander Kabaev 	  __throw_out_of_range(__N("deque::_M_range_check"));
95400db7afdSDavid E. O'Brien       }
95500db7afdSDavid E. O'Brien 
9561b86b14eSAlexander Kabaev     public:
9571b86b14eSAlexander Kabaev       /**
9581b86b14eSAlexander Kabaev        *  @brief  Provides access to the data contained in the %deque.
959f8a1b7d9SAlexander Kabaev        *  @param n The index of the element for which data should be
960f8a1b7d9SAlexander Kabaev        *  accessed.
9611b86b14eSAlexander Kabaev        *  @return  Read/write reference to data.
9621b86b14eSAlexander Kabaev        *  @throw  std::out_of_range  If @a n is an invalid index.
9631b86b14eSAlexander Kabaev        *
964f8a1b7d9SAlexander Kabaev        *  This function provides for safer data access.  The parameter
965f8a1b7d9SAlexander Kabaev        *  is first checked that it is in the range of the deque.  The
966f8a1b7d9SAlexander Kabaev        *  function throws out_of_range if the check fails.
9671b86b14eSAlexander Kabaev        */
9681b86b14eSAlexander Kabaev       reference
at(size_type __n)969ffeaf689SAlexander Kabaev       at(size_type __n)
970f8a1b7d9SAlexander Kabaev       {
971f8a1b7d9SAlexander Kabaev 	_M_range_check(__n);
972f8a1b7d9SAlexander Kabaev 	return (*this)[__n];
973f8a1b7d9SAlexander Kabaev       }
9741b86b14eSAlexander Kabaev 
9751b86b14eSAlexander Kabaev       /**
9761b86b14eSAlexander Kabaev        *  @brief  Provides access to the data contained in the %deque.
977f8a1b7d9SAlexander Kabaev        *  @param n The index of the element for which data should be
978f8a1b7d9SAlexander Kabaev        *  accessed.
9791b86b14eSAlexander Kabaev        *  @return  Read-only (constant) reference to data.
9801b86b14eSAlexander Kabaev        *  @throw  std::out_of_range  If @a n is an invalid index.
9811b86b14eSAlexander Kabaev        *
9821b86b14eSAlexander Kabaev        *  This function provides for safer data access.  The parameter is first
9831b86b14eSAlexander Kabaev        *  checked that it is in the range of the deque.  The function throws
9841b86b14eSAlexander Kabaev        *  out_of_range if the check fails.
9851b86b14eSAlexander Kabaev        */
9861b86b14eSAlexander Kabaev       const_reference
at(size_type __n)987ffeaf689SAlexander Kabaev       at(size_type __n) const
988ffeaf689SAlexander Kabaev       {
989ffeaf689SAlexander Kabaev 	_M_range_check(__n);
990ffeaf689SAlexander Kabaev 	return (*this)[__n];
991ffeaf689SAlexander Kabaev       }
9921b86b14eSAlexander Kabaev 
9931b86b14eSAlexander Kabaev       /**
994f8a1b7d9SAlexander Kabaev        *  Returns a read/write reference to the data at the first
995f8a1b7d9SAlexander Kabaev        *  element of the %deque.
9961b86b14eSAlexander Kabaev        */
9971b86b14eSAlexander Kabaev       reference
front()998ffeaf689SAlexander Kabaev       front()
999f8a1b7d9SAlexander Kabaev       { return *begin(); }
10001b86b14eSAlexander Kabaev 
10011b86b14eSAlexander Kabaev       /**
10021b86b14eSAlexander Kabaev        *  Returns a read-only (constant) reference to the data at the first
10031b86b14eSAlexander Kabaev        *  element of the %deque.
10041b86b14eSAlexander Kabaev        */
10051b86b14eSAlexander Kabaev       const_reference
front()1006ffeaf689SAlexander Kabaev       front() const
1007f8a1b7d9SAlexander Kabaev       { return *begin(); }
10081b86b14eSAlexander Kabaev 
10091b86b14eSAlexander Kabaev       /**
10101b86b14eSAlexander Kabaev        *  Returns a read/write reference to the data at the last element of the
10111b86b14eSAlexander Kabaev        *  %deque.
10121b86b14eSAlexander Kabaev        */
10131b86b14eSAlexander Kabaev       reference
back()10141b86b14eSAlexander Kabaev       back()
101500db7afdSDavid E. O'Brien       {
1016f8a1b7d9SAlexander Kabaev 	iterator __tmp = end();
10171b86b14eSAlexander Kabaev 	--__tmp;
10181b86b14eSAlexander Kabaev 	return *__tmp;
101900db7afdSDavid E. O'Brien       }
102000db7afdSDavid E. O'Brien 
10211b86b14eSAlexander Kabaev       /**
10221b86b14eSAlexander Kabaev        *  Returns a read-only (constant) reference to the data at the last
10231b86b14eSAlexander Kabaev        *  element of the %deque.
10241b86b14eSAlexander Kabaev        */
10251b86b14eSAlexander Kabaev       const_reference
back()10261b86b14eSAlexander Kabaev       back() const
10271b86b14eSAlexander Kabaev       {
1028f8a1b7d9SAlexander Kabaev 	const_iterator __tmp = end();
10291b86b14eSAlexander Kabaev 	--__tmp;
10301b86b14eSAlexander Kabaev 	return *__tmp;
10311b86b14eSAlexander Kabaev       }
10321b86b14eSAlexander Kabaev 
10331b86b14eSAlexander Kabaev       // [23.2.1.2] modifiers
10341b86b14eSAlexander Kabaev       /**
10351b86b14eSAlexander Kabaev        *  @brief  Add data to the front of the %deque.
10361b86b14eSAlexander Kabaev        *  @param  x  Data to be added.
10371b86b14eSAlexander Kabaev        *
1038f8a1b7d9SAlexander Kabaev        *  This is a typical stack operation.  The function creates an
1039f8a1b7d9SAlexander Kabaev        *  element at the front of the %deque and assigns the given
1040f8a1b7d9SAlexander Kabaev        *  data to it.  Due to the nature of a %deque this operation
1041f8a1b7d9SAlexander Kabaev        *  can be done in constant time.
10421b86b14eSAlexander Kabaev        */
104300db7afdSDavid E. O'Brien       void
push_front(const value_type & __x)10441b86b14eSAlexander Kabaev       push_front(const value_type& __x)
104500db7afdSDavid E. O'Brien       {
1046ffeaf689SAlexander Kabaev 	if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_first)
1047ffeaf689SAlexander Kabaev 	  {
1048f8a1b7d9SAlexander Kabaev 	    this->_M_impl.construct(this->_M_impl._M_start._M_cur - 1, __x);
1049ffeaf689SAlexander Kabaev 	    --this->_M_impl._M_start._M_cur;
105000db7afdSDavid E. O'Brien 	  }
105100db7afdSDavid E. O'Brien 	else
10521b86b14eSAlexander Kabaev 	  _M_push_front_aux(__x);
105300db7afdSDavid E. O'Brien       }
105400db7afdSDavid E. O'Brien 
10551b86b14eSAlexander Kabaev       /**
10561b86b14eSAlexander Kabaev        *  @brief  Add data to the end of the %deque.
10571b86b14eSAlexander Kabaev        *  @param  x  Data to be added.
10581b86b14eSAlexander Kabaev        *
1059f8a1b7d9SAlexander Kabaev        *  This is a typical stack operation.  The function creates an
1060f8a1b7d9SAlexander Kabaev        *  element at the end of the %deque and assigns the given data
1061f8a1b7d9SAlexander Kabaev        *  to it.  Due to the nature of a %deque this operation can be
1062f8a1b7d9SAlexander Kabaev        *  done in constant time.
10631b86b14eSAlexander Kabaev        */
106400db7afdSDavid E. O'Brien       void
push_back(const value_type & __x)10651b86b14eSAlexander Kabaev       push_back(const value_type& __x)
106600db7afdSDavid E. O'Brien       {
1067f8a1b7d9SAlexander Kabaev 	if (this->_M_impl._M_finish._M_cur
1068f8a1b7d9SAlexander Kabaev 	    != this->_M_impl._M_finish._M_last - 1)
1069ffeaf689SAlexander Kabaev 	  {
1070f8a1b7d9SAlexander Kabaev 	    this->_M_impl.construct(this->_M_impl._M_finish._M_cur, __x);
1071ffeaf689SAlexander Kabaev 	    ++this->_M_impl._M_finish._M_cur;
107200db7afdSDavid E. O'Brien 	  }
107300db7afdSDavid E. O'Brien 	else
10741b86b14eSAlexander Kabaev 	  _M_push_back_aux(__x);
107500db7afdSDavid E. O'Brien       }
107600db7afdSDavid E. O'Brien 
10771b86b14eSAlexander Kabaev       /**
10781b86b14eSAlexander Kabaev        *  @brief  Removes first element.
10791b86b14eSAlexander Kabaev        *
10801b86b14eSAlexander Kabaev        *  This is a typical stack operation.  It shrinks the %deque by one.
10811b86b14eSAlexander Kabaev        *
10821b86b14eSAlexander Kabaev        *  Note that no data is returned, and if the first element's data is
10831b86b14eSAlexander Kabaev        *  needed, it should be retrieved before pop_front() is called.
10841b86b14eSAlexander Kabaev        */
108500db7afdSDavid E. O'Brien       void
pop_front()108600db7afdSDavid E. O'Brien       pop_front()
108700db7afdSDavid E. O'Brien       {
1088f8a1b7d9SAlexander Kabaev 	if (this->_M_impl._M_start._M_cur
1089f8a1b7d9SAlexander Kabaev 	    != this->_M_impl._M_start._M_last - 1)
1090ffeaf689SAlexander Kabaev 	  {
1091f8a1b7d9SAlexander Kabaev 	    this->_M_impl.destroy(this->_M_impl._M_start._M_cur);
1092ffeaf689SAlexander Kabaev 	    ++this->_M_impl._M_start._M_cur;
109300db7afdSDavid E. O'Brien 	  }
109400db7afdSDavid E. O'Brien 	else
109500db7afdSDavid E. O'Brien 	  _M_pop_front_aux();
109600db7afdSDavid E. O'Brien       }
109700db7afdSDavid E. O'Brien 
10981b86b14eSAlexander Kabaev       /**
10991b86b14eSAlexander Kabaev        *  @brief  Removes last element.
11001b86b14eSAlexander Kabaev        *
11011b86b14eSAlexander Kabaev        *  This is a typical stack operation.  It shrinks the %deque by one.
11021b86b14eSAlexander Kabaev        *
11031b86b14eSAlexander Kabaev        *  Note that no data is returned, and if the last element's data is
11041b86b14eSAlexander Kabaev        *  needed, it should be retrieved before pop_back() is called.
11051b86b14eSAlexander Kabaev        */
11061b86b14eSAlexander Kabaev       void
pop_back()11071b86b14eSAlexander Kabaev       pop_back()
110800db7afdSDavid E. O'Brien       {
1109f8a1b7d9SAlexander Kabaev 	if (this->_M_impl._M_finish._M_cur
1110f8a1b7d9SAlexander Kabaev 	    != this->_M_impl._M_finish._M_first)
1111ffeaf689SAlexander Kabaev 	  {
1112ffeaf689SAlexander Kabaev 	    --this->_M_impl._M_finish._M_cur;
1113f8a1b7d9SAlexander Kabaev 	    this->_M_impl.destroy(this->_M_impl._M_finish._M_cur);
111400db7afdSDavid E. O'Brien 	  }
11151b86b14eSAlexander Kabaev 	else
11161b86b14eSAlexander Kabaev 	  _M_pop_back_aux();
111700db7afdSDavid E. O'Brien       }
111800db7afdSDavid E. O'Brien 
11191b86b14eSAlexander Kabaev       /**
11201b86b14eSAlexander Kabaev        *  @brief  Inserts given value into %deque before specified iterator.
11211b86b14eSAlexander Kabaev        *  @param  position  An iterator into the %deque.
11221b86b14eSAlexander Kabaev        *  @param  x  Data to be inserted.
11231b86b14eSAlexander Kabaev        *  @return  An iterator that points to the inserted data.
11241b86b14eSAlexander Kabaev        *
1125ffeaf689SAlexander Kabaev        *  This function will insert a copy of the given value before the
1126ffeaf689SAlexander Kabaev        *  specified location.
11271b86b14eSAlexander Kabaev        */
11281b86b14eSAlexander Kabaev       iterator
1129f8a1b7d9SAlexander Kabaev       insert(iterator __position, const value_type& __x);
11301b86b14eSAlexander Kabaev 
11311b86b14eSAlexander Kabaev       /**
11321b86b14eSAlexander Kabaev        *  @brief  Inserts a number of copies of given data into the %deque.
11331b86b14eSAlexander Kabaev        *  @param  position  An iterator into the %deque.
11341b86b14eSAlexander Kabaev        *  @param  n  Number of elements to be inserted.
11351b86b14eSAlexander Kabaev        *  @param  x  Data to be inserted.
11361b86b14eSAlexander Kabaev        *
1137ffeaf689SAlexander Kabaev        *  This function will insert a specified number of copies of the given
1138ffeaf689SAlexander Kabaev        *  data before the location specified by @a position.
11391b86b14eSAlexander Kabaev        */
114000db7afdSDavid E. O'Brien       void
insert(iterator __position,size_type __n,const value_type & __x)11411b86b14eSAlexander Kabaev       insert(iterator __position, size_type __n, const value_type& __x)
11421b86b14eSAlexander Kabaev       { _M_fill_insert(__position, __n, __x); }
114300db7afdSDavid E. O'Brien 
11441b86b14eSAlexander Kabaev       /**
11451b86b14eSAlexander Kabaev        *  @brief  Inserts a range into the %deque.
1146ffeaf689SAlexander Kabaev        *  @param  position  An iterator into the %deque.
11471b86b14eSAlexander Kabaev        *  @param  first  An input iterator.
11481b86b14eSAlexander Kabaev        *  @param  last   An input iterator.
11491b86b14eSAlexander Kabaev        *
1150f8a1b7d9SAlexander Kabaev        *  This function will insert copies of the data in the range
1151f8a1b7d9SAlexander Kabaev        *  [first,last) into the %deque before the location specified
1152f8a1b7d9SAlexander Kabaev        *  by @a pos.  This is known as "range insert."
11531b86b14eSAlexander Kabaev        */
11541b86b14eSAlexander Kabaev       template<typename _InputIterator>
115500db7afdSDavid E. O'Brien         void
insert(iterator __position,_InputIterator __first,_InputIterator __last)1156ffeaf689SAlexander Kabaev         insert(iterator __position, _InputIterator __first,
1157ffeaf689SAlexander Kabaev 	       _InputIterator __last)
115800db7afdSDavid E. O'Brien         {
11591b86b14eSAlexander Kabaev 	  // Check whether it's an integral type.  If so, it's not an iterator.
1160f8a1b7d9SAlexander Kabaev 	  typedef typename std::__is_integer<_InputIterator>::__type _Integral;
1161ffeaf689SAlexander Kabaev 	  _M_insert_dispatch(__position, __first, __last, _Integral());
116200db7afdSDavid E. O'Brien 	}
116300db7afdSDavid E. O'Brien 
11641b86b14eSAlexander Kabaev       /**
11651b86b14eSAlexander Kabaev        *  @brief  Remove element at given position.
11661b86b14eSAlexander Kabaev        *  @param  position  Iterator pointing to element to be erased.
11671b86b14eSAlexander Kabaev        *  @return  An iterator pointing to the next element (or end()).
11681b86b14eSAlexander Kabaev        *
11691b86b14eSAlexander Kabaev        *  This function will erase the element at the given position and thus
11701b86b14eSAlexander Kabaev        *  shorten the %deque by one.
11711b86b14eSAlexander Kabaev        *
11721b86b14eSAlexander Kabaev        *  The user is cautioned that
1173ffeaf689SAlexander Kabaev        *  this function only erases the element, and that if the element is
1174ffeaf689SAlexander Kabaev        *  itself a pointer, the pointed-to memory is not touched in any way.
1175ffeaf689SAlexander Kabaev        *  Managing the pointer is the user's responsibilty.
11761b86b14eSAlexander Kabaev        */
11771b86b14eSAlexander Kabaev       iterator
11781b86b14eSAlexander Kabaev       erase(iterator __position);
11791b86b14eSAlexander Kabaev 
11801b86b14eSAlexander Kabaev       /**
11811b86b14eSAlexander Kabaev        *  @brief  Remove a range of elements.
11821b86b14eSAlexander Kabaev        *  @param  first  Iterator pointing to the first element to be erased.
11831b86b14eSAlexander Kabaev        *  @param  last  Iterator pointing to one past the last element to be
11841b86b14eSAlexander Kabaev        *                erased.
11851b86b14eSAlexander Kabaev        *  @return  An iterator pointing to the element pointed to by @a last
11861b86b14eSAlexander Kabaev        *           prior to erasing (or end()).
11871b86b14eSAlexander Kabaev        *
11881b86b14eSAlexander Kabaev        *  This function will erase the elements in the range [first,last) and
11891b86b14eSAlexander Kabaev        *  shorten the %deque accordingly.
11901b86b14eSAlexander Kabaev        *
11911b86b14eSAlexander Kabaev        *  The user is cautioned that
11921b86b14eSAlexander Kabaev        *  this function only erases the elements, and that if the elements
11931b86b14eSAlexander Kabaev        *  themselves are pointers, the pointed-to memory is not touched in any
11941b86b14eSAlexander Kabaev        *  way.  Managing the pointer is the user's responsibilty.
11951b86b14eSAlexander Kabaev        */
11961b86b14eSAlexander Kabaev       iterator
11971b86b14eSAlexander Kabaev       erase(iterator __first, iterator __last);
11981b86b14eSAlexander Kabaev 
11991b86b14eSAlexander Kabaev       /**
12001b86b14eSAlexander Kabaev        *  @brief  Swaps data with another %deque.
12011b86b14eSAlexander Kabaev        *  @param  x  A %deque of the same element and allocator types.
12021b86b14eSAlexander Kabaev        *
12031b86b14eSAlexander Kabaev        *  This exchanges the elements between two deques in constant time.
12041b86b14eSAlexander Kabaev        *  (Four pointers, so it should be quite fast.)
12051b86b14eSAlexander Kabaev        *  Note that the global std::swap() function is specialized such that
12061b86b14eSAlexander Kabaev        *  std::swap(d1,d2) will feed to this function.
12071b86b14eSAlexander Kabaev        */
120800db7afdSDavid E. O'Brien       void
swap(deque & __x)12091b86b14eSAlexander Kabaev       swap(deque& __x)
121000db7afdSDavid E. O'Brien       {
1211ffeaf689SAlexander Kabaev 	std::swap(this->_M_impl._M_start, __x._M_impl._M_start);
1212ffeaf689SAlexander Kabaev 	std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish);
1213ffeaf689SAlexander Kabaev 	std::swap(this->_M_impl._M_map, __x._M_impl._M_map);
1214ffeaf689SAlexander Kabaev 	std::swap(this->_M_impl._M_map_size, __x._M_impl._M_map_size);
1215f8a1b7d9SAlexander Kabaev 
1216f8a1b7d9SAlexander Kabaev 	// _GLIBCXX_RESOLVE_LIB_DEFECTS
1217f8a1b7d9SAlexander Kabaev 	// 431. Swapping containers with unequal allocators.
1218f8a1b7d9SAlexander Kabaev 	std::__alloc_swap<_Tp_alloc_type>::_S_do_it(_M_get_Tp_allocator(),
1219f8a1b7d9SAlexander Kabaev 						    __x._M_get_Tp_allocator());
122000db7afdSDavid E. O'Brien       }
122100db7afdSDavid E. O'Brien 
122200db7afdSDavid E. O'Brien       /**
12231b86b14eSAlexander Kabaev        *  Erases all the elements.  Note that this function only erases the
12241b86b14eSAlexander Kabaev        *  elements, and that if the elements themselves are pointers, the
12251b86b14eSAlexander Kabaev        *  pointed-to memory is not touched in any way.  Managing the pointer is
12261b86b14eSAlexander Kabaev        *  the user's responsibilty.
122700db7afdSDavid E. O'Brien        */
1228f8a1b7d9SAlexander Kabaev       void
clear()1229f8a1b7d9SAlexander Kabaev       clear()
1230f8a1b7d9SAlexander Kabaev       { _M_erase_at_end(begin()); }
12311b86b14eSAlexander Kabaev 
12321b86b14eSAlexander Kabaev     protected:
12331b86b14eSAlexander Kabaev       // Internal constructor functions follow.
12341b86b14eSAlexander Kabaev 
12351b86b14eSAlexander Kabaev       // called by the range constructor to implement [23.1.1]/9
12361b86b14eSAlexander Kabaev       template<typename _Integer>
12371b86b14eSAlexander Kabaev         void
_M_initialize_dispatch(_Integer __n,_Integer __x,__true_type)12381b86b14eSAlexander Kabaev         _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type)
123900db7afdSDavid E. O'Brien         {
12401b86b14eSAlexander Kabaev 	  _M_initialize_map(__n);
12411b86b14eSAlexander Kabaev 	  _M_fill_initialize(__x);
124200db7afdSDavid E. O'Brien 	}
124300db7afdSDavid E. O'Brien 
12441b86b14eSAlexander Kabaev       // called by the range constructor to implement [23.1.1]/9
1245ffeaf689SAlexander Kabaev       template<typename _InputIterator>
12461b86b14eSAlexander Kabaev         void
_M_initialize_dispatch(_InputIterator __first,_InputIterator __last,__false_type)1247ffeaf689SAlexander Kabaev         _M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
12481b86b14eSAlexander Kabaev 			       __false_type)
12491b86b14eSAlexander Kabaev         {
1250f8a1b7d9SAlexander Kabaev 	  typedef typename std::iterator_traits<_InputIterator>::
1251f8a1b7d9SAlexander Kabaev 	    iterator_category _IterCategory;
12521b86b14eSAlexander Kabaev 	  _M_range_initialize(__first, __last, _IterCategory());
12531b86b14eSAlexander Kabaev 	}
12541b86b14eSAlexander Kabaev 
12551b86b14eSAlexander Kabaev       // called by the second initialize_dispatch above
12561b86b14eSAlexander Kabaev       //@{
12571b86b14eSAlexander Kabaev       /**
125800db7afdSDavid E. O'Brien        *  @if maint
125900db7afdSDavid E. O'Brien        *  @brief Fills the deque with whatever is in [first,last).
126000db7afdSDavid E. O'Brien        *  @param  first  An input iterator.
126100db7afdSDavid E. O'Brien        *  @param  last  An input iterator.
126200db7afdSDavid E. O'Brien        *  @return   Nothing.
126300db7afdSDavid E. O'Brien        *
126400db7afdSDavid E. O'Brien        *  If the iterators are actually forward iterators (or better), then the
126500db7afdSDavid E. O'Brien        *  memory layout can be done all at once.  Else we move forward using
126600db7afdSDavid E. O'Brien        *  push_back on each value from the iterator.
126700db7afdSDavid E. O'Brien        *  @endif
126800db7afdSDavid E. O'Brien        */
12691b86b14eSAlexander Kabaev       template<typename _InputIterator>
12701b86b14eSAlexander Kabaev         void
12711b86b14eSAlexander Kabaev         _M_range_initialize(_InputIterator __first, _InputIterator __last,
1272f8a1b7d9SAlexander Kabaev 			    std::input_iterator_tag);
12731b86b14eSAlexander Kabaev 
12741b86b14eSAlexander Kabaev       // called by the second initialize_dispatch above
12751b86b14eSAlexander Kabaev       template<typename _ForwardIterator>
12761b86b14eSAlexander Kabaev         void
12771b86b14eSAlexander Kabaev         _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
1278f8a1b7d9SAlexander Kabaev 			    std::forward_iterator_tag);
12791b86b14eSAlexander Kabaev       //@}
12801b86b14eSAlexander Kabaev 
12811b86b14eSAlexander Kabaev       /**
12821b86b14eSAlexander Kabaev        *  @if maint
12831b86b14eSAlexander Kabaev        *  @brief Fills the %deque with copies of value.
12841b86b14eSAlexander Kabaev        *  @param  value  Initial value.
12851b86b14eSAlexander Kabaev        *  @return   Nothing.
1286f8a1b7d9SAlexander Kabaev        *  @pre _M_start and _M_finish have already been initialized,
1287f8a1b7d9SAlexander Kabaev        *  but none of the %deque's elements have yet been constructed.
12881b86b14eSAlexander Kabaev        *
12891b86b14eSAlexander Kabaev        *  This function is called only when the user provides an explicit size
12901b86b14eSAlexander Kabaev        *  (with or without an explicit exemplar value).
12911b86b14eSAlexander Kabaev        *  @endif
12921b86b14eSAlexander Kabaev        */
12931b86b14eSAlexander Kabaev       void
12941b86b14eSAlexander Kabaev       _M_fill_initialize(const value_type& __value);
12951b86b14eSAlexander Kabaev 
12961b86b14eSAlexander Kabaev       // Internal assign functions follow.  The *_aux functions do the actual
12971b86b14eSAlexander Kabaev       // assignment work for the range versions.
12981b86b14eSAlexander Kabaev 
12991b86b14eSAlexander Kabaev       // called by the range assign to implement [23.1.1]/9
13001b86b14eSAlexander Kabaev       template<typename _Integer>
13011b86b14eSAlexander Kabaev         void
_M_assign_dispatch(_Integer __n,_Integer __val,__true_type)13021b86b14eSAlexander Kabaev         _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
130300db7afdSDavid E. O'Brien         {
13041b86b14eSAlexander Kabaev 	  _M_fill_assign(static_cast<size_type>(__n),
13051b86b14eSAlexander Kabaev 			 static_cast<value_type>(__val));
130600db7afdSDavid E. O'Brien 	}
130700db7afdSDavid E. O'Brien 
13081b86b14eSAlexander Kabaev       // called by the range assign to implement [23.1.1]/9
1309ffeaf689SAlexander Kabaev       template<typename _InputIterator>
13101b86b14eSAlexander Kabaev         void
_M_assign_dispatch(_InputIterator __first,_InputIterator __last,__false_type)1311ffeaf689SAlexander Kabaev         _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
1312ffeaf689SAlexander Kabaev 			   __false_type)
13131b86b14eSAlexander Kabaev         {
1314f8a1b7d9SAlexander Kabaev 	  typedef typename std::iterator_traits<_InputIterator>::
1315f8a1b7d9SAlexander Kabaev 	    iterator_category _IterCategory;
13161b86b14eSAlexander Kabaev 	  _M_assign_aux(__first, __last, _IterCategory());
13171b86b14eSAlexander Kabaev 	}
13181b86b14eSAlexander Kabaev 
13191b86b14eSAlexander Kabaev       // called by the second assign_dispatch above
13201b86b14eSAlexander Kabaev       template<typename _InputIterator>
13211b86b14eSAlexander Kabaev         void
13221b86b14eSAlexander Kabaev         _M_assign_aux(_InputIterator __first, _InputIterator __last,
1323f8a1b7d9SAlexander Kabaev 		      std::input_iterator_tag);
13241b86b14eSAlexander Kabaev 
13251b86b14eSAlexander Kabaev       // called by the second assign_dispatch above
13261b86b14eSAlexander Kabaev       template<typename _ForwardIterator>
13271b86b14eSAlexander Kabaev         void
_M_assign_aux(_ForwardIterator __first,_ForwardIterator __last,std::forward_iterator_tag)13281b86b14eSAlexander Kabaev         _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
1329f8a1b7d9SAlexander Kabaev 		      std::forward_iterator_tag)
133000db7afdSDavid E. O'Brien         {
1331ffeaf689SAlexander Kabaev 	  const size_type __len = std::distance(__first, __last);
1332ffeaf689SAlexander Kabaev 	  if (__len > size())
1333ffeaf689SAlexander Kabaev 	    {
133400db7afdSDavid E. O'Brien 	      _ForwardIterator __mid = __first;
1335ffeaf689SAlexander Kabaev 	      std::advance(__mid, size());
1336ffeaf689SAlexander Kabaev 	      std::copy(__first, __mid, begin());
13371b86b14eSAlexander Kabaev 	      insert(end(), __mid, __last);
133800db7afdSDavid E. O'Brien 	    }
13391b86b14eSAlexander Kabaev 	  else
1340f8a1b7d9SAlexander Kabaev 	    _M_erase_at_end(std::copy(__first, __last, begin()));
134100db7afdSDavid E. O'Brien 	}
134200db7afdSDavid E. O'Brien 
1343f8a1b7d9SAlexander Kabaev       // Called by assign(n,t), and the range assign when it turns out
1344f8a1b7d9SAlexander Kabaev       // to be the same thing.
134500db7afdSDavid E. O'Brien       void
_M_fill_assign(size_type __n,const value_type & __val)13461b86b14eSAlexander Kabaev       _M_fill_assign(size_type __n, const value_type& __val)
134700db7afdSDavid E. O'Brien       {
13481b86b14eSAlexander Kabaev 	if (__n > size())
13491b86b14eSAlexander Kabaev 	  {
1350ffeaf689SAlexander Kabaev 	    std::fill(begin(), end(), __val);
13511b86b14eSAlexander Kabaev 	    insert(end(), __n - size(), __val);
135200db7afdSDavid E. O'Brien 	  }
13531b86b14eSAlexander Kabaev 	else
135400db7afdSDavid E. O'Brien 	  {
1355f8a1b7d9SAlexander Kabaev 	    _M_erase_at_end(begin() + difference_type(__n));
1356ffeaf689SAlexander Kabaev 	    std::fill(begin(), end(), __val);
135700db7afdSDavid E. O'Brien 	  }
135800db7afdSDavid E. O'Brien       }
135900db7afdSDavid E. O'Brien 
13601b86b14eSAlexander Kabaev       //@{
13611b86b14eSAlexander Kabaev       /**
13621b86b14eSAlexander Kabaev        *  @if maint
13631b86b14eSAlexander Kabaev        *  @brief Helper functions for push_* and pop_*.
13641b86b14eSAlexander Kabaev        *  @endif
13651b86b14eSAlexander Kabaev        */
13661b86b14eSAlexander Kabaev       void _M_push_back_aux(const value_type&);
1367f8a1b7d9SAlexander Kabaev 
13681b86b14eSAlexander Kabaev       void _M_push_front_aux(const value_type&);
1369f8a1b7d9SAlexander Kabaev 
13701b86b14eSAlexander Kabaev       void _M_pop_back_aux();
1371f8a1b7d9SAlexander Kabaev 
13721b86b14eSAlexander Kabaev       void _M_pop_front_aux();
13731b86b14eSAlexander Kabaev       //@}
13741b86b14eSAlexander Kabaev 
13751b86b14eSAlexander Kabaev       // Internal insert functions follow.  The *_aux functions do the actual
13761b86b14eSAlexander Kabaev       // insertion work when all shortcuts fail.
13771b86b14eSAlexander Kabaev 
13781b86b14eSAlexander Kabaev       // called by the range insert to implement [23.1.1]/9
13791b86b14eSAlexander Kabaev       template<typename _Integer>
138000db7afdSDavid E. O'Brien         void
_M_insert_dispatch(iterator __pos,_Integer __n,_Integer __x,__true_type)13811b86b14eSAlexander Kabaev         _M_insert_dispatch(iterator __pos,
13821b86b14eSAlexander Kabaev 			   _Integer __n, _Integer __x, __true_type)
138300db7afdSDavid E. O'Brien         {
13841b86b14eSAlexander Kabaev 	  _M_fill_insert(__pos, static_cast<size_type>(__n),
13851b86b14eSAlexander Kabaev 			 static_cast<value_type>(__x));
138600db7afdSDavid E. O'Brien 	}
138700db7afdSDavid E. O'Brien 
13881b86b14eSAlexander Kabaev       // called by the range insert to implement [23.1.1]/9
13891b86b14eSAlexander Kabaev       template<typename _InputIterator>
139000db7afdSDavid E. O'Brien         void
_M_insert_dispatch(iterator __pos,_InputIterator __first,_InputIterator __last,__false_type)13911b86b14eSAlexander Kabaev         _M_insert_dispatch(iterator __pos,
139200db7afdSDavid E. O'Brien 			   _InputIterator __first, _InputIterator __last,
13931b86b14eSAlexander Kabaev 			   __false_type)
139400db7afdSDavid E. O'Brien         {
1395f8a1b7d9SAlexander Kabaev 	  typedef typename std::iterator_traits<_InputIterator>::
1396f8a1b7d9SAlexander Kabaev 	    iterator_category _IterCategory;
13971b86b14eSAlexander Kabaev           _M_range_insert_aux(__pos, __first, __last, _IterCategory());
139800db7afdSDavid E. O'Brien 	}
139900db7afdSDavid E. O'Brien 
14001b86b14eSAlexander Kabaev       // called by the second insert_dispatch above
14011b86b14eSAlexander Kabaev       template<typename _InputIterator>
140200db7afdSDavid E. O'Brien         void
14031b86b14eSAlexander Kabaev         _M_range_insert_aux(iterator __pos, _InputIterator __first,
1404f8a1b7d9SAlexander Kabaev 			    _InputIterator __last, std::input_iterator_tag);
14051b86b14eSAlexander Kabaev 
14061b86b14eSAlexander Kabaev       // called by the second insert_dispatch above
14071b86b14eSAlexander Kabaev       template<typename _ForwardIterator>
14081b86b14eSAlexander Kabaev         void
14091b86b14eSAlexander Kabaev         _M_range_insert_aux(iterator __pos, _ForwardIterator __first,
1410f8a1b7d9SAlexander Kabaev 			    _ForwardIterator __last, std::forward_iterator_tag);
14111b86b14eSAlexander Kabaev 
14121b86b14eSAlexander Kabaev       // Called by insert(p,n,x), and the range insert when it turns out to be
1413ffeaf689SAlexander Kabaev       // the same thing.  Can use fill functions in optimal situations,
1414ffeaf689SAlexander Kabaev       // otherwise passes off to insert_aux(p,n,x).
14151b86b14eSAlexander Kabaev       void
14161b86b14eSAlexander Kabaev       _M_fill_insert(iterator __pos, size_type __n, const value_type& __x);
14171b86b14eSAlexander Kabaev 
14181b86b14eSAlexander Kabaev       // called by insert(p,x)
14191b86b14eSAlexander Kabaev       iterator
14201b86b14eSAlexander Kabaev       _M_insert_aux(iterator __pos, const value_type& __x);
14211b86b14eSAlexander Kabaev 
14221b86b14eSAlexander Kabaev       // called by insert(p,n,x) via fill_insert
14231b86b14eSAlexander Kabaev       void
14241b86b14eSAlexander Kabaev       _M_insert_aux(iterator __pos, size_type __n, const value_type& __x);
14251b86b14eSAlexander Kabaev 
14261b86b14eSAlexander Kabaev       // called by range_insert_aux for forward iterators
14271b86b14eSAlexander Kabaev       template<typename _ForwardIterator>
14281b86b14eSAlexander Kabaev         void
14291b86b14eSAlexander Kabaev         _M_insert_aux(iterator __pos,
143000db7afdSDavid E. O'Brien 		      _ForwardIterator __first, _ForwardIterator __last,
14311b86b14eSAlexander Kabaev 		      size_type __n);
14321b86b14eSAlexander Kabaev 
1433f8a1b7d9SAlexander Kabaev 
1434f8a1b7d9SAlexander Kabaev       // Internal erase functions follow.
1435f8a1b7d9SAlexander Kabaev 
1436f8a1b7d9SAlexander Kabaev       void
1437f8a1b7d9SAlexander Kabaev       _M_destroy_data_aux(iterator __first, iterator __last);
1438f8a1b7d9SAlexander Kabaev 
1439f8a1b7d9SAlexander Kabaev       void
_M_destroy_data_dispatch(iterator,iterator,__true_type)1440f8a1b7d9SAlexander Kabaev       _M_destroy_data_dispatch(iterator, iterator, __true_type) { }
1441f8a1b7d9SAlexander Kabaev 
1442f8a1b7d9SAlexander Kabaev       void
_M_destroy_data_dispatch(iterator __first,iterator __last,__false_type)1443f8a1b7d9SAlexander Kabaev       _M_destroy_data_dispatch(iterator __first, iterator __last, __false_type)
1444f8a1b7d9SAlexander Kabaev       { _M_destroy_data_aux(__first, __last); }
1445f8a1b7d9SAlexander Kabaev 
1446f8a1b7d9SAlexander Kabaev       // Called by ~deque().
1447f8a1b7d9SAlexander Kabaev       // NB: Doesn't deallocate the nodes.
1448f8a1b7d9SAlexander Kabaev       template<typename _Alloc1>
1449f8a1b7d9SAlexander Kabaev         void
_M_destroy_data(iterator __first,iterator __last,const _Alloc1 &)1450f8a1b7d9SAlexander Kabaev         _M_destroy_data(iterator __first, iterator __last, const _Alloc1&)
1451f8a1b7d9SAlexander Kabaev         { _M_destroy_data_aux(__first, __last); }
1452f8a1b7d9SAlexander Kabaev 
1453f8a1b7d9SAlexander Kabaev       void
_M_destroy_data(iterator __first,iterator __last,const std::allocator<_Tp> &)1454f8a1b7d9SAlexander Kabaev       _M_destroy_data(iterator __first, iterator __last,
1455f8a1b7d9SAlexander Kabaev 		      const std::allocator<_Tp>&)
1456f8a1b7d9SAlexander Kabaev       {
1457f8a1b7d9SAlexander Kabaev 	typedef typename std::__is_scalar<value_type>::__type
1458f8a1b7d9SAlexander Kabaev 	  _Has_trivial_destructor;
1459f8a1b7d9SAlexander Kabaev 	_M_destroy_data_dispatch(__first, __last, _Has_trivial_destructor());
1460f8a1b7d9SAlexander Kabaev       }
1461f8a1b7d9SAlexander Kabaev 
1462f8a1b7d9SAlexander Kabaev       // Called by erase(q1, q2).
1463f8a1b7d9SAlexander Kabaev       void
_M_erase_at_begin(iterator __pos)1464f8a1b7d9SAlexander Kabaev       _M_erase_at_begin(iterator __pos)
1465f8a1b7d9SAlexander Kabaev       {
1466f8a1b7d9SAlexander Kabaev 	_M_destroy_data(begin(), __pos, _M_get_Tp_allocator());
1467f8a1b7d9SAlexander Kabaev 	_M_destroy_nodes(this->_M_impl._M_start._M_node, __pos._M_node);
1468f8a1b7d9SAlexander Kabaev 	this->_M_impl._M_start = __pos;
1469f8a1b7d9SAlexander Kabaev       }
1470f8a1b7d9SAlexander Kabaev 
1471f8a1b7d9SAlexander Kabaev       // Called by erase(q1, q2), resize(), clear(), _M_assign_aux,
1472f8a1b7d9SAlexander Kabaev       // _M_fill_assign, operator=.
1473f8a1b7d9SAlexander Kabaev       void
_M_erase_at_end(iterator __pos)1474f8a1b7d9SAlexander Kabaev       _M_erase_at_end(iterator __pos)
1475f8a1b7d9SAlexander Kabaev       {
1476f8a1b7d9SAlexander Kabaev 	_M_destroy_data(__pos, end(), _M_get_Tp_allocator());
1477f8a1b7d9SAlexander Kabaev 	_M_destroy_nodes(__pos._M_node + 1,
1478f8a1b7d9SAlexander Kabaev 			 this->_M_impl._M_finish._M_node + 1);
1479f8a1b7d9SAlexander Kabaev 	this->_M_impl._M_finish = __pos;
1480f8a1b7d9SAlexander Kabaev       }
1481f8a1b7d9SAlexander Kabaev 
14821b86b14eSAlexander Kabaev       //@{
14831b86b14eSAlexander Kabaev       /**
14841b86b14eSAlexander Kabaev        *  @if maint
14851b86b14eSAlexander Kabaev        *  @brief Memory-handling helpers for the previous internal insert
14861b86b14eSAlexander Kabaev        *         functions.
14871b86b14eSAlexander Kabaev        *  @endif
14881b86b14eSAlexander Kabaev        */
14891b86b14eSAlexander Kabaev       iterator
_M_reserve_elements_at_front(size_type __n)14901b86b14eSAlexander Kabaev       _M_reserve_elements_at_front(size_type __n)
149100db7afdSDavid E. O'Brien       {
1492ffeaf689SAlexander Kabaev 	const size_type __vacancies = this->_M_impl._M_start._M_cur
1493ffeaf689SAlexander Kabaev 	                              - this->_M_impl._M_start._M_first;
14941b86b14eSAlexander Kabaev 	if (__n > __vacancies)
14951b86b14eSAlexander Kabaev 	  _M_new_elements_at_front(__n - __vacancies);
1496ffeaf689SAlexander Kabaev 	return this->_M_impl._M_start - difference_type(__n);
149700db7afdSDavid E. O'Brien       }
14981b86b14eSAlexander Kabaev 
14991b86b14eSAlexander Kabaev       iterator
_M_reserve_elements_at_back(size_type __n)15001b86b14eSAlexander Kabaev       _M_reserve_elements_at_back(size_type __n)
150100db7afdSDavid E. O'Brien       {
1502ffeaf689SAlexander Kabaev 	const size_type __vacancies = (this->_M_impl._M_finish._M_last
1503ffeaf689SAlexander Kabaev 				       - this->_M_impl._M_finish._M_cur) - 1;
15041b86b14eSAlexander Kabaev 	if (__n > __vacancies)
15051b86b14eSAlexander Kabaev 	  _M_new_elements_at_back(__n - __vacancies);
1506ffeaf689SAlexander Kabaev 	return this->_M_impl._M_finish + difference_type(__n);
150700db7afdSDavid E. O'Brien       }
150800db7afdSDavid E. O'Brien 
15091b86b14eSAlexander Kabaev       void
15101b86b14eSAlexander Kabaev       _M_new_elements_at_front(size_type __new_elements);
15111b86b14eSAlexander Kabaev 
15121b86b14eSAlexander Kabaev       void
15131b86b14eSAlexander Kabaev       _M_new_elements_at_back(size_type __new_elements);
15141b86b14eSAlexander Kabaev       //@}
15151b86b14eSAlexander Kabaev 
15161b86b14eSAlexander Kabaev 
15171b86b14eSAlexander Kabaev       //@{
15181b86b14eSAlexander Kabaev       /**
15191b86b14eSAlexander Kabaev        *  @if maint
15201b86b14eSAlexander Kabaev        *  @brief Memory-handling helpers for the major %map.
15211b86b14eSAlexander Kabaev        *
1522f8a1b7d9SAlexander Kabaev        *  Makes sure the _M_map has space for new nodes.  Does not
1523f8a1b7d9SAlexander Kabaev        *  actually add the nodes.  Can invalidate _M_map pointers.
1524f8a1b7d9SAlexander Kabaev        *  (And consequently, %deque iterators.)
15251b86b14eSAlexander Kabaev        *  @endif
15261b86b14eSAlexander Kabaev        */
15271b86b14eSAlexander Kabaev       void
15281b86b14eSAlexander Kabaev       _M_reserve_map_at_back(size_type __nodes_to_add = 1)
152900db7afdSDavid E. O'Brien       {
1530ffeaf689SAlexander Kabaev 	if (__nodes_to_add + 1 > this->_M_impl._M_map_size
1531ffeaf689SAlexander Kabaev 	    - (this->_M_impl._M_finish._M_node - this->_M_impl._M_map))
15321b86b14eSAlexander Kabaev 	  _M_reallocate_map(__nodes_to_add, false);
153300db7afdSDavid E. O'Brien       }
153400db7afdSDavid E. O'Brien 
15351b86b14eSAlexander Kabaev       void
15361b86b14eSAlexander Kabaev       _M_reserve_map_at_front(size_type __nodes_to_add = 1)
153700db7afdSDavid E. O'Brien       {
1538f8a1b7d9SAlexander Kabaev 	if (__nodes_to_add > size_type(this->_M_impl._M_start._M_node
1539f8a1b7d9SAlexander Kabaev 				       - this->_M_impl._M_map))
15401b86b14eSAlexander Kabaev 	  _M_reallocate_map(__nodes_to_add, true);
154100db7afdSDavid E. O'Brien       }
154200db7afdSDavid E. O'Brien 
15431b86b14eSAlexander Kabaev       void
15441b86b14eSAlexander Kabaev       _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front);
15451b86b14eSAlexander Kabaev       //@}
15461b86b14eSAlexander Kabaev     };
154700db7afdSDavid E. O'Brien 
154800db7afdSDavid E. O'Brien 
15491b86b14eSAlexander Kabaev   /**
15501b86b14eSAlexander Kabaev    *  @brief  Deque equality comparison.
15511b86b14eSAlexander Kabaev    *  @param  x  A %deque.
15521b86b14eSAlexander Kabaev    *  @param  y  A %deque of the same type as @a x.
15531b86b14eSAlexander Kabaev    *  @return  True iff the size and elements of the deques are equal.
15541b86b14eSAlexander Kabaev    *
15551b86b14eSAlexander Kabaev    *  This is an equivalence relation.  It is linear in the size of the
15561b86b14eSAlexander Kabaev    *  deques.  Deques are considered equivalent if their sizes are equal,
15571b86b14eSAlexander Kabaev    *  and if corresponding elements compare equal.
15581b86b14eSAlexander Kabaev   */
15591b86b14eSAlexander Kabaev   template<typename _Tp, typename _Alloc>
1560ffeaf689SAlexander Kabaev     inline bool
1561ffeaf689SAlexander Kabaev     operator==(const deque<_Tp, _Alloc>& __x,
15621b86b14eSAlexander Kabaev                          const deque<_Tp, _Alloc>& __y)
1563ffeaf689SAlexander Kabaev     { return __x.size() == __y.size()
1564ffeaf689SAlexander Kabaev              && std::equal(__x.begin(), __x.end(), __y.begin()); }
156500db7afdSDavid E. O'Brien 
15661b86b14eSAlexander Kabaev   /**
15671b86b14eSAlexander Kabaev    *  @brief  Deque ordering relation.
15681b86b14eSAlexander Kabaev    *  @param  x  A %deque.
15691b86b14eSAlexander Kabaev    *  @param  y  A %deque of the same type as @a x.
1570ffeaf689SAlexander Kabaev    *  @return  True iff @a x is lexicographically less than @a y.
15711b86b14eSAlexander Kabaev    *
15721b86b14eSAlexander Kabaev    *  This is a total ordering relation.  It is linear in the size of the
15731b86b14eSAlexander Kabaev    *  deques.  The elements must be comparable with @c <.
15741b86b14eSAlexander Kabaev    *
1575ffeaf689SAlexander Kabaev    *  See std::lexicographical_compare() for how the determination is made.
15761b86b14eSAlexander Kabaev   */
15771b86b14eSAlexander Kabaev   template<typename _Tp, typename _Alloc>
1578ffeaf689SAlexander Kabaev     inline bool
1579ffeaf689SAlexander Kabaev     operator<(const deque<_Tp, _Alloc>& __x,
15801b86b14eSAlexander Kabaev 	      const deque<_Tp, _Alloc>& __y)
1581f8a1b7d9SAlexander Kabaev     { return std::lexicographical_compare(__x.begin(), __x.end(),
1582ffeaf689SAlexander Kabaev 					  __y.begin(), __y.end()); }
158300db7afdSDavid E. O'Brien 
15841b86b14eSAlexander Kabaev   /// Based on operator==
15851b86b14eSAlexander Kabaev   template<typename _Tp, typename _Alloc>
1586ffeaf689SAlexander Kabaev     inline bool
1587ffeaf689SAlexander Kabaev     operator!=(const deque<_Tp, _Alloc>& __x,
1588ffeaf689SAlexander Kabaev 	       const deque<_Tp, _Alloc>& __y)
1589ffeaf689SAlexander Kabaev     { return !(__x == __y); }
159000db7afdSDavid E. O'Brien 
15911b86b14eSAlexander Kabaev   /// Based on operator<
15921b86b14eSAlexander Kabaev   template<typename _Tp, typename _Alloc>
1593ffeaf689SAlexander Kabaev     inline bool
1594ffeaf689SAlexander Kabaev     operator>(const deque<_Tp, _Alloc>& __x,
1595ffeaf689SAlexander Kabaev 	      const deque<_Tp, _Alloc>& __y)
1596ffeaf689SAlexander Kabaev     { return __y < __x; }
159700db7afdSDavid E. O'Brien 
15981b86b14eSAlexander Kabaev   /// Based on operator<
15991b86b14eSAlexander Kabaev   template<typename _Tp, typename _Alloc>
1600ffeaf689SAlexander Kabaev     inline bool
1601ffeaf689SAlexander Kabaev     operator<=(const deque<_Tp, _Alloc>& __x,
1602ffeaf689SAlexander Kabaev 	       const deque<_Tp, _Alloc>& __y)
1603ffeaf689SAlexander Kabaev     { return !(__y < __x); }
16041b86b14eSAlexander Kabaev 
16051b86b14eSAlexander Kabaev   /// Based on operator<
16061b86b14eSAlexander Kabaev   template<typename _Tp, typename _Alloc>
1607ffeaf689SAlexander Kabaev     inline bool
1608ffeaf689SAlexander Kabaev     operator>=(const deque<_Tp, _Alloc>& __x,
1609ffeaf689SAlexander Kabaev 	       const deque<_Tp, _Alloc>& __y)
1610ffeaf689SAlexander Kabaev     { return !(__x < __y); }
161100db7afdSDavid E. O'Brien 
16121b86b14eSAlexander Kabaev   /// See std::deque::swap().
16131b86b14eSAlexander Kabaev   template<typename _Tp, typename _Alloc>
1614ffeaf689SAlexander Kabaev     inline void
swap(deque<_Tp,_Alloc> & __x,deque<_Tp,_Alloc> & __y)1615ffeaf689SAlexander Kabaev     swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y)
1616ffeaf689SAlexander Kabaev     { __x.swap(__y); }
1617f8a1b7d9SAlexander Kabaev 
1618f8a1b7d9SAlexander Kabaev _GLIBCXX_END_NESTED_NAMESPACE
161900db7afdSDavid E. O'Brien 
1620ffeaf689SAlexander Kabaev #endif /* _DEQUE_H */
1621