1 /* Test of sequential list data type implementation.
2 Copyright (C) 2006-2017 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_linked_list.h"
24 #include "gl_array_list.h"
27 static const char *objects
[15] =
29 "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o"
32 #define RANDOM(n) (rand () % (n))
33 #define RANDOM_OBJECT() objects[RANDOM (SIZEOF (objects))]
36 check_equals (gl_list_t list1
, gl_list_t list2
)
40 n
= gl_list_size (list1
);
41 ASSERT (n
== gl_list_size (list2
));
42 for (i
= 0; i
< n
; i
++)
44 ASSERT (gl_list_get_at (list1
, i
) == gl_list_get_at (list2
, i
));
49 check_all (gl_list_t list1
, gl_list_t list2
, gl_list_t list3
)
51 check_equals (list1
, list2
);
52 check_equals (list1
, list3
);
56 main (int argc
, char *argv
[])
58 gl_list_t list1
, list2
, list3
;
60 /* Allow the user to provide a non-default random seed on the command line. */
62 srand (atoi (argv
[1]));
65 size_t initial_size
= RANDOM (50);
66 const void **contents
=
67 (const void **) malloc (initial_size
* sizeof (const void *));
71 for (i
= 0; i
< initial_size
; i
++)
72 contents
[i
] = RANDOM_OBJECT ();
75 list1
= gl_list_nx_create (GL_ARRAY_LIST
, NULL
, NULL
, NULL
, true,
76 initial_size
, contents
);
77 ASSERT (list1
!= NULL
);
79 list2
= gl_list_nx_create_empty (GL_LINKED_LIST
, NULL
, NULL
, NULL
, true);
80 ASSERT (list2
!= NULL
);
81 for (i
= 0; i
< initial_size
; i
++)
82 ASSERT (gl_list_nx_add_last (list2
, contents
[i
]) != NULL
);
85 list3
= gl_list_nx_create (GL_LINKED_LIST
, NULL
, NULL
, NULL
, true,
86 initial_size
, contents
);
87 ASSERT (list3
!= NULL
);
89 check_all (list1
, list2
, list3
);
91 for (repeat
= 0; repeat
< 10000; repeat
++)
93 unsigned int operation
= RANDOM (16);
97 if (gl_list_size (list1
) > 0)
99 size_t index
= RANDOM (gl_list_size (list1
));
100 const char *obj
= RANDOM_OBJECT ();
101 gl_list_node_t node1
, node2
, node3
;
103 node1
= gl_list_nx_set_at (list1
, index
, obj
);
104 ASSERT (node1
!= NULL
);
105 ASSERT (gl_list_get_at (list1
, index
) == obj
);
106 ASSERT (gl_list_node_value (list1
, node1
) == obj
);
108 node2
= gl_list_nx_set_at (list2
, index
, obj
);
109 ASSERT (node2
!= NULL
);
110 ASSERT (gl_list_get_at (list2
, index
) == obj
);
111 ASSERT (gl_list_node_value (list2
, node2
) == obj
);
113 node3
= gl_list_nx_set_at (list3
, index
, obj
);
114 ASSERT (node3
!= NULL
);
115 ASSERT (gl_list_get_at (list3
, index
) == obj
);
116 ASSERT (gl_list_node_value (list3
, node3
) == obj
);
120 ASSERT (gl_list_node_value (list1
, gl_list_previous_node (list1
, node1
))
121 == gl_list_get_at (list1
, index
- 1));
122 ASSERT (gl_list_node_value (list2
, gl_list_previous_node (list3
, node3
))
123 == gl_list_get_at (list2
, index
- 1));
124 ASSERT (gl_list_node_value (list3
, gl_list_previous_node (list3
, node3
))
125 == gl_list_get_at (list2
, index
- 1));
127 if (index
+ 1 < gl_list_size (list1
))
129 ASSERT (gl_list_node_value (list1
, gl_list_next_node (list1
, node1
))
130 == gl_list_get_at (list1
, index
+ 1));
131 ASSERT (gl_list_node_value (list2
, gl_list_next_node (list3
, node3
))
132 == gl_list_get_at (list2
, index
+ 1));
133 ASSERT (gl_list_node_value (list3
, gl_list_next_node (list3
, node3
))
134 == gl_list_get_at (list2
, index
+ 1));
140 const char *obj
= RANDOM_OBJECT ();
141 gl_list_node_t node1
, node2
, node3
;
142 node1
= gl_list_search (list1
, obj
);
143 node2
= gl_list_search (list2
, obj
);
144 node3
= gl_list_search (list3
, obj
);
147 ASSERT (node2
== NULL
);
148 ASSERT (node3
== NULL
);
152 ASSERT (node2
!= NULL
);
153 ASSERT (node3
!= NULL
);
154 ASSERT (gl_list_node_value (list1
, node1
) == obj
);
155 ASSERT (gl_list_node_value (list2
, node2
) == obj
);
156 ASSERT (gl_list_node_value (list3
, node3
) == obj
);
162 const char *obj
= RANDOM_OBJECT ();
163 size_t index1
, index2
, index3
;
164 index1
= gl_list_indexof (list1
, obj
);
165 index2
= gl_list_indexof (list2
, obj
);
166 index3
= gl_list_indexof (list3
, obj
);
167 if (index1
== (size_t)(-1))
169 ASSERT (index2
== (size_t)(-1));
170 ASSERT (index3
== (size_t)(-1));
174 ASSERT (index2
!= (size_t)(-1));
175 ASSERT (index3
!= (size_t)(-1));
176 ASSERT (gl_list_get_at (list1
, index1
) == obj
);
177 ASSERT (gl_list_get_at (list2
, index2
) == obj
);
178 ASSERT (gl_list_get_at (list3
, index3
) == obj
);
179 ASSERT (index2
== index1
);
180 ASSERT (index3
== index1
);
184 case 3: /* add 1 element */
186 const char *obj
= RANDOM_OBJECT ();
187 gl_list_node_t node1
, node2
, node3
;
188 node1
= gl_list_nx_add_first (list1
, obj
);
189 ASSERT (node1
!= NULL
);
190 node2
= gl_list_nx_add_first (list2
, obj
);
191 ASSERT (node2
!= NULL
);
192 node3
= gl_list_nx_add_first (list3
, obj
);
193 ASSERT (node3
!= NULL
);
194 ASSERT (gl_list_node_value (list1
, node1
) == obj
);
195 ASSERT (gl_list_node_value (list2
, node2
) == obj
);
196 ASSERT (gl_list_node_value (list3
, node3
) == obj
);
197 ASSERT (gl_list_get_at (list1
, 0) == obj
);
198 ASSERT (gl_list_get_at (list2
, 0) == obj
);
199 ASSERT (gl_list_get_at (list3
, 0) == obj
);
202 case 4: /* add 1 element */
204 const char *obj
= RANDOM_OBJECT ();
205 gl_list_node_t node1
, node2
, node3
;
206 node1
= gl_list_nx_add_last (list1
, obj
);
207 ASSERT (node1
!= NULL
);
208 node2
= gl_list_nx_add_last (list2
, obj
);
209 ASSERT (node2
!= NULL
);
210 node3
= gl_list_nx_add_last (list3
, obj
);
211 ASSERT (node3
!= NULL
);
212 ASSERT (gl_list_node_value (list1
, node1
) == obj
);
213 ASSERT (gl_list_node_value (list2
, node2
) == obj
);
214 ASSERT (gl_list_node_value (list3
, node3
) == obj
);
215 ASSERT (gl_list_get_at (list1
, gl_list_size (list1
) - 1) == obj
);
216 ASSERT (gl_list_get_at (list2
, gl_list_size (list2
) - 1) == obj
);
217 ASSERT (gl_list_get_at (list3
, gl_list_size (list3
) - 1) == obj
);
220 case 5: /* add 3 elements */
222 const char *obj0
= RANDOM_OBJECT ();
223 const char *obj1
= RANDOM_OBJECT ();
224 const char *obj2
= RANDOM_OBJECT ();
225 gl_list_node_t node1
, node2
, node3
;
226 node1
= gl_list_nx_add_first (list1
, obj2
);
227 ASSERT (node1
!= NULL
);
228 node1
= gl_list_nx_add_before (list1
, node1
, obj0
);
229 ASSERT (node1
!= NULL
);
230 node1
= gl_list_nx_add_after (list1
, node1
, obj1
);
231 ASSERT (node1
!= NULL
);
232 node2
= gl_list_nx_add_first (list2
, obj2
);
233 ASSERT (node2
!= NULL
);
234 node2
= gl_list_nx_add_before (list2
, node2
, obj0
);
235 ASSERT (node2
!= NULL
);
236 node2
= gl_list_nx_add_after (list2
, node2
, obj1
);
237 ASSERT (node2
!= NULL
);
238 node3
= gl_list_nx_add_first (list3
, obj2
);
239 ASSERT (node3
!= NULL
);
240 node3
= gl_list_nx_add_before (list3
, node3
, obj0
);
241 ASSERT (node3
!= NULL
);
242 node3
= gl_list_nx_add_after (list3
, node3
, obj1
);
243 ASSERT (node3
!= NULL
);
244 ASSERT (gl_list_node_value (list1
, node1
) == obj1
);
245 ASSERT (gl_list_node_value (list2
, node2
) == obj1
);
246 ASSERT (gl_list_node_value (list3
, node3
) == obj1
);
247 ASSERT (gl_list_get_at (list1
, 0) == obj0
);
248 ASSERT (gl_list_get_at (list1
, 1) == obj1
);
249 ASSERT (gl_list_get_at (list1
, 2) == obj2
);
250 ASSERT (gl_list_get_at (list2
, 0) == obj0
);
251 ASSERT (gl_list_get_at (list2
, 1) == obj1
);
252 ASSERT (gl_list_get_at (list2
, 2) == obj2
);
253 ASSERT (gl_list_get_at (list3
, 0) == obj0
);
254 ASSERT (gl_list_get_at (list3
, 1) == obj1
);
255 ASSERT (gl_list_get_at (list3
, 2) == obj2
);
258 case 6: /* add 1 element */
260 size_t index
= RANDOM (gl_list_size (list1
) + 1);
261 const char *obj
= RANDOM_OBJECT ();
262 gl_list_node_t node1
, node2
, node3
;
263 node1
= gl_list_nx_add_at (list1
, index
, obj
);
264 ASSERT (node1
!= NULL
);
265 node2
= gl_list_nx_add_at (list2
, index
, obj
);
266 ASSERT (node2
!= NULL
);
267 node3
= gl_list_nx_add_at (list3
, index
, obj
);
268 ASSERT (node3
!= NULL
);
269 ASSERT (gl_list_get_at (list1
, index
) == obj
);
270 ASSERT (gl_list_node_value (list1
, node1
) == obj
);
271 ASSERT (gl_list_get_at (list2
, index
) == obj
);
272 ASSERT (gl_list_node_value (list2
, node2
) == obj
);
273 ASSERT (gl_list_get_at (list3
, index
) == obj
);
274 ASSERT (gl_list_node_value (list3
, node3
) == obj
);
277 ASSERT (gl_list_node_value (list1
, gl_list_previous_node (list1
, node1
))
278 == gl_list_get_at (list1
, index
- 1));
279 ASSERT (gl_list_node_value (list2
, gl_list_previous_node (list3
, node3
))
280 == gl_list_get_at (list2
, index
- 1));
281 ASSERT (gl_list_node_value (list3
, gl_list_previous_node (list3
, node3
))
282 == gl_list_get_at (list2
, index
- 1));
284 if (index
+ 1 < gl_list_size (list1
))
286 ASSERT (gl_list_node_value (list1
, gl_list_next_node (list1
, node1
))
287 == gl_list_get_at (list1
, index
+ 1));
288 ASSERT (gl_list_node_value (list2
, gl_list_next_node (list3
, node3
))
289 == gl_list_get_at (list2
, index
+ 1));
290 ASSERT (gl_list_node_value (list3
, gl_list_next_node (list3
, node3
))
291 == gl_list_get_at (list2
, index
+ 1));
295 case 7: case 8: /* remove 1 element */
296 if (gl_list_size (list1
) > 0)
298 size_t n
= gl_list_size (list1
);
299 const char *obj
= gl_list_get_at (list1
, RANDOM (n
));
300 gl_list_node_t node1
, node2
, node3
;
301 node1
= gl_list_search (list1
, obj
);
302 node2
= gl_list_search (list2
, obj
);
303 node3
= gl_list_search (list3
, obj
);
304 ASSERT (node1
!= NULL
);
305 ASSERT (node2
!= NULL
);
306 ASSERT (node3
!= NULL
);
307 ASSERT (gl_list_remove_node (list1
, node1
));
308 ASSERT (gl_list_remove_node (list2
, node2
));
309 ASSERT (gl_list_remove_node (list3
, node3
));
310 ASSERT (gl_list_size (list1
) == n
- 1);
313 case 9: case 10: /* remove 1 element */
314 if (gl_list_size (list1
) > 0)
316 size_t n
= gl_list_size (list1
);
317 size_t index
= RANDOM (n
);
318 ASSERT (gl_list_remove_at (list1
, index
));
319 ASSERT (gl_list_remove_at (list2
, index
));
320 ASSERT (gl_list_remove_at (list3
, index
));
321 ASSERT (gl_list_size (list1
) == n
- 1);
324 case 11: case 12: /* remove 1 element */
325 if (gl_list_size (list1
) > 0)
327 size_t n
= gl_list_size (list1
);
328 const char *obj
= gl_list_get_at (list1
, RANDOM (n
));
329 ASSERT (gl_list_remove (list1
, obj
));
330 ASSERT (gl_list_remove (list2
, obj
));
331 ASSERT (gl_list_remove (list3
, obj
));
332 ASSERT (gl_list_size (list1
) == n
- 1);
336 if (gl_list_size (list1
) > 0)
338 size_t n
= gl_list_size (list1
);
339 const char *obj
= "xyzzy";
340 ASSERT (!gl_list_remove (list1
, obj
));
341 ASSERT (!gl_list_remove (list2
, obj
));
342 ASSERT (!gl_list_remove (list3
, obj
));
343 ASSERT (gl_list_size (list1
) == n
);
348 size_t n
= gl_list_size (list1
);
349 gl_list_iterator_t iter1
, iter2
, iter3
;
351 iter1
= gl_list_iterator (list1
);
352 iter2
= gl_list_iterator (list2
);
353 iter3
= gl_list_iterator (list3
);
354 for (i
= 0; i
< n
; i
++)
356 ASSERT (gl_list_iterator_next (&iter1
, &elt
, NULL
));
357 ASSERT (gl_list_get_at (list1
, i
) == elt
);
358 ASSERT (gl_list_iterator_next (&iter2
, &elt
, NULL
));
359 ASSERT (gl_list_get_at (list2
, i
) == elt
);
360 ASSERT (gl_list_iterator_next (&iter3
, &elt
, NULL
));
361 ASSERT (gl_list_get_at (list3
, i
) == elt
);
363 ASSERT (!gl_list_iterator_next (&iter1
, &elt
, NULL
));
364 ASSERT (!gl_list_iterator_next (&iter2
, &elt
, NULL
));
365 ASSERT (!gl_list_iterator_next (&iter3
, &elt
, NULL
));
366 gl_list_iterator_free (&iter1
);
367 gl_list_iterator_free (&iter2
);
368 gl_list_iterator_free (&iter3
);
373 size_t end
= RANDOM (gl_list_size (list1
) + 1);
374 size_t start
= RANDOM (end
+ 1);
375 gl_list_iterator_t iter1
, iter2
, iter3
;
377 iter1
= gl_list_iterator_from_to (list1
, start
, end
);
378 iter2
= gl_list_iterator_from_to (list2
, start
, end
);
379 iter3
= gl_list_iterator_from_to (list3
, start
, end
);
380 for (i
= start
; i
< end
; i
++)
382 ASSERT (gl_list_iterator_next (&iter1
, &elt
, NULL
));
383 ASSERT (gl_list_get_at (list1
, i
) == elt
);
384 ASSERT (gl_list_iterator_next (&iter2
, &elt
, NULL
));
385 ASSERT (gl_list_get_at (list2
, i
) == elt
);
386 ASSERT (gl_list_iterator_next (&iter3
, &elt
, NULL
));
387 ASSERT (gl_list_get_at (list3
, i
) == elt
);
389 ASSERT (!gl_list_iterator_next (&iter1
, &elt
, NULL
));
390 ASSERT (!gl_list_iterator_next (&iter2
, &elt
, NULL
));
391 ASSERT (!gl_list_iterator_next (&iter3
, &elt
, NULL
));
392 gl_list_iterator_free (&iter1
);
393 gl_list_iterator_free (&iter2
);
394 gl_list_iterator_free (&iter3
);
398 check_all (list1
, list2
, list3
);
401 gl_list_free (list1
);
402 gl_list_free (list2
);
403 gl_list_free (list3
);