libstdc++
vector.tcc
Go to the documentation of this file.
1 // Vector implementation (out of line) -*- C++ -*-
2 
3 // Copyright (C) 2001-2018 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 /*
26  *
27  * Copyright (c) 1994
28  * Hewlett-Packard Company
29  *
30  * Permission to use, copy, modify, distribute and sell this software
31  * and its documentation for any purpose is hereby granted without fee,
32  * provided that the above copyright notice appear in all copies and
33  * that both that copyright notice and this permission notice appear
34  * in supporting documentation. Hewlett-Packard Company makes no
35  * representations about the suitability of this software for any
36  * purpose. It is provided "as is" without express or implied warranty.
37  *
38  *
39  * Copyright (c) 1996
40  * Silicon Graphics Computer Systems, Inc.
41  *
42  * Permission to use, copy, modify, distribute and sell this software
43  * and its documentation for any purpose is hereby granted without fee,
44  * provided that the above copyright notice appear in all copies and
45  * that both that copyright notice and this permission notice appear
46  * in supporting documentation. Silicon Graphics makes no
47  * representations about the suitability of this software for any
48  * purpose. It is provided "as is" without express or implied warranty.
49  */
50 
51 /** @file bits/vector.tcc
52  * This is an internal header file, included by other library headers.
53  * Do not attempt to use it directly. @headername{vector}
54  */
55 
56 #ifndef _VECTOR_TCC
57 #define _VECTOR_TCC 1
58 
59 namespace std _GLIBCXX_VISIBILITY(default)
60 {
61 _GLIBCXX_BEGIN_NAMESPACE_VERSION
62 _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
63 
64  template<typename _Tp, typename _Alloc>
65  void
67  reserve(size_type __n)
68  {
69  if (__n > this->max_size())
70  __throw_length_error(__N("vector::reserve"));
71  if (this->capacity() < __n)
72  {
73  const size_type __old_size = size();
74  pointer __tmp = _M_allocate_and_copy(__n,
75  _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(this->_M_impl._M_start),
76  _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(this->_M_impl._M_finish));
77  _GLIBCXX_ASAN_ANNOTATE_REINIT;
78  std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
79  _M_get_Tp_allocator());
80  _M_deallocate(this->_M_impl._M_start,
81  this->_M_impl._M_end_of_storage
82  - this->_M_impl._M_start);
83  this->_M_impl._M_start = __tmp;
84  this->_M_impl._M_finish = __tmp + __old_size;
85  this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
86  }
87  }
88 
89 #if __cplusplus >= 201103L
90  template<typename _Tp, typename _Alloc>
91  template<typename... _Args>
92 #if __cplusplus > 201402L
93  typename vector<_Tp, _Alloc>::reference
94 #else
95  void
96 #endif
98  emplace_back(_Args&&... __args)
99  {
100  if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
101  {
102  _GLIBCXX_ASAN_ANNOTATE_GROW(1);
103  _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
104  std::forward<_Args>(__args)...);
105  ++this->_M_impl._M_finish;
106  _GLIBCXX_ASAN_ANNOTATE_GREW(1);
107  }
108  else
109  _M_realloc_insert(end(), std::forward<_Args>(__args)...);
110 #if __cplusplus > 201402L
111  return back();
112 #endif
113  }
114 #endif
115 
116  template<typename _Tp, typename _Alloc>
117  typename vector<_Tp, _Alloc>::iterator
119 #if __cplusplus >= 201103L
120  insert(const_iterator __position, const value_type& __x)
121 #else
122  insert(iterator __position, const value_type& __x)
123 #endif
124  {
125  const size_type __n = __position - begin();
126  if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
127  if (__position == end())
128  {
129  _GLIBCXX_ASAN_ANNOTATE_GROW(1);
130  _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
131  __x);
132  ++this->_M_impl._M_finish;
133  _GLIBCXX_ASAN_ANNOTATE_GREW(1);
134  }
135  else
136  {
137 #if __cplusplus >= 201103L
138  const auto __pos = begin() + (__position - cbegin());
139  // __x could be an existing element of this vector, so make a
140  // copy of it before _M_insert_aux moves elements around.
141  _Temporary_value __x_copy(this, __x);
142  _M_insert_aux(__pos, std::move(__x_copy._M_val()));
143 #else
144  _M_insert_aux(__position, __x);
145 #endif
146  }
147  else
148 #if __cplusplus >= 201103L
149  _M_realloc_insert(begin() + (__position - cbegin()), __x);
150 #else
151  _M_realloc_insert(__position, __x);
152 #endif
153 
154  return iterator(this->_M_impl._M_start + __n);
155  }
156 
157  template<typename _Tp, typename _Alloc>
158  typename vector<_Tp, _Alloc>::iterator
160  _M_erase(iterator __position)
161  {
162  if (__position + 1 != end())
163  _GLIBCXX_MOVE3(__position + 1, end(), __position);
164  --this->_M_impl._M_finish;
165  _Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish);
166  _GLIBCXX_ASAN_ANNOTATE_SHRINK(1);
167  return __position;
168  }
169 
170  template<typename _Tp, typename _Alloc>
171  typename vector<_Tp, _Alloc>::iterator
173  _M_erase(iterator __first, iterator __last)
174  {
175  if (__first != __last)
176  {
177  if (__last != end())
178  _GLIBCXX_MOVE3(__last, end(), __first);
179  _M_erase_at_end(__first.base() + (end() - __last));
180  }
181  return __first;
182  }
183 
184  template<typename _Tp, typename _Alloc>
188  {
189  if (&__x != this)
190  {
191  _GLIBCXX_ASAN_ANNOTATE_REINIT;
192 #if __cplusplus >= 201103L
193  if (_Alloc_traits::_S_propagate_on_copy_assign())
194  {
195  if (!_Alloc_traits::_S_always_equal()
196  && _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
197  {
198  // replacement allocator cannot free existing storage
199  this->clear();
200  _M_deallocate(this->_M_impl._M_start,
201  this->_M_impl._M_end_of_storage
202  - this->_M_impl._M_start);
203  this->_M_impl._M_start = nullptr;
204  this->_M_impl._M_finish = nullptr;
205  this->_M_impl._M_end_of_storage = nullptr;
206  }
207  std::__alloc_on_copy(_M_get_Tp_allocator(),
208  __x._M_get_Tp_allocator());
209  }
210 #endif
211  const size_type __xlen = __x.size();
212  if (__xlen > capacity())
213  {