stl_vector.h
| 1 |
// Vector implementation -*- C++ -*-
|
|---|---|
| 2 |
|
| 3 |
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
| 4 |
// 2011 Free Software Foundation, Inc.
|
| 5 |
//
|
| 6 |
// This file is part of the GNU ISO C++ Library. This library is free
|
| 7 |
// software; you can redistribute it and/or modify it under the
|
| 8 |
// terms of the GNU General Public License as published by the
|
| 9 |
// Free Software Foundation; either version 3, or (at your option)
|
| 10 |
// any later version.
|
| 11 |
|
| 12 |
// This library is distributed in the hope that it will be useful,
|
| 13 |
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 14 |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 15 |
// GNU General Public License for more details.
|
| 16 |
|
| 17 |
// Under Section 7 of GPL version 3, you are granted additional
|
| 18 |
// permissions described in the GCC Runtime Library Exception, version
|
| 19 |
// 3.1, as published by the Free Software Foundation.
|
| 20 |
|
| 21 |
// You should have received a copy of the GNU General Public License and
|
| 22 |
// a copy of the GCC Runtime Library Exception along with this program;
|
| 23 |
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
| 24 |
// <http://www.gnu.org/licenses/>.
|
| 25 |
|
| 26 |
/*
|
| 27 |
*
|
| 28 |
* Copyright (c) 1994
|
| 29 |
* Hewlett-Packard Company
|
| 30 |
*
|
| 31 |
* Permission to use, copy, modify, distribute and sell this software
|
| 32 |
* and its documentation for any purpose is hereby granted without fee,
|
| 33 |
* provided that the above copyright notice appear in all copies and
|
| 34 |
* that both that copyright notice and this permission notice appear
|
| 35 |
* in supporting documentation. Hewlett-Packard Company makes no
|
| 36 |
* representations about the suitability of this software for any
|
| 37 |
* purpose. It is provided "as is" without express or implied warranty.
|
| 38 |
*
|
| 39 |
*
|
| 40 |
* Copyright (c) 1996
|
| 41 |
* Silicon Graphics Computer Systems, Inc.
|
| 42 |
*
|
| 43 |
* Permission to use, copy, modify, distribute and sell this software
|
| 44 |
* and its documentation for any purpose is hereby granted without fee,
|
| 45 |
* provided that the above copyright notice appear in all copies and
|
| 46 |
* that both that copyright notice and this permission notice appear
|
| 47 |
* in supporting documentation. Silicon Graphics makes no
|
| 48 |
* representations about the suitability of this software for any
|
| 49 |
* purpose. It is provided "as is" without express or implied warranty.
|
| 50 |
*/
|
| 51 |
|
| 52 |
/** @file bits/stl_vector.h
|
| 53 |
* This is an internal header file, included by other library headers.
|
| 54 |
* Do not attempt to use it directly. @headername{vector}
|
| 55 |
*/
|
| 56 |
|
| 57 |
#ifndef _STL_VECTOR_H
|
| 58 |
#define _STL_VECTOR_H 1 |
| 59 |
|
| 60 |
#include <bits/stl_iterator_base_funcs.h> |
| 61 |
#include <bits/functexcept.h> |
| 62 |
#include <bits/concept_check.h> |
| 63 |
#include <initializer_list> |
| 64 |
|
| 65 |
namespace std _GLIBCXX_VISIBILITY(default)
|
| 66 |
{
|
| 67 |
_GLIBCXX_BEGIN_NAMESPACE_CONTAINER |
| 68 |
|
| 69 |
/// See bits/stl_deque.h's _Deque_base for an explanation.
|
| 70 |
template<typename _Tp, typename _Alloc> |
| 71 |
struct _Vector_base
|
| 72 |
{
|
| 73 |
typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type;
|
| 74 |
|
| 75 |
struct _Vector_impl
|
| 76 |
: public _Tp_alloc_type |
| 77 |
{
|
| 78 |
typename _Tp_alloc_type::pointer _M_start; |
| 79 |
typename _Tp_alloc_type::pointer _M_finish; |
| 80 |
typename _Tp_alloc_type::pointer _M_end_of_storage; |
| 81 |
|
| 82 |
_Vector_impl() |
| 83 |
: _Tp_alloc_type(), _M_start(0), _M_finish(0), _M_end_of_storage(0) |
| 84 |
{ }
|
| 85 |
|
| 86 |
_Vector_impl(_Tp_alloc_type const& __a)
|
| 87 |
: _Tp_alloc_type(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0) |
| 88 |
{ }
|
| 89 |
}; |
| 90 |
|
| 91 |
public:
|
| 92 |
typedef _Alloc allocator_type;
|
| 93 |
|
| 94 |
_Tp_alloc_type& |
| 95 |
_M_get_Tp_allocator() |
| 96 |
{ return *static_cast<_Tp_alloc_type*>(&this->_M_impl); }
|
| 97 |
|
| 98 |
const _Tp_alloc_type&
|
| 99 |
_M_get_Tp_allocator() const
|
| 100 |
{ return *static_cast<const _Tp_alloc_type*>(&this->_M_impl); }
|
| 101 |
|
| 102 |
allocator_type |
| 103 |
get_allocator() const
|
| 104 |
{ return allocator_type(_M_get_Tp_allocator()); }
|
| 105 |
|
| 106 |
_Vector_base() |
| 107 |
: _M_impl() { }
|
| 108 |
|
| 109 |
_Vector_base(const allocator_type& __a)
|
| 110 |
: _M_impl(__a) { }
|
| 111 |
|
| 112 |
_Vector_base(size_t __n) |
| 113 |
: _M_impl() |
| 114 |
{
|
| 115 |
this->_M_impl._M_start = this->_M_allocate(__n); |
| 116 |
this->_M_impl._M_finish = this->_M_impl._M_start; |
| 117 |
this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; |
| 118 |
} |
| 119 |
|
| 120 |
_Vector_base(size_t __n, const allocator_type& __a)
|
| 121 |
: _M_impl(__a) |
| 122 |
{
|
| 123 |
this->_M_impl._M_start = this->_M_allocate(__n); |
| 124 |
this->_M_impl._M_finish = this->_M_impl._M_start; |
| 125 |
this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; |
| 126 |
} |
| 127 |
|
| 128 |
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
| 129 |
_Vector_base(_Vector_base&& __x) |
| 130 |
: _M_impl(__x._M_get_Tp_allocator()) |
| 131 |
{
|
| 132 |
this->_M_impl._M_start = __x._M_impl._M_start; |
| 133 |
this->_M_impl._M_finish = __x._M_impl._M_finish; |
| 134 |
this->_M_impl._M_end_of_storage = __x._M_impl._M_end_of_storage; |
| 135 |
__x._M_impl._M_start = 0;
|
| 136 |
__x._M_impl._M_finish = 0;
|
| 137 |
__x._M_impl._M_end_of_storage = 0;
|
| 138 |
} |
| 139 |
#endif
|
| 140 |
|
| 141 |
~_Vector_base() |
| 142 |
{ _M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage
|
| 143 |
- this->_M_impl._M_start); } |
| 144 |
|
| 145 |
public:
|
| 146 |
_Vector_impl _M_impl; |
| 147 |
|
| 148 |
typename _Tp_alloc_type::pointer |
| 149 |
_M_allocate(size_t __n) |
| 150 |
{ return __n != 0 ? _M_impl.allocate(__n) : 0; }
|
| 151 |
|
| 152 |
void
|
| 153 |
_M_deallocate(typename _Tp_alloc_type::pointer __p, size_t __n) |
| 154 |
{
|
| 155 |
if (__p)
|
| 156 |
_M_impl.deallocate(__p, __n); |
| 157 |
} |
| 158 |
}; |
| 159 |
|
| 160 |
|
| 161 |
/**
|
| 162 |
* @brief A standard container which offers fixed time access to
|
| 163 |
* individual elements in any order.
|
| 164 |
*
|
| 165 |
* @ingroup sequences
|
| 166 |
*
|
| 167 |
* Meets the requirements of a <a href="tables.html#65">container</a>, a
|
| 168 |
* <a href="tables.html#66">reversible container</a>, and a
|
| 169 |
* <a href="tables.html#67">sequence</a>, including the
|
| 170 |
* <a href="tables.html#68">optional sequence requirements</a> with the
|
| 171 |
* %exception of @c push_front and @c pop_front.
|
| 172 |
*
|
| 173 |
* In some terminology a %vector can be described as a dynamic
|
| 174 |
* C-style array, it offers fast and efficient access to individual
|
| 175 |
* elements in any order and saves the user from worrying about
|
| 176 |
* memory and size allocation. Subscripting ( @c [] ) access is
|
| 177 |
* also provided as with C-style arrays.
|
| 178 |
*/
|
| 179 |
template<typename _Tp, typename _Alloc = std::allocator<_Tp> > |
| 180 |
class vector : protected _Vector_base<_Tp, _Alloc> |
| 181 |
{
|
| 182 |
// Concept requirements.
|
| 183 |
typedef typename _Alloc::value_type _Alloc_value_type;
|
| 184 |
__glibcxx_class_requires(_Tp, _SGIAssignableConcept) |
| 185 |
__glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept) |
| 186 |
|
| 187 |
typedef _Vector_base<_Tp, _Alloc> _Base;
|
| 188 |
typedef typename _Base::_Tp_alloc_type _Tp_alloc_type;
|
| 189 |
|
| 190 |
public:
|
| 191 |
typedef _Tp value_type;
|
| 192 |
typedef typename _Tp_alloc_type::pointer pointer;
|
| 193 |
typedef typename _Tp_alloc_type::const_pointer const_pointer;
|
| 194 |
typedef typename _Tp_alloc_type::reference reference;
|
| 195 |
typedef typename _Tp_alloc_type::const_reference const_reference;
|
| 196 |
typedef __gnu_cxx::__normal_iterator<pointer, vector> iterator;
|
| 197 |
typedef __gnu_cxx::__normal_iterator<const_pointer, vector>
|
| 198 |
const_iterator; |
| 199 |
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
| 200 |
typedef std::reverse_iterator<iterator> reverse_iterator;
|
| 201 |
typedef size_t size_type;
|
| 202 |
typedef ptrdiff_t difference_type;
|
| 203 |
typedef _Alloc allocator_type;
|
| 204 |
|
| 205 |
protected:
|
| 206 |
using _Base::_M_allocate; |
| 207 |
using _Base::_M_deallocate; |
| 208 |
using _Base::_M_impl; |
| 209 |
using _Base::_M_get_Tp_allocator; |
| 210 |
|
| 211 |
bool _M_is_valid() const |
| 212 |
{
|
| 213 |
return (this->_M_impl._M_end_of_storage == 0 |
| 214 |
&& this->_M_impl._M_start == 0
|
| 215 |
&& this->_M_impl._M_finish == 0)
|
| 216 |
|| (this->_M_impl._M_start <= this->_M_impl._M_finish |
| 217 |
&& this->_M_impl._M_finish <= this->_M_impl._M_end_of_storage |
| 218 |
&& this->_M_impl._M_start < this->_M_impl._M_end_of_storage); |
| 219 |
} |
| 220 |
|
| 221 |
public:
|
| 222 |
// [23.2.4.1] construct/copy/destroy
|
| 223 |
// (assign() and get_allocator() are also listed in this section)
|
| 224 |
/**
|
| 225 |
* @brief Default constructor creates no elements.
|
| 226 |
*/
|
| 227 |
vector() |
| 228 |
: _Base() { }
|
| 229 |
|
| 230 |
/**
|
| 231 |
* @brief Creates a %vector with no elements.
|
| 232 |
* @param a An allocator object.
|
| 233 |
*/
|
| 234 |
explicit |
| 235 |
vector(const allocator_type& __a)
|
| 236 |
: _Base(__a) { }
|
| 237 |
|
| 238 |
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
| 239 |
/**
|
| 240 |
* @brief Creates a %vector with default constructed elements.
|
| 241 |
* @param n The number of elements to initially create.
|
| 242 |
*
|
| 243 |
* This constructor fills the %vector with @a n default
|
| 244 |
* constructed elements.
|
| 245 |
*/
|
| 246 |
explicit |
| 247 |
vector(size_type __n) |
| 248 |
: _Base(__n) |
| 249 |
{ _M_default_initialize(__n); }
|
| 250 |
|
| 251 |
/**
|
| 252 |
* @brief Creates a %vector with copies of an exemplar element.
|
| 253 |
* @param n The number of elements to initially create.
|
| 254 |
* @param value An element to copy.
|
| 255 |
* @param a An allocator.
|
| 256 |
*
|
| 257 |
* This constructor fills the %vector with @a n copies of @a value.
|
| 258 |
*/
|
| 259 |
vector(size_type __n, const value_type& __value,
|
| 260 |
const allocator_type& __a = allocator_type())
|
| 261 |
: _Base(__n, __a) |
| 262 |
{ _M_fill_initialize(__n, __value); }
|
| 263 |
#else
|
| 264 |
/**
|
| 265 |
* @brief Creates a %vector with copies of an exemplar element.
|
| 266 |
* @param n The number of elements to initially create.
|
| 267 |
* @param value An element to copy.
|
| 268 |
* @param a An allocator.
|
| 269 |
*
|
| 270 |
* This constructor fills the %vector with @a n copies of @a value.
|
| 271 |
*/
|
| 272 |
explicit |
| 273 |
vector(size_type __n, const value_type& __value = value_type(),
|
| 274 |
const allocator_type& __a = allocator_type())
|
| 275 |
: _Base(__n, __a) |
| 276 |
{ _M_fill_initialize(__n, __value); }
|
| 277 |
#endif
|
| 278 |
|
| 279 |
/**
|
| 280 |
* @brief %Vector copy constructor.
|
| 281 |
* @param x A %vector of identical element and allocator types.
|
| 282 |
*
|
| 283 |
* The newly-created %vector uses a copy of the allocation
|
| 284 |
* object used by @a x. All the elements of @a x are copied,
|
| 285 |
* but any extra memory in
|
| 286 |
* @a x (for fast expansion) will not be copied.
|
| 287 |
*/
|
| 288 |
vector(const vector& __x)
|
| 289 |
: _Base(__x.size(), __x._M_get_Tp_allocator()) |
| 290 |
{ this->_M_impl._M_finish =
|
| 291 |
std::__uninitialized_copy_a(__x.begin(), __x.end(), |
| 292 |
this->_M_impl._M_start, |
| 293 |
_M_get_Tp_allocator()); |
| 294 |
} |
| 295 |
|
| 296 |
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
| 297 |
/**
|
| 298 |
* @brief %Vector move constructor.
|
| 299 |
* @param x A %vector of identical element and allocator types.
|
| 300 |
*
|
| 301 |
* The newly-created %vector contains the exact contents of @a x.
|
| 302 |
* The contents of @a x are a valid, but unspecified %vector.
|
| 303 |
*/
|
| 304 |
vector(vector&& __x) |
| 305 |
: _Base(std::move(__x)) { }
|
| 306 |
|
| 307 |
/**
|
| 308 |
* @brief Builds a %vector from an initializer list.
|
| 309 |
* @param l An initializer_list.
|
| 310 |
* @param a An allocator.
|
| 311 |
*
|
| 312 |
* Create a %vector consisting of copies of the elements in the
|
| 313 |
* initializer_list @a l.
|
| 314 |
*
|
| 315 |
* This will call the element type's copy constructor N times
|
| 316 |
* (where N is @a l.size()) and do no memory reallocation.
|
| 317 |
*/
|
| 318 |
vector(initializer_list<value_type> __l, |
| 319 |
const allocator_type& __a = allocator_type())
|
| 320 |
: _Base(__a) |
| 321 |
{
|
| 322 |
_M_range_initialize(__l.begin(), __l.end(), |
| 323 |
random_access_iterator_tag()); |
| 324 |
} |
| 325 |
#endif
|
| 326 |
|
| 327 |
/**
|
| 328 |
* @brief Builds a %vector from a range.
|
| 329 |
* @param first An input iterator.
|
| 330 |
* @param last An input iterator.
|
| 331 |
* @param a An allocator.
|
| 332 |
*
|
| 333 |
* Create a %vector consisting of copies of the elements from
|
| 334 |
* [first,last).
|
| 335 |
*
|
| 336 |
* If the iterators are forward, bidirectional, or
|
| 337 |
* random-access, then this will call the elements' copy
|
| 338 |
* constructor N times (where N is distance(first,last)) and do
|
| 339 |
* no memory reallocation. But if only input iterators are
|
| 340 |
* used, then this will do at most 2N calls to the copy
|
| 341 |
* constructor, and logN memory reallocations.
|
| 342 |
*/
|
| 343 |
template<typename _InputIterator> |
| 344 |
vector(_InputIterator __first, _InputIterator __last, |
| 345 |
const allocator_type& __a = allocator_type())
|
| 346 |
: _Base(__a) |
| 347 |
{
|
| 348 |
// Check whether it's an integral type. If so, it's not an iterator.
|
| 349 |
typedef typename std::__is_integer<_InputIterator>::__type _Integral;
|
| 350 |
_M_initialize_dispatch(__first, __last, _Integral()); |
| 351 |
} |
| 352 |
|
| 353 |
/**
|
| 354 |
* The dtor only erases the elements, and note that if the
|
| 355 |
* elements themselves are pointers, the pointed-to memory is
|
| 356 |
* not touched in any way. Managing the pointer is the user's
|
| 357 |
* responsibility.
|
| 358 |
*/
|
| 359 |
~vector() |
| 360 |
{ std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
|
| 361 |
_M_get_Tp_allocator()); } |
| 362 |
|
| 363 |
/**
|
| 364 |
* @brief %Vector assignment operator.
|
| 365 |
* @param x A %vector of identical element and allocator types.
|
| 366 |
*
|
| 367 |
* All the elements of @a x are copied, but any extra memory in
|
| 368 |
* @a x (for fast expansion) will not be copied. Unlike the
|
| 369 |
* copy constructor, the allocator object is not copied.
|
| 370 |
*/
|
| 371 |
vector& |
| 372 |
operator=(const vector& __x);
|
| 373 |
|
| 374 |
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
| 375 |
/**
|
| 376 |
* @brief %Vector move assignment operator.
|
| 377 |
* @param x A %vector of identical element and allocator types.
|
| 378 |
*
|
| 379 |
* The contents of @a x are moved into this %vector (without copying).
|
| 380 |
* @a x is a valid, but unspecified %vector.
|
| 381 |
*/
|
| 382 |
vector& |
| 383 |
operator=(vector&& __x) |
| 384 |
{
|
| 385 |
// NB: DR 1204.
|
| 386 |
// NB: DR 675.
|
| 387 |
this->clear(); |
| 388 |
this->swap(__x); |
| 389 |
return *this;
|
| 390 |
} |
| 391 |
|
| 392 |
/**
|
| 393 |
* @brief %Vector list assignment operator.
|
| 394 |
* @param l An initializer_list.
|
| 395 |
*
|
| 396 |
* This function fills a %vector with copies of the elements in the
|
| 397 |
* initializer list @a l.
|
| 398 |
*
|
| 399 |
* Note that the assignment completely changes the %vector and
|
| 400 |
* that the resulting %vector's size is the same as the number
|
| 401 |
* of elements assigned. Old data may be lost.
|
| 402 |
*/
|
| 403 |
vector& |
| 404 |
operator=(initializer_list<value_type> __l) |
| 405 |
{
|
| 406 |
this->assign(__l.begin(), __l.end()); |
| 407 |
return *this;
|
| 408 |
} |
| 409 |
#endif
|
| 410 |
|
| 411 |
/**
|
| 412 |
* @brief Assigns a given value to a %vector.
|
| 413 |
* @param n Number of elements to be assigned.
|
| 414 |
* @param val Value to be assigned.
|
| 415 |
*
|
| 416 |
* This function fills a %vector with @a n copies of the given
|
| 417 |
* value. Note that the assignment completely changes the
|
| 418 |
* %vector and that the resulting %vector's size is the same as
|
| 419 |
* the number of elements assigned. Old data may be lost.
|
| 420 |
*/
|
| 421 |
void
|
| 422 |
assign(size_type __n, const value_type& __val)
|
| 423 |
{ _M_fill_assign(__n, __val); }
|
| 424 |
|
| 425 |
/**
|
| 426 |
* @brief Assigns a range to a %vector.
|
| 427 |
* @param first An input iterator.
|
| 428 |
* @param last An input iterator.
|
| 429 |
*
|
| 430 |
* This function fills a %vector with copies of the elements in the
|
| 431 |
* range [first,last).
|
| 432 |
*
|
| 433 |
* Note that the assignment completely changes the %vector and
|
| 434 |
* that the resulting %vector's size is the same as the number
|
| 435 |
* of elements assigned. Old data may be lost.
|
| 436 |
*/
|
| 437 |
template<typename _InputIterator> |
| 438 |
void
|
| 439 |
assign(_InputIterator __first, _InputIterator __last) |
| 440 |
{
|
| 441 |
// Check whether it's an integral type. If so, it's not an iterator.
|
| 442 |
typedef typename std::__is_integer<_InputIterator>::__type _Integral;
|
| 443 |
_M_assign_dispatch(__first, __last, _Integral()); |
| 444 |
} |
| 445 |
|
| 446 |
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
| 447 |
/**
|
| 448 |
* @brief Assigns an initializer list to a %vector.
|
| 449 |
* @param l An initializer_list.
|
| 450 |
*
|
| 451 |
* This function fills a %vector with copies of the elements in the
|
| 452 |
* initializer list @a l.
|
| 453 |
*
|
| 454 |
* Note that the assignment completely changes the %vector and
|
| 455 |
* that the resulting %vector's size is the same as the number
|
| 456 |
* of elements assigned. Old data may be lost.
|
| 457 |
*/
|
| 458 |
void
|
| 459 |
assign(initializer_list<value_type> __l) |
| 460 |
{ this->assign(__l.begin(), __l.end()); }
|
| 461 |
#endif
|
| 462 |
|
| 463 |
/// Get a copy of the memory allocation object.
|
| 464 |
using _Base::get_allocator; |
| 465 |
|
| 466 |
// iterators
|
| 467 |
/**
|
| 468 |
* Returns a read/write iterator that points to the first
|
| 469 |
* element in the %vector. Iteration is done in ordinary
|
| 470 |
* element order.
|
| 471 |
*/
|
| 472 |
iterator |
| 473 |
begin() |
| 474 |
{
|
| 475 |
#if __google_stl_debug_dangling_vector
|
| 476 |
if (!this->_M_is_valid())
|
| 477 |
__throw_logic_error("begin() on corrupt (dangling?) vector");
|
| 478 |
#endif
|
| 479 |
return iterator(this->_M_impl._M_start);
|
| 480 |
} |
| 481 |
|
| 482 |
/**
|
| 483 |
* Returns a read-only (constant) iterator that points to the
|
| 484 |
* first element in the %vector. Iteration is done in ordinary
|
| 485 |
* element order.
|
| 486 |
*/
|
| 487 |
const_iterator |
| 488 |
begin() const
|
| 489 |
{
|
| 490 |
#if __google_stl_debug_dangling_vector
|
| 491 |
if (!this->_M_is_valid())
|
| 492 |
__throw_logic_error("begin() on corrupt (dangling?) vector");
|
| 493 |
#endif
|
| 494 |
return const_iterator(this->_M_impl._M_start);
|
| 495 |
} |
| 496 |
|
| 497 |
/**
|
| 498 |
* Returns a read/write iterator that points one past the last
|
| 499 |
* element in the %vector. Iteration is done in ordinary
|
| 500 |
* element order.
|
| 501 |
*/
|
| 502 |
iterator |
| 503 |
end() |
| 504 |
{
|
| 505 |
#if __google_stl_debug_dangling_vector
|
| 506 |
if (!this->_M_is_valid())
|
| 507 |
__throw_logic_error("end() on corrupt (dangling?) vector");
|
| 508 |
#endif
|
| 509 |
return iterator(this->_M_impl._M_finish);
|
| 510 |
} |
| 511 |
|
| 512 |
/**
|
| 513 |
* Returns a read-only (constant) iterator that points one past
|
| 514 |
* the last element in the %vector. Iteration is done in
|
| 515 |
* ordinary element order.
|
| 516 |
*/
|
| 517 |
const_iterator |
| 518 |
end() const
|
| 519 |
{
|
| 520 |
#if __google_stl_debug_dangling_vector
|
| 521 |
if (!this->_M_is_valid())
|
| 522 |
__throw_logic_error("end() on corrupt (dangling?) vector");
|
| 523 |
#endif
|
| 524 |
return const_iterator(this->_M_impl._M_finish);
|
| 525 |
} |
| 526 |
|
| 527 |
/**
|
| 528 |
* Returns a read/write reverse iterator that points to the
|
| 529 |
* last element in the %vector. Iteration is done in reverse
|
| 530 |
* element order.
|
| 531 |
*/
|
| 532 |
reverse_iterator |
| 533 |
rbegin() |
| 534 |
{ return reverse_iterator(end()); }
|
| 535 |
|
| 536 |
/**
|
| 537 |
* Returns a read-only (constant) reverse iterator that points
|
| 538 |
* to the last element in the %vector. Iteration is done in
|
| 539 |
* reverse element order.
|
| 540 |
*/
|
| 541 |
const_reverse_iterator |
| 542 |
rbegin() const
|
| 543 |
{ return const_reverse_iterator(end()); }
|
| 544 |
|
| 545 |
/**
|
| 546 |
* Returns a read/write reverse iterator that points to one
|
| 547 |
* before the first element in the %vector. Iteration is done
|
| 548 |
* in reverse element order.
|
| 549 |
*/
|
| 550 |
reverse_iterator |
| 551 |
rend() |
| 552 |
{ return reverse_iterator(begin()); }
|
| 553 |
|
| 554 |
/**
|
| 555 |
* Returns a read-only (constant) reverse iterator that points
|
| 556 |
* to one before the first element in the %vector. Iteration
|
| 557 |
* is done in reverse element order.
|
| 558 |
*/
|
| 559 |
const_reverse_iterator |
| 560 |
rend() const
|
| 561 |
{ return const_reverse_iterator(begin()); }
|
| 562 |
|
| 563 |
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
| 564 |
/**
|
| 565 |
* Returns a read-only (constant) iterator that points to the
|
| 566 |
* first element in the %vector. Iteration is done in ordinary
|
| 567 |
* element order.
|
| 568 |
*/
|
| 569 |
const_iterator |
| 570 |
cbegin() const
|
| 571 |
{ return const_iterator(this->_M_impl._M_start); }
|
| 572 |
|
| 573 |
/**
|
| 574 |
* Returns a read-only (constant) iterator that points one past
|
| 575 |
* the last element in the %vector. Iteration is done in
|
| 576 |
* ordinary element order.
|
| 577 |
*/
|
| 578 |
const_iterator |
| 579 |
cend() const
|
| 580 |
{ return const_iterator(this->_M_impl._M_finish); }
|
| 581 |
|
| 582 |
/**
|
| 583 |
* Returns a read-only (constant) reverse iterator that points
|
| 584 |
* to the last element in the %vector. Iteration is done in
|
| 585 |
* reverse element order.
|
| 586 |
*/
|
| 587 |
const_reverse_iterator |
| 588 |
crbegin() const
|
| 589 |
{ return const_reverse_iterator(end()); }
|
| 590 |
|
| 591 |
/**
|
| 592 |
* Returns a read-only (constant) reverse iterator that points
|
| 593 |
* to one before the first element in the %vector. Iteration
|
| 594 |
* is done in reverse element order.
|
| 595 |
*/
|
| 596 |
const_reverse_iterator |
| 597 |
crend() const
|
| 598 |
{ return const_reverse_iterator(begin()); }
|
| 599 |
#endif
|
| 600 |
|
| 601 |
// [23.2.4.2] capacity
|
| 602 |
/** Returns the number of elements in the %vector. */
|
| 603 |
size_type |
| 604 |
size() const
|
| 605 |
{
|
| 606 |
#if __google_stl_debug_dangling_vector
|
| 607 |
if (!this->_M_is_valid())
|
| 608 |
__throw_logic_error("size() on corrupt (dangling?) vector");
|
| 609 |
#endif
|
| 610 |
return size_type(this->_M_impl._M_finish - this->_M_impl._M_start);
|
| 611 |
} |
| 612 |
|
| 613 |
/** Returns the size() of the largest possible %vector. */
|
| 614 |
size_type |
| 615 |
max_size() const
|
| 616 |
{ return _M_get_Tp_allocator().max_size(); }
|
| 617 |
|
| 618 |
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
| 619 |
/**
|
| 620 |
* @brief Resizes the %vector to the specified number of elements.
|
| 621 |
* @param new_size Number of elements the %vector should contain.
|
| 622 |
*
|
| 623 |
* This function will %resize the %vector to the specified
|
| 624 |
* number of elements. If the number is smaller than the
|
| 625 |
* %vector's current size the %vector is truncated, otherwise
|
| 626 |
* default constructed elements are appended.
|
| 627 |
*/
|
| 628 |
void
|
| 629 |
resize(size_type __new_size) |
| 630 |
{
|
| 631 |
if (__new_size > size())
|
| 632 |
_M_default_append(__new_size - size()); |
| 633 |
else if (__new_size < size()) |
| 634 |
_M_erase_at_end(this->_M_impl._M_start + __new_size); |
| 635 |
} |
| 636 |
|
| 637 |
/**
|
| 638 |
* @brief Resizes the %vector to the specified number of elements.
|
| 639 |
* @param new_size Number of elements the %vector should contain.
|
| 640 |
* @param x Data with which new elements should be populated.
|
| 641 |
*
|
| 642 |
* This function will %resize the %vector to the specified
|
| 643 |
* number of elements. If the number is smaller than the
|
| 644 |
* %vector's current size the %vector is truncated, otherwise
|
| 645 |
* the %vector is extended and new elements are populated with
|
| 646 |
* given data.
|
| 647 |
*/
|
| 648 |
void
|
| 649 |
resize(size_type __new_size, const value_type& __x)
|
| 650 |
{
|
| 651 |
if (__new_size > size())
|
| 652 |
insert(end(), __new_size - size(), __x); |
| 653 |
else if (__new_size < size()) |
| 654 |
_M_erase_at_end(this->_M_impl._M_start + __new_size); |
| 655 |
} |
| 656 |
#else
|
| 657 |
/**
|
| 658 |
* @brief Resizes the %vector to the specified number of elements.
|
| 659 |
* @param new_size Number of elements the %vector should contain.
|
| 660 |
* @param x Data with which new elements should be populated.
|
| 661 |
*
|
| 662 |
* This function will %resize the %vector to the specified
|
| 663 |
* number of elements. If the number is smaller than the
|
| 664 |
* %vector's current size the %vector is truncated, otherwise
|
| 665 |
* the %vector is extended and new elements are populated with
|
| 666 |
* given data.
|
| 667 |
*/
|
| 668 |
void
|
| 669 |
resize(size_type __new_size, value_type __x = value_type()) |
| 670 |
{
|
| 671 |
if (__new_size > size())
|
| 672 |
insert(end(), __new_size - size(), __x); |
| 673 |
else if (__new_size < size()) |
| 674 |
_M_erase_at_end(this->_M_impl._M_start + __new_size); |
| 675 |
} |
| 676 |
#endif
|
| 677 |
|
| 678 |
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
| 679 |
/** A non-binding request to reduce capacity() to size(). */
|
| 680 |
void
|
| 681 |
shrink_to_fit() |
| 682 |
{ std::__shrink_to_fit<vector>::_S_do_it(*this); }
|
| 683 |
#endif
|
| 684 |
|
| 685 |
/**
|
| 686 |
* Returns the total number of elements that the %vector can
|
| 687 |
* hold before needing to allocate more memory.
|
| 688 |
*/
|
| 689 |
size_type |
| 690 |
capacity() const
|
| 691 |
{
|
| 692 |
#if __google_stl_debug_dangling_vector
|
| 693 |
if (!this->_M_is_valid())
|
| 694 |
__throw_logic_error("capacity() on corrupt (dangling?) vector");
|
| 695 |
#endif
|
| 696 |
return size_type(this->_M_impl._M_end_of_storage
|
| 697 |
- this->_M_impl._M_start); } |
| 698 |
|
| 699 |
/**
|
| 700 |
* Returns true if the %vector is empty. (Thus begin() would
|
| 701 |
* equal end().)
|
| 702 |
*/
|
| 703 |
bool
|
| 704 |
empty() const
|
| 705 |
{ return begin() == end(); }
|
| 706 |
|
| 707 |
/**
|
| 708 |
* @brief Attempt to preallocate enough memory for specified number of
|
| 709 |
* elements.
|
| 710 |
* @param n Number of elements required.
|
| 711 |
* @throw std::length_error If @a n exceeds @c max_size().
|
| 712 |
*
|
| 713 |
* This function attempts to reserve enough memory for the
|
| 714 |
* %vector to hold the specified number of elements. If the
|
| 715 |
* number requested is more than max_size(), length_error is
|
| 716 |
* thrown.
|
| 717 |
*
|
| 718 |
* The advantage of this function is that if optimal code is a
|
| 719 |
* necessity and the user can determine the number of elements
|
| 720 |
* that will be required, the user can reserve the memory in
|
| 721 |
* %advance, and thus prevent a possible reallocation of memory
|
| 722 |
* and copying of %vector data.
|
| 723 |
*/
|
| 724 |
void
|
| 725 |
reserve(size_type __n); |
| 726 |
|
| 727 |
// element access
|
| 728 |
/**
|
| 729 |
* @brief Subscript access to the data contained in the %vector.
|
| 730 |
* @param n The index of the element for which data should be
|
| 731 |
* accessed.
|
| 732 |
* @return Read/write reference to data.
|
| 733 |
*
|
| 734 |
* This operator allows for easy, array-style, data access.
|
| 735 |
* Note that data access with this operator is unchecked and
|
| 736 |
* out_of_range lookups are not defined. (For checked lookups
|
| 737 |
* see at().)
|
| 738 |
*
|
| 739 |
* Local modification: range checks are performed if
|
| 740 |
* __google_stl_debug_vector is defined to non-zero.
|
| 741 |
*/
|
| 742 |
reference |
| 743 |
operator[](size_type __n) |
| 744 |
{
|
| 745 |
#if __google_stl_debug_vector
|
| 746 |
_M_range_check(__n); |
| 747 |
#endif
|
| 748 |
return *(this->_M_impl._M_start + __n);
|
| 749 |
} |
| 750 |
|
| 751 |
/**
|
| 752 |
* @brief Subscript access to the data contained in the %vector.
|
| 753 |
* @param n The index of the element for which data should be
|
| 754 |
* accessed.
|
| 755 |
* @return Read-only (constant) reference to data.
|
| 756 |
*
|
| 757 |
* This operator allows for easy, array-style, data access.
|
| 758 |
* Note that data access with this operator is unchecked and
|
| 759 |
* out_of_range lookups are not defined. (For checked lookups
|
| 760 |
* see at().)
|
| 761 |
*
|
| 762 |
* Local modification: range checks are performed if
|
| 763 |
* __google_stl_debug_vector is defined to non-zero.
|
| 764 |
*/
|
| 765 |
const_reference |
| 766 |
operator[](size_type __n) const
|
| 767 |
{
|
| 768 |
#if __google_stl_debug_vector
|
| 769 |
_M_range_check(__n); |
| 770 |
#endif
|
| 771 |
return *(this->_M_impl._M_start + __n);
|
| 772 |
} |
| 773 |
|
| 774 |
protected:
|
| 775 |
/// Safety check used only from at().
|
| 776 |
void
|
| 777 |
_M_range_check(size_type __n) const
|
| 778 |
{
|
| 779 |
if (__n >= this->size())
|
| 780 |
__throw_out_of_range(__N("vector::_M_range_check"));
|
| 781 |
} |
| 782 |
|
| 783 |
public:
|
| 784 |
/**
|
| 785 |
* @brief Provides access to the data contained in the %vector.
|
| 786 |
* @param n The index of the element for which data should be
|
| 787 |
* accessed.
|
| 788 |
* @return Read/write reference to data.
|
| 789 |
* @throw std::out_of_range If @a n is an invalid index.
|
| 790 |
*
|
| 791 |
* This function provides for safer data access. The parameter
|
| 792 |
* is first checked that it is in the range of the vector. The
|
| 793 |
* function throws out_of_range if the check fails.
|
| 794 |
*/
|
| 795 |
reference |
| 796 |
at(size_type __n) |
| 797 |
{
|
| 798 |
_M_range_check(__n); |
| 799 |
return (*this)[__n];
|
| 800 |
} |
| 801 |
|
| 802 |
/**
|
| 803 |
* @brief Provides access to the data contained in the %vector.
|
| 804 |
* @param n The index of the element for which data should be
|
| 805 |
* accessed.
|
| 806 |
* @return Read-only (constant) reference to data.
|
| 807 |
* @throw std::out_of_range If @a n is an invalid index.
|
| 808 |
*
|
| 809 |
* This function provides for safer data access. The parameter
|
| 810 |
* is first checked that it is in the range of the vector. The
|
| 811 |
* function throws out_of_range if the check fails.
|
| 812 |
*/
|
| 813 |
const_reference |
| 814 |
at(size_type __n) const
|
| 815 |
{
|
| 816 |
_M_range_check(__n); |
| 817 |
return (*this)[__n];
|
| 818 |
} |
| 819 |
|
| 820 |
/**
|
| 821 |
* Returns a read/write reference to the data at the first
|
| 822 |
* element of the %vector.
|
| 823 |
*/
|
| 824 |
reference |
| 825 |
front() |
| 826 |
{ return *begin(); }
|
| 827 |
|
| 828 |
/**
|
| 829 |
* Returns a read-only (constant) reference to the data at the first
|
| 830 |
* element of the %vector.
|
| 831 |
*/
|
| 832 |
const_reference |
| 833 |
front() const
|
| 834 |
{ return *begin(); }
|
| 835 |
|
| 836 |
/**
|
| 837 |
* Returns a read/write reference to the data at the last
|
| 838 |
* element of the %vector.
|
| 839 |
*/
|
| 840 |
reference |
| 841 |
back() |
| 842 |
{ return *(end() - 1); }
|
| 843 |
|
| 844 |
/**
|
| 845 |
* Returns a read-only (constant) reference to the data at the
|
| 846 |
* last element of the %vector.
|
| 847 |
*/
|
| 848 |
const_reference |
| 849 |
back() const
|
| 850 |
{ return *(end() - 1); }
|
| 851 |
|
| 852 |
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
| 853 |
// DR 464. Suggestion for new member functions in standard containers.
|
| 854 |
// data access
|
| 855 |
/**
|
| 856 |
* Returns a pointer such that [data(), data() + size()) is a valid
|
| 857 |
* range. For a non-empty %vector, data() == &front().
|
| 858 |
*/
|
| 859 |
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
| 860 |
_Tp* |
| 861 |
#else
|
| 862 |
pointer |
| 863 |
#endif
|
| 864 |
data() |
| 865 |
{ return std::__addressof(front()); }
|
| 866 |
|
| 867 |
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
| 868 |
const _Tp*
|
| 869 |
#else
|
| 870 |
const_pointer |
| 871 |
#endif
|
| 872 |
data() const
|
| 873 |
{ return std::__addressof(front()); }
|
| 874 |
|
| 875 |
// [23.2.4.3] modifiers
|
| 876 |
/**
|
| 877 |
* @brief Add data to the end of the %vector.
|
| 878 |
* @param x Data to be added.
|
| 879 |
*
|
| 880 |
* This is a typical stack operation. The function creates an
|
| 881 |
* element at the end of the %vector and assigns the given data
|
| 882 |
* to it. Due to the nature of a %vector this operation can be
|
| 883 |
* done in constant time if the %vector has preallocated space
|
| 884 |
* available.
|
| 885 |
*/
|
| 886 |
void
|
| 887 |
push_back(const value_type& __x)
|
| 888 |
{
|
| 889 |
if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
|
| 890 |
{
|
| 891 |
this->_M_impl.construct(this->_M_impl._M_finish, __x); |
| 892 |
++this->_M_impl._M_finish; |
| 893 |
} |
| 894 |
else
|
| 895 |
_M_insert_aux(end(), __x); |
| 896 |
} |
| 897 |
|
| 898 |
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
| 899 |
void
|
| 900 |
push_back(value_type&& __x) |
| 901 |
{ emplace_back(std::move(__x)); }
|
| 902 |
|
| 903 |
template<typename... _Args> |
| 904 |
void
|
| 905 |
emplace_back(_Args&&... __args); |
| 906 |
#endif
|
| 907 |
|
| 908 |
/**
|
| 909 |
* @brief Removes last element.
|
| 910 |
*
|
| 911 |
* This is a typical stack operation. It shrinks the %vector by one.
|
| 912 |
*
|
| 913 |
* Note that no data is returned, and if the last element's
|
| 914 |
* data is needed, it should be retrieved before pop_back() is
|
| 915 |
* called.
|
| 916 |
*/
|
| 917 |
void
|
| 918 |
pop_back() |
| 919 |
{
|
| 920 |
--this->_M_impl._M_finish; |
| 921 |
this->_M_impl.destroy(this->_M_impl._M_finish); |
| 922 |
} |
| 923 |
|
| 924 |
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
| 925 |
/**
|
| 926 |
* @brief Inserts an object in %vector before specified iterator.
|
| 927 |
* @param position An iterator into the %vector.
|
| 928 |
* @param args Arguments.
|
| 929 |
* @return An iterator that points to the inserted data.
|
| 930 |
*
|
| 931 |
* This function will insert an object of type T constructed
|
| 932 |
* with T(std::forward<Args>(args)...) before the specified location.
|
| 933 |
* Note that this kind of operation could be expensive for a %vector
|
| 934 |
* and if it is frequently used the user should consider using
|
| 935 |
* std::list.
|
| 936 |
*/
|
| 937 |
template<typename... _Args> |
| 938 |
iterator |
| 939 |
emplace(iterator __position, _Args&&... __args); |
| 940 |
#endif
|
| 941 |
|
| 942 |
/**
|
| 943 |
* @brief Inserts given value into %vector before specified iterator.
|
| 944 |
* @param position An iterator into the %vector.
|
| 945 |
* @param x Data to be inserted.
|
| 946 |
* @return An iterator that points to the inserted data.
|
| 947 |
*
|
| 948 |
* This function will insert a copy of the given value before
|
| 949 |
* the specified location. Note that this kind of operation
|
| 950 |
* could be expensive for a %vector and if it is frequently
|
| 951 |
* used the user should consider using std::list.
|
| 952 |
*/
|
| 953 |
iterator |
| 954 |
insert(iterator __position, const value_type& __x);
|
| 955 |
|
| 956 |
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
| 957 |
/**
|
| 958 |
* @brief Inserts given rvalue into %vector before specified iterator.
|
| 959 |
* @param position An iterator into the %vector.
|
| 960 |
* @param x Data to be inserted.
|
| 961 |
* @return An iterator that points to the inserted data.
|
| 962 |
*
|
| 963 |
* This function will insert a copy of the given rvalue before
|
| 964 |
* the specified location. Note that this kind of operation
|
| 965 |
* could be expensive for a %vector and if it is frequently
|
| 966 |
* used the user should consider using std::list.
|
| 967 |
*/
|
| 968 |
iterator |
| 969 |
insert(iterator __position, value_type&& __x) |
| 970 |
{ return emplace(__position, std::move(__x)); }
|
| 971 |
|
| 972 |
/**
|
| 973 |
* @brief Inserts an initializer_list into the %vector.
|
| 974 |
* @param position An iterator into the %vector.
|
| 975 |
* @param l An initializer_list.
|
| 976 |
*
|
| 977 |
* This function will insert copies of the data in the
|
| 978 |
* initializer_list @a l into the %vector before the location
|
| 979 |
* specified by @a position.
|
| 980 |
*
|
| 981 |
* Note that this kind of operation could be expensive for a
|
| 982 |
* %vector and if it is frequently used the user should
|
| 983 |
* consider using std::list.
|
| 984 |
*/
|
| 985 |
void
|
| 986 |
insert(iterator __position, initializer_list<value_type> __l) |
| 987 |
{ this->insert(__position, __l.begin(), __l.end()); }
|
| 988 |
#endif
|
| 989 |
|
| 990 |
/**
|
| 991 |
* @brief Inserts a number of copies of given data into the %vector.
|
| 992 |
* @param position An iterator into the %vector.
|
| 993 |
* @param n Number of elements to be inserted.
|
| 994 |
* @param x Data to be inserted.
|
| 995 |
*
|
| 996 |
* This function will insert a specified number of copies of
|
| 997 |
* the given data before the location specified by @a position.
|
| 998 |
*
|
| 999 |
* Note that this kind of operation could be expensive for a
|
| 1000 |
* %vector and if it is frequently used the user should
|
| 1001 |
* consider using std::list.
|
| 1002 |
*/
|
| 1003 |
void
|
| 1004 |
insert(iterator __position, size_type __n, const value_type& __x)
|
| 1005 |
{ _M_fill_insert(__position, __n, __x); }
|
| 1006 |
|
| 1007 |
/**
|
| 1008 |
* @brief Inserts a range into the %vector.
|
| 1009 |
* @param position An iterator into the %vector.
|
| 1010 |
* @param first An input iterator.
|
| 1011 |
* @param last An input iterator.
|
| 1012 |
*
|
| 1013 |
* This function will insert copies of the data in the range
|
| 1014 |
* [first,last) into the %vector before the location specified
|
| 1015 |
* by @a pos.
|
| 1016 |
*
|
| 1017 |
* Note that this kind of operation could be expensive for a
|
| 1018 |
* %vector and if it is frequently used the user should
|
| 1019 |
* consider using std::list.
|
| 1020 |
*/
|
| 1021 |
template<typename _InputIterator> |
| 1022 |
void
|
| 1023 |
insert(iterator __position, _InputIterator __first, |
| 1024 |
_InputIterator __last) |
| 1025 |
{
|
| 1026 |
// Check whether it's an integral type. If so, it's not an iterator.
|
| 1027 |
typedef typename std::__is_integer<_InputIterator>::__type _Integral;
|
| 1028 |
_M_insert_dispatch(__position, __first, __last, _Integral()); |
| 1029 |
} |
| 1030 |
|
| 1031 |
/**
|
| 1032 |
* @brief Remove element at given position.
|
| 1033 |
* @param position Iterator pointing to element to be erased.
|
| 1034 |
* @return An iterator pointing to the next element (or end()).
|
| 1035 |
*
|
| 1036 |
* This function will erase the element at the given position and thus
|
| 1037 |
* shorten the %vector by one.
|
| 1038 |
*
|
| 1039 |
* Note This operation could be expensive and if it is
|
| 1040 |
* frequently used the user should consider using std::list.
|
| 1041 |
* The user is also cautioned that this function only erases
|
| 1042 |
* the element, and that if the element is itself a pointer,
|
| 1043 |
* the pointed-to memory is not touched in any way. Managing
|
| 1044 |
* the pointer is the user's responsibility.
|
| 1045 |
*/
|
| 1046 |
iterator |
| 1047 |
erase(iterator __position); |
| 1048 |
|
| 1049 |
/**
|
| 1050 |
* @brief Remove a range of elements.
|
| 1051 |
* @param first Iterator pointing to the first element to be erased.
|
| 1052 |
* @param last Iterator pointing to one past the last element to be
|
| 1053 |
* erased.
|
| 1054 |
* @return An iterator pointing to the element pointed to by @a last
|
| 1055 |
* prior to erasing (or end()).
|
| 1056 |
*
|
| 1057 |
* This function will erase the elements in the range [first,last) and
|
| 1058 |
* shorten the %vector accordingly.
|
| 1059 |
*
|
| 1060 |
* Note This operation could be expensive and if it is
|
| 1061 |
* frequently used the user should consider using std::list.
|
| 1062 |
* The user is also cautioned that this function only erases
|
| 1063 |
* the elements, and that if the elements themselves are
|
| 1064 |
* pointers, the pointed-to memory is not touched in any way.
|
| 1065 |
* Managing the pointer is the user's responsibility.
|
| 1066 |
*/
|
| 1067 |
iterator |
| 1068 |
erase(iterator __first, iterator __last); |
| 1069 |
|
| 1070 |
/**
|
| 1071 |
* @brief Swaps data with another %vector.
|
| 1072 |
* @param x A %vector of the same element and allocator types.
|
| 1073 |
*
|
| 1074 |
* This exchanges the elements between two vectors in constant time.
|
| 1075 |
* (Three pointers, so it should be quite fast.)
|
| 1076 |
* Note that the global std::swap() function is specialized such that
|
| 1077 |
* std::swap(v1,v2) will feed to this function.
|
| 1078 |
*/
|
| 1079 |
void
|
| 1080 |
swap(vector& __x) |
| 1081 |
{
|
| 1082 |
#if __google_stl_debug_dangling_vector
|
| 1083 |
if (!this->_M_is_valid() || !__x._M_is_valid())
|
| 1084 |
__throw_logic_error("swap() on corrupt (dangling?) vector");
|
| 1085 |
#endif
|
| 1086 |
std::swap(this->_M_impl._M_start, __x._M_impl._M_start); |
| 1087 |
std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); |
| 1088 |
std::swap(this->_M_impl._M_end_of_storage, |
| 1089 |
__x._M_impl._M_end_of_storage); |
| 1090 |
|
| 1091 |
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
| 1092 |
// 431. Swapping containers with unequal allocators.
|
| 1093 |
std::__alloc_swap<_Tp_alloc_type>::_S_do_it(_M_get_Tp_allocator(), |
| 1094 |
__x._M_get_Tp_allocator()); |
| 1095 |
} |
| 1096 |
|
| 1097 |
/**
|
| 1098 |
* Erases all the elements. Note that this function only erases the
|
| 1099 |
* elements, and that if the elements themselves are pointers, the
|
| 1100 |
* pointed-to memory is not touched in any way. Managing the pointer is
|
| 1101 |
* the user's responsibility.
|
| 1102 |
*/
|
| 1103 |
void
|
| 1104 |
clear() |
| 1105 |
{
|
| 1106 |
#if __google_stl_debug_dangling_vector
|
| 1107 |
if (!this->_M_is_valid())
|
| 1108 |
__throw_logic_error("clear() on corrupt (dangling?) vector");
|
| 1109 |
#endif
|
| 1110 |
_M_erase_at_end(this->_M_impl._M_start); |
| 1111 |
} |
| 1112 |
|
| 1113 |
protected:
|
| 1114 |
/**
|
| 1115 |
* Memory expansion handler. Uses the member allocation function to
|
| 1116 |
* obtain @a n bytes of memory, and then copies [first,last) into it.
|
| 1117 |
*/
|
| 1118 |
template<typename _ForwardIterator> |
| 1119 |
pointer |
| 1120 |
_M_allocate_and_copy(size_type __n, |
| 1121 |
_ForwardIterator __first, _ForwardIterator __last) |
| 1122 |
{
|
| 1123 |
pointer __result = this->_M_allocate(__n); |
| 1124 |
__try |
| 1125 |
{
|
| 1126 |
std::__uninitialized_copy_a(__first, __last, __result, |
| 1127 |
_M_get_Tp_allocator()); |
| 1128 |
return __result;
|
| 1129 |
} |
| 1130 |
__catch(...) |
| 1131 |
{
|
| 1132 |
_M_deallocate(__result, __n); |
| 1133 |
__throw_exception_again; |
| 1134 |
} |
| 1135 |
} |
| 1136 |
|
| 1137 |
|
| 1138 |
// Internal constructor functions follow.
|
| 1139 |
|
| 1140 |
// Called by the range constructor to implement [23.1.1]/9
|
| 1141 |
|
| 1142 |
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
| 1143 |
// 438. Ambiguity in the "do the right thing" clause
|
| 1144 |
template<typename _Integer> |
| 1145 |
void
|
| 1146 |
_M_initialize_dispatch(_Integer __n, _Integer __value, __true_type) |
| 1147 |
{
|
| 1148 |
this->_M_impl._M_start = _M_allocate(static_cast<size_type>(__n)); |
| 1149 |
this->_M_impl._M_end_of_storage = |
| 1150 |
this->_M_impl._M_start + static_cast<size_type>(__n); |
| 1151 |
_M_fill_initialize(static_cast<size_type>(__n), __value); |
| 1152 |
} |
| 1153 |
|
| 1154 |
// Called by the range constructor to implement [23.1.1]/9
|
| 1155 |
template<typename _InputIterator> |
| 1156 |
void
|
| 1157 |
_M_initialize_dispatch(_InputIterator __first, _InputIterator __last, |
| 1158 |
__false_type) |
| 1159 |
{
|
| 1160 |
typedef typename std::iterator_traits<_InputIterator>::
|
| 1161 |
iterator_category _IterCategory; |
| 1162 |
_M_range_initialize(__first, __last, _IterCategory()); |
| 1163 |
} |
| 1164 |
|
| 1165 |
// Called by the second initialize_dispatch above
|
| 1166 |
template<typename _InputIterator> |
| 1167 |
void
|
| 1168 |
_M_range_initialize(_InputIterator __first, |
| 1169 |
_InputIterator __last, std::input_iterator_tag) |
| 1170 |
{
|
| 1171 |
for (; __first != __last; ++__first)
|
| 1172 |
push_back(*__first); |
| 1173 |
} |
| 1174 |
|
| 1175 |
// Called by the second initialize_dispatch above
|
| 1176 |
template<typename _ForwardIterator> |
| 1177 |
void
|
| 1178 |
_M_range_initialize(_ForwardIterator __first, |
| 1179 |
_ForwardIterator __last, std::forward_iterator_tag) |
| 1180 |
{
|
| 1181 |
const size_type __n = std::distance(__first, __last);
|
| 1182 |
this->_M_impl._M_start = this->_M_allocate(__n); |
| 1183 |
this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; |
| 1184 |
this->_M_impl._M_finish = |
| 1185 |
std::__uninitialized_copy_a(__first, __last, |
| 1186 |
this->_M_impl._M_start, |
| 1187 |
_M_get_Tp_allocator()); |
| 1188 |
} |
| 1189 |
|
| 1190 |
// Called by the first initialize_dispatch above and by the
|
| 1191 |
// vector(n,value,a) constructor.
|
| 1192 |
void
|
| 1193 |
_M_fill_initialize(size_type __n, const value_type& __value)
|
| 1194 |
{
|
| 1195 |
std::__uninitialized_fill_n_a(this->_M_impl._M_start, __n, __value, |
| 1196 |
_M_get_Tp_allocator()); |
| 1197 |
this->_M_impl._M_finish = this->_M_impl._M_end_of_storage; |
| 1198 |
} |
| 1199 |
|
| 1200 |
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
| 1201 |
// Called by the vector(n) constructor.
|
| 1202 |
void
|
| 1203 |
_M_default_initialize(size_type __n) |
| 1204 |
{
|
| 1205 |
std::__uninitialized_default_n_a(this->_M_impl._M_start, __n, |
| 1206 |
_M_get_Tp_allocator()); |
| 1207 |
this->_M_impl._M_finish = this->_M_impl._M_end_of_storage; |
| 1208 |
} |
| 1209 |
#endif
|
| 1210 |
|
| 1211 |
// Internal assign functions follow. The *_aux functions do the actual
|
| 1212 |
// assignment work for the range versions.
|
| 1213 |
|
| 1214 |
// Called by the range assign to implement [23.1.1]/9
|
| 1215 |
|
| 1216 |
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
| 1217 |
// 438. Ambiguity in the "do the right thing" clause
|
| 1218 |
template<typename _Integer> |
| 1219 |
void
|
| 1220 |
_M_assign_dispatch(_Integer __n, _Integer __val, __true_type) |
| 1221 |
{ _M_fill_assign(__n, __val); }
|
| 1222 |
|
| 1223 |
// Called by the range assign to implement [23.1.1]/9
|
| 1224 |
template<typename _InputIterator> |
| 1225 |
void
|
| 1226 |
_M_assign_dispatch(_InputIterator __first, _InputIterator __last, |
| 1227 |
__false_type) |
| 1228 |
{
|
| 1229 |
typedef typename std::iterator_traits<_InputIterator>::
|
| 1230 |
iterator_category _IterCategory; |
| 1231 |
_M_assign_aux(__first, __last, _IterCategory()); |
| 1232 |
} |
| 1233 |
|
| 1234 |
// Called by the second assign_dispatch above
|
| 1235 |
template<typename _InputIterator> |
| 1236 |
void
|
| 1237 |
_M_assign_aux(_InputIterator __first, _InputIterator __last, |
| 1238 |
std::input_iterator_tag); |
| 1239 |
|
| 1240 |
// Called by the second assign_dispatch above
|
| 1241 |
template<typename _ForwardIterator> |
| 1242 |
void
|
| 1243 |
_M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, |
| 1244 |
std::forward_iterator_tag); |
| 1245 |
|
| 1246 |
// Called by assign(n,t), and the range assign when it turns out
|
| 1247 |
// to be the same thing.
|
| 1248 |
void
|
| 1249 |
_M_fill_assign(size_type __n, const value_type& __val);
|
| 1250 |
|
| 1251 |
|
| 1252 |
// Internal insert functions follow.
|
| 1253 |
|
| 1254 |
// Called by the range insert to implement [23.1.1]/9
|
| 1255 |
|
| 1256 |
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
| 1257 |
// 438. Ambiguity in the "do the right thing" clause
|
| 1258 |
template<typename _Integer> |
| 1259 |
void
|
| 1260 |
_M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val, |
| 1261 |
__true_type) |
| 1262 |
{ _M_fill_insert(__pos, __n, __val); }
|
| 1263 |
|
| 1264 |
// Called by the range insert to implement [23.1.1]/9
|
| 1265 |
template<typename _InputIterator> |
| 1266 |
void
|
| 1267 |
_M_insert_dispatch(iterator __pos, _InputIterator __first, |
| 1268 |
_InputIterator __last, __false_type) |
| 1269 |
{
|
| 1270 |
typedef typename std::iterator_traits<_InputIterator>::
|
| 1271 |
iterator_category _IterCategory; |
| 1272 |
_M_range_insert(__pos, __first, __last, _IterCategory()); |
| 1273 |
} |
| 1274 |
|
| 1275 |
// Called by the second insert_dispatch above
|
| 1276 |
template<typename _InputIterator> |
| 1277 |
void
|
| 1278 |
_M_range_insert(iterator __pos, _InputIterator __first, |
| 1279 |
_InputIterator __last, std::input_iterator_tag); |
| 1280 |
|
| 1281 |
// Called by the second insert_dispatch above
|
| 1282 |
template<typename _ForwardIterator> |
| 1283 |
void
|
| 1284 |
_M_range_insert(iterator __pos, _ForwardIterator __first, |
| 1285 |
_ForwardIterator __last, std::forward_iterator_tag); |
| 1286 |
|
| 1287 |
// Called by insert(p,n,x), and the range insert when it turns out to be
|
| 1288 |
// the same thing.
|
| 1289 |
void
|
| 1290 |
_M_fill_insert(iterator __pos, size_type __n, const value_type& __x);
|
| 1291 |
|
| 1292 |
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
| 1293 |
// Called by resize(n).
|
| 1294 |
void
|
| 1295 |
_M_default_append(size_type __n); |
| 1296 |
#endif
|
| 1297 |
|
| 1298 |
// Called by insert(p,x)
|
| 1299 |
#ifndef __GXX_EXPERIMENTAL_CXX0X__
|
| 1300 |
void
|
| 1301 |
_M_insert_aux(iterator __position, const value_type& __x);
|
| 1302 |
#else
|
| 1303 |
template<typename... _Args> |
| 1304 |
void
|
| 1305 |
_M_insert_aux(iterator __position, _Args&&... __args); |
| 1306 |
#endif
|
| 1307 |
|
| 1308 |
// Called by the latter.
|
| 1309 |
size_type |
| 1310 |
_M_check_len(size_type __n, const char* __s) const |
| 1311 |
{
|
| 1312 |
if (max_size() - size() < __n)
|
| 1313 |
__throw_length_error(__N(__s)); |
| 1314 |
|
| 1315 |
const size_type __len = size() + std::max(size(), __n);
|
| 1316 |
return (__len < size() || __len > max_size()) ? max_size() : __len;
|
| 1317 |
} |
| 1318 |
|
| 1319 |
// Internal erase functions follow.
|
| 1320 |
|
| 1321 |
// Called by erase(q1,q2), clear(), resize(), _M_fill_assign,
|
| 1322 |
// _M_assign_aux.
|
| 1323 |
void
|
| 1324 |
_M_erase_at_end(pointer __pos) |
| 1325 |
{
|
| 1326 |
std::_Destroy(__pos, this->_M_impl._M_finish, _M_get_Tp_allocator()); |
| 1327 |
this->_M_impl._M_finish = __pos; |
| 1328 |
} |
| 1329 |
}; |
| 1330 |
|
| 1331 |
|
| 1332 |
/**
|
| 1333 |
* @brief Vector equality comparison.
|
| 1334 |
* @param x A %vector.
|
| 1335 |
* @param y A %vector of the same type as @a x.
|
| 1336 |
* @return True iff the size and elements of the vectors are equal.
|
| 1337 |
*
|
| 1338 |
* This is an equivalence relation. It is linear in the size of the
|
| 1339 |
* vectors. Vectors are considered equivalent if their sizes are equal,
|
| 1340 |
* and if corresponding elements compare equal.
|
| 1341 |
*/
|
| 1342 |
template<typename _Tp, typename _Alloc> |
| 1343 |
inline bool |
| 1344 |
operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) |
| 1345 |
{ return (__x.size() == __y.size()
|
| 1346 |
&& std::equal(__x.begin(), __x.end(), __y.begin())); } |
| 1347 |
|
| 1348 |
/**
|
| 1349 |
* @brief Vector ordering relation.
|
| 1350 |
* @param x A %vector.
|
| 1351 |
* @param y A %vector of the same type as @a x.
|
| 1352 |
* @return True iff @a x is lexicographically less than @a y.
|
| 1353 |
*
|
| 1354 |
* This is a total ordering relation. It is linear in the size of the
|
| 1355 |
* vectors. The elements must be comparable with @c <.
|
| 1356 |
*
|
| 1357 |
* See std::lexicographical_compare() for how the determination is made.
|
| 1358 |
*/
|
| 1359 |
template<typename _Tp, typename _Alloc> |
| 1360 |
inline bool |
| 1361 |
operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) |
| 1362 |
{ return std::lexicographical_compare(__x.begin(), __x.end(),
|
| 1363 |
__y.begin(), __y.end()); } |
| 1364 |
|
| 1365 |
/// Based on operator==
|
| 1366 |
template<typename _Tp, typename _Alloc> |
| 1367 |
inline bool |
| 1368 |
operator!=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) |
| 1369 |
{ return !(__x == __y); }
|
| 1370 |
|
| 1371 |
/// Based on operator<
|
| 1372 |
template<typename _Tp, typename _Alloc> |
| 1373 |
inline bool |
| 1374 |
operator>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) |
| 1375 |
{ return __y < __x; }
|
| 1376 |
|
| 1377 |
/// Based on operator<
|
| 1378 |
template<typename _Tp, typename _Alloc> |
| 1379 |
inline bool |
| 1380 |
operator<=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) |
| 1381 |
{ return !(__y < __x); }
|
| 1382 |
|
| 1383 |
/// Based on operator<
|
| 1384 |
template<typename _Tp, typename _Alloc> |
| 1385 |
inline bool |
| 1386 |
operator>=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) |
| 1387 |
{ return !(__x < __y); }
|
| 1388 |
|
| 1389 |
/// See std::vector::swap().
|
| 1390 |
template<typename _Tp, typename _Alloc> |
| 1391 |
inline void |
| 1392 |
swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y) |
| 1393 |
{ __x.swap(__y); }
|
| 1394 |
|
| 1395 |
_GLIBCXX_END_NAMESPACE_CONTAINER |
| 1396 |
} // namespace std
|
| 1397 |
|
| 1398 |
#endif /* _STL_VECTOR_H */ |