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

  1. #ifndef __LIST_CC
  2. #define __LIST_CC
  3. #pragma option push -b -a8 -pc -Vx- -Ve- -w-inl -w-aus -w-sig
  4.  
  5. /***************************************************************************
  6.  *
  7.  * list.cc - Non-nline list definitions for the Standard Library
  8.  *
  9.  ***************************************************************************
  10.  *
  11.  * Copyright (c) 1994
  12.  * Hewlett-Packard Company
  13.  *
  14.  * Permission to use, copy, modify, distribute and sell this software
  15.  * and its documentation for any purpose is hereby granted without fee,
  16.  * provided that the above copyright notice appear in all copies and
  17.  * that both that copyright notice and this permission notice appear
  18.  * in supporting documentation.  Hewlett-Packard Company makes no
  19.  * representations about the suitability of this software for any
  20.  * purpose.  It is provided "as is" without express or implied warranty.
  21.  *
  22.  *
  23.  ***************************************************************************
  24.  *
  25.  * Copyright (c) 1994-1999 Rogue Wave Software, Inc.  All Rights Reserved.
  26.  *
  27.  * This computer software is owned by Rogue Wave Software, Inc. and is
  28.  * protected by U.S. copyright laws and other laws and by international
  29.  * treaties.  This computer software is furnished by Rogue Wave Software,
  30.  * Inc. pursuant to a written license agreement and may be used, copied,
  31.  * transmitted, and stored only in accordance with the terms of such
  32.  * license and with the inclusion of the above copyright notice.  This
  33.  * computer software or any other copies thereof may not be provided or
  34.  * otherwise made available to any other person.
  35.  *
  36.  * U.S. Government Restricted Rights.  This computer software is provided
  37.  * with Restricted Rights.  Use, duplication, or disclosure by the
  38.  * Government is subject to restrictions as set forth in subparagraph (c)
  39.  * (1) (ii) of The Rights in Technical Data and Computer Software clause
  40.  * at DFARS 252.227-7013 or subparagraphs (c) (1) and (2) of the
  41.  * Commercial Computer Software รป Restricted Rights at 48 CFR 52.227-19,
  42.  * as applicable.  Manufacturer is Rogue Wave Software, Inc., 5500
  43.  * Flatiron Parkway, Boulder, Colorado 80301 USA.
  44.  *
  45.  **************************************************************************/
  46.  
  47. #include <stdcomp.h>
  48. #include <limits>
  49.  
  50. #define _RWSTD_LIST_SORT_COUNTERS 64
  51.  
  52. #ifndef _RWSTD_NO_NAMESPACE
  53. namespace std {
  54. #endif
  55.  
  56.   template <class T, class Allocator>
  57.   void list<T,Allocator>::__deallocate_buffers ()
  58.   {
  59.     while (__buffer_list.data())
  60.     {
  61.       __buffer_pointer tmp = __buffer_list;
  62.       __buffer_list = (__buffer_pointer)(__buffer_list.data()->next_buffer);
  63.       __list_node_alloc_type(__buffer_list).deallocate(tmp->buffer,tmp->size);
  64.       __buffer_alloc_type(__buffer_list).deallocate(tmp,1);
  65.     }
  66.     __free_list = 0;
  67.     __next_avail = 0;
  68.     __last = 0;
  69.   }
  70.  
  71. //
  72. // This requires that T have a default constructor.
  73. //
  74.  
  75.   template <class T, class Allocator>
  76.   void list<T,Allocator>::resize (size_type new_size)
  77.   {
  78.     T value;
  79.     if (new_size > size())
  80.       insert(end(), new_size - size(), value);
  81.     else if (new_size < size())
  82.     {
  83.       iterator tmp = begin();
  84.       advance(tmp, (difference_type) new_size);
  85.       erase(tmp, end());
  86.     }
  87.   }
  88.  
  89.   template <class T, class Allocator>
  90.   void list<T,Allocator>::resize (size_type new_size, T value)
  91.   {
  92.     if (new_size > size())
  93.       insert(end(), new_size - size(), value);
  94.     else if (new_size < size())
  95.     {
  96.       iterator tmp = begin();
  97.       advance(tmp, (difference_type) new_size);
  98.       erase(tmp, end());
  99.     }
  100.   }
  101.  
  102. #ifndef _RWSTD_NO_MEMBER_TEMPLATES
  103.   template <class T, class Allocator>   
  104.   template<class InputIterator>
  105.   void list<T,Allocator>::__insert_aux2 (iterator position, InputIterator first,
  106.                                   InputIterator locallast)
  107.   {
  108.     while (first != locallast) insert(position, *first++);
  109.   }
  110. #endif // _RWSTD_NO_MEMBER_TEMPLATES
  111.  
  112. #ifdef _RWSTD_NO_MEMBER_TEMPLATES
  113.   template <class T, class Allocator>   
  114.   void list<T, Allocator>::insert (iterator position, 
  115.                                    const_iterator first,
  116.                                    const_iterator locallast)
  117.   {
  118.     while (first != locallast) insert(position, *first++);
  119.   }
  120.   template <class T, class Allocator>
  121.   void list<T, Allocator>::insert (iterator position, 
  122.                                    const T* first, const T* locallast)
  123.   {
  124.     while (first != locallast) insert(position, *first++);
  125.   }
  126. #endif // _RWSTD_NO_MEMBER_TEMPLATES
  127.  
  128.   template <class T, class Allocator>
  129.   void list<T, Allocator>::__insert_aux (iterator position, 
  130.                                          size_type n, const T& x)
  131.   {
  132.     while (n--) insert(position, x);
  133.   }
  134.  
  135.   template <class T, class Allocator>
  136.   _TYPENAME list<T, Allocator>::iterator 
  137.   list<T, Allocator>::erase (iterator first, iterator locallast)
  138.   {
  139.     iterator tmp = end();
  140.     while (first != locallast) 
  141.     {
  142.       tmp = erase(first++);
  143.     }
  144.     return tmp;
  145.   }
  146.  
  147.   template <class T, class Allocator>
  148.   list<T, Allocator>& list<T, Allocator>::operator= (const list<T, Allocator>& x)
  149.   {
  150.     if (this != &x)
  151.     {
  152.       iterator first1 = begin();
  153.       iterator last1 = end();
  154.       const_iterator first2 = x.begin();
  155.       const_iterator last2 = x.end();
  156.       while (first1 != last1 && first2 != last2) *first1++ = *first2++;
  157.       if (first2 == last2)
  158.         erase(first1, last1);
  159.       else
  160.         insert(last1, first2, last2);
  161.     }
  162.     return *this;
  163.   }
  164.  
  165.   template <class T, class Allocator>
  166.   void list<T, Allocator>::remove (const T& value)
  167.   {
  168.     iterator first = begin();
  169.     iterator last = end();
  170.     while (first != last)
  171.     {
  172.       iterator next = first;
  173.       ++next;
  174.       if (*first == value) erase(first);
  175.       first = next;
  176.     }
  177.   }
  178.  
  179.   template <class T, class Allocator>
  180.   void list<T, Allocator>::unique ()
  181.   {
  182.     iterator first = begin();
  183.     iterator last = end();
  184.     if (first == last) return;
  185.     iterator next = first;
  186.     while (++next != last)
  187.     {
  188.       if (*first == *next)
  189.         erase(next);
  190.       else
  191.         first = next;
  192.       next = first;
  193.     }
  194.   }
  195.  
  196.   template <class T, class Allocator>
  197.           void list<T, Allocator>::merge (list<T, Allocator>& x)
  198.   {
  199.  
  200.     iterator first1 = begin();
  201.     iterator last1 = end();
  202.     iterator first2 = x.begin();
  203.     iterator last2 = x.end();
  204.     while (first1 != last1 && first2 != last2)
  205.     {
  206.       if (*first2 < *first1)
  207.       {
  208.         iterator next = first2;
  209.         __transfer(first1, first2, ++next, x);
  210.         first2 = next;
  211.       }
  212.       else
  213.         first1++;
  214.     }
  215.     if (first2 != last2) 
  216.       __transfer(last1, first2, last2, x);
  217.   }
  218.  
  219.   template <class T, class Allocator>
  220.   void list<T, Allocator>::reverse ()
  221.   {
  222.     if (size() < 2) return;
  223.     for (iterator first = ++begin(); first != end();)
  224.     {
  225.       iterator old = first++;
  226.       __transfer(begin(), old, first, *this);
  227.     }
  228.   }
  229.  
  230.   // sorts list by moving nodes within list.  This preserves iterators pointing to
  231.   // elements of the list.
  232.   template <class T, class Allocator>
  233.           void list<T, Allocator>::sort ()
  234.   {
  235.       for (unsigned int n = 1; n < size(); n *= 2) {
  236.           iterator i1 = begin(), i2 = begin(), i3 = begin();
  237.           __advance(i2, (difference_type) n, end());
  238.           __advance(i3, (difference_type) (2*n), end());
  239.           for (unsigned int m = 0; m < (size()+(2*n))/(n*2); m++) {
  240.               if (i1 != end() && i2 != end()) {
  241.                   __adjacent_merge(i1, i2, i3);
  242.                   i1 = i3;
  243.                   i2 = i3;
  244.                   __advance(i2, (difference_type) n, end());
  245.                   __advance(i3, (difference_type) 2*n, end());
  246.               }
  247.           }
  248.       }
  249.   }
  250.  
  251. #ifndef _RWSTD_NO_MEMBER_TEMPLATES
  252.   template<class T, class Allocator>
  253.   template<class Predicate> void list<T, Allocator>::remove_if (Predicate pred)
  254.   {
  255.     iterator first = begin();
  256.     iterator last = end();
  257.     while (first != last)
  258.     {
  259.       iterator next = first;
  260.       ++next;
  261.       if (pred(*first)) erase(first);
  262.       first = next;
  263.     }
  264.   }
  265.  
  266.   template<class T, class Allocator>
  267.   template<class BinaryPredicate> void list<T, Allocator>::unique (BinaryPredicate pred)
  268.   {
  269.     iterator first = begin();
  270.     iterator last = end();
  271.     if (first == last) return;
  272.     iterator next = first;
  273.     while (++next != last)
  274.     {
  275.       if (pred(*first, *next))
  276.         erase(next);
  277.       else
  278.         first = next;
  279.       next = first;
  280.     }
  281.   }
  282.  
  283.   template<class T, class Allocator>
  284.   template<class Compare> void list<T, Allocator>::merge (list<T, Allocator>& x, Compare comp)
  285.   {
  286.     iterator first1 = begin();
  287.     iterator last1  = end();
  288.     iterator first2 = x.begin();
  289.     iterator last2  = x.end();
  290.     while (first1 != last1 && first2 != last2)
  291.     {
  292.       if (comp(*first2, *first1))
  293.       {
  294.         iterator next = first2;
  295.         __transfer(first1, first2, ++next, x);
  296.         first2 = next;
  297.       }
  298.       else
  299.         first1++;
  300.     }
  301.     if (first2 != last2) 
  302.       __transfer(last1, first2, last2, x);
  303.   }
  304.  
  305.   template <class T, class Allocator>
  306.     template<class Compare> void list<T, Allocator>::sort (Compare comp)
  307.   {
  308.       for (int n = 1; n < size(); n *= 2) {
  309.           iterator i1 = begin(), i2 = begin(), i3 = begin();
  310.           __advance(i2, (difference_type) n, end());
  311.           __advance(i3, (difference_type) (2*n), end());
  312.           for (int m = 0; m < (size()+(2*n))/(n*2); m++) {
  313.               if (i1 != end() && i2 != end()) {
  314.                   __adjacent_merge(i1, i2, i3, comp);
  315.                   i1 = i3;
  316.                   i2 = i3;
  317.                   __advance(i2, (difference_type) n, end());
  318.                   __advance(i3, (difference_type) 2*n, end());
  319.               }
  320.           }
  321.       }
  322.   }
  323.  
  324. /*
  325.   template<class T, class Allocator>
  326.   template<class Compare> void list<T, Allocator>::sort (Compare comp)
  327.   {
  328.     if (size() < 2) return;
  329.  
  330.     list<T, Allocator> carry(get_allocator());
  331.     list<T, Allocator> counter[ _RWSTD_LIST_SORT_COUNTERS];
  332.     for (int i = 0; i < _RWSTD_LIST_SORT_COUNTERS; i++)
  333.       counter[i].__set_allocator(get_allocator());
  334.     int fill = 0;
  335.     while (!empty())
  336.     {
  337.       carry.splice(carry.begin(), *this, begin());
  338.       int i = 0;
  339.       while (i < fill && !counter[i].empty())
  340.       {
  341.         counter[i].merge(carry, comp);
  342.         carry.swap(counter[i++]);
  343.       }
  344.       carry.swap(counter[i]);         
  345.       if (i == fill) ++fill;
  346.     } 
  347.     while (fill--) merge(counter[fill], comp);
  348.   }
  349.   */
  350. #endif /*_RWSTD_NO_MEMBER_TEMPLATES*/
  351.  
  352. #undef _RWSTD_LIST_SORT_COUNTERS
  353.  
  354. #ifndef _RWSTD_NO_NAMESPACE
  355. }
  356. #endif
  357.  
  358. #pragma option pop
  359. #endif /* __LIST_CC */
  360.