home *** CD-ROM | disk | FTP | other *** search
/ PC Format (South-Africa) 2001 June / PCFJune.iso / Xenon / C++ / FreeCommandLineTools.exe / Include / vector.cc < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-31  |  14.1 KB  |  427 lines

  1. #ifndef __VECTOR_CC
  2. #define __VECTOR_CC
  3. #pragma option push -b -a8 -pc -Vx- -Ve- -w-inl -w-aus -w-sig
  4. /***************************************************************************
  5.  *
  6.  * vector.cc - Non-inline definitions for the Standard Library vector class
  7.  *
  8.  ***************************************************************************
  9.  *
  10.  * Copyright (c) 1994
  11.  * Hewlett-Packard Company
  12.  *
  13.  * Permission to use, copy, modify, distribute and sell this software
  14.  * and its documentation for any purpose is hereby granted without fee,
  15.  * provided that the above copyright notice appear in all copies and
  16.  * that both that copyright notice and this permission notice appear
  17.  * in supporting documentation.  Hewlett-Packard Company makes no
  18.  * representations about the suitability of this software for any
  19.  * purpose.  It is provided "as is" without express or implied warranty.
  20.  *
  21.  *
  22.  ***************************************************************************
  23.  *
  24.  * Copyright (c) 1994-1999 Rogue Wave Software, Inc.  All Rights Reserved.
  25.  *
  26.  * This computer software is owned by Rogue Wave Software, Inc. and is
  27.  * protected by U.S. copyright laws and other laws and by international
  28.  * treaties.  This computer software is furnished by Rogue Wave Software,
  29.  * Inc. pursuant to a written license agreement and may be used, copied,
  30.  * transmitted, and stored only in accordance with the terms of such
  31.  * license and with the inclusion of the above copyright notice.  This
  32.  * computer software or any other copies thereof may not be provided or
  33.  * otherwise made available to any other person.
  34.  *
  35.  * U.S. Government Restricted Rights.  This computer software is provided
  36.  * with Restricted Rights.  Use, duplication, or disclosure by the
  37.  * Government is subject to restrictions as set forth in subparagraph (c)
  38.  * (1) (ii) of The Rights in Technical Data and Computer Software clause
  39.  * at DFARS 252.227-7013 or subparagraphs (c) (1) and (2) of the
  40.  * Commercial Computer Software รป Restricted Rights at 48 CFR 52.227-19,
  41.  * as applicable.  Manufacturer is Rogue Wave Software, Inc., 5500
  42.  * Flatiron Parkway, Boulder, Colorado 80301 USA.
  43.  *
  44.  **************************************************************************/
  45. #include <stdcomp.h>
  46.  
  47. #ifndef _RWSTD_NO_NAMESPACE
  48. namespace std {
  49. #endif
  50.  
  51. //
  52. // This requires that T have a default constructor.
  53. //
  54.  
  55.   template <class T, class Allocator>
  56.   void vector<T,Allocator>::resize (size_type new_size)
  57.   {
  58.     T value;
  59.     if (new_size > size())
  60.       insert(end(), new_size - size(), value);
  61.     else if (new_size < size())
  62.       erase(begin() + new_size, end());
  63.   }
  64.  
  65.   template <class T, class Allocator>
  66.   void vector<T,Allocator>::resize (size_type new_size, T value)
  67.   {
  68.     if (new_size > size())
  69.       insert(end(), new_size - size(), value);
  70.     else if (new_size < size())
  71.       erase(begin() + new_size, end());
  72.   }
  73.  
  74.   template <class T, class Allocator>
  75.   vector<T,Allocator>& vector<T,Allocator>::operator= (const vector<T,Allocator>& x)
  76.   {
  77.     if (&x == this) return *this;
  78.     if (x.size() > capacity())
  79.     {
  80.       __value_alloc_type va(__end_of_storage);
  81.       iterator tmp = va.allocate(x.end() - x.begin(),0);
  82. #ifndef _RWSTD_NO_EXCEPTIONS
  83.       try {
  84.         __end_of_storage = uninitialized_copy(x.begin(), x.end(), tmp);
  85.       } catch(...) {
  86.         va.deallocate(tmp,x.end()-x.begin());
  87.         throw;
  88.       }
  89. #else
  90.       __end_of_storage = uninitialized_copy(x.begin(), x.end(), tmp);
  91. #endif // _RWSTD_NO_EXCEPTIONS
  92.       __destroy(__start, __finish);
  93.       va.deallocate(__start,__end_of_storage.data()-__start);
  94.       __start = tmp;
  95.     }
  96.     else if (size() >= x.size())
  97.     {
  98.       iterator i = copy(x.begin(), x.end(), begin());
  99.       __destroy(i, __finish);
  100.     }
  101.     else
  102.     {
  103.       copy(x.begin(), x.begin() + size(), begin());
  104.       uninitialized_copy(x.begin() + size(), x.end(), begin() + size());
  105.     }
  106.     __finish = begin() + x.size();
  107.     return *this;
  108.   }
  109.  
  110.   template <class T, class Allocator>
  111.   void vector<T,Allocator>::__insert_aux (
  112.       iterator position, const T& x)
  113.   {
  114.     if (__finish != __end_of_storage.data())
  115.     {
  116.       __value_alloc_type(__end_of_storage).construct(__finish, *(__finish - 1));
  117.       copy_backward(position, __finish - 1, __finish);
  118.       *position = x;
  119.       ++__finish;
  120.     }
  121.     else
  122.     {
  123.       //
  124.       // We always allocate enough space for a number of additional
  125.       // elements in the vector, unless the size of each element is
  126.       // very large. See definition of __rw_allocation_size in
  127.       // memory.
  128.       //
  129.       __value_alloc_type va(__end_of_storage);
  130.       size_type len = __RWSTD::__rw_allocation_size((value_type*)0,size(),__buffer_size);
  131.       iterator tmp = va.allocate(len,__start);
  132.       uninitialized_copy(begin(), position, tmp);
  133.       va.construct((tmp + (position - begin())), x);
  134. #ifndef _RWSTD_NO_EXCEPTIONS
  135.       try {
  136.         uninitialized_copy(position, end(), tmp + (position - begin()) + 1); 
  137.       } catch(...) {
  138.         va.deallocate(tmp,len);
  139.         throw;
  140.       }
  141. #else
  142.       uninitialized_copy(position, end(), tmp + (position - begin()) + 1); 
  143. #endif // _RWSTD_NO_EXCEPTIONS
  144.       __destroy(begin(), end());
  145.       va.deallocate(begin(),__end_of_storage.data() - begin());
  146.       __end_of_storage = tmp + len;
  147.       __finish = tmp + size() + 1;
  148.       __start = tmp;
  149.     }
  150.   }
  151.  
  152.   template <class T, class Allocator>
  153.   void vector<T,Allocator>::__insert_aux (
  154.       iterator position, size_type n, const T& x)
  155.   {
  156.     if (n == 0) return;
  157.     if ((size_type)(__end_of_storage.data() - __finish) >= n)
  158.     {
  159.       iterator old_end = end();
  160.       if ((size_type)(end() - position) > n)
  161.       {
  162.         uninitialized_copy(old_end - n, old_end, old_end);
  163.         __finish += n;
  164.         copy_backward(position, old_end - n, old_end);
  165.         fill(position, position + n, x);
  166.       }
  167.       else
  168.       {
  169.         size_type first_part = n - (old_end - position);
  170.         uninitialized_fill_n(old_end, first_part, x);
  171.         __finish += first_part;
  172.         uninitialized_copy(position, old_end, position + n);
  173.         __finish += n - first_part;
  174.         fill(position, old_end, x);
  175.  
  176.       }
  177.  
  178.     }
  179.     else
  180.     {
  181.       __value_alloc_type va(__end_of_storage);
  182.       size_type len = size() + max(size(), n);
  183.       iterator tmp = va.allocate(len,__start);
  184. #ifndef _RWSTD_NO_EXCEPTIONS
  185.       try {
  186.         uninitialized_copy(begin(), position, tmp);
  187.         uninitialized_fill_n(tmp + (position - begin()), n, x);
  188.         uninitialized_copy(position, end(), tmp + (position - begin() + n));
  189.       } catch(...) {
  190.         va.deallocate(tmp,len);
  191.         throw;
  192.       }
  193. #else
  194.       uninitialized_copy(begin(), position, tmp);
  195.       uninitialized_fill_n(tmp + (position - begin()), n, x);
  196.       uninitialized_copy(position, end(), tmp + (position - begin() + n));
  197. #endif // _RWSTD_NO_EXCEPTIONS
  198.       __destroy(begin(), end());
  199.       va.deallocate(begin(),__end_of_storage.data() - begin());
  200.       __end_of_storage = tmp + len;
  201.       __finish = tmp + size() + n;
  202.       __start = tmp;
  203.     }
  204.   }
  205.  
  206. #ifndef _RWSTD_NO_MEMBER_TEMPLATES
  207.   template<class T, class Allocator>
  208.   template<class InputIterator>
  209.   void vector<T,Allocator>::__insert_aux2 (iterator position, 
  210.                                     InputIterator first, 
  211.                                     InputIterator last)
  212. #else
  213.   template<class T, class Allocator>
  214.   void vector<T,Allocator>::__insert_aux2 (iterator position,
  215.                                     const_iterator first,
  216.                                     const_iterator last)
  217. #endif
  218.   {
  219.     if (first == last) return;
  220.     size_type n;
  221.     __initialize(n, size_type(0));
  222.     distance(first, last, n);
  223.  
  224.     if ((size_type)(__end_of_storage.data() - __finish) >= n)
  225.     {
  226.       iterator old_end = end();
  227.       if ((size_type)(old_end - position) > n)
  228.       {
  229.         uninitialized_copy(old_end - n, old_end, old_end);
  230.         __finish += n;
  231.         copy_backward(position, old_end - n, old_end);
  232.         copy(first, last, position);
  233.       }
  234.       else
  235.       {
  236.         size_type first_part = (old_end - position);
  237. #ifndef _RWSTD_NO_MEMBER_TEMPLATES
  238.         InputIterator iter(first);
  239. #else
  240.         const_iterator iter(first);
  241. #endif
  242.         advance(iter, first_part);
  243.         uninitialized_copy(iter, last, old_end);
  244. //        uninitialized_copy(first + first_part, last, old_end);
  245.         __finish += n - first_part;
  246.         uninitialized_copy(position, old_end, position + n);
  247.         __finish += first_part;
  248.         copy(first, iter, position);
  249. //        copy(first, first + (old_end - position), position);
  250.       }
  251.  
  252.     }
  253.     else
  254.     {
  255.       __value_alloc_type va(__end_of_storage);
  256.       size_type len = size() + max(size(), n);
  257.       iterator tmp = va.allocate(len,__start);
  258. #ifndef _RWSTD_NO_EXCEPTIONS
  259.       try {
  260.         uninitialized_copy(begin(), position, tmp);
  261.         uninitialized_copy(first, last, tmp + (position - begin()));
  262.         uninitialized_copy(position, end(), tmp + (position - begin() + n));
  263.       } catch(...) {
  264.         va.deallocate(tmp,len);
  265.         throw;
  266.       }
  267. #else
  268.       uninitialized_copy(begin(), position, tmp);
  269.       uninitialized_copy(first, last, tmp + (position - begin()));
  270.       uninitialized_copy(position, end(), tmp + (position - begin() + n));
  271. #endif // _RWSTD_NO_EXCEPTIONS
  272.       __destroy(begin(), end());
  273.       va.deallocate(begin(),__end_of_storage.data() - begin());
  274.       __end_of_storage = tmp + len;
  275.       __finish = tmp + size() + n;
  276.       __start = tmp;
  277.     }
  278.   }
  279.  
  280. #ifndef _RWSTD_NO_MEMBER_TEMPLATES
  281. // The body of this function is duplicated in src/vecbool.cpp and
  282. // further down in this file as well.
  283. #ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
  284.   template <class Allocator>
  285.   template<class InputIterator>
  286.   void vector<bool, Allocator >::insert 
  287. #else
  288.   template<class InputIterator>
  289.   void vector<bool, allocator<bool> >::insert 
  290. #endif // _RWSTD_NO_CLASS_PARTIAL_SPEC
  291.   (iterator position, 
  292.    InputIterator first,
  293.    InputIterator last)
  294.  
  295.   {
  296.     if (first == last) return;
  297.     size_type n;
  298.     __initialize(n, size_type(0));
  299.     distance(first, last, n);
  300.     if (capacity() - size() >= n)
  301.     {
  302.       copy_backward(position, end(), __finish + n);
  303.       copy(first, last, position);
  304.       __finish += n;
  305.     }
  306.     else
  307.     {
  308.       size_type len = size() + max(size(), n);
  309.       unsigned int* q = __bit_alloc(len);
  310.       iterator i = copy(begin(), position, iterator(q, 0));
  311.       i = copy(first, last, i);
  312.       __finish = copy(position, end(), i);
  313.       __value_alloc_type(__end_of_storage).deallocate(__start.p,__end_of_storage.data() - __start.p);
  314.       __end_of_storage = q + (len + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT;
  315.       __start = iterator(q, 0);
  316.     }
  317.   }
  318. #endif // _RWSTD_NO_MEMBER_TEMPLATES
  319.  
  320. #ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
  321. // Duplicates of the followign functions exist in src/stl/vecbool.cpp.
  322. // Which set is used depends on the availability of partial specialization.
  323.  
  324.   template <class Allocator>
  325.   void vector<bool,Allocator >::flip ()
  326.   {
  327.     for (iterator i = begin(); !(i == end()); i++)
  328.       *i = !(*i);
  329.   }
  330.  
  331.   template <class Allocator>
  332.   void vector<bool,Allocator >::swap (reference x, reference y)
  333.   {
  334.     bool tmp = x; x = y; y = tmp;
  335.   }
  336.  
  337.   template <class Allocator>
  338.   void vector<bool,Allocator >::__insert_aux (iterator position, bool x)
  339.   {
  340.     if (__finish.p != __end_of_storage.data())
  341.     {
  342.       __copy_backward(position, __finish - 1, __finish);
  343.       *position = x;
  344.       ++__finish;
  345.     }
  346.     else
  347.     {
  348.       size_type len = size() ? 2 * size() : _RWSTD_WORD_BIT;
  349.       unsigned int* q = __bit_alloc(len);
  350.       iterator i = __copy(begin(), position, iterator(q, 0));
  351.       *i++ = x;
  352.       __finish = __copy(position, end(), i);
  353.       __value_alloc_type(__end_of_storage).deallocate(__start.p,__end_of_storage.data() - __start.p);
  354.       __end_of_storage = q + (len + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT;
  355.       __start = iterator(q, 0);
  356.     }
  357.   }
  358.  
  359.   template <class Allocator>
  360.   void vector<bool,Allocator >::insert (iterator position, size_type n, const bool& x)
  361.   {
  362.     if (n == 0) return;
  363.     if (capacity() - size() >= n)
  364.     {
  365.       __copy_backward(position, end(), __finish + n);
  366.       __fill(position, position + n, x);
  367.       __finish += n;
  368.     }
  369.     else
  370.     {
  371.       size_type len = size() + max(size(), n);
  372.       unsigned int* q = __bit_alloc(len);
  373.       iterator i = __copy(begin(), position, iterator(q, 0));
  374.       __fill_n(i, n, x);
  375.       __finish = __copy(position, end(), i + n);
  376.       __value_alloc_type(__end_of_storage).deallocate(__start.p,__end_of_storage.data() - __start.p);
  377.       __end_of_storage = q + (len + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT;
  378.       __start = iterator(q, 0);
  379.     }
  380.   }
  381. #ifdef _RWSTD_NO_MEMBER_TEMPLATES
  382.   template <class Allocator>
  383.   void vector<bool,Allocator >::insert (iterator position, const_iterator first,
  384.                                         const_iterator last)
  385.   {
  386.     if (first == last) return;
  387.     size_type n;
  388.     __initialize(n, size_type(0));
  389.     distance(first, last, n);
  390.     if (capacity() - size() >= n)
  391.     {
  392.       __copy_backward(position, end(), __finish + n);
  393.       __copy(first, last, position);
  394.       __finish += n;
  395.     }
  396.     else
  397.     {
  398.       size_type len = size() + max(size(), n);
  399.       unsigned int* q = __bit_alloc(len);
  400.       iterator i = __copy(begin(), position, iterator(q, 0));
  401.       i = __copy(first, last, i);
  402.       __finish = __copy(position, end(), i);
  403.       __value_alloc_type(__end_of_storage).deallocate(__start.p,__end_of_storage.data() - __start.p);
  404.       __end_of_storage = q + (len + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT;
  405.       __start = iterator(q, 0);
  406.     }
  407.   }
  408. #endif // _RWSTD_NO_MEMBER_TEMPLATES
  409.  
  410.   template <class Allocator>
  411.   void vector<bool,Allocator >::resize (size_type new_size, bool c)
  412.   {
  413.     if (new_size > size())
  414.       insert(end(), new_size - size(), c);
  415.     else if (new_size < size())
  416.       erase(begin() + new_size, end());
  417.   }
  418.  
  419. #endif // _RWSTD_NO_CLASS_PARTIAL_SPEC
  420.  
  421. #ifndef _RWSTD_NO_NAMESPACE
  422. }
  423. #endif
  424.  
  425. #pragma option pop
  426. #endif /* __VECTOR_CC */
  427.