home *** CD-ROM | disk | FTP | other *** search
/ PC World 1998 October / PCWorld_1998-10_cd.bin / software / prehled / komix / DATA.Z / CList.cxx < prev    next >
C/C++ Source or Header  |  1996-05-31  |  4KB  |  207 lines

  1. /*---------------------------------------------------------------------------
  2.  *
  3.  * Copyright (c) 1994 by Westmount Technology B.V., Delft, The Netherlands.
  4.  *
  5.  * This software is furnished under a license and may be used only in
  6.  * accordance with the terms of such license and with the inclusion of
  7.  * the above copyright notice. This software or any other copies thereof
  8.  * may not be provided or otherwise made available to any other person.
  9.  * No title to and ownership of the software is hereby transferred.
  10.  *
  11.  * The information in this software is subject to change without notice
  12.  * and should not be construed as a commitment by Westmount Technology B.V.
  13.  *
  14.  *---------------------------------------------------------------------------
  15.  *
  16.  *    File        : @(#)CList.cxx    1.1
  17.  *    Author        : peku
  18.  *    Original date    : 5-1-1994
  19.  *    Description    : Compact Lists
  20.  *
  21.  *---------------------------------------------------------------------------
  22.  */
  23. static const char SccsId[]="@(#)CList.cxx    1.1    18 Oct 1994 Copyright 1994 Westmount Technology";
  24.  
  25. #ifndef CLIST_HXX
  26. #include "CList.hxx"
  27. #endif
  28.  
  29. static void
  30. shift_left ( register void** p, register void** q, void** endp)
  31. {
  32.     while ( q < endp ) *p++ = *q++;
  33. }
  34.  
  35. static void
  36. shift_right ( void** startp, register void** q, void** p)
  37. {
  38.     while ( q >= startp ) *p-- = *q--;
  39. }
  40.  
  41.  
  42. GenCList::GenCList(unsigned size, int gf):
  43.         GenFlexArray(size),
  44.         idx (0)
  45. {
  46.     if ( gf > 0 ) grow_factor = gf * DEFAULT_ARRAY_SIZE;
  47.     else if ( gf < 0 ) grow_factor = gf - 1;
  48. }
  49.  
  50.  
  51. GenCList::GenCList(const GenCList& cpy):
  52.     GenFlexArray(cpy),
  53.     idx(cpy.idx),
  54.     grow_factor(cpy.grow_factor)
  55. {
  56.     /* empty */
  57. }
  58.  
  59.  
  60. GenCList&
  61. GenCList::operator= (const GenCList& asgn)
  62. {
  63.     this->GenFlexArray::operator= (asgn);
  64.     idx = asgn.idx;
  65.     grow_factor = asgn.grow_factor;
  66.  
  67.     return *this;
  68. }
  69.  
  70.  
  71. void
  72. GenCList::reset()
  73. {
  74.     idx = 0;
  75. }
  76.  
  77.  
  78. void
  79. GenCList::reset ( unsigned new_size )
  80. {
  81.     GenFlexArray::reSize(new_size);
  82.     idx = 0;
  83. }
  84.  
  85.  
  86.  
  87. int
  88. GenCList::grow(unsigned min_size)
  89. {
  90.     if ( sz < min_size && grow_factor == 0) {
  91.     return 0;
  92.     }
  93.     while ( sz < min_size && v )
  94.     reSize( (grow_factor>0) ? sz + grow_factor : sz * (-grow_factor) );
  95.     
  96.     return v != 0;
  97. }
  98.  
  99.  
  100. GenCList&
  101. GenCList::append (void* e)
  102. {
  103.     if ( idx < sz || grow(sz+1) ) v[idx++] = e;
  104.     return *this;
  105. }
  106.  
  107. GenCList&
  108. GenCList::append (const GenCList& lst)
  109. {
  110.     if ( lst.idx == 0 ) return *this;        // appending empty list?!
  111.     if ( idx+lst.idx < sz  || grow (idx+lst.idx) ) {
  112.     shift_left ( &v[idx], lst.v, &lst.v[lst.idx] );
  113.     idx += lst.idx;
  114.     }
  115.     return *this;
  116. }
  117.  
  118. GenCList&
  119. GenCList::insert_at(int i, void* elem)
  120. {
  121.     if ( i == idx )
  122.     return append(elem);    // insert at the end
  123.  
  124.     else if ( idx < sz || grow(sz+1) ) {
  125.     shift_right ( &v[i], &v[idx-1], &v[idx] );
  126.     v[i] = elem;
  127.     idx++;
  128.     }
  129.  
  130.     return *this;
  131.  
  132. }
  133.  
  134. GenCList&
  135. GenCList::insert_at(int i, const GenCList& lst)
  136. {
  137.     if ( lst.idx == 0 ) return *this;    // appending empty list?!
  138.  
  139.     else if ( i == idx )
  140.     return append(lst);
  141.  
  142.     else if ( idx+lst.idx < sz  || grow (idx+lst.idx) ) {
  143.     if ( &lst == this ) {
  144.         // copy the same list in two parts:
  145.         shift_right ( &v[i], &v[idx-1], &v[2*idx-1] );    // make room
  146.         shift_right ( &v[0], &v[i-1], &v[2*i-1] );        // copy all before i
  147.         shift_left  ( &v[2*i], &v[idx+i], &v[2*idx] );    // copy shifted part
  148.     }
  149.     else {
  150.         shift_right ( &v[i], &v[idx-1], &v[idx+lst.idx-1] );
  151.         shift_left ( &v[i], lst.v, &lst.v[lst.idx] );
  152.     }
  153.     idx += lst.idx;
  154.     }
  155.     return *this;
  156. }
  157.  
  158. GenCList&
  159. GenCList::remove_last()
  160. {
  161.     idx--;
  162.     return *this;
  163. }
  164.  
  165. GenCList&
  166. GenCList::remove_at(int i)
  167. {
  168.     if ( i == idx )
  169.     remove_last();
  170.  
  171.     else { 
  172.     shift_left ( &v[i], &v[i+1], &v[idx] );
  173.     idx--;
  174.     }
  175.  
  176.     return *this;
  177. }
  178.  
  179. GenCList&
  180. GenCList::remove(int i, int j)
  181. {
  182.     if ( 0 > i || i > j || j >= idx ) { return *this; }
  183.  
  184.     if ( j == idx - 1) {
  185.     // remove up to end: no shifting required
  186.     idx = i;
  187.     }
  188.     else {
  189.     shift_left ( &v[i], &v[j+1], &v[idx] );
  190.     void** endp = &v[idx];
  191.     idx = idx - 1 - j + i;
  192.     }
  193.     return *this;
  194. }
  195.  
  196. GenCList&
  197. GenCList::remove(void *elem)
  198. {
  199.     register int i, end;
  200.     for (i = 0, end = size(); i < end; ++i)
  201.         if (at(i) == elem) {
  202.         remove_at(i);
  203.             return *this;
  204.     }
  205.     return *this;
  206. }
  207.