7 NEW, FREE, GET_LENGTH, FOREACH, FOREACH_RANGE, SORT, SORT_ITER,
10 GET_BEGIN_ITER, GET_END_ITER, GET_ITER_AT_POS, APPEND, PREPEND,
11 INSERT_BEFORE, MOVE, INSERT_SORTED, INSERT_SORTED_ITER, SORT_CHANGED,
12 SORT_CHANGED_ITER, REMOVE, REMOVE_RANGE, MOVE_RANGE, SEARCH, SEARCH_ITER,
17 /* operations on GSequenceIter * */
18 ITER_IS_BEGIN, ITER_IS_END, ITER_NEXT, ITER_PREV, ITER_GET_POSITION,
19 ITER_MOVE, ITER_GET_SEQUENCE,
22 ITER_COMPARE, RANGE_GET_MIDPOINT,
26 typedef struct SequenceInfo
33 void g_sequence_self_test_internal_to_glib_dont_use (GSequence *sequence);
36 check_integrity (SequenceInfo *info)
41 g_sequence_self_test_internal_to_glib_dont_use (info->sequence);
43 if (g_sequence_get_length (info->sequence) != info->n_items)
45 g_sequence_get_length (info->sequence), info->n_items);
46 g_assert (info->n_items == g_queue_get_length (info->queue));
47 g_assert (g_sequence_get_length (info->sequence) == info->n_items);
49 iter = g_sequence_get_begin_iter (info->sequence);
50 list = info->queue->head;
51 while (iter != g_sequence_get_end_iter (info->sequence))
53 g_assert (list->data == iter);
55 iter = g_sequence_iter_next (iter);
59 g_assert (info->n_items == g_queue_get_length (info->queue));
60 g_assert (g_sequence_get_length (info->sequence) == info->n_items);
70 new_item (SequenceInfo *seq)
72 Item *item = g_new (Item, 1);
75 item->number = g_random_int ();
77 /* There have been bugs in the past where the GSequence would
78 * dereference the user pointers. This will make sure such
79 * behavior causes crashes
81 return ((char *)item + 1);
85 fix_pointer (gconstpointer data)
87 return (Item *)((char *)data - 1);
91 get_item (GSequenceIter *iter)
93 return fix_pointer (g_sequence_get (iter));
97 free_item (gpointer data)
99 Item *item = fix_pointer (data);
100 item->seq->n_items--;
105 seq_foreach (gpointer data,
108 Item *item = fix_pointer (data);
109 GList **link = user_data;
112 g_assert (*link != NULL);
114 iter = (*link)->data;
116 g_assert (get_item (iter) == item);
118 item->number = g_random_int();
120 *link = (*link)->next;
124 compare_items (gconstpointer a,
128 const Item *item_a = fix_pointer (a);
129 const Item *item_b = fix_pointer (b);
131 if (item_a->number < item_b->number)
133 else if (item_a->number == item_b->number)
140 check_sorted (SequenceInfo *info)
144 GSequenceIter *last_iter;
146 check_integrity (info);
150 for (list = info->queue->head; list != NULL; list = list->next)
152 GSequenceIter *iter = list->data;
153 Item *item = get_item (iter);
155 g_assert (item->number >= last);
156 /* Check that the ordering is the same as that of the queue,
157 * ie. that the sort is stable
160 g_assert (iter == g_sequence_iter_next (last_iter));
168 compare_iters (gconstpointer a,
172 GSequenceIter *iter_a = (GSequenceIter *)a;
173 GSequenceIter *iter_b = (GSequenceIter *)b;
174 /* compare_items() will fix up the pointers */
175 Item *item_a = g_sequence_get (iter_a);
176 Item *item_b = g_sequence_get (iter_b);
178 return compare_items (item_a, item_b, data);
181 /* A version of g_queue_link_index() that treats NULL as just
185 queue_link_index (SequenceInfo *seq, GList *link)
188 return g_queue_link_index (seq->queue, link);
190 return g_queue_get_length (seq->queue);
194 get_random_range (SequenceInfo *seq,
195 GSequenceIter **begin_iter,
196 GSequenceIter **end_iter,
200 int length = g_queue_get_length (seq->queue);
201 int b = g_random_int_range (0, length + 1);
202 int e = g_random_int_range (b, length + 1);
204 g_assert (length == g_sequence_get_length (seq->sequence));
207 *begin_iter = g_sequence_get_iter_at_pos (seq->sequence, b);
209 *end_iter = g_sequence_get_iter_at_pos (seq->sequence, e);
211 *begin_link = g_queue_peek_nth_link (seq->queue, b);
213 *end_link = g_queue_peek_nth_link (seq->queue, e);
214 if (begin_iter && begin_link)
217 queue_link_index (seq, *begin_link) ==
218 g_sequence_iter_get_position (*begin_iter));
220 if (end_iter && end_link)
223 queue_link_index (seq, *end_link) ==
224 g_sequence_iter_get_position (*end_iter));
229 get_random_position (SequenceInfo *seq)
231 int length = g_queue_get_length (seq->queue);
233 g_assert (length == g_sequence_get_length (seq->sequence));
235 return g_random_int_range (-2, length + 5);
238 static GSequenceIter *
239 get_random_iter (SequenceInfo *seq,
243 int pos = get_random_position (seq);
245 *link = g_queue_peek_nth_link (seq->queue, pos);
246 iter = g_sequence_get_iter_at_pos (seq->sequence, pos);
248 g_assert (queue_link_index (seq, *link) == g_sequence_iter_get_position (iter));
253 dump_info (SequenceInfo *seq)
259 iter = g_sequence_get_begin_iter (seq->sequence);
260 list = seq->queue->head;
262 while (iter != g_sequence_get_end_iter (seq->sequence))
264 Item *item = get_item (iter);
265 g_print ("%p %p %d\n", list->data, iter, item->number);
267 iter = g_sequence_iter_next (iter);
273 /* A version of g_queue_insert_before() that appends if link is NULL */
275 queue_insert_before (SequenceInfo *seq, GList *link, gpointer data)
278 g_queue_insert_before (seq->queue, link, data);
280 g_queue_push_tail (seq->queue, data);
284 run_random_tests (guint32 seed)
286 #define N_ITERATIONS 60000
287 #define N_SEQUENCES 8
289 SequenceInfo sequences[N_SEQUENCES];
292 g_print (" seed: %u\n", seed);
294 g_random_set_seed (seed);
296 for (k = 0; k < N_SEQUENCES; ++k)
298 sequences[k].queue = g_queue_new ();
299 sequences[k].sequence = g_sequence_new (free_item);
300 sequences[k].n_items = 0;
303 #define RANDOM_SEQUENCE() &(sequences[g_random_int_range (0, N_SEQUENCES)])
305 for (k = 0; k < N_ITERATIONS; ++k)
308 SequenceInfo *seq = RANDOM_SEQUENCE();
309 int op = g_random_int_range (0, N_OPS);
312 g_print ("%d\n", op);
320 g_queue_free (seq->queue);
321 g_sequence_free (seq->sequence);
323 g_assert (seq->n_items == 0);
325 seq->queue = g_queue_new ();
326 seq->sequence = g_sequence_new (free_item);
328 check_integrity (seq);
333 int slen = g_sequence_get_length (seq->sequence);
334 int qlen = g_queue_get_length (seq->queue);
336 g_assert (slen == qlen);
341 GList *link = seq->queue->head;
342 g_sequence_foreach (seq->sequence, seq_foreach, &link);
343 g_assert (link == NULL);
348 GSequenceIter *begin_iter, *end_iter;
349 GList *begin_link, *end_link;
351 get_random_range (seq, &begin_iter, &end_iter, &begin_link, &end_link);
353 check_integrity (seq);
355 g_sequence_foreach_range (begin_iter, end_iter, seq_foreach, &begin_link);
357 g_assert (begin_link == end_link);
364 g_sequence_sort (seq->sequence, compare_items, NULL);
365 g_queue_sort (seq->queue, compare_iters, NULL);
374 g_sequence_sort_iter (seq->sequence,
375 (GSequenceIterCompareFunc)compare_iters, NULL);
376 g_queue_sort (seq->queue, compare_iters, NULL);
385 GSequenceIter *begin_iter;
386 GSequenceIter *end_iter;
387 GSequenceIter *penultimate_iter;
389 begin_iter = g_sequence_get_begin_iter (seq->sequence);
390 check_integrity (seq);
392 end_iter = g_sequence_get_end_iter (seq->sequence);
393 check_integrity (seq);
395 penultimate_iter = g_sequence_iter_prev (end_iter);
396 check_integrity (seq);
398 if (g_sequence_get_length (seq->sequence) > 0)
400 g_assert (seq->queue->head);
401 g_assert (seq->queue->head->data == begin_iter);
402 g_assert (seq->queue->tail);
403 g_assert (seq->queue->tail->data == penultimate_iter);
407 g_assert (penultimate_iter == end_iter);
408 g_assert (begin_iter == end_iter);
409 g_assert (penultimate_iter == begin_iter);
410 g_assert (seq->queue->head == NULL);
411 g_assert (seq->queue->tail == NULL);
415 case GET_ITER_AT_POS:
419 g_assert (g_queue_get_length (seq->queue) == g_sequence_get_length (seq->sequence));
421 for (i = 0; i < 10; ++i)
423 int pos = get_random_position (seq);
424 GSequenceIter *iter = g_sequence_get_iter_at_pos (seq->sequence, pos);
425 GList *link = g_queue_peek_nth_link (seq->queue, pos);
426 check_integrity (seq);
427 if (pos >= g_sequence_get_length (seq->sequence) || pos < 0)
429 g_assert (iter == g_sequence_get_end_iter (seq->sequence));
430 g_assert (link == NULL);
435 g_assert (link->data == iter);
442 for (i = 0; i < 10; ++i)
444 GSequenceIter *iter = g_sequence_append (seq->sequence, new_item (seq));
445 g_queue_push_tail (seq->queue, iter);
451 for (i = 0; i < 10; ++i)
453 GSequenceIter *iter = g_sequence_prepend (seq->sequence, new_item (seq));
454 g_queue_push_head (seq->queue, iter);
460 for (i = 0; i < 10; ++i)
463 GSequenceIter *iter = get_random_iter (seq, &link);
464 GSequenceIter *new_iter;
465 check_integrity (seq);
467 new_iter = g_sequence_insert_before (iter, new_item (seq));
469 queue_insert_before (seq, link, new_iter);
475 GList *link1, *link2;
476 GSequenceIter *iter1 = get_random_iter (seq, &link1);
477 GSequenceIter *iter2 = get_random_iter (seq, &link2);
479 if (!g_sequence_iter_is_end (iter1))
481 g_sequence_move (iter1, iter2);
484 g_assert (g_sequence_iter_is_end (iter2));
486 queue_insert_before (seq, link2, link1->data);
488 g_queue_delete_link (seq->queue, link1);
491 check_integrity (seq);
493 iter1 = get_random_iter (seq, NULL);
495 /* Moving an iter to itself should have no effect */
496 if (!g_sequence_iter_is_end (iter1))
497 g_sequence_move (iter1, iter1);
505 g_sequence_sort (seq->sequence, compare_items, NULL);
506 g_queue_sort (seq->queue, compare_iters, NULL);
510 for (i = 0; i < 15; ++i)
512 GSequenceIter *iter =
513 g_sequence_insert_sorted (
514 seq->sequence, new_item(seq), compare_items, NULL);
516 g_queue_insert_sorted (seq->queue, iter, compare_iters, NULL);
524 case INSERT_SORTED_ITER:
529 g_sequence_sort (seq->sequence, compare_items, NULL);
530 g_queue_sort (seq->queue, compare_iters, NULL);
534 for (i = 0; i < 15; ++i)
538 iter = g_sequence_insert_sorted_iter (seq->sequence,
540 (GSequenceIterCompareFunc)compare_iters,
543 g_queue_insert_sorted (seq->queue, iter, compare_iters, NULL);
555 g_sequence_sort (seq->sequence, compare_items, NULL);
556 g_queue_sort (seq->queue, compare_iters, NULL);
560 for (i = 0; i < 15; ++i)
563 GSequenceIter *iter = get_random_iter (seq, &link);
565 if (!g_sequence_iter_is_end (iter))
567 g_sequence_set (iter, new_item (seq));
568 g_sequence_sort_changed (iter, compare_items, NULL);
570 g_queue_delete_link (seq->queue, link);
571 g_queue_insert_sorted (seq->queue, iter, compare_iters, NULL);
578 case SORT_CHANGED_ITER:
582 g_sequence_sort (seq->sequence, compare_items, NULL);
583 g_queue_sort (seq->queue, compare_iters, NULL);
587 for (i = 0; i < 15; ++i)
590 GSequenceIter *iter = get_random_iter (seq, &link);
592 if (!g_sequence_iter_is_end (iter))
594 g_sequence_set (iter, new_item (seq));
595 g_sequence_sort_changed_iter (iter,
596 (GSequenceIterCompareFunc)compare_iters, NULL);
598 g_queue_delete_link (seq->queue, link);
599 g_queue_insert_sorted (seq->queue, iter, compare_iters, NULL);
610 for (i = 0; i < 15; ++i)
613 GSequenceIter *iter = get_random_iter (seq, &link);
615 if (!g_sequence_iter_is_end (iter))
617 g_sequence_remove (iter);
618 g_queue_delete_link (seq->queue, link);
625 GSequenceIter *begin_iter, *end_iter;
626 GList *begin_link, *end_link;
629 get_random_range (seq, &begin_iter, &end_iter, &begin_link, &end_link);
631 g_sequence_remove_range (begin_iter, end_iter);
634 while (list != end_link)
636 GList *next = list->next;
638 g_queue_delete_link (seq->queue, list);
646 SequenceInfo *src = RANDOM_SEQUENCE();
647 SequenceInfo *dst = RANDOM_SEQUENCE();
649 GSequenceIter *begin_iter, *end_iter;
650 GList *begin_link, *end_link;
652 GSequenceIter *dst_iter;
657 g_assert (src->queue);
658 g_assert (dst->queue);
660 get_random_range (src, &begin_iter, &end_iter, &begin_link, &end_link);
661 dst_iter = get_random_iter (dst, &dst_link);
663 g_sequence_move_range (dst_iter, begin_iter, end_iter);
665 if (dst_link == begin_link || (src == dst && dst_link == end_link))
667 check_integrity (src);
668 check_integrity (dst);
672 if (queue_link_index (src, begin_link) >=
673 queue_link_index (src, end_link))
679 queue_link_index (src, dst_link) >= queue_link_index (src, begin_link) &&
680 queue_link_index (src, dst_link) <= queue_link_index (src, end_link))
686 while (list != end_link)
688 GList *next = list->next;
689 Item *item = get_item (list->data);
691 g_assert (dst->queue);
692 queue_insert_before (dst, dst_link, list->data);
693 g_queue_delete_link (src->queue, list);
695 g_assert (item->seq == src);
708 GSequenceIter *search_iter;
709 GSequenceIter *insert_iter;
711 g_sequence_sort (seq->sequence, compare_items, NULL);
712 g_queue_sort (seq->queue, compare_iters, NULL);
716 item = new_item (seq);
717 search_iter = g_sequence_search (seq->sequence, item, compare_items, NULL);
719 insert_iter = g_sequence_insert_sorted (seq->sequence, item, compare_items, NULL);
721 g_assert (search_iter == g_sequence_iter_next (insert_iter));
723 g_queue_insert_sorted (seq->queue, insert_iter, compare_iters, NULL);
729 GSequenceIter *search_iter;
730 GSequenceIter *insert_iter;
732 g_sequence_sort (seq->sequence, compare_items, NULL);
733 g_queue_sort (seq->queue, compare_iters, NULL);
737 item = new_item (seq);
738 search_iter = g_sequence_search_iter (seq->sequence,
740 (GSequenceIterCompareFunc)compare_iters, NULL);
742 insert_iter = g_sequence_insert_sorted (seq->sequence, item, compare_items, NULL);
744 g_assert (search_iter == g_sequence_iter_next (insert_iter));
746 g_queue_insert_sorted (seq->queue, insert_iter, compare_iters, NULL);
757 iter = get_random_iter (seq, &link);
759 if (!g_sequence_iter_is_end (iter))
764 check_integrity (seq);
766 /* Test basic functionality */
767 item = new_item (seq);
768 g_sequence_set (iter, item);
769 g_assert (g_sequence_get (iter) == item);
771 /* Make sure that existing items are freed */
772 for (i = 0; i < 15; ++i)
773 g_sequence_set (iter, new_item (seq));
775 check_integrity (seq);
777 g_sequence_set (iter, new_item (seq));
782 /* operations on GSequenceIter * */
787 iter = g_sequence_get_iter_at_pos (seq->sequence, 0);
789 g_assert (g_sequence_iter_is_begin (iter));
791 check_integrity (seq);
793 if (g_sequence_get_length (seq->sequence) > 0)
795 g_assert (!g_sequence_iter_is_begin (
796 g_sequence_get_end_iter (seq->sequence)));
800 g_assert (g_sequence_iter_is_begin (
801 g_sequence_get_end_iter (seq->sequence)));
804 g_assert (g_sequence_iter_is_begin (g_sequence_get_begin_iter (seq->sequence)));
810 int len = g_sequence_get_length (seq->sequence);
812 iter = g_sequence_get_iter_at_pos (seq->sequence, len);
814 g_assert (g_sequence_iter_is_end (iter));
818 g_assert (!g_sequence_iter_is_end (
819 g_sequence_get_begin_iter (seq->sequence)));
823 g_assert (g_sequence_iter_is_end (
824 g_sequence_get_begin_iter (seq->sequence)));
827 g_assert (g_sequence_iter_is_end (g_sequence_get_end_iter (seq->sequence)));
832 GSequenceIter *iter1, *iter2, *iter3, *end;
834 iter1 = g_sequence_append (seq->sequence, new_item (seq));
835 iter2 = g_sequence_append (seq->sequence, new_item (seq));
836 iter3 = g_sequence_append (seq->sequence, new_item (seq));
838 end = g_sequence_get_end_iter (seq->sequence);
840 g_assert (g_sequence_iter_next (iter1) == iter2);
841 g_assert (g_sequence_iter_next (iter2) == iter3);
842 g_assert (g_sequence_iter_next (iter3) == end);
843 g_assert (g_sequence_iter_next (end) == end);
845 g_queue_push_tail (seq->queue, iter1);
846 g_queue_push_tail (seq->queue, iter2);
847 g_queue_push_tail (seq->queue, iter3);
852 GSequenceIter *iter1, *iter2, *iter3, *begin;
854 iter1 = g_sequence_prepend (seq->sequence, new_item (seq));
855 iter2 = g_sequence_prepend (seq->sequence, new_item (seq));
856 iter3 = g_sequence_prepend (seq->sequence, new_item (seq));
858 begin = g_sequence_get_begin_iter (seq->sequence);
860 g_assert (g_sequence_iter_prev (iter1) == iter2);
861 g_assert (g_sequence_iter_prev (iter2) == iter3);
862 g_assert (iter3 == begin);
863 g_assert (g_sequence_iter_prev (iter3) == begin);
864 g_assert (g_sequence_iter_prev (begin) == begin);
866 g_queue_push_head (seq->queue, iter1);
867 g_queue_push_head (seq->queue, iter2);
868 g_queue_push_head (seq->queue, iter3);
871 case ITER_GET_POSITION:
874 GSequenceIter *iter = get_random_iter (seq, &link);
876 g_assert (g_sequence_iter_get_position (iter) ==
877 queue_link_index (seq, link));
882 int len = g_sequence_get_length (seq->sequence);
886 iter = get_random_iter (seq, NULL);
887 pos = g_sequence_iter_get_position (iter);
888 iter = g_sequence_iter_move (iter, len - pos);
889 g_assert (g_sequence_iter_is_end (iter));
892 iter = get_random_iter (seq, NULL);
893 pos = g_sequence_iter_get_position (iter);
896 g_assert (!g_sequence_iter_is_end (iter));
898 iter = g_sequence_iter_move (iter, 1);
900 g_assert (g_sequence_iter_is_end (iter));
903 case ITER_GET_SEQUENCE:
905 GSequenceIter *iter = get_random_iter (seq, NULL);
907 g_assert (g_sequence_iter_get_sequence (iter) == seq->sequence);
914 GList *link1, *link2;
915 GSequenceIter *iter1 = get_random_iter (seq, &link1);
916 GSequenceIter *iter2 = get_random_iter (seq, &link2);
918 int cmp = g_sequence_iter_compare (iter1, iter2);
919 int pos1 = queue_link_index (seq, link1);
920 int pos2 = queue_link_index (seq, link2);
924 g_assert (pos1 == pos2);
928 g_assert (pos1 < pos2);
932 g_assert (pos1 > pos2);
936 case RANGE_GET_MIDPOINT:
938 GSequenceIter *iter1 = get_random_iter (seq, NULL);
939 GSequenceIter *iter2 = get_random_iter (seq, NULL);
940 GSequenceIter *iter3;
943 cmp = g_sequence_iter_compare (iter1, iter2);
954 iter3 = g_sequence_range_get_midpoint (iter1, iter2);
958 g_assert (iter3 == iter1);
959 g_assert (iter3 == iter2);
962 g_assert (g_sequence_iter_get_position (iter3) >=
963 g_sequence_iter_get_position (iter1));
964 g_assert (g_sequence_iter_get_position (iter2) >=
965 g_sequence_iter_get_position (iter3));
971 check_integrity (seq);
975 /* Random seeds known to have failed at one point
977 static gulong seeds[] =
990 static void standalone_tests (void);
993 get_seed (int argc, char **argv)
999 return strtol (argv[1], &endptr, 0);
1003 return g_random_int();
1011 guint32 seed = get_seed (argc, argv);
1014 /* Run stand alone tests */
1015 g_print ("running standalone tests\n");
1018 g_print ("running regression tests:\n");
1019 /* Run regression tests */
1020 for (i = 0; i < G_N_ELEMENTS (seeds); ++i)
1022 run_random_tests (seeds[i]);
1025 /* Run with a new random seed */
1026 g_print ("random seed:\n");
1027 run_random_tests (seed);
1034 /* Single, stand-alone tests */
1037 test_out_of_range_jump (void)
1039 GSequence *seq = g_sequence_new (NULL);
1040 GSequenceIter *iter = g_sequence_get_begin_iter (seq);
1042 g_sequence_iter_move (iter, 5);
1044 g_assert (g_sequence_iter_is_begin (iter));
1045 g_assert (g_sequence_iter_is_end (iter));
1049 compare (gconstpointer a, gconstpointer b, gpointer userdata)
1053 ai = GPOINTER_TO_INT (a);
1054 bi = GPOINTER_TO_INT (b);
1065 compare_iter (GSequenceIter *a,
1069 return compare (g_sequence_get (a),
1075 test_insert_sorted_non_pointer (void)
1079 for (i = 0; i < 10; i++)
1081 GSequence *seq = g_sequence_new (NULL);
1084 for (j = 0; j < 10000; j++)
1086 g_sequence_insert_sorted (
1087 seq, GINT_TO_POINTER (g_random_int()),
1090 g_sequence_insert_sorted_iter (
1091 seq, GINT_TO_POINTER (g_random_int()),
1092 compare_iter, NULL);
1095 g_sequence_free (seq);
1100 test_stable_sort (void)
1103 GSequence *seq = g_sequence_new (NULL);
1105 #define N_ITEMS 1000
1107 GSequenceIter *iters[N_ITEMS];
1108 GSequenceIter *iter;
1110 for (i = 0; i < N_ITEMS; ++i)
1111 iters[i] = g_sequence_append (seq, GINT_TO_POINTER (3000));
1114 iter = g_sequence_get_begin_iter (seq);
1115 while (!g_sequence_iter_is_end (iter))
1117 g_assert (iters[i++] == iter);
1119 iter = g_sequence_iter_next (iter);
1122 g_sequence_sort (seq, compare, NULL);
1125 iter = g_sequence_get_begin_iter (seq);
1126 while (!g_sequence_iter_is_end (iter))
1128 g_assert (iters[i++] == iter);
1130 iter = g_sequence_iter_next (iter);
1133 for (i = N_ITEMS - 1; i >= 0; --i)
1134 g_sequence_sort_changed (iters[i], compare, NULL);
1137 iter = g_sequence_get_begin_iter (seq);
1138 while (!g_sequence_iter_is_end (iter))
1140 g_assert (iters[i++] == iter);
1142 iter = g_sequence_iter_next (iter);
1147 standalone_tests (void)
1149 test_out_of_range_jump ();
1150 test_insert_sorted_non_pointer ();
1151 test_stable_sort ();