1 /* Test of sequential list data type implementation.
2 Copyright (C) 2006-2020 Free Software Foundation, Inc.
3 Written by Bruno Haible <bruno@clisp.org>, 2006.
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
20 #include "gl_rbtree_list.h"
24 #include "gl_array_list.h"
27 extern void gl_rbtree_list_check_invariants (gl_list_t list
);
29 static const char *objects
[15] =
31 "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o"
34 #define RANDOM(n) (rand () % (n))
35 #define RANDOM_OBJECT() objects[RANDOM (SIZEOF (objects))]
38 check_equals (gl_list_t list1
, gl_list_t list2
)
42 n
= gl_list_size (list1
);
43 ASSERT (n
== gl_list_size (list2
));
44 for (i
= 0; i
< n
; i
++)
46 ASSERT (gl_list_get_at (list1
, i
) == gl_list_get_at (list2
, i
));
51 check_all (gl_list_t list1
, gl_list_t list2
, gl_list_t list3
)
53 gl_rbtree_list_check_invariants (list2
);
54 gl_rbtree_list_check_invariants (list3
);
55 check_equals (list1
, list2
);
56 check_equals (list1
, list3
);
60 main (int argc
, char *argv
[])
62 gl_list_t list1
, list2
, list3
;
64 /* Allow the user to provide a non-default random seed on the command line. */
66 srand (atoi (argv
[1]));
69 size_t initial_size
= RANDOM (50);
70 const void **contents
=
71 (const void **) malloc (initial_size
* sizeof (const void *));
75 for (i
= 0; i
< initial_size
; i
++)
76 contents
[i
] = RANDOM_OBJECT ();
79 list1
= gl_list_nx_create (GL_ARRAY_LIST
, NULL
, NULL
, NULL
, true,
80 initial_size
, contents
);
81 ASSERT (list1
!= NULL
);
83 list2
= gl_list_nx_create_empty (GL_RBTREE_LIST
, NULL
, NULL
, NULL
, true);
84 ASSERT (list2
!= NULL
);
85 for (i
= 0; i
< initial_size
; i
++)
86 ASSERT (gl_list_nx_add_last (list2
, contents
[i
]) != NULL
);
89 list3
= gl_list_nx_create (GL_RBTREE_LIST
, NULL
, NULL
, NULL
, true,
90 initial_size
, contents
);
91 ASSERT (list3
!= NULL
);
93 check_all (list1
, list2
, list3
);
95 for (repeat
= 0; repeat
< 10000; repeat
++)
97 unsigned int operation
= RANDOM (18);
101 if (gl_list_size (list1
) > 0)
103 size_t index
= RANDOM (gl_list_size (list1
));
104 const char *obj
= RANDOM_OBJECT ();
105 gl_list_node_t node1
, node2
, node3
;
107 node1
= gl_list_nx_set_at (list1
, index
, obj
);
108 ASSERT (node1
!= NULL
);
109 ASSERT (gl_list_get_at (list1
, index
) == obj
);
110 ASSERT (gl_list_node_value (list1
, node1
) == obj
);
112 node2
= gl_list_nx_set_at (list2
, index
, obj
);
113 ASSERT (node2
!= NULL
);
114 ASSERT (gl_list_get_at (list2
, index
) == obj
);
115 ASSERT (gl_list_node_value (list2
, node2
) == obj
);
117 node3
= gl_list_nx_set_at (list3
, index
, obj
);
118 ASSERT (node3
!= NULL
);
119 ASSERT (gl_list_get_at (list3
, index
) == obj
);
120 ASSERT (gl_list_node_value (list3
, node3
) == obj
);
124 ASSERT (gl_list_node_value (list1
, gl_list_previous_node (list1
, node1
))
125 == gl_list_get_at (list1
, index
- 1));
126 ASSERT (gl_list_node_value (list2
, gl_list_previous_node (list3
, node3
))
127 == gl_list_get_at (list2
, index
- 1));
128 ASSERT (gl_list_node_value (list3
, gl_list_previous_node (list3
, node3
))
129 == gl_list_get_at (list2
, index
- 1));
131 if (index
+ 1 < gl_list_size (list1
))
133 ASSERT (gl_list_node_value (list1
, gl_list_next_node (list1
, node1
))
134 == gl_list_get_at (list1
, index
+ 1));
135 ASSERT (gl_list_node_value (list2
, gl_list_next_node (list3
, node3
))
136 == gl_list_get_at (list2
, index
+ 1));
137 ASSERT (gl_list_node_value (list3
, gl_list_next_node (list3
, node3
))
138 == gl_list_get_at (list2
, index
+ 1));
144 const char *obj
= RANDOM_OBJECT ();
145 gl_list_node_t node1
, node2
, node3
;
146 node1
= gl_list_search (list1
, obj
);
147 node2
= gl_list_search (list2
, obj
);
148 node3
= gl_list_search (list3
, obj
);
151 ASSERT (node2
== NULL
);
152 ASSERT (node3
== NULL
);
156 ASSERT (node2
!= NULL
);
157 ASSERT (node3
!= NULL
);
158 ASSERT (gl_list_node_value (list1
, node1
) == obj
);
159 ASSERT (gl_list_node_value (list2
, node2
) == obj
);
160 ASSERT (gl_list_node_value (list3
, node3
) == obj
);
166 const char *obj
= RANDOM_OBJECT ();
167 size_t index1
, index2
, index3
;
168 index1
= gl_list_indexof (list1
, obj
);
169 index2
= gl_list_indexof (list2
, obj
);
170 index3
= gl_list_indexof (list3
, obj
);
171 if (index1
== (size_t)(-1))
173 ASSERT (index2
== (size_t)(-1));
174 ASSERT (index3
== (size_t)(-1));
178 ASSERT (index2
!= (size_t)(-1));
179 ASSERT (index3
!= (size_t)(-1));
180 ASSERT (gl_list_get_at (list1
, index1
) == obj
);
181 ASSERT (gl_list_get_at (list2
, index2
) == obj
);
182 ASSERT (gl_list_get_at (list3
, index3
) == obj
);
183 ASSERT (index2
== index1
);
184 ASSERT (index3
== index1
);
188 case 3: /* add 1 element */
190 const char *obj
= RANDOM_OBJECT ();
191 gl_list_node_t node1
, node2
, node3
;
192 node1
= gl_list_nx_add_first (list1
, obj
);
193 ASSERT (node1
!= NULL
);
194 node2
= gl_list_nx_add_first (list2
, obj
);
195 ASSERT (node2
!= NULL
);
196 node3
= gl_list_nx_add_first (list3
, obj
);
197 ASSERT (node3
!= NULL
);
198 ASSERT (gl_list_node_value (list1
, node1
) == obj
);
199 ASSERT (gl_list_node_value (list2
, node2
) == obj
);
200 ASSERT (gl_list_node_value (list3
, node3
) == obj
);
201 ASSERT (gl_list_get_at (list1
, 0) == obj
);
202 ASSERT (gl_list_get_at (list2
, 0) == obj
);
203 ASSERT (gl_list_get_at (list3
, 0) == obj
);
206 case 4: /* add 1 element */
208 const char *obj
= RANDOM_OBJECT ();
209 gl_list_node_t node1
, node2
, node3
;
210 node1
= gl_list_nx_add_last (list1
, obj
);
211 ASSERT (node1
!= NULL
);
212 node2
= gl_list_nx_add_last (list2
, obj
);
213 ASSERT (node2
!= NULL
);
214 node3
= gl_list_nx_add_last (list3
, obj
);
215 ASSERT (node3
!= NULL
);
216 ASSERT (gl_list_node_value (list1
, node1
) == obj
);
217 ASSERT (gl_list_node_value (list2
, node2
) == obj
);
218 ASSERT (gl_list_node_value (list3
, node3
) == obj
);
219 ASSERT (gl_list_get_at (list1
, gl_list_size (list1
) - 1) == obj
);
220 ASSERT (gl_list_get_at (list2
, gl_list_size (list2
) - 1) == obj
);
221 ASSERT (gl_list_get_at (list3
, gl_list_size (list3
) - 1) == obj
);
224 case 5: /* add 3 elements */
226 const char *obj0
= RANDOM_OBJECT ();
227 const char *obj1
= RANDOM_OBJECT ();
228 const char *obj2
= RANDOM_OBJECT ();
229 gl_list_node_t node1
, node2
, node3
;
230 node1
= gl_list_nx_add_first (list1
, obj2
);
231 ASSERT (node1
!= NULL
);
232 node1
= gl_list_nx_add_before (list1
, node1
, obj0
);
233 ASSERT (node1
!= NULL
);
234 node1
= gl_list_nx_add_after (list1
, node1
, obj1
);
235 ASSERT (node1
!= NULL
);
236 node2
= gl_list_nx_add_first (list2
, obj2
);
237 ASSERT (node2
!= NULL
);
238 node2
= gl_list_nx_add_before (list2
, node2
, obj0
);
239 ASSERT (node2
!= NULL
);
240 node2
= gl_list_nx_add_after (list2
, node2
, obj1
);
241 ASSERT (node2
!= NULL
);
242 node3
= gl_list_nx_add_first (list3
, obj2
);
243 ASSERT (node3
!= NULL
);
244 node3
= gl_list_nx_add_before (list3
, node3
, obj0
);
245 ASSERT (node3
!= NULL
);
246 node3
= gl_list_nx_add_after (list3
, node3
, obj1
);
247 ASSERT (node3
!= NULL
);
248 ASSERT (gl_list_node_value (list1
, node1
) == obj1
);
249 ASSERT (gl_list_node_value (list2
, node2
) == obj1
);
250 ASSERT (gl_list_node_value (list3
, node3
) == obj1
);
251 ASSERT (gl_list_get_at (list1
, 0) == obj0
);
252 ASSERT (gl_list_get_at (list1
, 1) == obj1
);
253 ASSERT (gl_list_get_at (list1
, 2) == obj2
);
254 ASSERT (gl_list_get_at (list2
, 0) == obj0
);
255 ASSERT (gl_list_get_at (list2
, 1) == obj1
);
256 ASSERT (gl_list_get_at (list2
, 2) == obj2
);
257 ASSERT (gl_list_get_at (list3
, 0) == obj0
);
258 ASSERT (gl_list_get_at (list3
, 1) == obj1
);
259 ASSERT (gl_list_get_at (list3
, 2) == obj2
);
262 case 6: /* add 1 element */
264 size_t index
= RANDOM (gl_list_size (list1
) + 1);
265 const char *obj
= RANDOM_OBJECT ();
266 gl_list_node_t node1
, node2
, node3
;
267 node1
= gl_list_nx_add_at (list1
, index
, obj
);
268 ASSERT (node1
!= NULL
);
269 node2
= gl_list_nx_add_at (list2
, index
, obj
);
270 ASSERT (node2
!= NULL
);
271 node3
= gl_list_nx_add_at (list3
, index
, obj
);
272 ASSERT (node3
!= NULL
);
273 ASSERT (gl_list_get_at (list1
, index
) == obj
);
274 ASSERT (gl_list_node_value (list1
, node1
) == obj
);
275 ASSERT (gl_list_get_at (list2
, index
) == obj
);
276 ASSERT (gl_list_node_value (list2
, node2
) == obj
);
277 ASSERT (gl_list_get_at (list3
, index
) == obj
);
278 ASSERT (gl_list_node_value (list3
, node3
) == obj
);
281 ASSERT (gl_list_node_value (list1
, gl_list_previous_node (list1
, node1
))
282 == gl_list_get_at (list1
, index
- 1));
283 ASSERT (gl_list_node_value (list2
, gl_list_previous_node (list3
, node3
))
284 == gl_list_get_at (list2
, index
- 1));
285 ASSERT (gl_list_node_value (list3
, gl_list_previous_node (list3
, node3
))
286 == gl_list_get_at (list2
, index
- 1));
288 if (index
+ 1 < gl_list_size (list1
))
290 ASSERT (gl_list_node_value (list1
, gl_list_next_node (list1
, node1
))
291 == gl_list_get_at (list1
, index
+ 1));
292 ASSERT (gl_list_node_value (list2
, gl_list_next_node (list3
, node3
))
293 == gl_list_get_at (list2
, index
+ 1));
294 ASSERT (gl_list_node_value (list3
, gl_list_next_node (list3
, node3
))
295 == gl_list_get_at (list2
, index
+ 1));
299 case 7: case 8: /* remove 1 element */
300 if (gl_list_size (list1
) > 0)
302 size_t n
= gl_list_size (list1
);
303 const char *obj
= gl_list_get_at (list1
, RANDOM (n
));
304 gl_list_node_t node1
, node2
, node3
;
305 node1
= gl_list_search (list1
, obj
);
306 node2
= gl_list_search (list2
, obj
);
307 node3
= gl_list_search (list3
, obj
);
308 ASSERT (node1
!= NULL
);
309 ASSERT (node2
!= NULL
);
310 ASSERT (node3
!= NULL
);
311 ASSERT (gl_list_remove_node (list1
, node1
));
312 ASSERT (gl_list_remove_node (list2
, node2
));
313 ASSERT (gl_list_remove_node (list3
, node3
));
314 ASSERT (gl_list_size (list1
) == n
- 1);
317 case 9: case 10: /* remove 1 element */
318 if (gl_list_size (list1
) > 0)
320 size_t n
= gl_list_size (list1
);
321 size_t index
= RANDOM (n
);
322 ASSERT (gl_list_remove_at (list1
, index
));
323 ASSERT (gl_list_remove_at (list2
, index
));
324 ASSERT (gl_list_remove_at (list3
, index
));
325 ASSERT (gl_list_size (list1
) == n
- 1);
328 case 11: /* remove first element */
330 size_t n
= gl_list_size (list1
);
331 bool removed1
= gl_list_remove_first (list1
);
332 ASSERT (gl_list_remove_first (list2
) == removed1
);
333 ASSERT (gl_list_remove_first (list3
) == removed1
);
334 ASSERT (gl_list_size (list1
) == n
- (int) removed1
);
337 case 12: /* remove last element */
339 size_t n
= gl_list_size (list1
);
340 bool removed1
= gl_list_remove_last (list1
);
341 ASSERT (gl_list_remove_last (list2
) == removed1
);
342 ASSERT (gl_list_remove_last (list3
) == removed1
);
343 ASSERT (gl_list_size (list1
) == n
- (int) removed1
);
346 case 13: case 14: /* remove 1 element */
347 if (gl_list_size (list1
) > 0)
349 size_t n
= gl_list_size (list1
);
350 const char *obj
= gl_list_get_at (list1
, RANDOM (n
));
351 ASSERT (gl_list_remove (list1
, obj
));
352 ASSERT (gl_list_remove (list2
, obj
));
353 ASSERT (gl_list_remove (list3
, obj
));
354 ASSERT (gl_list_size (list1
) == n
- 1);
358 if (gl_list_size (list1
) > 0)
360 size_t n
= gl_list_size (list1
);
361 const char *obj
= "xyzzy";
362 ASSERT (!gl_list_remove (list1
, obj
));
363 ASSERT (!gl_list_remove (list2
, obj
));
364 ASSERT (!gl_list_remove (list3
, obj
));
365 ASSERT (gl_list_size (list1
) == n
);
370 size_t n
= gl_list_size (list1
);
371 gl_list_iterator_t iter1
, iter2
, iter3
;
373 iter1
= gl_list_iterator (list1
);
374 iter2
= gl_list_iterator (list2
);
375 iter3
= gl_list_iterator (list3
);
376 for (i
= 0; i
< n
; i
++)
378 ASSERT (gl_list_iterator_next (&iter1
, &elt
, NULL
));
379 ASSERT (gl_list_get_at (list1
, i
) == elt
);
380 ASSERT (gl_list_iterator_next (&iter2
, &elt
, NULL
));
381 ASSERT (gl_list_get_at (list2
, i
) == elt
);
382 ASSERT (gl_list_iterator_next (&iter3
, &elt
, NULL
));
383 ASSERT (gl_list_get_at (list3
, i
) == elt
);
385 ASSERT (!gl_list_iterator_next (&iter1
, &elt
, NULL
));
386 ASSERT (!gl_list_iterator_next (&iter2
, &elt
, NULL
));
387 ASSERT (!gl_list_iterator_next (&iter3
, &elt
, NULL
));
388 gl_list_iterator_free (&iter1
);
389 gl_list_iterator_free (&iter2
);
390 gl_list_iterator_free (&iter3
);
395 size_t end
= RANDOM (gl_list_size (list1
) + 1);
396 size_t start
= RANDOM (end
+ 1);
397 gl_list_iterator_t iter1
, iter2
, iter3
;
399 iter1
= gl_list_iterator_from_to (list1
, start
, end
);
400 iter2
= gl_list_iterator_from_to (list2
, start
, end
);
401 iter3
= gl_list_iterator_from_to (list3
, start
, end
);
402 for (i
= start
; i
< end
; i
++)
404 ASSERT (gl_list_iterator_next (&iter1
, &elt
, NULL
));
405 ASSERT (gl_list_get_at (list1
, i
) == elt
);
406 ASSERT (gl_list_iterator_next (&iter2
, &elt
, NULL
));
407 ASSERT (gl_list_get_at (list2
, i
) == elt
);
408 ASSERT (gl_list_iterator_next (&iter3
, &elt
, NULL
));
409 ASSERT (gl_list_get_at (list3
, i
) == elt
);
411 ASSERT (!gl_list_iterator_next (&iter1
, &elt
, NULL
));
412 ASSERT (!gl_list_iterator_next (&iter2
, &elt
, NULL
));
413 ASSERT (!gl_list_iterator_next (&iter3
, &elt
, NULL
));
414 gl_list_iterator_free (&iter1
);
415 gl_list_iterator_free (&iter2
);
416 gl_list_iterator_free (&iter3
);
420 check_all (list1
, list2
, list3
);
423 gl_list_free (list1
);
424 gl_list_free (list2
);
425 gl_list_free (list3
);