home *** CD-ROM | disk | FTP | other *** search
/ PC Plus SuperCD (UK) 2000 May / PCP163A.iso / Runimage / Cbuilder4 / Include / VECTOR.CC < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-26  |  14.4 KB  |  429 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.  * (c) Copyright 1994, 1998 Rogue Wave Software, Inc.
  25.  * ALL RIGHTS RESERVED
  26.  *
  27.  * The software and information contained herein are proprietary to, and
  28.  * comprise valuable trade secrets of, Rogue Wave Software, Inc., which
  29.  * intends to preserve as trade secrets such software and information.
  30.  * This software is furnished pursuant to a written license agreement and
  31.  * may be used, copied, transmitted, and stored only in accordance with
  32.  * the terms of such license and with the inclusion of the above copyright
  33.  * notice.  This software and information or any other copies thereof may
  34.  * not be provided or otherwise made available to any other person.
  35.  *
  36.  * Notwithstanding any other lease or license that may pertain to, or
  37.  * accompany the delivery of, this computer software and information, the
  38.  * rights of the Government regarding its use, reproduction and disclosure
  39.  * are as set forth in Section 52.227-19 of the FARS Computer
  40.  * Software-Restricted Rights clause.
  41.  * 
  42.  * Use, duplication, or disclosure by the Government is subject to
  43.  * restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
  44.  * Technical Data and Computer Software clause at DFARS 252.227-7013.
  45.  * Contractor/Manufacturer is Rogue Wave Software, Inc.,
  46.  * P.O. Box 2328, Corvallis, Oregon 97339.
  47.  *
  48.  * This computer software and information is distributed with "restricted
  49.  * rights."  Use, duplication or disclosure is subject to restrictions as
  50.  * set forth in NASA FAR SUP 18-52.227-79 (April 1985) "Commercial
  51.  * Computer Software-Restricted Rights (April 1985)."  If the Clause at
  52.  * 18-52.227-74 "Rights in Data General" is specified in the contract,
  53.  * then the "Alternate III" clause applies.
  54.  *
  55.  **************************************************************************/
  56. #include <stdcomp.h>
  57.  
  58. #ifndef _RWSTD_NO_NAMESPACE
  59. namespace std {
  60. #endif
  61.  
  62. //
  63. // This requires that T have a default constructor.
  64. //
  65.  
  66.   template <class T, class Allocator>
  67.   void vector<T,Allocator>::resize (size_type new_size)
  68.   {
  69.     T value;
  70.     if (new_size > size())
  71.       insert(end(), new_size - size(), value);
  72.     else if (new_size < size())
  73.       erase(begin() + new_size, end());
  74.   }
  75.  
  76.   template <class T, class Allocator>
  77.   void vector<T,Allocator>::resize (size_type new_size, T value)
  78.   {
  79.     if (new_size > size())
  80.       insert(end(), new_size - size(), value);
  81.     else if (new_size < size())
  82.       erase(begin() + new_size, end());
  83.   }
  84.  
  85.   template <class T, class Allocator>
  86.   vector<T,Allocator>& vector<T,Allocator>::operator= (const vector<T,Allocator>& x)
  87.   {
  88.     if (&x == this) return *this;
  89.     if (x.size() > capacity())
  90.     {
  91.       __value_alloc_type va(__end_of_storage);
  92.       iterator tmp = va.allocate(x.end() - x.begin(),0);
  93. #ifndef _RWSTD_NO_EXCEPTIONS
  94.       try {
  95.         __end_of_storage = uninitialized_copy(x.begin(), x.end(), tmp);
  96.       } catch(...) {
  97.         va.deallocate(tmp,x.end()-x.begin());
  98.         throw;
  99.       }
  100. #else
  101.       __end_of_storage = uninitialized_copy(x.begin(), x.end(), tmp);
  102. #endif // _RWSTD_NO_EXCEPTIONS
  103.       __destroy(__start, __finish);
  104.       va.deallocate(__start,__end_of_storage.data()-__start);
  105.       __start = tmp;
  106.     }
  107.     else if (size() >= x.size())
  108.     {
  109.       iterator i = copy(x.begin(), x.end(), begin());
  110.       __destroy(i, __finish);
  111.     }
  112.     else
  113.     {
  114.       copy(x.begin(), x.begin() + size(), begin());
  115.       uninitialized_copy(x.begin() + size(), x.end(), begin() + size());
  116.     }
  117.     __finish = begin() + x.size();
  118.     return *this;
  119.   }
  120.  
  121.   template <class T, class Allocator>
  122.   void vector<T,Allocator>::__insert_aux (
  123.       iterator position, const T& x)
  124.   {
  125.     if (__finish != __end_of_storage.data())
  126.     {
  127.       __value_alloc_type(__end_of_storage).construct(__finish, *(__finish - 1));
  128.       copy_backward(position, __finish - 1, __finish);
  129.       *position = x;
  130.       ++__finish;
  131.     }
  132.     else
  133.     {
  134.       //
  135.       // We always allocate enough space for a number of additional
  136.       // elements in the vector, unless the size of each element is
  137.       // very large. See definition of __rw_allocation_size in
  138.       // memory.
  139.       //
  140.       __value_alloc_type va(__end_of_storage);
  141.       size_type len = __RWSTD::__rw_allocation_size((value_type*)0,size(),__buffer_size);
  142.       iterator tmp = va.allocate(len,__start);
  143.       uninitialized_copy(begin(), position, tmp);
  144.       va.construct((tmp + (position - begin())), x);
  145. #ifndef _RWSTD_NO_EXCEPTIONS
  146.       try {
  147.         uninitialized_copy(position, end(), tmp + (position - begin()) + 1); 
  148.       } catch(...) {
  149.         va.deallocate(tmp,len);
  150.         throw;
  151.       }
  152. #else
  153.       uninitialized_copy(position, end(), tmp + (position - begin()) + 1); 
  154. #endif // _RWSTD_NO_EXCEPTIONS
  155.       __destroy(begin(), end());
  156.       va.deallocate(begin(),__end_of_storage.data() - begin());
  157.       __end_of_storage = tmp + len;
  158.       __finish = tmp + size() + 1;
  159.       __start = tmp;
  160.     }
  161.   }
  162.  
  163.   template <class T, class Allocator>
  164.   void vector<T,Allocator>::__insert_aux (
  165.       iterator position, size_type n, const T& x)
  166.   {
  167.     if (n == 0) return;
  168.     if ((size_type)(__end_of_storage.data() - __finish) >= n)
  169.     {
  170.       iterator old_end = end();
  171.       if ((size_type)(end() - position) > n)
  172.       {
  173.         uninitialized_copy(old_end - n, old_end, old_end);
  174.         __finish += n;
  175.         copy_backward(position, old_end - n, old_end);
  176.         fill(position, position + n, x);
  177.       }
  178.       else
  179.       {
  180.         size_type first_part = n - (old_end - position);
  181.         uninitialized_fill_n(old_end, first_part, x);
  182.         __finish += first_part;
  183.         uninitialized_copy(position, old_end, position + n);
  184.         __finish += n - first_part;
  185.         fill(position, old_end, x);
  186.  
  187.       }
  188.  
  189.     }
  190.     else
  191.     {
  192.       __value_alloc_type va(__end_of_storage);
  193.       size_type len = size() + max(size(), n);
  194.       iterator tmp = va.allocate(len,__start);
  195. #ifndef _RWSTD_NO_EXCEPTIONS
  196.       try {
  197.         uninitialized_copy(begin(), position, tmp);
  198.         uninitialized_fill_n(tmp + (position - begin()), n, x);
  199.         uninitialized_copy(position, end(), tmp + (position - begin() + n));
  200.       } catch(...) {
  201.         va.deallocate(tmp,len);
  202.         throw;
  203.       }
  204. #else
  205.       uninitialized_copy(begin(), position, tmp);
  206.       uninitialized_fill_n(tmp + (position - begin()), n, x);
  207.       uninitialized_copy(position, end(), tmp + (position - begin() + n));
  208. #endif // _RWSTD_NO_EXCEPTIONS
  209.       __destroy(begin(), end());
  210.       va.deallocate(begin(),__end_of_storage.data() - begin());
  211.       __end_of_storage = tmp + len;
  212.       __finish = tmp + size() + n;
  213.       __start = tmp;
  214.     }
  215.   }
  216.  
  217. #ifndef _RWSTD_NO_MEMBER_TEMPLATES
  218.   template<class T, class Allocator>
  219.   template<class InputIterator>
  220.   void vector<T,Allocator>::insert (iterator position, 
  221.                                     InputIterator first, 
  222.                                     InputIterator last)
  223. #else
  224.   template<class T, class Allocator>
  225.   void vector<T,Allocator>::insert (iterator position,
  226.                                     const_iterator first,
  227.                                     const_iterator last)
  228. #endif
  229.   {
  230.     if (first == last) return;
  231.     size_type n;
  232.     __initialize(n, size_type(0));
  233.     distance(first, last, n);
  234.  
  235.     if ((size_type)(__end_of_storage.data() - __finish) >= n)
  236.     {
  237.       iterator old_end = end();
  238.       if ((size_type)(old_end - position) > n)
  239.       {
  240.         uninitialized_copy(old_end - n, old_end, old_end);
  241.         __finish += n;
  242.         copy_backward(position, old_end - n, old_end);
  243.         copy(first, last, position);
  244.       }
  245.       else
  246.       {
  247.         size_type first_part = (old_end - position);
  248.         uninitialized_copy(first + first_part, last, old_end);
  249.         __finish += n - first_part;
  250.         uninitialized_copy(position, old_end, position + n);
  251.         __finish += first_part;
  252.         copy(first, first + (old_end - position), position);
  253.       }
  254.  
  255.     }
  256.     else
  257.     {
  258.       __value_alloc_type va(__end_of_storage);
  259.       size_type len = size() + max(size(), n);
  260.       iterator tmp = va.allocate(len,__start);
  261. #ifndef _RWSTD_NO_EXCEPTIONS
  262.       try {
  263.         uninitialized_copy(begin(), position, tmp);
  264.         uninitialized_copy(first, last, tmp + (position - begin()));
  265.         uninitialized_copy(position, end(), tmp + (position - begin() + n));
  266.       } catch(...) {
  267.         va.deallocate(tmp,len);
  268.         throw;
  269.       }
  270. #else
  271.       uninitialized_copy(begin(), position, tmp);
  272.       uninitialized_copy(first, last, tmp + (position - begin()));
  273.       uninitialized_copy(position, end(), tmp + (position - begin() + n));
  274. #endif // _RWSTD_NO_EXCEPTIONS
  275.       __destroy(begin(), end());
  276.       va.deallocate(begin(),__end_of_storage.data() - begin());
  277.       __end_of_storage = tmp + len;
  278.       __finish = tmp + size() + n;
  279.       __start = tmp;
  280.     }
  281.   }
  282.  
  283. #ifndef _RWSTD_NO_MEMBER_TEMPLATES
  284. // The body of this function is duplicated in src/vecbool.cpp and
  285. // further down in this file as well.
  286. #ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
  287.   template <class Allocator>
  288.   template<class InputIterator>
  289.   void vector<bool, Allocator >::insert 
  290. #else
  291.   template<class InputIterator>
  292.   void vector<bool, allocator<bool> >::insert 
  293. #endif // _RWSTD_NO_CLASS_PARTIAL_SPEC
  294.   (iterator position, 
  295.    InputIterator first,
  296.    InputIterator last)
  297.  
  298.   {
  299.     if (first == last) return;
  300.     size_type n;
  301.     __initialize(n, size_type(0));
  302.     distance(first, last, n);
  303.     if (capacity() - size() >= n)
  304.     {
  305.       copy_backward(position, end(), __finish + n);
  306.       copy(first, last, position);
  307.       __finish += n;
  308.     }
  309.     else
  310.     {
  311.       size_type len = size() + max(size(), n);
  312.       unsigned int* q = __bit_alloc(len);
  313.       iterator i = copy(begin(), position, iterator(q, 0));
  314.       i = copy(first, last, i);
  315.       __finish = copy(position, end(), i);
  316.       __value_alloc_type(__end_of_storage).deallocate(__start.p,__end_of_storage.data() - __start.p);
  317.       __end_of_storage = q + (len + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT;
  318.       __start = iterator(q, 0);
  319.     }
  320.   }
  321. #endif // _RWSTD_NO_MEMBER_TEMPLATES
  322.  
  323. #ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
  324. // Duplicates of the followign functions exist in src/stl/vecbool.cpp.
  325. // Which set is used depends on the availability of partial specialization.
  326.  
  327.   template <class Allocator>
  328.   void vector<bool,Allocator >::flip ()
  329.   {
  330.     for (iterator i = begin(); !(i == end()); i++)
  331.       *i = !(*i);
  332.   }
  333.  
  334.   template <class Allocator>
  335.   void vector<bool,Allocator >::swap (reference x, reference y)
  336.   {
  337.     bool tmp = x; x = y; y = tmp;
  338.   }
  339.  
  340.   template <class Allocator>
  341.   void vector<bool,Allocator >::__insert_aux (iterator position, bool x)
  342.   {
  343.     if (__finish.p != __end_of_storage.data())
  344.     {
  345.       __copy_backward(position, __finish - 1, __finish);
  346.       *position = x;
  347.       ++__finish;
  348.     }
  349.     else
  350.     {
  351.       size_type len = size() ? 2 * size() : _RWSTD_WORD_BIT;
  352.       unsigned int* q = __bit_alloc(len);
  353.       iterator i = __copy(begin(), position, iterator(q, 0));
  354.       *i++ = x;
  355.       __finish = __copy(position, end(), i);
  356.       __value_alloc_type(__end_of_storage).deallocate(__start.p,__end_of_storage.data() - __start.p);
  357.       __end_of_storage = q + (len + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT;
  358.       __start = iterator(q, 0);
  359.     }
  360.   }
  361.  
  362.   template <class Allocator>
  363.   void vector<bool,Allocator >::insert (iterator position, size_type n, const bool& x)
  364.   {
  365.     if (n == 0) return;
  366.     if (capacity() - size() >= n)
  367.     {
  368.       __copy_backward(position, end(), __finish + n);
  369.       __fill(position, position + n, x);
  370.       __finish += n;
  371.     }
  372.     else
  373.     {
  374.       size_type len = size() + max(size(), n);
  375.       unsigned int* q = __bit_alloc(len);
  376.       iterator i = __copy(begin(), position, iterator(q, 0));
  377.       __fill_n(i, n, x);
  378.       __finish = __copy(position, end(), i + n);
  379.       __value_alloc_type(__end_of_storage).deallocate(__start.p,__end_of_storage.data() - __start.p);
  380.       __end_of_storage = q + (len + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT;
  381.       __start = iterator(q, 0);
  382.     }
  383.   }
  384. #ifdef _RWSTD_NO_MEMBER_TEMPLATES
  385.   template <class Allocator>
  386.   void vector<bool,Allocator >::insert (iterator position, const_iterator first,
  387.                                         const_iterator last)
  388.   {
  389.     if (first == last) return;
  390.     size_type n;
  391.     __initialize(n, size_type(0));
  392.     distance(first, last, n);
  393.     if (capacity() - size() >= n)
  394.     {
  395.       __copy_backward(position, end(), __finish + n);
  396.       __copy(first, last, position);
  397.       __finish += n;
  398.     }
  399.     else
  400.     {
  401.       size_type len = size() + max(size(), n);
  402.       unsigned int* q = __bit_alloc(len);
  403.       iterator i = __copy(begin(), position, iterator(q, 0));
  404.       i = __copy(first, last, i);
  405.       __finish = __copy(position, end(), i);
  406.       __value_alloc_type(__end_of_storage).deallocate(__start.p,__end_of_storage.data() - __start.p);
  407.       __end_of_storage = q + (len + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT;
  408.       __start = iterator(q, 0);
  409.     }
  410.   }
  411. #endif // _RWSTD_NO_MEMBER_TEMPLATES
  412.  
  413.   template <class Allocator>
  414.   void vector<bool,Allocator >::resize (size_type new_size, bool c)
  415.   {
  416.     if (new_size > size())
  417.       insert(end(), new_size - size(), c);
  418.     else if (new_size < size())
  419.       erase(begin() + new_size, end());
  420.   }
  421.  
  422. #endif // _RWSTD_NO_CLASS_PARTIAL_SPEC
  423.  
  424. #ifndef _RWSTD_NO_NAMESPACE
  425. }
  426. #endif
  427. #pragma option pop
  428. #endif /* __VECTOR_CC */
  429.