stl_vector.h
上传用户:sichengcw
上传日期:2009-02-17
资源大小:202k
文件大小:17k
源码类别:

STL

开发平台:

Visual C++

  1. /*
  2.  *
  3.  * Copyright (c) 1994
  4.  * Hewlett-Packard Company
  5.  *
  6.  * Permission to use, copy, modify, distribute and sell this software
  7.  * and its documentation for any purpose is hereby granted without fee,
  8.  * provided that the above copyright notice appear in all copies and
  9.  * that both that copyright notice and this permission notice appear
  10.  * in supporting documentation.  Hewlett-Packard Company makes no
  11.  * representations about the suitability of this software for any
  12.  * purpose.  It is provided "as is" without express or implied warranty.
  13.  *
  14.  *
  15.  * Copyright (c) 1996
  16.  * Silicon Graphics Computer Systems, Inc.
  17.  *
  18.  * Permission to use, copy, modify, distribute and sell this software
  19.  * and its documentation for any purpose is hereby granted without fee,
  20.  * provided that the above copyright notice appear in all copies and
  21.  * that both that copyright notice and this permission notice appear
  22.  * in supporting documentation.  Silicon Graphics makes no
  23.  * representations about the suitability of this software for any
  24.  * purpose.  It is provided "as is" without express or implied warranty.
  25.  */
  26. /* NOTE: This is an internal header file, included by other STL headers.
  27.  *   You should not attempt to use it directly.
  28.  */
  29. #ifndef __SGI_STL_INTERNAL_VECTOR_H
  30. #define __SGI_STL_INTERNAL_VECTOR_H
  31. __STL_BEGIN_NAMESPACE 
  32. #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
  33. #pragma set woff 1174
  34. #endif
  35. template <class T, class Alloc = alloc>
  36. class vector {
  37. public:
  38.   typedef T value_type;
  39.   typedef value_type* pointer;
  40.   typedef const value_type* const_pointer;
  41.   typedef value_type* iterator;
  42.   typedef const value_type* const_iterator;
  43.   typedef value_type& reference;
  44.   typedef const value_type& const_reference;
  45.   typedef size_t size_type;
  46.   typedef ptrdiff_t difference_type;
  47. #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
  48.   typedef reverse_iterator<const_iterator> const_reverse_iterator;
  49.   typedef reverse_iterator<iterator> reverse_iterator;
  50. #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  51.   typedef reverse_iterator<const_iterator, value_type, const_reference, 
  52.                            difference_type>  const_reverse_iterator;
  53.   typedef reverse_iterator<iterator, value_type, reference, difference_type>
  54.           reverse_iterator;
  55. #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
  56. protected:
  57.   typedef simple_alloc<value_type, Alloc> data_allocator;
  58.   iterator start;
  59.   iterator finish;
  60.   iterator end_of_storage;
  61.   void insert_aux(iterator position, const T& x);
  62.   void deallocate() {
  63.     if (start) data_allocator::deallocate(start, end_of_storage - start);
  64.   }
  65.   void fill_initialize(size_type n, const T& value) {
  66.     start = allocate_and_fill(n, value);
  67.     finish = start + n;
  68.     end_of_storage = finish;
  69.   }
  70. public:
  71.   iterator begin() { return start; }
  72.   const_iterator begin() const { return start; }
  73.   iterator end() { return finish; }
  74.   const_iterator end() const { return finish; }
  75.   reverse_iterator rbegin() { return reverse_iterator(end()); }
  76.   const_reverse_iterator rbegin() const { 
  77.     return const_reverse_iterator(end()); 
  78.   }
  79.   reverse_iterator rend() { return reverse_iterator(begin()); }
  80.   const_reverse_iterator rend() const { 
  81.     return const_reverse_iterator(begin()); 
  82.   }
  83.   size_type size() const { return size_type(end() - begin()); }
  84.   size_type max_size() const { return size_type(-1) / sizeof(T); }
  85.   size_type capacity() const { return size_type(end_of_storage - begin()); }
  86.   bool empty() const { return begin() == end(); }
  87.   reference operator[](size_type n) { return *(begin() + n); }
  88.   const_reference operator[](size_type n) const { return *(begin() + n); }
  89.   vector() : start(0), finish(0), end_of_storage(0) {}
  90.   vector(size_type n, const T& value) { fill_initialize(n, value); }
  91.   vector(int n, const T& value) { fill_initialize(n, value); }
  92.   vector(long n, const T& value) { fill_initialize(n, value); }
  93.   explicit vector(size_type n) { fill_initialize(n, T()); }
  94.   vector(const vector<T, Alloc>& x) {
  95.     start = allocate_and_copy(x.end() - x.begin(), x.begin(), x.end());
  96.     finish = start + (x.end() - x.begin());
  97.     end_of_storage = finish;
  98.   }
  99. #ifdef __STL_MEMBER_TEMPLATES
  100.   template <class InputIterator>
  101.   vector(InputIterator first, InputIterator last) :
  102.     start(0), finish(0), end_of_storage(0)
  103.   {
  104.     range_initialize(first, last, iterator_category(first));
  105.   }
  106. #else /* __STL_MEMBER_TEMPLATES */
  107.   vector(const_iterator first, const_iterator last) {
  108.     size_type n = 0;
  109.     distance(first, last, n);
  110.     start = allocate_and_copy(n, first, last);
  111.     finish = start + n;
  112.     end_of_storage = finish;
  113.   }
  114. #endif /* __STL_MEMBER_TEMPLATES */
  115.   ~vector() { 
  116.     destroy(start, finish);
  117.     deallocate();
  118.   }
  119.   vector<T, Alloc>& operator=(const vector<T, Alloc>& x);
  120.   void reserve(size_type n) {
  121.     if (capacity() < n) {
  122.       const size_type old_size = size();
  123.       iterator tmp = allocate_and_copy(n, start, finish);
  124.       destroy(start, finish);
  125.       deallocate();
  126.       start = tmp;
  127.       finish = tmp + old_size;
  128.       end_of_storage = start + n;
  129.     }
  130.   }
  131.   reference front() { return *begin(); }
  132.   const_reference front() const { return *begin(); }
  133.   reference back() { return *(end() - 1); }
  134.   const_reference back() const { return *(end() - 1); }
  135.   void push_back(const T& x) {
  136.     if (finish != end_of_storage) {
  137.       construct(finish, x);
  138.       ++finish;
  139.     }
  140.     else
  141.       insert_aux(end(), x);
  142.   }
  143.   void swap(vector<T, Alloc>& x) {
  144.     __STD::swap(start, x.start);
  145.     __STD::swap(finish, x.finish);
  146.     __STD::swap(end_of_storage, x.end_of_storage);
  147.   }
  148.   iterator insert(iterator position, const T& x) {
  149.     size_type n = position - begin();
  150.     if (finish != end_of_storage && position == end()) {
  151.       construct(finish, x);
  152.       ++finish;
  153.     }
  154.     else
  155.       insert_aux(position, x);
  156.     return begin() + n;
  157.   }
  158.   iterator insert(iterator position) { return insert(position, T()); }
  159. #ifdef __STL_MEMBER_TEMPLATES
  160.   template <class InputIterator>
  161.   void insert(iterator position, InputIterator first, InputIterator last) {
  162.     range_insert(position, first, last, iterator_category(first));
  163.   }
  164. #else /* __STL_MEMBER_TEMPLATES */
  165.   void insert(iterator position,
  166.               const_iterator first, const_iterator last);
  167. #endif /* __STL_MEMBER_TEMPLATES */
  168.   void insert (iterator pos, size_type n, const T& x);
  169.   void insert (iterator pos, int n, const T& x) {
  170.     insert(pos, (size_type) n, x);
  171.   }
  172.   void insert (iterator pos, long n, const T& x) {
  173.     insert(pos, (size_type) n, x);
  174.   }
  175.   void pop_back() {
  176.     --finish;
  177.     destroy(finish);
  178.   }
  179.   iterator erase(iterator position) {
  180.     if (position + 1 != end())
  181.       copy(position + 1, finish, position);
  182.     --finish;
  183.     destroy(finish);
  184.     return position;
  185.   }
  186.   iterator erase(iterator first, iterator last) {
  187.     iterator i = copy(last, finish, first);
  188.     destroy(i, finish);
  189.     finish = finish - (last - first);
  190.     return first;
  191.   }
  192.   void resize(size_type new_size, const T& x) {
  193.     if (new_size < size()) 
  194.       erase(begin() + new_size, end());
  195.     else
  196.       insert(end(), new_size - size(), x);
  197.   }
  198.   void resize(size_type new_size) { resize(new_size, T()); }
  199.   void clear() { erase(begin(), end()); }
  200. protected:
  201.   iterator allocate_and_fill(size_type n, const T& x) {
  202.     iterator result = data_allocator::allocate(n);
  203.     __STL_TRY {
  204.       uninitialized_fill_n(result, n, x);
  205.       return result;
  206.     }
  207.     __STL_UNWIND(data_allocator::deallocate(result, n));
  208.   }
  209. #ifdef __STL_MEMBER_TEMPLATES
  210.   template <class ForwardIterator>
  211.   iterator allocate_and_copy(size_type n,
  212.                              ForwardIterator first, ForwardIterator last) {
  213.     iterator result = data_allocator::allocate(n);
  214.     __STL_TRY {
  215.       uninitialized_copy(first, last, result);
  216.       return result;
  217.     }
  218.     __STL_UNWIND(data_allocator::deallocate(result, n));
  219.   }
  220. #else /* __STL_MEMBER_TEMPLATES */
  221.   iterator allocate_and_copy(size_type n,
  222.                              const_iterator first, const_iterator last) {
  223.     iterator result = data_allocator::allocate(n);
  224.     __STL_TRY {
  225.       uninitialized_copy(first, last, result);
  226.       return result;
  227.     }
  228.     __STL_UNWIND(data_allocator::deallocate(result, n));
  229.   }
  230. #endif /* __STL_MEMBER_TEMPLATES */
  231. #ifdef __STL_MEMBER_TEMPLATES
  232.   template <class InputIterator>
  233.   void range_initialize(InputIterator first, InputIterator last,
  234.                         input_iterator_tag) {
  235.     for ( ; first != last; ++first)
  236.       push_back(*first);
  237.   }
  238.   // This function is only called by the constructor.  We have to worry
  239.   //  about resource leaks, but not about maintaining invariants.
  240.   template <class ForwardIterator>
  241.   void range_initialize(ForwardIterator first, ForwardIterator last,
  242.                         forward_iterator_tag) {
  243.     size_type n = 0;
  244.     distance(first, last, n);
  245.     start = allocate_and_copy(n, first, last);
  246.     finish = start + n;
  247.     end_of_storage = finish;
  248.   }
  249.   template <class InputIterator>
  250.   void range_insert(iterator pos,
  251.                     InputIterator first, InputIterator last,
  252.                     input_iterator_tag);
  253.   template <class ForwardIterator>
  254.   void range_insert(iterator pos,
  255.                     ForwardIterator first, ForwardIterator last,
  256.                     forward_iterator_tag);
  257. #endif /* __STL_MEMBER_TEMPLATES */
  258. };
  259. template <class T, class Alloc>
  260. inline bool operator==(const vector<T, Alloc>& x, const vector<T, Alloc>& y) {
  261.   return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
  262. }
  263. template <class T, class Alloc>
  264. inline bool operator<(const vector<T, Alloc>& x, const vector<T, Alloc>& y) {
  265.   return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
  266. }
  267. #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
  268. template <class T, class Alloc>
  269. inline void swap(vector<T, Alloc>& x, vector<T, Alloc>& y) {
  270.   x.swap(y);
  271. }
  272. #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
  273. template <class T, class Alloc>
  274. vector<T, Alloc>& vector<T, Alloc>::operator=(const vector<T, Alloc>& x) {
  275.   if (&x != this) {
  276.     if (x.size() > capacity()) {
  277.       iterator tmp = allocate_and_copy(x.end() - x.begin(),
  278.                                        x.begin(), x.end());
  279.       destroy(start, finish);
  280.       deallocate();
  281.       start = tmp;
  282.       end_of_storage = start + (x.end() - x.begin());
  283.     }
  284.     else if (size() >= x.size()) {
  285.       iterator i = copy(x.begin(), x.end(), begin());
  286.       destroy(i, finish);
  287.     }
  288.     else {
  289.       copy(x.begin(), x.begin() + size(), start);
  290.       uninitialized_copy(x.begin() + size(), x.end(), finish);
  291.     }
  292.     finish = start + x.size();
  293.   }
  294.   return *this;
  295. }
  296. template <class T, class Alloc>
  297. void vector<T, Alloc>::insert_aux(iterator position, const T& x) {
  298.   if (finish != end_of_storage) {
  299.     construct(finish, *(finish - 1));
  300.     ++finish;
  301.     T x_copy = x;
  302.     copy_backward(position, finish - 2, finish - 1);
  303.     *position = x_copy;
  304.   }
  305.   else {
  306.     const size_type old_size = size();
  307.     const size_type len = old_size != 0 ? 2 * old_size : 1;
  308.     iterator new_start = data_allocator::allocate(len);
  309.     iterator new_finish = new_start;
  310.     __STL_TRY {
  311.       new_finish = uninitialized_copy(start, position, new_start);
  312.       construct(new_finish, x);
  313.       ++new_finish;
  314.       new_finish = uninitialized_copy(position, finish, new_finish);
  315.     }
  316. #       ifdef  __STL_USE_EXCEPTIONS 
  317.     catch(...) {
  318.       destroy(new_start, new_finish); 
  319.       data_allocator::deallocate(new_start, len);
  320.       throw;
  321.     }
  322. #       endif /* __STL_USE_EXCEPTIONS */
  323.     destroy(begin(), end());
  324.     deallocate();
  325.     start = new_start;
  326.     finish = new_finish;
  327.     end_of_storage = new_start + len;
  328.   }
  329. }
  330. template <class T, class Alloc>
  331. void vector<T, Alloc>::insert(iterator position, size_type n, const T& x) {
  332.   if (n != 0) {
  333.     if (size_type(end_of_storage - finish) >= n) {
  334.       T x_copy = x;
  335.       const size_type elems_after = finish - position;
  336.       iterator old_finish = finish;
  337.       if (elems_after > n) {
  338.         uninitialized_copy(finish - n, finish, finish);
  339.         finish += n;
  340.         copy_backward(position, old_finish - n, old_finish);
  341.         fill(position, position + n, x_copy);
  342.       }
  343.       else {
  344.         uninitialized_fill_n(finish, n - elems_after, x_copy);
  345.         finish += n - elems_after;
  346.         uninitialized_copy(position, old_finish, finish);
  347.         finish += elems_after;
  348.         fill(position, old_finish, x_copy);
  349.       }
  350.     }
  351.     else {
  352.       const size_type old_size = size();        
  353.       const size_type len = old_size + max(old_size, n);
  354.       iterator new_start = data_allocator::allocate(len);
  355.       iterator new_finish = new_start;
  356.       __STL_TRY {
  357.         new_finish = uninitialized_copy(start, position, new_start);
  358.         new_finish = uninitialized_fill_n(new_finish, n, x);
  359.         new_finish = uninitialized_copy(position, finish, new_finish);
  360.       }
  361. #         ifdef  __STL_USE_EXCEPTIONS 
  362.       catch(...) {
  363.         destroy(new_start, new_finish);
  364.         data_allocator::deallocate(new_start, len);
  365.         throw;
  366.       }
  367. #         endif /* __STL_USE_EXCEPTIONS */
  368.       destroy(start, finish);
  369.       deallocate();
  370.       start = new_start;
  371.       finish = new_finish;
  372.       end_of_storage = new_start + len;
  373.     }
  374.   }
  375. }
  376. #ifdef __STL_MEMBER_TEMPLATES
  377. template <class T, class Alloc> template <class InputIterator>
  378. void vector<T, Alloc>::range_insert(iterator pos,
  379.                                     InputIterator first, InputIterator last,
  380.                                     input_iterator_tag) {
  381.   for ( ; first != last; ++first) {
  382.     pos = insert(pos, *first);
  383.     ++pos;
  384.   }
  385. }
  386. template <class T, class Alloc> template <class ForwardIterator>
  387. void vector<T, Alloc>::range_insert(iterator position,
  388.                                     ForwardIterator first,
  389.                                     ForwardIterator last,
  390.                                     forward_iterator_tag) {
  391.   if (first != last) {
  392.     size_type n = 0;
  393.     distance(first, last, n);
  394.     if (size_type(end_of_storage - finish) >= n) {
  395.       const size_type elems_after = finish - position;
  396.       iterator old_finish = finish;
  397.       if (elems_after > n) {
  398.         uninitialized_copy(finish - n, finish, finish);
  399.         finish += n;
  400.         copy_backward(position, old_finish - n, old_finish);
  401.         copy(first, last, position);
  402.       }
  403.       else {
  404.         ForwardIterator mid = first;
  405.         advance(mid, elems_after);
  406.         uninitialized_copy(mid, last, finish);
  407.         finish += n - elems_after;
  408.         uninitialized_copy(position, old_finish, finish);
  409.         finish += elems_after;
  410.         copy(first, mid, position);
  411.       }
  412.     }
  413.     else {
  414.       const size_type old_size = size();
  415.       const size_type len = old_size + max(old_size, n);
  416.       iterator new_start = data_allocator::allocate(len);
  417.       iterator new_finish = new_start;
  418.       __STL_TRY {
  419.         new_finish = uninitialized_copy(start, position, new_start);
  420.         new_finish = uninitialized_copy(first, last, new_finish);
  421.         new_finish = uninitialized_copy(position, finish, new_finish);
  422.       }
  423. #         ifdef __STL_USE_EXCEPTIONS
  424.       catch(...) {
  425.         destroy(new_start, new_finish);
  426.         data_allocator::deallocate(new_start, len);
  427.         throw;
  428.       }
  429. #         endif /* __STL_USE_EXCEPTIONS */
  430.       destroy(start, finish);
  431.       deallocate();
  432.       start = new_start;
  433.       finish = new_finish;
  434.       end_of_storage = new_start + len;
  435.     }
  436.   }
  437. }
  438. #else /* __STL_MEMBER_TEMPLATES */
  439. template <class T, class Alloc>
  440. void vector<T, Alloc>::insert(iterator position, 
  441.                               const_iterator first, 
  442.                               const_iterator last) {
  443.   if (first != last) {
  444.     size_type n = 0;
  445.     distance(first, last, n);
  446.     if (size_type(end_of_storage - finish) >= n) {
  447.       const size_type elems_after = finish - position;
  448.       iterator old_finish = finish;
  449.       if (elems_after > n) {
  450.         uninitialized_copy(finish - n, finish, finish);
  451.         finish += n;
  452.         copy_backward(position, old_finish - n, old_finish);
  453.         copy(first, last, position);
  454.       }
  455.       else {
  456.         uninitialized_copy(first + elems_after, last, finish);
  457.         finish += n - elems_after;
  458.         uninitialized_copy(position, old_finish, finish);
  459.         finish += elems_after;
  460.         copy(first, first + elems_after, position);
  461.       }
  462.     }
  463.     else {
  464.       const size_type old_size = size();
  465.       const size_type len = old_size + max(old_size, n);
  466.       iterator new_start = data_allocator::allocate(len);
  467.       iterator new_finish = new_start;
  468.       __STL_TRY {
  469.         new_finish = uninitialized_copy(start, position, new_start);
  470.         new_finish = uninitialized_copy(first, last, new_finish);
  471.         new_finish = uninitialized_copy(position, finish, new_finish);
  472.       }
  473. #         ifdef __STL_USE_EXCEPTIONS
  474.       catch(...) {
  475.         destroy(new_start, new_finish);
  476.         data_allocator::deallocate(new_start, len);
  477.         throw;
  478.       }
  479. #         endif /* __STL_USE_EXCEPTIONS */
  480.       destroy(start, finish);
  481.       deallocate();
  482.       start = new_start;
  483.       finish = new_finish;
  484.       end_of_storage = new_start + len;
  485.     }
  486.   }
  487. }
  488. #endif /* __STL_MEMBER_TEMPLATES */
  489. #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
  490. #pragma reset woff 1174
  491. #endif
  492. __STL_END_NAMESPACE 
  493. #endif /* __SGI_STL_INTERNAL_VECTOR_H */
  494. // Local Variables:
  495. // mode:C++
  496. // End: