7f4c1d59da31a0643f621295e25cb91bd3f6af22
[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   f_list_element[f_length] = &element;
125   f_length++;
126   notify (APPENDED, (void *)(size_t) (f_length - 1));
127 }
128
129
130 // /////////////////////////////////////////////////////////////////
131 // remove - remove an element from the list 
132 // /////////////////////////////////////////////////////////////////
133
134 void
135 List::remove (FolioObject &element)
136 {
137   /* -------- Look for the element in the list -------- */
138   int location = find (element);
139
140   if (location != -1)
141     remove (location);
142 }
143
144
145 // /////////////////////////////////////////////////////////////////
146 // remove - remove an element from the list 
147 // /////////////////////////////////////////////////////////////////
148
149 void
150 List::remove (unsigned int location)
151 {
152   // NOTE: check bounds 
153   // Shift the array back and overwrite deleted element.
154   f_length--;
155   for (int i = location; i < f_length; i++)
156     f_list_element[i] = f_list_element[i+1];
157 }
158
159
160 // /////////////////////////////////////////////////////////////////
161 // insert - insert an element in the list
162 // /////////////////////////////////////////////////////////////////
163
164 void
165 List::insert (unsigned int location, FolioObject *element)
166 {
167   check_space();
168
169   if (location > f_length)
170     abort();
171  
172   // Shift the array forward to make room for new insertion.
173   for (unsigned int i = f_length; i > location; i--)
174     f_list_element[i] = f_list_element[i-1];
175
176   // Insert the new element in the list.
177   f_list_element[location] = element;
178   f_length++;
179   notify (INSERTED, (void *)(size_t) location);
180 }
181
182
183 // /////////////////////////////////////////////////////////////////
184 // find - find an element in a list
185 // /////////////////////////////////////////////////////////////////
186
187 int
188 List::find (FolioObject &element)
189 {
190   /* -------- Search through the list, looking for element. -------- */
191   register int i;
192
193   for (i = 0; i < f_length; i++)
194     if (f_list_element[i] == &element)
195       return (i);
196
197   return (-1);
198 }
199
200
201 // /////////////////////////////////////////////////////////////////
202 // copy
203 // /////////////////////////////////////////////////////////////////
204
205 List *
206 List::copy() const
207 {
208     // copy the contents of the list into a new one 
209
210     // NOTE: use length() instead of f_length because it may be more general
211     List *retlist = new List(length());
212     for (unsigned int i = 0 ; i < length(); i++)
213       retlist->append((*this)[i]);
214
215     return retlist ;
216 }
217
218
219 // /////////////////////////////////////////////////////////////////
220 // remove_all - remove all the elements from the list
221 // /////////////////////////////////////////////////////////////////
222
223 void
224 List::remove_all (bool)
225 {
226   unsigned short length = f_length;
227   // Set length to 0, in case object dtor tries to mess with the list. 
228   f_length = 0;
229   // Reverse order delete is important for Long_Lived objects!! 
230   while (length)
231     delete f_list_element[--length];
232 }
233
234
235 /*
236
237   NOTE: Here's how to make the list use less space per list:
238
239   Make length an internal_length shorts.
240
241   change grow_method to a bit field of length 1.
242   change increment to a bit field of length 7.
243
244   if grow_method is multiple, use the increment as a literal.
245   if grow_method is add, use a static lookup table based on
246   the increment value.
247
248 */
249