home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / graphtal / list.h < prev    next >
C/C++ Source or Header  |  1992-10-28  |  5KB  |  191 lines

  1. /*
  2.  * Copyright (c) 1987, 1988, 1989, 1990, 1991 Stanford University
  3.  * Copyright (c) 1991 Silicon Graphics, Inc.
  4.  *
  5.  * Permission to use, copy, modify, distribute, and sell this software and 
  6.  * its documentation for any purpose is hereby granted without fee, provided
  7.  * that (i) the above copyright notices and this permission notice appear in
  8.  * all copies of the software and related documentation, and (ii) the names of
  9.  * Stanford and Silicon Graphics may not be used in any advertising or
  10.  * publicity relating to the software without the specific, prior written
  11.  * permission of Stanford and Silicon Graphics.
  12.  * 
  13.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  14.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  15.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  16.  *
  17.  * IN NO EVENT SHALL STANFORD OR SILICON GRAPHICS BE LIABLE FOR
  18.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  19.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  20.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  21.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  22.  * OF THIS SOFTWARE.
  23.  * 
  24.  * 11.8.92 Christoph Streit: removed Lists of pointers and changed 
  25.  *                           include files
  26.  *
  27.  * Generic list implemented as dynamic array
  28.  */
  29.  
  30. #ifndef List_H
  31. # define List_H
  32.  
  33. #define delete_list_items() delete [] items_
  34.  
  35. extern void ListImpl_range_error(long index);
  36. extern long ListImpl_best_new_count(long count, unsigned long size);
  37.  
  38. #if defined(__STDC__) || defined(__ANSI_CPP__) || defined(__DECCXX)
  39. #define __ListItr(List) List##_Iterator
  40. #define ListItr(List) __ListItr(List)
  41. #else
  42. #define __ListItr(List) List/**/_Iterator
  43. #define ListItr(List) __ListItr(List)
  44. #endif
  45.  
  46. #define declareList(List,T) \
  47. class List { \
  48. public: \
  49.     List(); \
  50.     List(long size); \
  51.     ~List(); \
  52. \
  53.     long count() const; \
  54.     T& item(long index) const; \
  55. \
  56.     void prepend(const T&); \
  57.     void append(const T&); \
  58.     void insert(long index, const T&); \
  59.     void remove(long index); \
  60.     void remove_all(); \
  61. private: \
  62.     T* items_; \
  63.     long size_; \
  64.     long count_; \
  65.     long free_; \
  66. }; \
  67. \
  68. inline long List::count() const { return count_; } \
  69. \
  70. inline T& List::item(long index) const { \
  71.     if (index < 0 || index >= count_) { \
  72.     ListImpl_range_error(index); \
  73.     } \
  74.     long i = index < free_ ? index : index + size_ - count_; \
  75.     return items_[i]; \
  76. } \
  77. \
  78. inline void List::append(const T& item) { insert(count_, item); } \
  79. inline void List::prepend(const T& item) { insert(0, item); } \
  80. \
  81. class ListItr(List) { \
  82. public: \
  83.     ListItr(List)(const List&); \
  84. \
  85.     int more() const; \
  86.     T& cur() const; \
  87.     void next(); \
  88. private: \
  89.     const List* list_; \
  90.     long cur_; \
  91.     long end_; \
  92. }; \
  93. \
  94. inline int ListItr(List)::more() const { return cur_ < end_; } \
  95. inline T& ListItr(List)::cur() const { return list_->item(cur_); } \
  96. inline void ListItr(List)::next() { ++cur_; } 
  97.  
  98. /*
  99.  * List implementation
  100.  */
  101.  
  102. #define implementList(List,T) \
  103. List::List() { \
  104.     size_ = 0; \
  105.     items_ = 0; \
  106.     count_ = 0; \
  107.     free_ = 0; \
  108. } \
  109. \
  110. List::List(long size) { \
  111.     if (size > 0) { \
  112.         size_ = ListImpl_best_new_count(size, sizeof(T)); \
  113.         items_ = new T[size_]; \
  114.     } else { \
  115.         size_ = 0; \
  116.         items_ = 0; \
  117.     } \
  118.     count_ = 0; \
  119.     free_ = 0; \
  120. } \
  121. \
  122. List::~List() { \
  123.   delete_list_items(); \
  124. } \
  125. \
  126. void List::insert(long index, const T& item) { \
  127.     if (count_ == size_) { \
  128.         long size = ListImpl_best_new_count(size_ + 1, sizeof(T)); \
  129.         T* items = new T[size]; \
  130.         if (items_ != 0) { \
  131.             register long i; \
  132.             for (i = 0; i < free_; ++i) { \
  133.                 items[i] = items_[i]; \
  134.             } \
  135.             for (i = 0; i < count_ - free_; ++i) { \
  136.                 items[free_ + size - count_ + i] = \
  137.                     items_[free_ + size_ - count_ + i]; \
  138.             } \
  139.             delete_list_items(); \
  140.         } \
  141.         items_ = items; \
  142.         size_ = size; \
  143.     } \
  144.     if (index >= 0 && index <= count_) { \
  145.     if (index < free_) { \
  146.             for (register long i = free_ - index - 1; i >= 0; --i) { \
  147.                 items_[index + size_ - count_ + i] = items_[index + i]; \
  148.             } \
  149.         } else if (index > free_) { \
  150.             for (register long i = 0; i < index - free_; ++i) { \
  151.                 items_[free_ + i] = items_[free_ + size_ - count_ + i]; \
  152.             } \
  153.         } \
  154.         free_ = index + 1; \
  155.         count_ += 1; \
  156.         items_[index] = item; \
  157.     } \
  158. } \
  159. \
  160. void List::remove(long index) { \
  161.     if (index >= 0 && index <= count_) { \
  162.         if (index < free_) { \
  163.             for (register long i = free_ - index - 2; i >= 0; --i) { \
  164.                 items_[size_ - count_ + index + 1 + i] = \
  165.             items_[index + 1 + i]; \
  166.             } \
  167.         } else if (index > free_) { \
  168.             for (register long i = 0; i < index - free_; ++i) { \
  169.                 items_[free_ + i] = items_[free_ + size_ - count_ + i]; \
  170.             } \
  171.         } \
  172.         free_ = index; \
  173.         count_ -= 1; \
  174.     } \
  175. } \
  176. \
  177. void List::remove_all() { \
  178.     count_ = 0; \
  179.     free_ = 0; \
  180. } \
  181. \
  182. ListItr(List)::ListItr(List)(const List& list) { \
  183.     list_ = &list; \
  184.     cur_ = 0; \
  185.     end_ = list.count(); \
  186. }
  187.  
  188. #define forall_items()
  189.  
  190. #endif // List_H
  191.