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

  1. #ifndef __LIST_H
  2. #define __LIST_H
  3. #pragma option push -b -a8 -pc -Vx- -Ve- -w-inl -w-aus -w-sig
  4. // -*- C++ -*-
  5. #ifndef __STD_LIST__
  6. #define __STD_LIST__
  7.  
  8. /***************************************************************************
  9.  *
  10.  * list - list declarations for the Standard Library
  11.  *
  12.  ***************************************************************************
  13.  *
  14.  * Copyright (c) 1994
  15.  * Hewlett-Packard Company
  16.  *
  17.  * Permission to use, copy, modify, distribute and sell this software
  18.  * and its documentation for any purpose is hereby granted without fee,
  19.  * provided that the above copyright notice appear in all copies and
  20.  * that both that copyright notice and this permission notice appear
  21.  * in supporting documentation.  Hewlett-Packard Company makes no
  22.  * representations about the suitability of this software for any
  23.  * purpose.  It is provided "as is" without express or implied warranty.
  24.  *
  25.  *
  26.  ***************************************************************************
  27.  *
  28.  * Copyright (c) 1994-1999 Rogue Wave Software, Inc.  All Rights Reserved.
  29.  *
  30.  * This computer software is owned by Rogue Wave Software, Inc. and is
  31.  * protected by U.S. copyright laws and other laws and by international
  32.  * treaties.  This computer software is furnished by Rogue Wave Software,
  33.  * Inc. pursuant to a written license agreement and may be used, copied,
  34.  * transmitted, and stored only in accordance with the terms of such
  35.  * license and with the inclusion of the above copyright notice.  This
  36.  * computer software or any other copies thereof may not be provided or
  37.  * otherwise made available to any other person.
  38.  *
  39.  * U.S. Government Restricted Rights.  This computer software is provided
  40.  * with Restricted Rights.  Use, duplication, or disclosure by the
  41.  * Government is subject to restrictions as set forth in subparagraph (c)
  42.  * (1) (ii) of The Rights in Technical Data and Computer Software clause
  43.  * at DFARS 252.227-7013 or subparagraphs (c) (1) and (2) of the
  44.  * Commercial Computer Software รป Restricted Rights at 48 CFR 52.227-19,
  45.  * as applicable.  Manufacturer is Rogue Wave Software, Inc., 5500
  46.  * Flatiron Parkway, Boulder, Colorado 80301 USA.
  47.  *
  48.  **************************************************************************/
  49. #include <stdcomp.h>
  50.  
  51. #include <algorithm>
  52. #include <iterator>
  53. #include <memory>
  54. #include <stdexcept>
  55. #include <rw/rwdispatch.h>
  56.  
  57. #ifndef list
  58. #define list list
  59. #endif
  60. #ifndef _RWSTD_NO_NAMESPACE
  61. namespace std {
  62. #endif
  63.  
  64. //
  65. // Note that _RWSTD_COMPLEX_DEFAULT(x)
  66. // will expand to: ' = x', or nothing,
  67. // depending on your compiler's capabilities and/or
  68. // flag settings (see stdcomp.h).
  69. //
  70.   template <class T, class Allocator _RWSTD_COMPLEX_DEFAULT(allocator<T>) >
  71.   class list
  72.   {
  73.   protected:
  74.     struct __list_node;
  75.     struct __list_node_buffer;
  76.     friend struct __list_node;
  77.     friend struct __list_node_buffer;
  78.  
  79. #ifdef _RWSTD_ALLOCATOR
  80.     typedef _TYPENAME Allocator::template rebind<__list_node>::other  __list_node_alloc_type;
  81.     typedef _TYPENAME Allocator::template rebind<T>::other __value_alloc_type;
  82.     typedef _TYPENAME Allocator::template rebind<__list_node_buffer>::other  __buffer_alloc_type;
  83. #else
  84.     typedef allocator_interface<Allocator,__list_node>  __list_node_alloc_type;
  85.     typedef allocator_interface<Allocator,T>          __value_alloc_type;
  86.     typedef allocator_interface<Allocator,__list_node_buffer>   __buffer_alloc_type;
  87. #endif // _RWSTD_ALLOCATOR
  88.  
  89.   public:
  90.     //
  91.     // types
  92.     //
  93.     typedef _TYPENAME __value_alloc_type::reference        reference;
  94.     typedef _TYPENAME __value_alloc_type::const_reference  const_reference;
  95.     typedef _TYPENAME __value_alloc_type::size_type        size_type;
  96.     typedef _TYPENAME __value_alloc_type::difference_type  difference_type;
  97.     typedef T                                    value_type;
  98.     typedef Allocator                            allocator_type;
  99.     typedef _TYPENAME __value_alloc_type::pointer        pointer;
  100.     typedef _TYPENAME __value_alloc_type::const_pointer  const_pointer;
  101.  
  102.   protected:
  103.     typedef _TYPENAME __list_node_alloc_type::pointer    __link_type;
  104.     typedef _TYPENAME __buffer_alloc_type::pointer       __buffer_pointer;
  105.  
  106.     struct __list_node
  107.     {
  108.       __link_type next;
  109.       __link_type prev;
  110.       T           data;
  111.     };
  112.  
  113.     struct __list_node_buffer
  114.     {
  115.       __buffer_pointer next_buffer;
  116.       size_type        size;
  117.       __link_type      buffer;
  118.     };
  119.  
  120.     size_type          __buffer_size;    
  121.     __RWSTD::__rw_basis<__buffer_pointer,allocator_type>   __buffer_list;
  122.     __link_type        __free_list;
  123.     __link_type        __next_avail;
  124.     __link_type        __last;
  125.     __link_type        __node;
  126.     size_type          __length;
  127.     
  128.     void __add_new_buffer (size_type n)
  129.     {
  130.       __buffer_pointer tmp = 
  131.         __buffer_alloc_type(__buffer_list).allocate(
  132.           _RWSTD_STATIC_CAST(size_type,1),__buffer_list.data());
  133. #ifndef _RWSTD_NO_EXCEPTIONS
  134.       try {
  135.         tmp->buffer = __list_node_alloc_type(__buffer_list).allocate(n,__last);
  136.       } catch(...) {
  137.         __buffer_alloc_type(__buffer_list).deallocate(tmp,1);
  138.         throw;
  139.       }      
  140. #else
  141.       tmp->buffer = __list_node_alloc_type(__buffer_list).allocate(n,__last);
  142. #endif // _RWSTD_NO_EXCEPTIONS
  143.       tmp->next_buffer = __buffer_list;
  144.       tmp->size = n;
  145.       __buffer_list = tmp;
  146.       __next_avail = __buffer_list.data()->buffer; 
  147.       __last = __next_avail + n;
  148.     }
  149.     void __deallocate_buffers ();
  150.     __link_type __get_node (size_type n)
  151.     {
  152.       __link_type tmp = __free_list;
  153.       return __free_list ? (__free_list = (__link_type)(__free_list->next), tmp) 
  154.       : (__next_avail == __last ? (__add_new_buffer(n), __next_avail++) 
  155.          : __next_avail++);
  156.     }
  157.     void __put_node (__link_type p) { p->next = __free_list; __free_list = p; }
  158.  
  159.     void __init(size_type n = 0)  
  160.     {
  161.       __buffer_size = max((size_type)1,
  162.                         __RWSTD::__rw_allocation_size((value_type*)0,
  163.                                                       (size_type)0,
  164.                                                       (size_type)0));
  165.       __node = __get_node(n == 0 ? __buffer_size : n + 1);
  166.       (*__node).next = __node;
  167.       (*__node).prev = __node; 
  168.     }
  169.     void __init(size_type n, value_type value)  
  170.     {
  171.       __init(n);
  172. #ifndef _RWSTD_NO_EXCEPTIONS
  173.       try {
  174.         insert(begin(), n, value);
  175.       } catch(...) {
  176.         __deallocate_buffers();
  177.         throw;
  178.       }
  179. #else
  180.       insert(begin(), n, value);
  181. #endif
  182.     }
  183.  
  184.     typedef _RW_STD::iterator<bidirectional_iterator_tag, value_type,
  185.                     difference_type, pointer,reference> __it;
  186.     typedef _RW_STD::iterator<bidirectional_iterator_tag, value_type, 
  187.                     difference_type, const_pointer, const_reference> __cit;
  188.  
  189.   public:
  190.     
  191.     class iterator;
  192.     class const_iterator;
  193.     friend class iterator;
  194.     friend class const_iterator;
  195.  
  196.     class iterator : public __it
  197.     {
  198.       friend class list<T,Allocator>;
  199.       friend class const_iterator;
  200.  
  201.     protected:
  202.       
  203.       __link_type node;
  204.       iterator (__link_type x) : node(x) {}
  205.     
  206.     public:
  207.  
  208.       iterator () {}
  209.       bool operator== (const iterator& x) const { return node == x.node; }
  210.       bool operator!= (const iterator& x) const { return !(*this == x); }
  211.       reference operator* () const { return (*node).data; } 
  212. #ifndef _RWSTD_NO_NONCLASS_ARROW_RETURN
  213.       pointer operator-> () const { return &(node->data); }
  214. #endif
  215.       iterator& operator++ ()
  216.       { 
  217.         node = (__link_type)((*node).next); return *this;
  218.       }
  219.       iterator operator++ (int)
  220.       {
  221.         iterator tmp = *this; ++*this; return tmp;
  222.       }
  223.       iterator& operator-- ()
  224.       {
  225.         node = (__link_type)((*node).prev); return *this;
  226.       }
  227.       iterator operator-- (int)
  228.       {
  229.         iterator tmp = *this; --*this; return tmp;
  230.       }
  231.     };  // End of definition of iterator class.
  232.  
  233.     class const_iterator : public __cit
  234.     {
  235.       friend class list<T,Allocator>;
  236.  
  237.     protected:
  238.       
  239.       __link_type node;
  240.       const_iterator (__link_type x) : node(x) {}
  241.     
  242.     public:
  243.  
  244.       const_iterator () {}
  245. #if !defined(_MSC_VER) || defined(__BORLANDC__)
  246.       const_iterator (const  _TYPENAME list<T,Allocator>::iterator& x) : node(x.node) {}
  247. #else
  248.       const_iterator (const iterator& x) : node(x.node) {}
  249. #endif
  250.       bool operator== (const const_iterator& x) const {return node==x.node;}
  251.       bool operator!= (const const_iterator x) const { return !(*this == x); } 
  252.       const_reference operator* () const { return (*node).data; }
  253. #ifndef _RWSTD_NO_NONCLASS_ARROW_RETURN
  254.       const_pointer operator-> () const { return &(node->data); }
  255. #endif
  256.       const_iterator& operator++ ()
  257.       { 
  258.         node = (__link_type)((*node).next); return *this;
  259.       }
  260.       const_iterator operator++ (int)
  261.       {
  262.         const_iterator tmp = *this; ++*this; return tmp;
  263.       }
  264.       const_iterator& operator-- ()
  265.       {
  266.         node = (__link_type)((*node).prev); return *this;
  267.       }
  268.       const_iterator operator-- (int)
  269.       {
  270.         const_iterator tmp = *this;
  271.         --*this;
  272.         return tmp;
  273.       }
  274.     };  // End of definition of const_iterator class.
  275.  
  276. #ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC 
  277.     typedef _RW_STD::reverse_iterator<const_iterator> const_reverse_iterator;
  278.     typedef _RW_STD::reverse_iterator<iterator>  reverse_iterator;
  279. #else
  280.     typedef __reverse_bi_iterator<const_iterator, 
  281.       bidirectional_iterator_tag, value_type, 
  282.       const_reference, const_pointer, difference_type>
  283.       const_reverse_iterator;
  284.     typedef __reverse_bi_iterator<iterator, 
  285.       bidirectional_iterator_tag, value_type,
  286.       reference, pointer, difference_type>
  287.       reverse_iterator;
  288. #endif
  289.  
  290.     //
  291.     // construct/copy/destroy
  292.     //
  293.     list (const Allocator& alloc _RWSTD_DEFAULT_ARG(Allocator())) 
  294.       : __length(0), __buffer_list(0,alloc),
  295.         __free_list(0), __next_avail(0), __last(0), __node(0)
  296.     {
  297.       __init(1);
  298.     }
  299.     
  300. #ifdef _RWSTD_NO_DEFAULT_TEMPLATE_ARGS  
  301.     list (void) 
  302.       : __length(0), __buffer_list(0,Allocator()),
  303.         __free_list(0), __next_avail(0), __last(0), __node(0)
  304.     {
  305.       __init(1);
  306.     }
  307.  
  308.     list (size_type n, const T& value)
  309.       : __length(0), __buffer_list(0,Allocator()),
  310.         __free_list(0), __next_avail(0), __last(0), __node(0)
  311.     {
  312.       __init(n,value);
  313.     }
  314. #endif // _RWSTD_NO_DEFAULT_TEMPLATE_ARGS
  315.     _EXPLICIT list (size_type n) 
  316.       : __length(0), __buffer_list(0,Allocator()),
  317.         __free_list(0), __next_avail(0), __last(0), __node(0)
  318.     {
  319.       T value = T();
  320.       __init(n,value);
  321.     }
  322.  
  323. #ifndef _RWSTD_NO_MEMBER_TEMPLATES
  324.  
  325.     template<class InputIterator>
  326.     void __init_aux (InputIterator first, InputIterator locallast, _RW_is_not_integer)
  327.     {
  328.       __init();
  329. #ifndef _RWSTD_NO_EXCEPTIONS
  330.       try {
  331.         insert(begin(), first, locallast);
  332.       } catch(...) {
  333.         __deallocate_buffers();
  334.         throw;
  335.       }
  336. #else
  337.       insert(begin(), first, locallast);
  338. #endif
  339.     }
  340.     template<class InputIterator>
  341.     void __init_aux (InputIterator first, InputIterator last, _RW_is_integer)
  342.     { __init(first, last); }
  343.  
  344.     template<class InputIterator>
  345.     list (InputIterator first, InputIterator locallast,
  346.           const Allocator& alloc _RWSTD_DEFAULT_ARG(Allocator()))
  347.       : __length(0), __buffer_list(0,alloc),
  348.         __free_list(0), __next_avail(0), __last(0), __node(0)
  349.     {
  350.         typedef _TYPENAME _RWdispatch<InputIterator>::_RWtype _RWtype;
  351.         __init_aux(first, locallast, _RWtype());
  352.     }
  353.     list (size_type n, const T& value,
  354.           const Allocator& alloc _RWSTD_DEFAULT_ARG(Allocator()))
  355.       :  __length(0), __buffer_list(0,alloc),
  356.         __free_list(0), __next_avail(0), __last(0), __node(0)
  357.     { __init(n, value); }
  358. #else
  359.     //
  360.     // Build a list of size n with each element set to a copy of value.
  361.     //
  362.     list (size_type n, const T& value,
  363.           const Allocator& alloc _RWSTD_DEFAULT_ARG(Allocator())) 
  364.       : __length(0), __buffer_list(0,alloc),
  365.        __free_list(0), __next_avail(0), __last(0), __node(0)
  366.     {
  367.       __init(n, value);
  368.     }
  369.  
  370.     list (const_iterator first, const_iterator locallast,
  371.           const Allocator& alloc _RWSTD_DEFAULT_ARG(Allocator()))
  372.       : __length(0), __buffer_list(0,alloc),
  373.         __free_list(0), __next_avail(0), __last(0), __node(0)
  374.     {
  375.       __init();
  376. #ifndef _RWSTD_NO_EXCEPTIONS
  377.       try {
  378.         insert(begin(), first, locallast);
  379.       } catch(...) {
  380.         __deallocate_buffers();
  381.         throw;
  382.       }
  383. #else
  384.       insert(begin(), first, locallast);
  385. #endif
  386.     }
  387.     list (const T* first, const T* locallast,
  388.           const Allocator& alloc _RWSTD_DEFAULT_ARG(Allocator()))
  389.       : __length(0), __buffer_list(0,alloc),
  390.        __free_list(0), __next_avail(0), __last(0), __node(0)
  391.     {
  392.       __init();
  393. #ifndef _RWSTD_NO_EXCEPTIONS
  394.       try {
  395.         insert(begin(), first, locallast);
  396.       } catch(...) {
  397.         __deallocate_buffers();
  398.         throw;
  399.       }
  400. #else
  401.       insert(begin(), first, locallast);
  402. #endif
  403.     }
  404.  
  405. #ifdef _RWSTD_NO_DEFAULT_TEMPLATE_ARGS
  406.     list (const_iterator first, const_iterator locallast)
  407.       : __length(0), __buffer_list(0,Allocator()),
  408.         __free_list(0), __next_avail(0), __last(0), __node(0)
  409.     {
  410.       __init();
  411. #ifndef _RWSTD_NO_EXCEPTIONS
  412.       try {
  413.         insert(begin(), first, locallast);
  414.       } catch(...) {
  415.         __deallocate_buffers();
  416.         throw;
  417.       }
  418. #else
  419.       insert(begin(), first, locallast);
  420. #endif
  421.     }
  422.  
  423.     list (const T* first, const T* locallast)
  424.       : __length(0), __buffer_list(0,Allocator()),
  425.         __free_list(0), __next_avail(0), __last(0), __node(0)
  426.     {
  427.       __init();
  428. #ifndef _RWSTD_NO_EXCEPTIONS
  429.       try {
  430.         insert(begin(), first, locallast);
  431.       } catch(...) {
  432.         __deallocate_buffers();
  433.         throw;
  434.       }
  435. #else
  436.       insert(begin(), first, locallast);
  437. #endif
  438.     }
  439. #endif // _RWSTD_NO_DEFAULT_TEMPLATE_ARGS
  440. #endif // _RWSTD_NO_MEMBER_TEMPLATES
  441.  
  442.     list (const list<T,Allocator>& x) : __length(0), __buffer_list(0,x.get_allocator()),
  443.       __free_list(0), __next_avail(0), __last(0), __node(0)
  444.     {
  445.       __init();
  446. #ifndef _RWSTD_NO_EXCEPTIONS
  447.       try {
  448.         insert(begin(), x.begin(), x.end());
  449.       } catch(...) {
  450.         __deallocate_buffers();
  451.         throw;
  452.       }
  453. #else
  454.       insert(begin(), x.begin(), x.end());
  455. #endif
  456.     }
  457.  
  458.     ~list ()
  459.     {
  460.       if (__node)
  461.       {
  462.         erase(begin(), end());
  463.         __put_node(__node);
  464.         __deallocate_buffers();
  465.       }
  466.     }
  467.     list<T,Allocator>& operator= (const list<T,Allocator>& x);   
  468.  
  469. #ifndef _RWSTD_NO_MEMBER_TEMPLATES
  470.     template<class InputIterator>
  471.             void assign (InputIterator first, InputIterator last)
  472.     {
  473.         erase(begin(), end());
  474.         typedef _TYPENAME _RWdispatch<InputIterator>::_RWtype _RWtype;
  475.         __insert_aux(begin(), first, last, _RWtype());
  476.     }
  477.     void assign (size_type n, const T& t)
  478.     {
  479.         erase(begin(), end()); insert(begin(), n, t);
  480.     }
  481. #else
  482.     void assign (const_iterator first, const_iterator last)
  483.     { erase(begin(), end()); insert(begin(), first, last); }
  484.     void assign (const T* first, const T* last)
  485.     { erase(begin(), end()); insert(begin(), first, last); }
  486.     //
  487.     // Assign n copies of t to this list.
  488.     //
  489.     void assign (size_type n, const T& t)
  490.     { erase(begin(), end()); insert(begin(), n, t); }
  491. #endif // _RWSTD_NO_MEMBER_TEMPLATES
  492.  
  493.     allocator_type get_allocator() const
  494.     {
  495.       return (allocator_type)__buffer_list;
  496.     }
  497.  
  498.     //
  499.     // Iterators.
  500.     //
  501.     iterator       begin ()       { return _RWSTD_STATIC_CAST(__link_type,((*__node).next)); }
  502.     const_iterator begin () const { return _RWSTD_STATIC_CAST(__link_type,((*__node).next)); }
  503.  
  504.     iterator       end ()         { return __node;                      }
  505.     const_iterator end ()   const { return __node;                      }
  506.     reverse_iterator rbegin ()
  507.     { 
  508.       reverse_iterator tmp(end()); return tmp;
  509.     }
  510.     const_reverse_iterator rbegin () const
  511.     { 
  512.       const_reverse_iterator tmp(end()); return tmp;
  513.     }
  514.     reverse_iterator rend ()
  515.     { 
  516.       reverse_iterator tmp(begin()); return tmp;
  517.     }
  518.     const_reverse_iterator rend () const
  519.     {
  520.       const_reverse_iterator tmp(begin()); return tmp;
  521.     }
  522.  
  523.     //
  524.     // Capacity.
  525.     //
  526.     bool empty ()         const { return __length == 0;                }
  527.     size_type size ()     const { return __length;                     }
  528.     size_type max_size () const 
  529.     { return __list_node_alloc_type(__buffer_list).max_size(); }
  530.     void resize (size_type new_size);
  531.     void resize (size_type new_size, T value);
  532.  
  533.     //
  534.     // Element access.
  535.     //
  536.     reference       front ()       { return *begin();   }
  537.     const_reference front () const { return *begin();   }
  538.     reference       back  ()       { return *(--end()); }
  539.     const_reference back  () const { return *(--end()); }
  540.  
  541.     //
  542.     // Modifiers.
  543.     //
  544.     //
  545.     void push_front (const T& x) { insert(begin(), x); }
  546.     void push_back  (const T& x) { insert(end(), x);   }
  547.     void pop_front  ()           { erase(begin());     }
  548.     void pop_back   ()           { iterator tmp = end(); erase(--tmp); }
  549.  
  550.     //
  551.     // Insert x at position.
  552.     //
  553.     iterator insert (iterator position, const T& x)
  554.     {
  555.       __value_alloc_type va(__buffer_list);
  556.       __link_type tmp = __get_node(__buffer_size);
  557. #ifndef _RWSTD_NO_EXCEPTIONS
  558.       try {
  559.        va.construct(va.address((*tmp).data),x);
  560.       } catch(...) {
  561.         __put_node(tmp);
  562.         throw;
  563.       }      
  564. #else
  565.       va.construct(va.address((*tmp).data),x);
  566. #endif // _RWSTD_NO_EXCEPTIONS
  567.       (*tmp).next = position.node;
  568.       (*tmp).prev = (*position.node).prev;
  569.       (*(__link_type((*position.node).prev))).next = tmp;
  570.       (*position.node).prev = tmp;
  571.       ++__length;
  572.       return tmp;
  573.     }
  574.  
  575. #ifndef _RWSTD_NO_MEMBER_TEMPLATES
  576.     template<class InputIterator>
  577.     void insert (iterator position, InputIterator first, 
  578.                  InputIterator last)
  579.     {
  580.         typedef _TYPENAME _RWdispatch<InputIterator>::_RWtype _RWtype;
  581.         __insert_aux(position, first, last, _RWtype());
  582.     }
  583.     void insert (iterator position, size_type n, const T& value)
  584.     { __insert_aux(position,n,value); }
  585. #else
  586.     void insert (iterator position, size_type n, const T& x)
  587.     { __insert_aux(position,n,x); }
  588.     void insert (iterator position, const T* first, const T* last);
  589.     void insert (iterator position, const_iterator first, const_iterator last);
  590. #endif // _RWSTD_NO_MEMBER_TEMPLATES
  591.  
  592.     iterator erase (iterator position)
  593.     {
  594.       if (position == end())
  595.         return end();
  596.       iterator tmp = (iterator)(__link_type((*position.node).next));
  597.       (*(__link_type((*position.node).prev))).next = (*position.node).next;
  598.       (*(__link_type((*position.node).next))).prev = (*position.node).prev;
  599.       --__length;
  600.       __value_alloc_type va(__buffer_list);
  601.       va.destroy(va.address((*position.node).data));
  602.       __put_node(position.node);
  603.       return tmp;
  604.     }
  605.     iterator erase      (iterator first, iterator last);
  606.     void swap (list<T,Allocator>& x)
  607.     {
  608.       if((allocator_type)__buffer_list==(allocator_type)x.__buffer_list)
  609.       {
  610.  
  611. #ifndef _RWSTD_NO_NAMESPACE
  612.         std::swap(__node, x.__node); 
  613.         std::swap(__length, x.__length);
  614.         std::swap(__buffer_list,x.__buffer_list);
  615.         std::swap(__free_list,x.__free_list);
  616.         std::swap(__next_avail,x.__next_avail);
  617.         std::swap(__last,x.__last);
  618. #else
  619.         ::swap(__node, x.__node); 
  620.         ::swap(__length, x.__length);
  621.         ::swap(__buffer_list,x.__buffer_list);
  622.         ::swap(__free_list,x.__free_list);
  623.         ::swap(__next_avail,x.__next_avail);
  624.         ::swap(__last,x.__last);
  625. #endif // _RWSTD_NO_NAMESPACE
  626.       }
  627.       else
  628.       {
  629.         list<T,Allocator> _x = *this;
  630.         *this=x;
  631.         x=_x;
  632.       }
  633.     }
  634.  
  635.     void clear()
  636.     {
  637.       erase(begin(),end());
  638.     }
  639.  
  640.   protected:
  641.     
  642.     void __transfer (iterator position, iterator first, 
  643.                      iterator last, list<T,Allocator>& x)
  644.     {
  645.       if (this == &x)
  646.       {
  647.         (*(__link_type((*last.node).prev))).next = position.node;
  648.         (*(__link_type((*first.node).prev))).next = last.node;
  649.         (*(__link_type((*position.node).prev))).next = first.node;  
  650.         __link_type tmp = __link_type((*position.node).prev);
  651.         (*position.node).prev = (*last.node).prev;
  652.         (*last.node).prev = (*first.node).prev; 
  653.         (*first.node).prev = tmp;
  654.       }
  655.       else
  656.       {
  657.         insert(position,first,last);
  658.         x.erase(first,last);
  659.       }
  660.     }
  661.  
  662.     void __advance(iterator &i, difference_type n, iterator end)
  663.     {
  664.         for (int j = 0; j < (int) n; j++) {
  665.             if (i != end) ++i;
  666.         }
  667.     }
  668.  
  669.     // uses transfer_node to merge in list by transfering nodes to list
  670.     void __adjacent_merge (iterator first1, iterator last1,
  671.                            iterator last2)
  672.     {
  673.         iterator first2 = last1;
  674.         int n = 0;
  675.         distance(first1, last1, n);
  676.         int count = 0;
  677.  
  678.         while (count <= n && first2 != last2)
  679.         {
  680.             if (*first2 < *first1)
  681.             {
  682.                 iterator next = first2;
  683.                 __transfer(first1, first2, ++next, *this);
  684.                 first2 = next;
  685.             }
  686.             else {
  687.                 first1++;
  688.                 count++;
  689.             }
  690.         }
  691.     }
  692.  
  693. #ifndef _RWSTD_NO_MEMBER_TEMPLATES
  694.     // uses transfer_node to merge in list by transfering nodes to list
  695.     template<class Compare>
  696.     void __adjacent_merge (iterator first1, iterator last1,
  697.                            iterator last2, Compare comp)
  698.     {
  699.         iterator first2 = last1;
  700.         int n = 0;
  701.         distance(first1, last1, n);
  702.         int count = 0;
  703.  
  704.         while (count <= n && first2 != last2)
  705.         {
  706.             if (comp(*first2,*first1))
  707.             {
  708.                 iterator next = first2;
  709.                 __transfer(first1, first2, ++next, *this);
  710.                 first2 = next;
  711.             }
  712.             else {
  713.                 first1++;
  714.                 count++;
  715.             }
  716.         }
  717.     }
  718. #endif
  719.  
  720. // used by the sort() member function
  721.     void __set_allocator(allocator_type a)
  722.     {  
  723.       __buffer_list = a; 
  724.     }
  725.     void __insert_aux (iterator position, size_type n, const T& x);
  726. #ifndef _RWSTD_NO_MEMBER_TEMPLATES
  727.     template<class InputIterator>
  728.     void __insert_aux (iterator position, InputIterator first, InputIterator last, _RW_is_not_integer)
  729.     { __insert_aux2 (position, first, last); }
  730.     template<class InputIterator>
  731.     void __insert_aux (iterator position, InputIterator first, InputIterator last, _RW_is_integer)
  732.     { __insert_aux (position, (size_type)first, last); }
  733.     template<class InputIterator>
  734.     void __insert_aux2 (iterator position, InputIterator first, InputIterator last);
  735. #endif
  736.  
  737.   public:
  738.  
  739.     //
  740.     // list operations.
  741.     //
  742.     void splice (iterator position, list<T,Allocator>& x)
  743.     {
  744.       if (!x.empty())
  745.         __transfer(position, x.begin(), x.end(), x);
  746.     }
  747.     void splice (iterator position, list<T,Allocator>& x, iterator i)
  748.     { 
  749.       iterator k = i;
  750.       if (k != position && ++k != position)
  751.       {
  752.         iterator j = i;
  753.         __transfer(position, i, ++j, x);
  754.       }
  755.     }
  756.     void splice (iterator position, list<T,Allocator>& x, iterator first, iterator last)
  757.     {
  758.       if (first != last)
  759.       {
  760.         difference_type n;
  761.         __initialize(n, difference_type(0));
  762.         distance(first, last, n);
  763.         __transfer(position, first, last, x);
  764.       }
  765.     }
  766.     void remove  (const T& value);
  767.     void unique  ();
  768.     void merge   (list<T,Allocator>& x);
  769.     void reverse ();
  770.     void sort    ();
  771.  
  772. #ifndef _RWSTD_NO_MEMBER_TEMPLATES
  773.     template<class Predicate>       void remove_if (Predicate pred);
  774.     template<class BinaryPredicate> void unique    (BinaryPredicate pred);
  775.     template<class Compare>         void merge     (list<T,Allocator>& x, Compare comp);
  776.     template<class Compare>         void sort      (Compare comp);
  777. #endif // _RWSTD_NO_MEMBER_TEMPLATES
  778.  
  779. #ifndef _RWSTD_STRICT_ANSI
  780.     // Non-standard function for setting buffer allocation size
  781.     size_type allocation_size() { return __buffer_size; }
  782.     size_type allocation_size(size_type new_size) 
  783.     { 
  784.       size_type tmp = __buffer_size; 
  785.       __buffer_size = max((size_type)1,new_size);
  786.       return tmp;
  787.     }
  788. #endif // _RWSTD_STRICT_ANSI
  789.   };
  790.  
  791.   template <class T, class Allocator>
  792.   inline bool operator== (const list<T,Allocator>& x, const list<T,Allocator>& y)
  793.   {
  794.     return x.size() == y.size() && equal(x.begin(), x.end(), y.begin());
  795.   }
  796.  
  797.   template <class T, class Allocator>
  798.   inline bool operator< (const list<T,Allocator>& x, const list<T,Allocator>& y)
  799.   {
  800.     return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
  801.   }
  802.  
  803. #if !defined(_RWSTD_NO_NAMESPACE) || !defined(_RWSTD_NO_PART_SPEC_OVERLOAD)
  804.   template <class T, class Allocator>
  805.   inline bool operator!= (const list<T,Allocator>& x, const list<T,Allocator>& y)
  806.   {
  807.     return !(x == y);
  808.   }
  809.  
  810.   template <class T, class Allocator>
  811.   inline bool operator> (const list<T,Allocator>& x, const list<T,Allocator>& y)
  812.   {
  813.     return y < x;
  814.   }
  815.  
  816.   template <class T, class Allocator>
  817.   inline bool operator>= (const list<T,Allocator>& x, const list<T,Allocator>& y)
  818.   {
  819.     return !(x < y);
  820.   }
  821.  
  822.   template <class T, class Allocator>
  823.   inline bool operator<= (const list<T,Allocator>& x, const list<T,Allocator>& y)
  824.   {
  825.     return !(y <  x);
  826.   }
  827.  
  828.   template <class T, class Allocator>
  829.   inline void swap(list<T,Allocator>& a, list<T,Allocator>& b)
  830.   {
  831.     a.swap(b);
  832.   }
  833. #endif // !defined(_RWSTD_NO_NAMESPACE) || !defined(_RWSTD_NO_PART_SPEC_OVERLOAD)
  834.  
  835. #ifndef _RWSTD_NO_NAMESPACE
  836. }
  837. #endif
  838.  
  839. #ifdef _RWSTD_NO_TEMPLATE_REPOSITORY
  840. #include <list.cc>
  841. #endif
  842.  
  843. #undef list
  844. #endif /*__STD_LIST__*/
  845.  
  846. #ifndef __USING_STD_NAMES__
  847.   using namespace std;
  848. #endif
  849.  
  850. #pragma option pop
  851. #endif /* __LIST_H */
  852.