STL-Vector源码剖析
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: