2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
24 * $XConsortium: List.cc /main/4 1996/08/06 09:18:55 rcs $
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.
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.
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
52 strcasecmp(register const char *s1,
53 register const char *s2)
58 c1 = isupper(*s1) ? tolower(*s1) : *s1;
59 c2 = isupper(*s2) ? tolower(*s2) : *s2;
65 return (int) (*s1 - *s2);
71 // /////////////////////////////////////////////////////////////////
73 // /////////////////////////////////////////////////////////////////
75 List::List (int initial_size, int increment, grow_method_t method,
77 : f_dtor_delete_elements (delete_elements)
79 assert (initial_size >= 0);
81 f_internal_length = initial_size;
82 f_grow_method = method;
84 f_increment = initial_size;
86 f_increment = increment;
87 assert (f_increment > 0);
88 f_list_element = (FolioObject **)
89 malloc (sizeof (FolioObject *) * initial_size);
93 // /////////////////////////////////////////////////////////////////
95 // /////////////////////////////////////////////////////////////////
99 if (f_dtor_delete_elements)
101 free ((char *) f_list_element);
104 // /////////////////////////////////////////////////////////////////
105 // check_space - create more space for elements if necessary
106 // /////////////////////////////////////////////////////////////////
109 List::check_space (int num_additions)
111 if (f_length + num_additions > f_internal_length)
113 // Loop until internal_length has grown large enough.
114 while (f_length + num_additions > f_internal_length)
116 switch (f_grow_method)
119 f_internal_length = f_internal_length + f_increment;
122 f_internal_length = f_internal_length * f_increment;
130 (FolioObject **) realloc ((char *) f_list_element,
131 sizeof (FolioObject *) * f_internal_length);
136 // /////////////////////////////////////////////////////////////////
137 // append - append an element to the list
138 // /////////////////////////////////////////////////////////////////
141 List::append (FolioObject &element)
145 /* -------- Add the element. -------- */
146 if (&element == NULL)
148 f_list_element[f_length] = &element;
150 notify (APPENDED, (void *)(size_t) (f_length - 1));
154 // /////////////////////////////////////////////////////////////////
155 // remove - remove an element from the list
156 // /////////////////////////////////////////////////////////////////
159 List::remove (FolioObject &element)
161 /* -------- Look for the element in the list -------- */
162 int location = find (element);
169 // /////////////////////////////////////////////////////////////////
170 // remove - remove an element from the list
171 // /////////////////////////////////////////////////////////////////
174 List::remove (unsigned int location)
176 // NOTE: check bounds
177 // Shift the array back and overwrite deleted element.
179 for (int i = location; i < f_length; i++)
180 f_list_element[i] = f_list_element[i+1];
184 // /////////////////////////////////////////////////////////////////
185 // insert - insert an element in the list
186 // /////////////////////////////////////////////////////////////////
189 List::insert (unsigned int location, FolioObject *element)
193 if (location > f_length)
196 // Shift the array forward to make room for new insertion.
197 for (unsigned int i = f_length; i > location; i--)
198 f_list_element[i] = f_list_element[i-1];
200 // Insert the new element in the list.
201 f_list_element[location] = element;
203 notify (INSERTED, (void *)(size_t) location);
207 // /////////////////////////////////////////////////////////////////
208 // find - find an element in a list
209 // /////////////////////////////////////////////////////////////////
212 List::find (FolioObject &element)
214 /* -------- Search through the list, looking for element. -------- */
217 for (i = 0; i < f_length; i++)
218 if (f_list_element[i] == &element)
225 // /////////////////////////////////////////////////////////////////
227 // /////////////////////////////////////////////////////////////////
232 // copy the contents of the list into a new one
234 // NOTE: use length() instead of f_length because it may be more general
235 List *retlist = new List(length());
236 for (unsigned int i = 0 ; i < length(); i++)
237 retlist->append((*this)[i]);
243 // /////////////////////////////////////////////////////////////////
244 // remove_all - remove all the elements from the list
245 // /////////////////////////////////////////////////////////////////
248 List::remove_all (bool)
250 unsigned short length = f_length;
251 // Set length to 0, in case object dtor tries to mess with the list.
253 // Reverse order delete is important for Long_Lived objects!!
255 delete f_list_element[--length];
261 NOTE: Here's how to make the list use less space per list:
263 Make length an internal_length shorts.
265 change grow_method to a bit field of length 1.
266 change increment to a bit field of length 7.
268 if grow_method is multiple, use the increment as a literal.
269 if grow_method is add, use a static lookup table based on