Remove Unixware and openserver support
[oweals/cde.git] / cde / programs / dtinfo / dtinfo / src / Basic / List.C
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /*
24  * $XConsortium: List.cc /main/4 1996/08/06 09:18:55 rcs $
25  *
26  * Copyright (c) 1992 HaL Computer Systems, Inc.  All rights reserved.
27  * UNPUBLISHED -- rights reserved under the Copyright Laws of the United
28  * States.  Use of a copyright notice is precautionary only and does not
29  * imply publication or disclosure.
30  * 
31  * This software contains confidential information and trade secrets of HaL
32  * Computer Systems, Inc.  Use, disclosure, or reproduction is prohibited
33  * without the prior express written permission of HaL Computer Systems, Inc.
34  * 
35  *                         RESTRICTED RIGHTS LEGEND
36  * Use, duplication, or disclosure by the Government is subject to
37  * restrictions as set forth in subparagraph (c)(l)(ii) of the Rights in
38  * Technical Data and Computer Software clause at DFARS 252.227-7013.
39  *                        HaL Computer Systems, Inc.
40  *                  1315 Dell Avenue, Campbell, CA  95008
41  * 
42  */
43
44 #define C_List
45 #define L_Basic
46
47 #include "Prelude.h"
48
49 // /////////////////////////////////////////////////////////////////
50 // class constructor
51 // /////////////////////////////////////////////////////////////////
52
53 List::List (int initial_size, int increment, grow_method_t method,
54             bool delete_elements)
55 : f_dtor_delete_elements (delete_elements)
56 {
57   assert (initial_size >= 0);
58   f_length = 0;
59   f_internal_length = initial_size;
60   f_grow_method = method;
61   if (increment == 0)
62     f_increment = initial_size;
63   else
64     f_increment = increment;
65   assert (f_increment > 0);
66   f_list_element = (FolioObject **)
67     malloc (sizeof (FolioObject *) * initial_size);
68 }
69
70
71 // /////////////////////////////////////////////////////////////////
72 // class destructor
73 // /////////////////////////////////////////////////////////////////
74
75 List::~List()
76 {
77   if (f_dtor_delete_elements)
78     remove_all (TRUE);
79   free ((char *) f_list_element);
80 }
81
82 // /////////////////////////////////////////////////////////////////
83 // check_space - create more space for elements if necessary
84 // /////////////////////////////////////////////////////////////////
85
86 void
87 List::check_space (int num_additions)
88 {
89   if (f_length + num_additions > f_internal_length)
90     {
91       // Loop until internal_length has grown large enough. 
92       while (f_length + num_additions > f_internal_length)
93         {
94           switch (f_grow_method)
95             {
96               case GROW_ADD:
97               f_internal_length = f_internal_length + f_increment;
98               break;
99               case GROW_MULTIPLY:
100               f_internal_length = f_internal_length * f_increment;
101               break;
102               default:
103               abort ();         // harsh!
104             }
105         }
106
107       f_list_element =
108         (FolioObject **) realloc ((char *) f_list_element,
109                                   sizeof (FolioObject *) * f_internal_length);
110     }
111 }    
112
113
114 // /////////////////////////////////////////////////////////////////
115 // append - append an element to the list
116 // /////////////////////////////////////////////////////////////////
117
118 void
119 List::append (FolioObject &element)
120 {
121   check_space();
122
123   /* -------- Add the element. -------- */
124   if (&element == NULL)
125     abort();
126   f_list_element[f_length] = &element;
127   f_length++;
128   notify (APPENDED, (void *)(size_t) (f_length - 1));
129 }
130
131
132 // /////////////////////////////////////////////////////////////////
133 // remove - remove an element from the list 
134 // /////////////////////////////////////////////////////////////////
135
136 void
137 List::remove (FolioObject &element)
138 {
139   /* -------- Look for the element in the list -------- */
140   int location = find (element);
141
142   if (location != -1)
143     remove (location);
144 }
145
146
147 // /////////////////////////////////////////////////////////////////
148 // remove - remove an element from the list 
149 // /////////////////////////////////////////////////////////////////
150
151 void
152 List::remove (unsigned int location)
153 {
154   // NOTE: check bounds 
155   // Shift the array back and overwrite deleted element.
156   f_length--;
157   for (int i = location; i < f_length; i++)
158     f_list_element[i] = f_list_element[i+1];
159 }
160
161
162 // /////////////////////////////////////////////////////////////////
163 // insert - insert an element in the list
164 // /////////////////////////////////////////////////////////////////
165
166 void
167 List::insert (unsigned int location, FolioObject *element)
168 {
169   check_space();
170
171   if (location > f_length)
172     abort();
173  
174   // Shift the array forward to make room for new insertion.
175   for (unsigned int i = f_length; i > location; i--)
176     f_list_element[i] = f_list_element[i-1];
177
178   // Insert the new element in the list.
179   f_list_element[location] = element;
180   f_length++;
181   notify (INSERTED, (void *)(size_t) location);
182 }
183
184
185 // /////////////////////////////////////////////////////////////////
186 // find - find an element in a list
187 // /////////////////////////////////////////////////////////////////
188
189 int
190 List::find (FolioObject &element)
191 {
192   /* -------- Search through the list, looking for element. -------- */
193   register int i;
194
195   for (i = 0; i < f_length; i++)
196     if (f_list_element[i] == &element)
197       return (i);
198
199   return (-1);
200 }
201
202
203 // /////////////////////////////////////////////////////////////////
204 // copy
205 // /////////////////////////////////////////////////////////////////
206
207 List *
208 List::copy() const
209 {
210     // copy the contents of the list into a new one 
211
212     // NOTE: use length() instead of f_length because it may be more general
213     List *retlist = new List(length());
214     for (unsigned int i = 0 ; i < length(); i++)
215       retlist->append((*this)[i]);
216
217     return retlist ;
218 }
219
220
221 // /////////////////////////////////////////////////////////////////
222 // remove_all - remove all the elements from the list
223 // /////////////////////////////////////////////////////////////////
224
225 void
226 List::remove_all (bool)
227 {
228   unsigned short length = f_length;
229   // Set length to 0, in case object dtor tries to mess with the list. 
230   f_length = 0;
231   // Reverse order delete is important for Long_Lived objects!! 
232   while (length)
233     delete f_list_element[--length];
234 }
235
236
237 /*
238
239   NOTE: Here's how to make the list use less space per list:
240
241   Make length an internal_length shorts.
242
243   change grow_method to a bit field of length 1.
244   change increment to a bit field of length 7.
245
246   if grow_method is multiple, use the increment as a literal.
247   if grow_method is add, use a static lookup table based on
248   the increment value.
249
250 */
251