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