1 G++ 2.91.57,cygnus\cygwin-b20\include\g++\stl_vector.h 完整列表
2 /*
3 *
4 * Copyright (c) 1994
5 * Hewlett-Packard Company
6 *
7 * Permission to use, copy, modify, distribute and sell this software
8 * and its documentation for any purpose is hereby granted without fee,
9 * provided that the above copyright notice appear in all copies and
10 * that both that copyright notice and this permission notice appear
11 * in supporting documentation. Hewlett-Packard Company makes no
12 * representations about the suitability of this software for any
13 * purpose. It is provided "as is" without express or implied warranty.
14 *
15 *
16 * Copyright (c) 1996
17 * Silicon Graphics Computer Systems, Inc.
18 *
19 * Permission to use, copy, modify, distribute and sell this software
20 * and its documentation for any purpose is hereby granted without fee,
21 * provided that the above copyright notice appear in all copies and
22 * that both that copyright notice and this permission notice appear
23 * in supporting documentation. Silicon Graphics makes no
24 * representations about the suitability of this software for any
25 * purpose. It is provided "as is" without express or implied warranty.
26 */
27
28 /* NOTE: This is an internal header file, included by other STL headers.
29 * You should not attempt to use it directly.
30 */
31
32 #ifndef __SGI_STL_INTERNAL_VECTOR_H
33 #define __SGI_STL_INTERNAL_VECTOR_H
34
35 __STL_BEGIN_NAMESPACE
36
37 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
38 #pragma set woff 1174
39 #endif
40
41 template <class T, class Alloc = alloc> // 預設使用 alloc 為配置器
42 class vector {
43 public:
44 // 以下標示 (1),(2),(3),(4),(5),代表 iterator_traits<I> 所服務的5個型別。
45 typedef T value_type; // (1)
46 typedef value_type* pointer; // (2)
47 typedef const value_type* const_pointer;
48 typedef const value_type* const_iterator;
49 typedef value_type& reference; // (3)
50 typedef const value_type& const_reference;
51 typedef size_t size_type;
52 typedef ptrdiff_t difference_type; // (4)
53 // 以下,由於vector 所維護的是一個連續線性空間,所以不論其元素型別為何,
54 // 原生指標都可以做為其迭代器而滿足所有需求。
55 typedef value_type* iterator;
56 /* 根據上述寫法,如果客端寫出這樣的碼:
57 vector<Shape>::iterator is;
58 is 的型別其實就是Shape*
59 而STL 內部運用 iterator_traits<is>::reference 時,獲得 Shape&
60 運用iterator_traits<is>::iterator_category 時,獲得
61 random_access_iterator_tag (5)
62 (此乃iterator_traits 針對原生指標的特化結果)
63 */
64
65 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
66 typedef reverse_iterator<const_iterator> const_reverse_iterator;
67 typedef reverse_iterator<iterator> reverse_iterator;
68 #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
69 typedef reverse_iterator<const_iterator, value_type, const_reference,
70 difference_type> const_reverse_iterator;
71 typedef reverse_iterator<iterator, value_type, reference, difference_type>
72 reverse_iterator;
73 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
74 protected:
75 // 專屬之空間配置器,每次配置一個元素大小
76 typedef simple_alloc<value_type, Alloc> data_allocator;
77
78 // vector採用簡單的線性連續空間。以兩個迭代器start和end分別指向頭尾,
79 // 並以迭代器end_of_storage指向容量尾端。容量可能比(尾-頭)還大,
80 // 多餘即備用空間。
81 iterator start;
82 iterator finish;
83 iterator end_of_storage;
84
85 void insert_aux(iterator position, const T& x);
86 void deallocate() {
87 if (start)
88 data_allocator::deallocate(start, end_of_storage - start);
89 }
90
91 void fill_initialize(size_type n, const T& value) {
92 start = allocate_and_fill(n, value); // 配置空間並設初值
93 finish = start + n; // 調整水位
94 end_of_storage = finish; // 調整水位
95 }
96 public:
97 iterator begin() { return start; }
98 const_iterator begin() const { return start; }
99 iterator end() { return finish; }
100 const_iterator end() const { return finish; }
101 reverse_iterator rbegin() { return reverse_iterator(end()); }
102 const_reverse_iterator rbegin() const {
103 return const_reverse_iterator(end());
104 }
105 reverse_iterator rend() { return reverse_iterator(begin()); }
106 const_reverse_iterator rend() const {
107 return const_reverse_iterator(begin());
108 }
109 size_type size() const { return size_type(end() - begin()); }
110 size_type max_size() const { return size_type(-1) / sizeof(T); }
111 size_type capacity() const { return size_type(end_of_storage - begin()); }
112 bool empty() const { return begin() == end(); }
113 reference operator[](size_type n) { return *(begin() + n); }
114 const_reference operator[](size_type n) const { return *(begin() + n); }
115
116 vector() : start(0), finish(0), end_of_storage(0) {}
117 // 以下建構式,允許指定大小 n 和初值 value
118 vector(size_type n, const T& value) { fill_initialize(n, value); }
119 vector(int n, const T& value) { fill_initialize(n, value); }
120 vector(long n, const T& value) { fill_initialize(n, value); }
121 explicit vector(size_type n) { fill_initialize(n, T()); }
122
123 vector(const vector<T, Alloc>& x) {
124 start = allocate_and_copy(x.end() - x.begin(), x.begin(), x.end());
125 finish = start + (x.end() - x.begin());
126 end_of_storage = finish;
127 }
128 #ifdef __STL_MEMBER_TEMPLATES
129 template <class InputIterator>
130 vector(InputIterator first, InputIterator last) :
131 start(0), finish(0), end_of_storage(0)
132 {
133 range_initialize(first, last, iterator_category(first));
134 }
135 #else /* __STL_MEMBER_TEMPLATES */
136 vector(const_iterator first, const_iterator last) {
137 size_type n = 0;
138 distance(first, last, n);
139 start = allocate_and_copy(n, first, last);
140 finish = start + n;
141 end_of_storage = finish;
142 }
143 #endif /* __STL_MEMBER_TEMPLATES */
144 ~vector() {
145 destroy(start, finish); // 全域函式,建構/解構基本工具。
146 deallocate(); // 先前定義好的成員函式
147 }
148 vector<T, Alloc>& operator=(const vector<T, Alloc>& x);
149 void reserve(size_type n) {
150 if (capacity() < n) {
151 const size_type old_size = size();
152 iterator tmp = allocate_and_copy(n, start, finish);
153 destroy(start, finish);
154 deallocate();
155 start = tmp;
156 finish = tmp + old_size;
157 end_of_storage = start + n;
158 }
159 }
160
161 // 取出第一個元素內容
162 reference front() { return *begin(); }
163 const_reference front() const { return *begin(); }
164 // 取出最後一個元素內容
165 reference back() { return *(end() - 1); }
166 const_reference back() const { return *(end() - 1); }
167 // 增加一個元素,做為最後元素
168 void push_back(const T& x) {
169 if (finish != end_of_storage) { // 還有備用空間
170 construct(finish, x); // 直接在備用空間中建構元素。
171 ++finish; // 調整水位高度
172 }
173 else // 已無備用空間
174 insert_aux(end(), x);
175 }
176 void swap(vector<T, Alloc>& x) {
177 __STD::swap(start, x.start);
178 __STD::swap(finish, x.finish);
179 __STD::swap(end_of_storage, x.end_of_storage);
180 }
181 iterator insert(iterator position, const T& x) {
182 size_type n = position - begin();
183 if (finish != end_of_storage && position == end()) {
184 construct(finish, x); // 全域函式,建構/解構基本工具。
185 ++finish;
186 }
187 else
188 insert_aux(position, x);
189 return begin() + n;
190 }
191 iterator insert(iterator position) { return insert(position, T()); }
192 #ifdef __STL_MEMBER_TEMPLATES
193 template <class InputIterator>
194 void insert(iterator position, InputIterator first, InputIterator last){
195 range_insert(position, first, last, iterator_category(first));
196 }
197 #else /* __STL_MEMBER_TEMPLATES */
198 void insert(iterator position,
199 const_iterator first, const_iterator last);
200 #endif /* __STL_MEMBER_TEMPLATES */
201
202 void insert (iterator pos, size_type n, const T& x);
203 void insert (iterator pos, int n, const T& x) {
204 insert(pos, (size_type) n, x);
205 }
206 void insert (iterator pos, long n, const T& x) {
207 insert(pos, (size_type) n, x);
208 }
209
210 void pop_back() {
211 --finish;
212 destroy(finish); // 全域函式,建構/解構基本工具。
213 }
214 // 將迭代器 position 所指之元素移除
215 iterator erase(iterator position) {
216 if (position + 1 != end()) // 如果 p 不是指向最後一個元素
217 // 將 p 之後的元素一一向前遞移
218 copy(position + 1, finish, position);
219
220 --finish; // 調整水位
221 destroy(finish); // 全域函式,建構/解構基本工具。
222 return position;
223 }
224 iterator erase(iterator first, iterator last) {
225 iterator i = copy(last, finish, first);
226 destroy(i, finish); // 全域函式,建構/解構基本工具。
227 finish = finish - (last - first);
228 return first;
229 }
230 void resize(size_type new_size, const T& x) {
231 if (new_size < size())
232 erase(begin() + new_size, end());
233 else
234 insert(end(), new_size - size(), x);
235 }
236 void resize(size_type new_size) { resize(new_size, T()); }
237 // 清除全部元素。注意,並未釋放空間,以備可能未來還會新加入元素。
238 void clear() { erase(begin(), end()); }
239
240 protected:
241 iterator allocate_and_fill(size_type n, const T& x) {
242 iterator result = data_allocator::allocate(n); // 配置n個元素空間
243 __STL_TRY {
244 // 全域函式,記憶體低階工具,將result所指之未初始化空間設定初值為 x,n個
245 // 定義於 <stl_uninitialized.h>。
246 uninitialized_fill_n(result, n, x);
247 return result;
248 }
249 // "commit or rollback" 語意:若非全部成功,就一個不留。
250 __STL_UNWIND(data_allocator::deallocate(result, n));
251 }
252
253 #ifdef __STL_MEMBER_TEMPLATES
254 template <class ForwardIterator>
255 iterator allocate_and_copy(size_type n,
256 ForwardIterator first, ForwardIterator last) {
257 iterator result = data_allocator::allocate(n);
258 __STL_TRY {
259 uninitialized_copy(first, last, result);
260 return result;
261 }
262 __STL_UNWIND(data_allocator::deallocate(result, n));
263 }
264 #else /* __STL_MEMBER_TEMPLATES */
265 iterator allocate_and_copy(size_type n,
266 const_iterator first, const_iterator last) {
267 iterator result = data_allocator::allocate(n);
268 __STL_TRY {
269 uninitialized_copy(first, last, result);
270 return result;
271 }
272 __STL_UNWIND(data_allocator::deallocate(result, n));
273 }
274 #endif /* __STL_MEMBER_TEMPLATES */
275
276
277 #ifdef __STL_MEMBER_TEMPLATES
278 template <class InputIterator>
279 void range_initialize(InputIterator first, InputIterator last,
280 input_iterator_tag) {
281 for ( ; first != last; ++first)
282 push_back(*first);
283 }
284
285 // This function is only called by the constructor. We have to worry
286 // about resource leaks, but not about maintaining invariants.
287 template <class ForwardIterator>
288 void range_initialize(ForwardIterator first, ForwardIterator last,
289 forward_iterator_tag) {
290 size_type n = 0;
291 distance(first, last, n);
292 start = allocate_and_copy(n, first, last);
293 finish = start + n;
294 end_of_storage = finish;
295 }
296
297 template <class InputIterator>
298 void range_insert(iterator pos,
299 InputIterator first, InputIterator last,
300 input_iterator_tag);
301
302 template <class ForwardIterator>
303 void range_insert(iterator pos,
304 ForwardIterator first, ForwardIterator last,
305 forward_iterator_tag);
306
307 #endif /* __STL_MEMBER_TEMPLATES */
308 };
309
310 template <class T, class Alloc>
311 inline bool operator==(const vector<T, Alloc>& x, const vector<T, Alloc>& y) {
312 return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
313 }
314
315 template <class T, class Alloc>
316 inline bool operator<(const vector<T, Alloc>& x, const vector<T, Alloc>& y) {
317 return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
318 }
319
320 #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
321
322 template <class T, class Alloc>
323 inline void swap(vector<T, Alloc>& x, vector<T, Alloc>& y) {
324 x.swap(y);
325 }
326
327 #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
328
329 template <class T, class Alloc>
330 vector<T, Alloc>& vector<T, Alloc>::operator=(const vector<T, Alloc>& x) {
331 if (&x != this) { // 判斷是否 self-assignment
332 if (x.size() > capacity()) { // 如果標的物比我本身的容量還大
333 iterator tmp = allocate_and_copy(x.end() - x.begin(),
334 x.begin(), x.end());
335 destroy(start, finish); // 把整個舊的vector 摧毀
336 deallocate(); // 釋放舊空間
337 start = tmp; // 設定指向新空間
338 end_of_storage = start + (x.end() - x.begin());
339 }
340 else if (size() >= x.size()) { // 如果標的物大小 <= 我的大小
341 iterator i = copy(x.begin(), x.end(), begin());
342 destroy(i, finish);
343 }
344 else {
345 copy(x.begin(), x.begin() + size(), start);
346 uninitialized_copy(x.begin() + size(), x.end(), finish);
347 }
348 finish = start + x.size();
349 }
350 return *this;
351 }
352
353 template <class T, class Alloc>
354 void vector<T, Alloc>::insert_aux(iterator position, const T& x) {
355 if (finish != end_of_storage) { // 還有備用空間
356 // 在備用空間起始處建構一個元素,並以vector 最後一個元素值為其初值。
357 construct(finish, *(finish - 1));
358 // 調整水位。
359 ++finish;
360 // 以下做啥用?
361 T x_copy = x;
362 copy_backward(position, finish - 2, finish - 1);
363 *position = x_copy;
364 }
365 else { // 已無備用空間
366 const size_type old_size = size();
367 const size_type len = old_size != 0 ? 2 * old_size : 1;
368 // 以上配置原則:如果原大小為0,則配置 1(個元素大小);
369 // 如果原大小不為0,則配置原大小的兩倍,
370 // 前半段用來放置原資料,後半段準備用來放置新資料。
371
372 iterator new_start = data_allocator::allocate(len); // 實際配置
373 iterator new_finish = new_start;
374 __STL_TRY {
375 // 將原vector 的內容拷貝到新 vector。
376 new_finish = uninitialized_copy(start, position, new_start);
377 // 為新元素設定初值x
378 construct(new_finish, x);
379 // 調整水位。
380 ++new_finish;
381 // 將原vector 的備用空間中的內容也忠實拷貝過來(啥用途?)
382 new_finish = uninitialized_copy(position, finish, new_finish);
383 }
384
385 # ifdef __STL_USE_EXCEPTIONS
386 catch(...) {
387 // "commit or rollback" 語意:若非全部成功,就一個不留。
388 destroy(new_start, new_finish);
389 data_allocator::deallocate(new_start, len);
390 throw;
391 }
392 # endif /* __STL_USE_EXCEPTIONS */
393
394 // 解構並釋放原 vector
395 destroy(begin(), end());
396 deallocate();
397
398 // 調整迭代器,指向新vector
399 start = new_start;
400 finish = new_finish;
401 end_of_storage = new_start + len;
402 }
403 }
404
405 // 從 position 開始,安插 n 個元素,元素初值為 x
406 template <class T, class Alloc>
407 void vector<T, Alloc>::insert(iterator position, size_type n, const T& x) {
408 if (n != 0) { // 當 n != 0 才進行以下所有動作
409 if (size_type(end_of_storage - finish) >= n) {
410 // 備用空間大於等於「新增元素個數」
411 T x_copy = x;
412 // 以下計算安插點之後的現有元素個數
413 const size_type elems_after = finish - position;
414 iterator old_finish = finish;
415 if (elems_after > n) {
416 // 「安插點之後的現有元素個數」大於「新增元素個數」
417 uninitialized_copy(finish - n, finish, finish);
418 finish += n; // 將vector 尾端標記後移
419 copy_backward(position, old_finish - n, old_finish);
420 fill(position, position + n, x_copy); // 從安插點開始填入新值
421 }
422 else {
423 // 「安插點之後的現有元素個數」小於等於「新增元素個數」
424 uninitialized_fill_n(finish, n - elems_after, x_copy);
425 finish += n - elems_after;
426 uninitialized_copy(position, old_finish, finish);
427 finish += elems_after;
428 fill(position, old_finish, x_copy);
429 }
430 }
431 else {
432 // 備用空間小於「新增元素個數」(那就必須配置額外的記憶體)
433 // 首先決定新長度:舊長度的兩倍,或舊長度+新增元素個數。
434 const size_type old_size = size();
435 const size_type len = old_size + max(old_size, n);
436 // 以下配置新的vector 空間
437 iterator new_start = data_allocator::allocate(len);
438 iterator new_finish = new_start;
439 __STL_TRY {
440 // 以下首先將舊vector 的安插點之前的元素複製到新空間。
441 new_finish = uninitialized_copy(start, position, new_start);
442 // 以下再將新增元素(初值皆為 n)填入新空間。
443 new_finish = uninitialized_fill_n(new_finish, n, x);
444 // 以下再將舊vector 的安插點之後的元素複製到新空間。
445 new_finish = uninitialized_copy(position, finish, new_finish);
446 }
447 # ifdef __STL_USE_EXCEPTIONS
448 catch(...) {
449 // 如有異常發生,實現 "commit or rollback" semantics.
450 destroy(new_start, new_finish);
451 data_allocator::deallocate(new_start, len);
452 throw;
453 }
454 # endif /* __STL_USE_EXCEPTIONS */
455 // 以下清除並釋放舊的 vector
456 destroy(start, finish);
457 deallocate();
458 // 以下調整水位標記
459 start = new_start;
460 finish = new_finish;
461 end_of_storage = new_start + len;
462 }
463 }
464 }
465
466 #ifdef __STL_MEMBER_TEMPLATES
467
468 template <class T, class Alloc> template <class InputIterator>
469 void vector<T, Alloc>::range_insert(iterator pos,
470 InputIterator first, InputIterator last,
471 input_iterator_tag) {
472 for ( ; first != last; ++first) {
473 pos = insert(pos, *first);
474 ++pos;
475 }
476 }
477
478 template <class T, class Alloc> template <class ForwardIterator>
479 void vector<T, Alloc>::range_insert(iterator position,
480 ForwardIterator first,
481 ForwardIterator last,
482 forward_iterator_tag) {
483 if (first != last) {
484 size_type n = 0;
485 distance(first, last, n);
486 if (size_type(end_of_storage - finish) >= n) {
487 const size_type elems_after = finish - position;
488 iterator old_finish = finish;
489 if (elems_after > n) {
490 uninitialized_copy(finish - n, finish, finish);
491 finish += n;
492 copy_backward(position, old_finish - n, old_finish);
493 copy(first, last, position);
494 }
495 else {
496 ForwardIterator mid = first;
497 advance(mid, elems_after);
498 uninitialized_copy(mid, last, finish);
499 finish += n - elems_after;
500 uninitialized_copy(position, old_finish, finish);
501 finish += elems_after;
502 copy(first, mid, position);
503 }
504 }
505 else {
506 const size_type old_size = size();
507 const size_type len = old_size + max(old_size, n);
508 iterator new_start = data_allocator::allocate(len);
509 iterator new_finish = new_start;
510 __STL_TRY {
511 new_finish = uninitialized_copy(start, position, new_start);
512 new_finish = uninitialized_copy(first, last, new_finish);
513 new_finish = uninitialized_copy(position, finish, new_finish);
514 }
515 # ifdef __STL_USE_EXCEPTIONS
516 catch(...) {
517 destroy(new_start, new_finish);
518 data_allocator::deallocate(new_start, len);
519 throw;
520 }
521 # endif /* __STL_USE_EXCEPTIONS */
522 destroy(start, finish);
523 deallocate();
524 start = new_start;
525 finish = new_finish;
526 end_of_storage = new_start + len;
527 }
528 }
529 }
530
531 #else /* __STL_MEMBER_TEMPLATES */
532
533 template <class T, class Alloc>
534 void vector<T, Alloc>::insert(iterator position,
535 const_iterator first,
536 const_iterator last) {
537 if (first != last) {
538 size_type n = 0;
539 distance(first, last, n);
540 if (size_type(end_of_storage - finish) >= n) {
541 const size_type elems_after = finish - position;
542 iterator old_finish = finish;
543 if (elems_after > n) {
544 uninitialized_copy(finish - n, finish, finish);
545 finish += n;
546 copy_backward(position, old_finish - n, old_finish);
547 copy(first, last, position);
548 }
549 else {
550 uninitialized_copy(first + elems_after, last, finish);
551 finish += n - elems_after;
552 uninitialized_copy(position, old_finish, finish);
553 finish += elems_after;
554 copy(first, first + elems_after, position);
555 }
556 }
557 else {
558 const size_type old_size = size();
559 const size_type len = old_size + max(old_size, n);
560 iterator new_start = data_allocator::allocate(len);
561 iterator new_finish = new_start;
562 __STL_TRY {
563 new_finish = uninitialized_copy(start, position, new_start);
564 new_finish = uninitialized_copy(first, last, new_finish);
565 new_finish = uninitialized_copy(position, finish, new_finish);
566 }
567 # ifdef __STL_USE_EXCEPTIONS
568 catch(...) {
569 destroy(new_start, new_finish);
570 data_allocator::deallocate(new_start, len);
571 throw;
572 }
573 # endif /* __STL_USE_EXCEPTIONS */
574 destroy(start, finish);
575 deallocate();
576 start = new_start;
577 finish = new_finish;
578 end_of_storage = new_start + len;
579 }
580 }
581 }
582
583 #endif /* __STL_MEMBER_TEMPLATES */
584
585 #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
586 #pragma reset woff 1174
587 #endif
588
589 __STL_END_NAMESPACE
590
591 #endif /* __SGI_STL_INTERNAL_VECTOR_H */
592
593 // Local Variables:
594 // mode:C++
595 // End: