This function controls the size of memory nodes.
This function started off as a compiler kludge from SGI, but seems to be a useful wrapper around a repeated constant expression. The 512 is tunable (and no other code needs to change), but no investigation has been done since inheriting the SGI code. Touch _GLIBCXX_DEQUE_BUF_SIZE only if you know what you are doing, however: changing it breaks the binary compatibility!!
A deque::iterator.
Quite a bit of intelligence here. Much of the functionality of deque is actually passed off to this class. A deque holds two of these internally, marking its valid range. Access to elements is done as offsets of either of those two, relying on operator overloading in this class.
All the functions are op overloads except for _M_set_node.
Prepares to traverse new_node. Sets everything except _M_cur, which should therefore be set by the caller immediately afterwards, based on _M_first and _M_last.
Deque base class. This class provides the unified face for deque's allocation. This class's constructor and destructor allocate and deallocate (but do not initialize) storage. This makes exception safety easier.
Nothing in this class ever constructs or destroys an actual Tp element. (Deque handles that itself.) Only/All memory management is performed here.
Layout storage.
The initial underlying memory layout is a bit complicated...
A standard container using fixed-size memory allocation and constant-time manipulation of elements at either end.
In previous HP/SGI versions of deque, there was an extra template parameter so users could control the node size. This extension turned out to violate the C++ standard (it can be detected using template template parameters), and it was removed.
Here's how a deque<Tp> manages memory. Each deque has 4 members:
map_size is at least 8. map is an array of map_size pointers-to-nodes. (The name map has nothing to do with the std::map class, and nodes should not be confused with std::list's usage of node.)
Not every pointer in the map array will point to a node. If the initial number of elements in the deque is small, the /middle/ map pointers will be valid, and the ones at the edges will be unused. This same situation will arise as the map grows: available map pointers, if any, will be on the ends. As new nodes are created, only a subset of the map's pointers need to be copied outward.
A total of four data members accumulated down the hierarchy. May be accessed via _M_impl.*
Default constructor creates no elements.
Creates a deque with no elements.
Creates a deque with copies of an exemplar element.
Deque copy constructor.
Builds a deque from a range.
Create a deque consisting of copies of the elements from [__first, __last).
If the iterators are forward, bidirectional, or random-access, then this will call the elements' copy constructor N times (where N is distance(__first,__last)) and do no memory reallocation. But if only input iterators are used, then this will do at most 2N calls to the copy constructor, and logN memory reallocations.
The dtor only erases the elements, and note that if the elements themselves are pointers, the pointed-to memory is not touched in any way. Managing the pointer is the user's responsibility.
Deque assignment operator.
Assigns a given value to a deque.
Assigns a range to a deque.
This function fills a deque with copies of the elements in the range [__first,__last).
Note that the assignment completely changes the deque and that the resulting deque's size is the same as the number of elements assigned. Old data may be lost.
Get a copy of the memory allocation object.
Returns a read/write iterator that points to the first element in the deque. Iteration is done in ordinary element order.
Returns a read-only (constant) iterator that points to the first element in the deque. Iteration is done in ordinary element order.
Returns a read/write iterator that points one past the last element in the deque. Iteration is done in ordinary element order.
Returns a read-only (constant) iterator that points one past the last element in the deque. Iteration is done in ordinary element order.
Returns a read/write reverse iterator that points to the last element in the deque. Iteration is done in reverse element order.
Returns a read-only (constant) reverse iterator that points to the last element in the deque. Iteration is done in reverse element order.
Returns a read/write reverse iterator that points to one before the first element in the deque. Iteration is done in reverse element order.
Returns a read-only (constant) reverse iterator that points to one before the first element in the deque. Iteration is done in reverse element order.
Returns the number of elements in the deque.
Returns the size() of the largest possible deque.
Resizes the deque to the specified number of elements.
This function will resize the deque to the specified number of elements. If the number is smaller than the deque's current size the deque is truncated, otherwise the deque is extended and new elements are populated with given data.
Returns true if the deque is empty. (Thus begin() would equal end().)
Subscript access to the data contained in the deque.
This operator allows for easy, array-style, data access. Note that data access with this operator is unchecked and out_of_range lookups are not defined. (For checked lookups see at().)
Subscript access to the data contained in the deque.
This operator allows for easy, array-style, data access. Note that data access with this operator is unchecked and out_of_range lookups are not defined. (For checked lookups see at().)
Safety check used only from at().
Provides access to the data contained in the deque.
This function provides for safer data access. The parameter is first checked that it is in the range of the deque. The function throws out_of_range if the check fails.
Provides access to the data contained in the deque.
This function provides for safer data access. The parameter is first checked that it is in the range of the deque. The function throws out_of_range if the check fails.
Returns a read/write reference to the data at the first element of the deque.
Returns a read-only (constant) reference to the data at the first element of the deque.
Returns a read/write reference to the data at the last element of the deque.
Returns a read-only (constant) reference to the data at the last element of the deque.
Add data to the front of the deque.
This is a typical stack operation. The function creates an element at the front of the deque and assigns the given data to it. Due to the nature of a deque this operation can be done in constant time.
Add data to the end of the deque.
This is a typical stack operation. The function creates an element at the end of the deque and assigns the given data to it. Due to the nature of a deque this operation can be done in constant time.
Removes first element.
This is a typical stack operation. It shrinks the deque by one.
Note that no data is returned, and if the first element's data is needed, it should be retrieved before pop_front() is called.
Removes last element.
This is a typical stack operation. It shrinks the deque by one.
Note that no data is returned, and if the last element's data is needed, it should be retrieved before pop_back() is called.
Inserts given value into deque before specified iterator.
This function will insert a copy of the given value before the specified location.
Inserts a number of copies of given data into the deque.
This function will insert a specified number of copies of the given data before the location specified by __position.
Inserts a range into the deque.
This function will insert copies of the data in the range [__first,__last) into the deque before the location specified by __position. This is known as range insert.
Remove element at given position.
This function will erase the element at the given position and thus shorten the deque by one.
The user is cautioned that this function only erases the element, and that if the element is itself a pointer, the pointed-to memory is not touched in any way. Managing the pointer is the user's responsibility.
Remove a range of elements.
This function will erase the elements in the range [__first,__last) and shorten the deque accordingly.
The user is cautioned that this function only erases the elements, and that if the elements themselves are pointers, the pointed-to memory is not touched in any way. Managing the pointer is the user's responsibility.
Swaps data with another deque.
This exchanges the elements between two deques in constant time. (Four pointers, so it should be quite fast.) Note that the global std::swap() function is specialized such that std::swap(d1,d2) will feed to this function.
Erases all the elements. Note that this function only erases the elements, and that if the elements themselves are pointers, the pointed-to memory is not touched in any way. Managing the pointer is the user's responsibility.
Fills the deque with whatever is in [first,last).
If the iterators are actually forward iterators (or better), then the memory layout can be done all at once. Else we move forward using push_back on each value from the iterator.
Fills the deque with copies of value.
This function is called only when the user provides an explicit size (with or without an explicit exemplar value).
Helper functions for push_* and pop_*.
Memory-handling helpers for the previous internal insert functions.
Memory-handling helpers for the major map.
Makes sure the _M_map has space for new nodes. Does not actually add the nodes. Can invalidate _M_map pointers. (And consequently, deque iterators.)
Deque equality comparison.
This is an equivalence relation. It is linear in the size of the deques. Deques are considered equivalent if their sizes are equal, and if corresponding elements compare equal.
Deque ordering relation.
This is a total ordering relation. It is linear in the size of the deques. The elements must be comparable with <
.
See std::lexicographical_compare() for how the determination is made.
68 _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
84 #ifndef _GLIBCXX_DEQUE_BUF_SIZE
85 #define _GLIBCXX_DEQUE_BUF_SIZE 512
89 __deque_buf_size(
size_t __size)
105 template<
typename _Tp,
typename _Ref,
typename _Ptr>
106 struct _Deque_iterator
108 typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator;
109 typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
111 static size_t _S_buffer_size()
112 {
return __deque_buf_size(
sizeof(_Tp)); }
114 typedef std::random_access_iterator_tag iterator_category;
115 typedef _Tp value_type;
116 typedef _Ptr pointer;
117 typedef _Ref reference;
118 typedef size_t size_type;
120 typedef _Tp** _Map_pointer;
121 typedef _Deque_iterator _Self;
126 _Map_pointer _M_node;
128 _Deque_iterator(_Tp* __x, _Map_pointer __y)
129 : _M_cur(__x), _M_first(*__y),
130 _M_last(*__y + _S_buffer_size()), _M_node(__y) { }
133 : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) { }
135 _Deque_iterator(
const iterator& __x)
136 : _M_cur(__x._M_cur), _M_first(__x._M_first),
137 _M_last(__x._M_last), _M_node(__x._M_node) { }
151 if (_M_cur == _M_last)
153 _M_set_node(_M_node + 1);
170 if (_M_cur == _M_first)
172 _M_set_node(_M_node - 1);
188 operator+=(difference_type __n)
190 const difference_type __offset = __n + (_M_cur - _M_first);
191 if (__offset >= 0 && __offset < difference_type(_S_buffer_size()))
195 const difference_type __node_offset =
196 __offset > 0 ? __offset / difference_type(_S_buffer_size())
197 : -difference_type((-__offset - 1)
198 / _S_buffer_size()) - 1;
199 _M_set_node(_M_node + __node_offset);
200 _M_cur = _M_first + (__offset - __node_offset
201 * difference_type(_S_buffer_size()));
214 operator-=(difference_type __n)
215 {
return *
this += -__n; }
225 operator[](difference_type __n)
const
226 {
return *(*
this + __n); }
234 _M_set_node(_Map_pointer __new_node)
236 _M_node = __new_node;
237 _M_first = *__new_node;
238 _M_last = _M_first + difference_type(_S_buffer_size());
245 template<
typename _Tp,
typename _Ref,
typename _Ptr>
247 operator==(
const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
248 const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
249 {
return __x._M_cur == __y._M_cur; }
251 template<
typename _Tp,
typename _RefL,
typename _PtrL,
252 typename _RefR,
typename _PtrR>
254 operator==(
const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
255 const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
256 {
return __x._M_cur == __y._M_cur; }
258 template<
typename _Tp,
typename _Ref,
typename _Ptr>
260 operator!=(
const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
261 const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
262 {
return !(__x == __y); }
264 template<
typename _Tp,
typename _RefL,
typename _PtrL,
265 typename _RefR,
typename _PtrR>
267 operator!=(
const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
268 const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
269 {
return !(__x == __y); }
271 template<
typename _Tp,
typename _Ref,
typename _Ptr>
273 operator<(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
274 const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
275 {
return (__x._M_node == __y._M_node) ? (__x._M_cur < __y._M_cur)
276 : (__x._M_node < __y._M_node); }
278 template<
typename _Tp,
typename _RefL,
typename _PtrL,
279 typename _RefR,
typename _PtrR>
281 operator<(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
282 const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
283 {
return (__x._M_node == __y._M_node) ? (__x._M_cur < __y._M_cur)
284 : (__x._M_node < __y._M_node); }
286 template<
typename _Tp,
typename _Ref,
typename _Ptr>
288 operator>(
const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
289 const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
290 {
return __y < __x; }
292 template<
typename _Tp,
typename _RefL,
typename _PtrL,
293 typename _RefR,
typename _PtrR>
295 operator>(
const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
296 const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
297 {
return __y < __x; }
299 template<
typename _Tp,
typename _Ref,
typename _Ptr>
301 operator<=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
302 const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
303 {
return !(__y < __x); }
305 template<
typename _Tp,
typename _RefL,
typename _PtrL,
306 typename _RefR,
typename _PtrR>
308 operator<=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
309 const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
310 {
return !(__y < __x); }
312 template<
typename _Tp,
typename _Ref,
typename _Ptr>
314 operator>=(
const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
315 const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
316 {
return !(__x < __y); }
318 template<
typename _Tp,
typename _RefL,
typename _PtrL,
319 typename _RefR,
typename _PtrR>
321 operator>=(
const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
322 const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
323 {
return !(__x < __y); }
329 template<
typename _Tp,
typename _Ref,
typename _Ptr>
330 inline typename _Deque_iterator<_Tp, _Ref, _Ptr>::difference_type
331 operator-(
const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,
332 const _Deque_iterator<_Tp, _Ref, _Ptr>& __y)
334 return typename _Deque_iterator<_Tp, _Ref, _Ptr>::difference_type
335 (_Deque_iterator<_Tp, _Ref, _Ptr>::_S_buffer_size())
336 * (__x._M_node - __y._M_node - 1) + (__x._M_cur - __x._M_first)
337 + (__y._M_last - __y._M_cur);
340 template<
typename _Tp,
typename _RefL,
typename _PtrL,
341 typename _RefR,
typename _PtrR>
342 inline typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type
343 operator-(
const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,
344 const _Deque_iterator<_Tp, _RefR, _PtrR>& __y)
346 return typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type
347 (_Deque_iterator<_Tp, _RefL, _PtrL>::_S_buffer_size())
348 * (__x._M_node - __y._M_node - 1) + (__x._M_cur - __x._M_first)
349 + (__y._M_last - __y._M_cur);
352 template<
typename _Tp,
typename _Ref,
typename _Ptr>
353 inline _Deque_iterator<_Tp, _Ref, _Ptr>
355 {
return __x + __n; }
357 template<
typename _Tp>
359 fill(
const _Deque_iterator<_Tp, _Tp&, _Tp*>&,
360 const _Deque_iterator<_Tp, _Tp&, _Tp*>&,
const _Tp&);
362 template<
typename _Tp>
363 _Deque_iterator<_Tp, _Tp&, _Tp*>
364 copy(_Deque_iterator<_Tp, const _Tp&, const _Tp*>,
365 _Deque_iterator<_Tp, const _Tp&, const _Tp*>,
366 _Deque_iterator<_Tp, _Tp&, _Tp*>);
368 template<
typename _Tp>
369 inline _Deque_iterator<_Tp, _Tp&, _Tp*>
370 copy(_Deque_iterator<_Tp, _Tp&, _Tp*> __first,
371 _Deque_iterator<_Tp, _Tp&, _Tp*> __last,
372 _Deque_iterator<_Tp, _Tp&, _Tp*> __result)
373 {
return std::copy(_Deque_iterator<_Tp, const _Tp&, const _Tp*>(__first),
374 _Deque_iterator<_Tp, const _Tp&, const _Tp*>(__last),
377 template<
typename _Tp>
378 _Deque_iterator<_Tp, _Tp&, _Tp*>
379 copy_backward(_Deque_iterator<_Tp, const _Tp&, const _Tp*>,
380 _Deque_iterator<_Tp, const _Tp&, const _Tp*>,
381 _Deque_iterator<_Tp, _Tp&, _Tp*>);
383 template<
typename _Tp>
384 inline _Deque_iterator<_Tp, _Tp&, _Tp*>
385 copy_backward(_Deque_iterator<_Tp, _Tp&, _Tp*> __first,
386 _Deque_iterator<_Tp, _Tp&, _Tp*> __last,
387 _Deque_iterator<_Tp, _Tp&, _Tp*> __result)
388 {
return std::copy_backward(_Deque_iterator<_Tp,
389 const _Tp&,
const _Tp*>(__first),
391 const _Tp&,
const _Tp*>(__last),
394 #if __cplusplus >= 201103L
395 template<
typename _Tp>
396 _Deque_iterator<_Tp, _Tp&, _Tp*>
397 move(_Deque_iterator<_Tp, const _Tp&, const _Tp*>,
398 _Deque_iterator<_Tp, const _Tp&, const _Tp*>,
399 _Deque_iterator<_Tp, _Tp&, _Tp*>);
401 template<
typename _Tp>
402 inline _Deque_iterator<_Tp, _Tp&, _Tp*>
403 move(_Deque_iterator<_Tp, _Tp&, _Tp*> __first,
404 _Deque_iterator<_Tp, _Tp&, _Tp*> __last,
405 _Deque_iterator<_Tp, _Tp&, _Tp*> __result)
406 {
return std::move(_Deque_iterator<_Tp, const _Tp&, const _Tp*>(__first),
407 _Deque_iterator<_Tp, const _Tp&, const _Tp*>(__last),
410 template<
typename _Tp>
411 _Deque_iterator<_Tp, _Tp&, _Tp*>
412 move_backward(_Deque_iterator<_Tp, const _Tp&, const _Tp*>,
413 _Deque_iterator<_Tp, const _Tp&, const _Tp*>,
414 _Deque_iterator<_Tp, _Tp&, _Tp*>);
416 template<
typename _Tp>
417 inline _Deque_iterator<_Tp, _Tp&, _Tp*>
418 move_backward(_Deque_iterator<_Tp, _Tp&, _Tp*> __first,
419 _Deque_iterator<_Tp, _Tp&, _Tp*> __last,
420 _Deque_iterator<_Tp, _Tp&, _Tp*> __result)
421 {
return std::move_backward(_Deque_iterator<_Tp,
422 const _Tp&,
const _Tp*>(__first),
424 const _Tp&,
const _Tp*>(__last),
438 template<
typename _Tp,
typename _Alloc>
442 typedef _Alloc allocator_type;
445 get_allocator() const _GLIBCXX_NOEXCEPT
446 {
return allocator_type(_M_get_Tp_allocator()); }
448 typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator;
449 typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
453 { _M_initialize_map(0); }
455 _Deque_base(
size_t __num_elements)
457 { _M_initialize_map(__num_elements); }
459 _Deque_base(
const allocator_type& __a,
size_t __num_elements)
461 { _M_initialize_map(__num_elements); }
463 _Deque_base(
const allocator_type& __a)
467 #if __cplusplus >= 201103L
468 _Deque_base(_Deque_base&& __x)
469 : _M_impl(std::move(__x._M_get_Tp_allocator()))
471 _M_initialize_map(0);
472 if (__x._M_impl._M_map)
474 std::swap(this->_M_impl._M_start, __x._M_impl._M_start);
475 std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish);
476 std::swap(this->_M_impl._M_map, __x._M_impl._M_map);
477 std::swap(this->_M_impl._M_map_size, __x._M_impl._M_map_size);
488 typedef typename _Alloc::template rebind<_Tp*>::other _Map_alloc_type;
490 typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type;
493 :
public _Tp_alloc_type
501 : _Tp_alloc_type(), _M_map(0), _M_map_size(0),
502 _M_start(), _M_finish()
505 _Deque_impl(
const _Tp_alloc_type& __a)
506 : _Tp_alloc_type(__a), _M_map(0), _M_map_size(0),
507 _M_start(), _M_finish()
510 #if __cplusplus >= 201103L
511 _Deque_impl(_Tp_alloc_type&& __a)
512 : _Tp_alloc_type(std::move(__a)), _M_map(0), _M_map_size(0),
513 _M_start(), _M_finish()
519 _M_get_Tp_allocator() _GLIBCXX_NOEXCEPT
520 {
return *
static_cast<_Tp_alloc_type*
>(&this->_M_impl); }
522 const _Tp_alloc_type&
523 _M_get_Tp_allocator() const _GLIBCXX_NOEXCEPT
524 {
return *
static_cast<const _Tp_alloc_type*
>(&this->_M_impl); }
527 _M_get_map_allocator() const _GLIBCXX_NOEXCEPT
528 {
return _Map_alloc_type(_M_get_Tp_allocator()); }
533 return _M_impl._Tp_alloc_type::allocate(__deque_buf_size(
sizeof(_Tp)));
537 _M_deallocate_node(_Tp* __p)
539 _M_impl._Tp_alloc_type::deallocate(__p, __deque_buf_size(
sizeof(_Tp)));
543 _M_allocate_map(
size_t __n)
544 {
return _M_get_map_allocator().allocate(__n); }
547 _M_deallocate_map(_Tp** __p,
size_t __n)
548 { _M_get_map_allocator().deallocate(__p, __n); }
551 void _M_initialize_map(
size_t);
552 void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish);
553 void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish);
554 enum { _S_initial_map_size = 8 };
559 template<
typename _Tp,
typename _Alloc>
560 _Deque_base<_Tp, _Alloc>::
563 if (this->_M_impl._M_map)
565 _M_destroy_nodes(this->_M_impl._M_start._M_node,
566 this->_M_impl._M_finish._M_node + 1);
567 _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size);
579 template<
typename _Tp,
typename _Alloc>
581 _Deque_base<_Tp, _Alloc>::
582 _M_initialize_map(
size_t __num_elements)
584 const size_t __num_nodes = (__num_elements/ __deque_buf_size(
sizeof(_Tp))
587 this->_M_impl._M_map_size =
std::max((
size_t) _S_initial_map_size,
588 size_t(__num_nodes + 2));
589 this->_M_impl._M_map = _M_allocate_map(this->_M_impl._M_map_size);
596 _Tp** __nstart = (this->_M_impl._M_map
597 + (this->_M_impl._M_map_size - __num_nodes) / 2);
598 _Tp** __nfinish = __nstart + __num_nodes;
601 { _M_create_nodes(__nstart, __nfinish); }
604 _M_deallocate_map(this->_M_impl._M_map, this->_M_impl._M_map_size);
605 this->_M_impl._M_map = 0;
606 this->_M_impl._M_map_size = 0;
610 this->_M_impl._M_start._M_set_node(__nstart);
611 this->_M_impl._M_finish._M_set_node(__nfinish - 1);
612 this->_M_impl._M_start._M_cur = _M_impl._M_start._M_first;
613 this->_M_impl._M_finish._M_cur = (this->_M_impl._M_finish._M_first
615 % __deque_buf_size(
sizeof(_Tp)));
618 template<
typename _Tp,
typename _Alloc>
620 _Deque_base<_Tp, _Alloc>::
621 _M_create_nodes(_Tp** __nstart, _Tp** __nfinish)
626 for (__cur = __nstart; __cur < __nfinish; ++__cur)
627 *__cur = this->_M_allocate_node();
631 _M_destroy_nodes(__nstart, __cur);
636 template<
typename _Tp,
typename _Alloc>
638 _Deque_base<_Tp, _Alloc>::
639 _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish)
641 for (_Tp** __n = __nstart; __n < __nfinish; ++__n)
642 _M_deallocate_node(*__n);
729 template<
typename _Tp,
typename _Alloc = std::allocator<_Tp> >
730 class deque :
protected _Deque_base<_Tp, _Alloc>
733 typedef typename _Alloc::value_type _Alloc_value_type;
737 typedef _Deque_base<_Tp, _Alloc> _Base;
738 typedef typename _Base::_Tp_alloc_type _Tp_alloc_type;
741 typedef _Tp value_type;
742 typedef typename _Tp_alloc_type::pointer pointer;
743 typedef typename _Tp_alloc_type::const_pointer const_pointer;
744 typedef typename _Tp_alloc_type::reference reference;
745 typedef typename _Tp_alloc_type::const_reference const_reference;
746 typedef typename _Base::iterator iterator;
747 typedef typename _Base::const_iterator const_iterator;
748 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
749 typedef std::reverse_iterator<iterator> reverse_iterator;
750 typedef
size_t size_type;
752 typedef _Alloc allocator_type;
755 typedef pointer* _Map_pointer;
757 static
size_t _S_buffer_size()
758 {
return __deque_buf_size(
sizeof(_Tp)); }
761 using _Base::_M_initialize_map;
762 using _Base::_M_create_nodes;
763 using _Base::_M_destroy_nodes;
764 using _Base::_M_allocate_node;
765 using _Base::_M_deallocate_node;
766 using _Base::_M_allocate_map;
767 using _Base::_M_deallocate_map;
768 using _Base::_M_get_Tp_allocator;
774 using _Base::_M_impl;
790 deque(
const allocator_type& __a)
793 #if __cplusplus >= 201103L
804 { _M_default_initialize(); }
814 deque(size_type __n,
const value_type& __value,
815 const allocator_type& __a = allocator_type())
817 { _M_fill_initialize(__value); }
828 deque(size_type __n,
const value_type& __value = value_type(),
829 const allocator_type& __a = allocator_type())
831 { _M_fill_initialize(__value); }
841 deque(
const deque& __x)
842 : _Base(__x._M_get_Tp_allocator(), __x.size())
843 { std::__uninitialized_copy_a(__x.begin(), __x.end(),
844 this->_M_impl._M_start,
845 _M_get_Tp_allocator()); }
847 #if __cplusplus >= 201103L
856 : _Base(std::move(__x)) { }
869 deque(initializer_list<value_type> __l,
870 const allocator_type& __a = allocator_type())
873 _M_range_initialize(__l.begin(), __l.end(),
874 random_access_iterator_tag());
893 #if __cplusplus >= 201103L
894 template<
typename _InputIterator,
895 typename = std::_RequireInputIter<_InputIterator>>
896 deque(_InputIterator __first, _InputIterator __last,
897 const allocator_type& __a = allocator_type())
899 { _M_initialize_dispatch(__first, __last, __false_type()); }
901 template<
typename _InputIterator>
902 deque(_InputIterator __first, _InputIterator __last,
903 const allocator_type& __a = allocator_type())
907 typedef typename std::__is_integer<_InputIterator>::__type _Integral;
908 _M_initialize_dispatch(__first, __last, _Integral());
917 ~deque() _GLIBCXX_NOEXCEPT
918 { _M_destroy_data(begin(), end(), _M_get_Tp_allocator()); }
928 operator=(
const deque& __x);
930 #if __cplusplus >= 201103L
939 operator=(deque&& __x)
960 operator=(initializer_list<value_type> __l)
962 this->assign(__l.begin(), __l.end());
978 assign(size_type __n,
const value_type& __val)
979 { _M_fill_assign(__n, __val); }
993 #if __cplusplus >= 201103L
994 template<
typename _InputIterator,
995 typename = std::_RequireInputIter<_InputIterator>>
997 assign(_InputIterator __first, _InputIterator __last)
998 { _M_assign_dispatch(__first, __last, __false_type()); }
1000 template<
typename _InputIterator>
1002 assign(_InputIterator __first, _InputIterator __last)
1004 typedef typename std::__is_integer<_InputIterator>::__type _Integral;
1005 _M_assign_dispatch(__first, __last, _Integral());
1009 #if __cplusplus >= 201103L
1022 assign(initializer_list<value_type> __l)
1023 { this->assign(__l.begin(), __l.end()); }
1028 get_allocator() const _GLIBCXX_NOEXCEPT
1029 {
return _Base::get_allocator(); }
1037 begin() _GLIBCXX_NOEXCEPT
1038 {
return this->_M_impl._M_start; }
1045 begin() const _GLIBCXX_NOEXCEPT
1046 {
return this->_M_impl._M_start; }
1054 end() _GLIBCXX_NOEXCEPT
1055 {
return this->_M_impl._M_finish; }
1063 end() const _GLIBCXX_NOEXCEPT
1064 {
return this->_M_impl._M_finish; }
1072 rbegin() _GLIBCXX_NOEXCEPT
1073 {
return reverse_iterator(this->_M_impl._M_finish); }
1080 const_reverse_iterator
1081 rbegin() const _GLIBCXX_NOEXCEPT
1082 {
return const_reverse_iterator(this->_M_impl._M_finish); }
1090 rend() _GLIBCXX_NOEXCEPT
1091 {
return reverse_iterator(this->_M_impl._M_start); }
1098 const_reverse_iterator
1099 rend() const _GLIBCXX_NOEXCEPT
1100 {
return const_reverse_iterator(this->_M_impl._M_start); }
1102 #if __cplusplus >= 201103L
1108 cbegin() const noexcept
1109 {
return this->_M_impl._M_start; }
1117 cend() const noexcept
1118 {
return this->_M_impl._M_finish; }
1125 const_reverse_iterator
1126 crbegin() const noexcept
1127 {
return const_reverse_iterator(this->_M_impl._M_finish); }
1134 const_reverse_iterator
1135 crend() const noexcept
1136 {
return const_reverse_iterator(this->_M_impl._M_start); }
1142 size() const _GLIBCXX_NOEXCEPT
1143 {
return this->_M_impl._M_finish - this->_M_impl._M_start; }
1147 max_size() const _GLIBCXX_NOEXCEPT
1148 {
return _M_get_Tp_allocator().max_size(); }
1150 #if __cplusplus >= 201103L
1161 resize(size_type __new_size)
1163 const size_type __len = size();
1164 if (__new_size > __len)
1165 _M_default_append(__new_size - __len);
1166 else if (__new_size < __len)
1167 _M_erase_at_end(this->_M_impl._M_start
1168 + difference_type(__new_size));
1183 resize(size_type __new_size,
const value_type& __x)
1185 const size_type __len = size();
1186 if (__new_size > __len)
1187 insert(this->_M_impl._M_finish, __new_size - __len, __x);
1188 else if (__new_size < __len)
1189 _M_erase_at_end(this->_M_impl._M_start
1190 + difference_type(__new_size));
1205 resize(size_type __new_size, value_type __x = value_type())
1207 const size_type __len = size();
1208 if (__new_size > __len)
1209 insert(this->_M_impl._M_finish, __new_size - __len, __x);
1210 else if (__new_size < __len)
1211 _M_erase_at_end(this->_M_impl._M_start
1212 + difference_type(__new_size));
1216 #if __cplusplus >= 201103L
1220 { _M_shrink_to_fit(); }
1228 empty() const _GLIBCXX_NOEXCEPT
1229 {
return this->_M_impl._M_finish == this->_M_impl._M_start; }
1244 operator[](size_type __n)
1245 {
return this->_M_impl._M_start[difference_type(__n)]; }
1259 operator[](size_type __n)
const
1260 {
return this->_M_impl._M_start[difference_type(__n)]; }
1265 _M_range_check(size_type __n)
const
1267 if (__n >= this->size())
1268 __throw_out_of_range(__N(
"deque::_M_range_check"));
1286 _M_range_check(__n);
1287 return (*
this)[__n];
1302 at(size_type __n)
const
1304 _M_range_check(__n);
1305 return (*
this)[__n];
1314 {
return *begin(); }
1322 {
return *begin(); }
1331 iterator __tmp = end();
1343 const_iterator __tmp = end();
1359 push_front(
const value_type& __x)
1361 if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_first)
1363 this->_M_impl.construct(this->_M_impl._M_start._M_cur - 1, __x);
1364 --this->_M_impl._M_start._M_cur;
1367 _M_push_front_aux(__x);
1370 #if __cplusplus >= 201103L
1372 push_front(value_type&& __x)
1373 { emplace_front(std::move(__x)); }
1375 template<
typename... _Args>
1377 emplace_front(_Args&&... __args);
1390 push_back(
const value_type& __x)
1392 if (this->_M_impl._M_finish._M_cur
1393 != this->_M_impl._M_finish._M_last - 1)
1395 this->_M_impl.construct(this->_M_impl._M_finish._M_cur, __x);
1396 ++this->_M_impl._M_finish._M_cur;
1399 _M_push_back_aux(__x);
1402 #if __cplusplus >= 201103L
1404 push_back(value_type&& __x)
1405 { emplace_back(std::move(__x)); }
1407 template<
typename... _Args>
1409 emplace_back(_Args&&... __args);
1423 if (this->_M_impl._M_start._M_cur
1424 != this->_M_impl._M_start._M_last - 1)
1426 this->_M_impl.destroy(this->_M_impl._M_start._M_cur);
1427 ++this->_M_impl._M_start._M_cur;
1444 if (this->_M_impl._M_finish._M_cur
1445 != this->_M_impl._M_finish._M_first)
1447 --this->_M_impl._M_finish._M_cur;
1448 this->_M_impl.destroy(this->_M_impl._M_finish._M_cur);
1454 #if __cplusplus >= 201103L
1464 template<
typename... _Args>
1466 emplace(iterator __position, _Args&&... __args);
1479 insert(iterator __position,
const value_type& __x);
1481 #if __cplusplus >= 201103L
1492 insert(iterator __position, value_type&& __x)
1493 {
return emplace(__position, std::move(__x)); }
1505 insert(iterator __p, initializer_list<value_type> __l)
1506 { this->insert(__p, __l.begin(), __l.end()); }
1519 insert(iterator __position, size_type __n,
const value_type& __x)
1520 { _M_fill_insert(__position, __n, __x); }
1532 #if __cplusplus >= 201103L
1533 template<
typename _InputIterator,
1534 typename = std::_RequireInputIter<_InputIterator>>
1536 insert(iterator __position, _InputIterator __first,
1537 _InputIterator __last)
1538 { _M_insert_dispatch(__position, __first, __last, __false_type()); }
1540 template<
typename _InputIterator>
1542 insert(iterator __position, _InputIterator __first,
1543 _InputIterator __last)
1546 typedef typename std::__is_integer<_InputIterator>::__type _Integral;
1547 _M_insert_dispatch(__position, __first, __last, _Integral());
1565 erase(iterator __position);
1584 erase(iterator __first, iterator __last);
1598 std::swap(this->_M_impl._M_start, __x._M_impl._M_start);
1599 std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish);
1600 std::swap(this->_M_impl._M_map, __x._M_impl._M_map);
1601 std::swap(this->_M_impl._M_map_size, __x._M_impl._M_map_size);
1605 std::__alloc_swap<_Tp_alloc_type>::_S_do_it(_M_get_Tp_allocator(),
1606 __x._M_get_Tp_allocator());
1616 clear() _GLIBCXX_NOEXCEPT
1617 { _M_erase_at_end(begin()); }
1626 template<
typename _Integer>
1628 _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type)
1630 _M_initialize_map(static_cast<size_type>(__n));
1631 _M_fill_initialize(__x);
1635 template<
typename _InputIterator>
1637 _M_initialize_dispatch(_InputIterator __first, _InputIterator __last,
1640 typedef typename std::iterator_traits<_InputIterator>::
1641 iterator_category _IterCategory;
1642 _M_range_initialize(__first, __last, _IterCategory());
1657 template<
typename _InputIterator>
1659 _M_range_initialize(_InputIterator __first, _InputIterator __last,
1660 std::input_iterator_tag);
1663 template<
typename _ForwardIterator>
1665 _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last,
1666 std::forward_iterator_tag);
1680 _M_fill_initialize(
const value_type& __value);
1682 #if __cplusplus >= 201103L
1685 _M_default_initialize();
1695 template<
typename _Integer>
1697 _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
1698 { _M_fill_assign(__n, __val); }
1701 template<
typename _InputIterator>
1703 _M_assign_dispatch(_InputIterator __first, _InputIterator __last,
1706 typedef typename std::iterator_traits<_InputIterator>::
1707 iterator_category _IterCategory;
1708 _M_assign_aux(__first, __last, _IterCategory());
1712 template<
typename _InputIterator>
1714 _M_assign_aux(_InputIterator __first, _InputIterator __last,
1715 std::input_iterator_tag);
1718 template<
typename _ForwardIterator>
1720 _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
1721 std::forward_iterator_tag)
1723 const size_type __len = std::distance(__first, __last);
1726 _ForwardIterator __mid = __first;
1727 std::advance(__mid, size());
1728 std::copy(__first, __mid, begin());
1729 insert(end(), __mid, __last);
1732 _M_erase_at_end(std::copy(__first, __last, begin()));
1738 _M_fill_assign(size_type __n,
const value_type& __val)
1742 std::fill(begin(), end(), __val);
1743 insert(end(), __n - size(), __val);
1747 _M_erase_at_end(begin() + difference_type(__n));
1748 std::fill(begin(), end(), __val);
1753 #if __cplusplus < 201103L
1755 void _M_push_back_aux(
const value_type&);
1757 void _M_push_front_aux(
const value_type&);
1759 template<
typename... _Args>
1760 void _M_push_back_aux(_Args&&... __args);
1762 template<
typename... _Args>
1763 void _M_push_front_aux(_Args&&... __args);
1766 void _M_pop_back_aux();
1768 void _M_pop_front_aux();
1778 template<
typename _Integer>
1780 _M_insert_dispatch(iterator __pos,
1781 _Integer __n, _Integer __x, __true_type)
1782 { _M_fill_insert(__pos, __n, __x); }
1785 template<
typename _InputIterator>
1787 _M_insert_dispatch(iterator __pos,
1788 _InputIterator __first, _InputIterator __last,
1791 typedef typename std::iterator_traits<_InputIterator>::
1792 iterator_category _IterCategory;
1793 _M_range_insert_aux(__pos, __first, __last, _IterCategory());
1797 template<
typename _InputIterator>
1799 _M_range_insert_aux(iterator __pos, _InputIterator __first,
1800 _InputIterator __last, std::input_iterator_tag);
1803 template<
typename _ForwardIterator>
1805 _M_range_insert_aux(iterator __pos, _ForwardIterator __first,
1806 _ForwardIterator __last, std::forward_iterator_tag);
1812 _M_fill_insert(iterator __pos, size_type __n,
const value_type& __x);
1815 #if __cplusplus < 201103L
1817 _M_insert_aux(iterator __pos,
const value_type& __x);
1819 template<
typename... _Args>
1821 _M_insert_aux(iterator __pos, _Args&&... __args);
1826 _M_insert_aux(iterator __pos, size_type __n,
const value_type& __x);
1829 template<
typename _ForwardIterator>
1831 _M_insert_aux(iterator __pos,
1832 _ForwardIterator __first, _ForwardIterator __last,
1839 _M_destroy_data_aux(iterator __first, iterator __last);
1843 template<
typename _Alloc1>
1845 _M_destroy_data(iterator __first, iterator __last,
const _Alloc1&)
1846 { _M_destroy_data_aux(__first, __last); }
1849 _M_destroy_data(iterator __first, iterator __last,
1850 const std::allocator<_Tp>&)
1852 if (!__has_trivial_destructor(value_type))
1853 _M_destroy_data_aux(__first, __last);
1858 _M_erase_at_begin(iterator __pos)
1860 _M_destroy_data(begin(), __pos, _M_get_Tp_allocator());
1861 _M_destroy_nodes(this->_M_impl._M_start._M_node, __pos._M_node);
1862 this->_M_impl._M_start = __pos;
1868 _M_erase_at_end(iterator __pos)
1870 _M_destroy_data(__pos, end(), _M_get_Tp_allocator());
1871 _M_destroy_nodes(__pos._M_node + 1,
1872 this->_M_impl._M_finish._M_node + 1);
1873 this->_M_impl._M_finish = __pos;
1876 #if __cplusplus >= 201103L
1879 _M_default_append(size_type __n);
1888 _M_reserve_elements_at_front(size_type __n)
1890 const size_type __vacancies = this->_M_impl._M_start._M_cur
1891 - this->_M_impl._M_start._M_first;
1892 if (__n > __vacancies)
1893 _M_new_elements_at_front(__n - __vacancies);
1894 return this->_M_impl._M_start - difference_type(__n);
1898 _M_reserve_elements_at_back(size_type __n)
1900 const size_type __vacancies = (this->_M_impl._M_finish._M_last
1901 - this->_M_impl._M_finish._M_cur) - 1;
1902 if (__n > __vacancies)
1903 _M_new_elements_at_back(__n - __vacancies);
1904 return this->_M_impl._M_finish + difference_type(__n);
1908 _M_new_elements_at_front(size_type __new_elements);
1911 _M_new_elements_at_back(size_type __new_elements);
1924 _M_reserve_map_at_back(size_type __nodes_to_add = 1)
1926 if (__nodes_to_add + 1 > this->_M_impl._M_map_size
1927 - (this->_M_impl._M_finish._M_node - this->_M_impl._M_map))
1928 _M_reallocate_map(__nodes_to_add,
false);
1932 _M_reserve_map_at_front(size_type __nodes_to_add = 1)
1934 if (__nodes_to_add > size_type(this->_M_impl._M_start._M_node
1935 - this->_M_impl._M_map))
1936 _M_reallocate_map(__nodes_to_add,
true);
1940 _M_reallocate_map(size_type __nodes_to_add,
bool __add_at_front);
1955 template<
typename _Tp,
typename _Alloc>
1958 const deque<_Tp, _Alloc>& __y)
1959 {
return __x.size() == __y.size()
1960 && std::equal(__x.begin(), __x.end(), __y.begin()); }
1973 template<
typename _Tp,
typename _Alloc>
1975 operator<(const deque<_Tp, _Alloc>& __x,
1976 const deque<_Tp, _Alloc>& __y)
1977 {
return std::lexicographical_compare(__x.begin(), __x.end(),
1978 __y.begin(), __y.end()); }
1981 template<
typename _Tp,
typename _Alloc>
1984 const deque<_Tp, _Alloc>& __y)
1985 {
return !(__x == __y); }
1988 template<
typename _Tp,
typename _Alloc>
1990 operator>(
const deque<_Tp, _Alloc>& __x,
1991 const deque<_Tp, _Alloc>& __y)
1992 {
return __y < __x; }
1995 template<
typename _Tp,
typename _Alloc>
1997 operator<=(const deque<_Tp, _Alloc>& __x,
1998 const deque<_Tp, _Alloc>& __y)
1999 {
return !(__y < __x); }
2002 template<
typename _Tp,
typename _Alloc>
2005 const deque<_Tp, _Alloc>& __y)
2006 {
return !(__x < __y); }
2009 template<
typename _Tp,
typename _Alloc>
2011 swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y)
2014 #undef _GLIBCXX_DEQUE_BUF_SIZE
2016 _GLIBCXX_END_NAMESPACE_CONTAINER
bool operator>=(const _Safe_iterator< _IteratorL, _Sequence > &__lhs, const _Safe_iterator< _IteratorR, _Sequence > &__rhs)
Definition: safe_iterator.h:644
bool operator==(const exception_ptr &, const exception_ptr &) _GLIBCXX_USE_NOEXCEPT __attribute__((__pure__))
std::size_t __size(__stack_t __stack)
Definition: profiler_node.h:68
#define __try
Definition: exception_defines.h:35
#define __throw_exception_again
Definition: exception_defines.h:37
#define __glibcxx_class_requires(_a, _b)
Definition: concept_check.h:48
_Safe_iterator< _Iterator, _Sequence > operator+(typename _Safe_iterator< _Iterator, _Sequence >::difference_type __n, const _Safe_iterator< _Iterator, _Sequence > &__i)
Definition: safe_iterator.h:712
bool operator>(const _Safe_iterator< _IteratorL, _Sequence > &__lhs, const _Safe_iterator< _IteratorR, _Sequence > &__rhs)
Definition: safe_iterator.h:612
_Safe_iterator< _IteratorL, _Sequence >::difference_type operator-(const _Safe_iterator< _IteratorL, _Sequence > &__lhs, const _Safe_iterator< _IteratorR, _Sequence > &__rhs)
Definition: safe_iterator.h:680
#define __glibcxx_class_requires2(_a, _b, _c)
Definition: concept_check.h:49
bool operator!=(const exception_ptr &, const exception_ptr &) _GLIBCXX_USE_NOEXCEPT __attribute__((__pure__))
const _Tp & max(const _Tp &__a, const _Tp &__b)
Equivalent to std::max.
Definition: base.h:150
#define _GLIBCXX_DEQUE_BUF_SIZE
#define __catch(X)
Definition: exception_defines.h:36
__PTRDIFF_TYPE__ ptrdiff_t
Definition: stddef.h:147
void swap(exception_ptr &__lhs, exception_ptr &__rhs)
Definition: exception_ptr.h:160