1 #undef G_DISABLE_ASSERT 2 #undef G_LOG_DOMAIN 3 4 #include <time.h> 5 #include <stdlib.h> 6 7 #include <glib.h> 8 9 10 static gboolean verbose = FALSE; 11 12 13 static void 14 check_integrity (GQueue *queue) 15 { 16 GList *list; 17 GList *last; 18 GList *links; 19 GList *link; 20 gint n; 21 22 g_assert (queue->length < 4000000000u); 23 24 g_assert (g_queue_get_length (queue) == queue->length); 25 26 if (!queue->head) 27 g_assert (!queue->tail); 28 if (!queue->tail) 29 g_assert (!queue->head); 30 31 n = 0; 32 last = NULL; 33 for (list = queue->head; list != NULL; list = list->next) 34 { 35 if (!list->next) 36 last = list; 37 ++n; 38 } 39 g_assert (n == queue->length); 40 g_assert (last == queue->tail); 41 42 n = 0; 43 last = NULL; 44 for (list = queue->tail; list != NULL; list = list->prev) 45 { 46 if (!list->prev) 47 last = list; 48 ++n; 49 } 50 g_assert (n == queue->length); 51 g_assert (last == queue->head); 52 53 links = NULL; 54 for (list = queue->head; list != NULL; list = list->next) 55 links = g_list_prepend (links, list); 56 57 link = links; 58 for (list = queue->tail; list != NULL; list = list->prev) 59 { 60 g_assert (list == link->data); 61 link = link->next; 62 } 63 g_list_free (links); 64 65 links = NULL; 66 for (list = queue->tail; list != NULL; list = list->prev) 67 links = g_list_prepend (links, list); 68 69 link = links; 70 for (list = queue->head; list != NULL; list = list->next) 71 { 72 g_assert (list == link->data); 73 link = link->next; 74 } 75 g_list_free (links); 76 } 77 78 static gboolean 79 rnd_bool (void) 80 { 81 return g_random_int_range (0, 2); 82 } 83 84 static void 85 check_max (gpointer elm, gpointer user_data) 86 { 87 gint *best = user_data; 88 gint element = GPOINTER_TO_INT (elm); 89 90 if (element > *best) 91 *best = element; 92 } 93 94 static void 95 check_min (gpointer elm, gpointer user_data) 96 { 97 gint *best = user_data; 98 gint element = GPOINTER_TO_INT (elm); 99 100 if (element < *best) 101 *best = element; 102 } 103 104 static gint 105 find_min (GQueue *queue) 106 { 107 gint min = G_MAXINT; 108 109 g_queue_foreach (queue, check_min, &min); 110 111 return min; 112 } 113 114 static gint 115 find_max (GQueue *queue) 116 { 117 gint max = G_MININT; 118 119 g_queue_foreach (queue, check_max, &max); 120 121 return max; 122 } 123 124 static void 125 delete_elm (gpointer elm, gpointer user_data) 126 { 127 g_queue_remove ((GQueue *)user_data, elm); 128 check_integrity ((GQueue *)user_data); 129 } 130 131 static void 132 delete_all (GQueue *queue) 133 { 134 g_queue_foreach (queue, delete_elm, queue); 135 } 136 137 static int 138 compare_int (gconstpointer a, gconstpointer b, gpointer data) 139 { 140 int ai = GPOINTER_TO_INT (a); 141 int bi = GPOINTER_TO_INT (b); 142 143 if (ai > bi) 144 return 1; 145 else if (ai == bi) 146 return 0; 147 else 148 return -1; 149 } 150 151 static gint 152 get_random_position (GQueue *queue, gboolean allow_offlist) 153 { 154 int n; 155 enum { OFF_QUEUE, HEAD, TAIL, MIDDLE, LAST } where; 156 157 if (allow_offlist) 158 where = g_random_int_range (OFF_QUEUE, LAST); 159 else 160 where = g_random_int_range (HEAD, LAST); 161 162 switch (where) 163 { 164 case OFF_QUEUE: 165 n = g_random_int (); 166 break; 167 168 case HEAD: 169 n = 0; 170 break; 171 172 case TAIL: 173 if (allow_offlist) 174 n = queue->length; 175 else 176 n = queue->length - 1; 177 break; 178 179 case MIDDLE: 180 if (queue->length == 0) 181 n = 0; 182 else 183 n = g_random_int_range (0, queue->length); 184 break; 185 186 default: 187 g_assert_not_reached(); 188 n = 100; 189 break; 190 191 } 192 193 return n; 194 } 195 196 static void 197 random_test (int seed) 198 { 199 typedef enum { 200 IS_EMPTY, GET_LENGTH, REVERSE, COPY, 201 FOREACH, FIND, FIND_CUSTOM, SORT, 202 PUSH_HEAD, PUSH_TAIL, PUSH_NTH, POP_HEAD, 203 POP_TAIL, POP_NTH, PEEK_HEAD, PEEK_TAIL, 204 PEEK_NTH, INDEX, REMOVE, REMOVE_ALL, 205 INSERT_BEFORE, INSERT_AFTER, INSERT_SORTED, PUSH_HEAD_LINK, 206 PUSH_TAIL_LINK, PUSH_NTH_LINK, POP_HEAD_LINK, POP_TAIL_LINK, 207 POP_NTH_LINK, PEEK_HEAD_LINK, PEEK_TAIL_LINK, PEEK_NTH_LINK, 208 LINK_INDEX, UNLINK, DELETE_LINK, LAST_OP 209 } QueueOp; 210 211 #define N_ITERATIONS 500000 212 #define N_QUEUES 3 213 214 #define RANDOM_QUEUE() &(queues[g_random_int_range(0, N_QUEUES)]) 215 216 typedef struct QueueInfo QueueInfo; 217 struct QueueInfo 218 { 219 GQueue *queue; 220 GList *tail; 221 GList *head; 222 guint length; 223 }; 224 225 gint i; 226 QueueOp op; 227 QueueInfo queues[N_QUEUES]; 228 229 if (verbose) 230 g_print ("seed: %d\n", seed); 231 232 g_random_set_seed (seed); 233 234 for (i = 0; i < N_QUEUES; ++i) 235 { 236 queues[i].queue = g_queue_new (); 237 queues[i].head = NULL; 238 queues[i].tail = NULL; 239 queues[i].length = 0; 240 } 241 242 for (i = 0; i < N_ITERATIONS; ++i) 243 { 244 int j; 245 QueueInfo *qinf = RANDOM_QUEUE(); 246 GQueue *q = qinf->queue; 247 op = g_random_int_range (IS_EMPTY, LAST_OP); 248 249 g_assert (qinf->head == q->head); 250 g_assert (qinf->tail == q->tail); 251 g_assert (qinf->length == q->length); 252 253 switch (op) 254 { 255 case IS_EMPTY: 256 { 257 if (g_queue_is_empty (qinf->queue)) 258 { 259 g_assert (q->head == NULL); 260 g_assert (q->tail == NULL); 261 g_assert (q->length == 0); 262 } 263 else 264 { 265 g_assert (q->head); 266 g_assert (q->tail); 267 g_assert (q->length > 0); 268 } 269 } 270 break; 271 case GET_LENGTH: 272 { 273 int l; 274 275 l = g_queue_get_length (q); 276 277 g_assert (qinf->length == q->length); 278 g_assert (qinf->length == l); 279 } 280 break; 281 case REVERSE: 282 g_queue_reverse (q); 283 g_assert (qinf->tail == q->head); 284 g_assert (qinf->head == q->tail); 285 g_assert (qinf->length == q->length); 286 qinf->tail = q->tail; 287 qinf->head = q->head; 288 break; 289 case COPY: 290 { 291 QueueInfo *random_queue = RANDOM_QUEUE(); 292 GQueue *new_queue = g_queue_copy (random_queue->queue); 293 294 g_queue_free (qinf->queue); 295 q = qinf->queue = new_queue; 296 qinf->head = new_queue->head; 297 qinf->tail = g_list_last (new_queue->head); 298 qinf->length = new_queue->length; 299 } 300 break; 301 case FOREACH: 302 delete_all (q); 303 qinf->head = NULL; 304 qinf->tail = NULL; 305 qinf->length = 0; 306 break; 307 case FIND: 308 { 309 gboolean find_existing = rnd_bool (); 310 int first = find_max (q); 311 int second = find_min (q); 312 313 if (q->length == 0) 314 find_existing = FALSE; 315 316 if (!find_existing) 317 first++; 318 if (!find_existing) 319 second--; 320 321 if (find_existing) 322 { 323 g_assert (g_queue_find (q, GINT_TO_POINTER (first))); 324 g_assert (g_queue_find (q, GINT_TO_POINTER (second))); 325 } 326 else 327 { 328 g_assert (!g_queue_find (q, GINT_TO_POINTER (first))); 329 g_assert (!g_queue_find (q, GINT_TO_POINTER (second))); 330 } 331 } 332 break; 333 case FIND_CUSTOM: 334 break; 335 case SORT: 336 { 337 if (!g_queue_is_empty (q)) 338 { 339 int max = find_max (q); 340 int min = find_min (q); 341 g_queue_remove_all (q, GINT_TO_POINTER (max)); 342 check_integrity (q); 343 g_queue_remove_all (q, GINT_TO_POINTER (min)); 344 check_integrity (q); 345 g_queue_push_head (q, GINT_TO_POINTER (max)); 346 if (max != min) 347 g_queue_push_head (q, GINT_TO_POINTER (min)); 348 qinf->length = q->length; 349 } 350 351 check_integrity (q); 352 353 g_queue_sort (q, compare_int, NULL); 354 355 check_integrity (q); 356 357 qinf->head = g_queue_find (q, GINT_TO_POINTER (find_min(q))); 358 qinf->tail = g_queue_find (q, GINT_TO_POINTER (find_max(q))); 359 360 g_assert (qinf->tail == q->tail); 361 } 362 break; 363 case PUSH_HEAD: 364 { 365 int x = g_random_int_range (0, 435435); 366 g_queue_push_head (q, GINT_TO_POINTER (x)); 367 if (!qinf->head) 368 qinf->tail = qinf->head = q->head; 369 else 370 qinf->head = qinf->head->prev; 371 qinf->length++; 372 } 373 break; 374 case PUSH_TAIL: 375 { 376 int x = g_random_int_range (0, 236546); 377 g_queue_push_tail (q, GINT_TO_POINTER (x)); 378 if (!qinf->tail) 379 qinf->tail = qinf->head = q->head; 380 else 381 qinf->tail = qinf->tail->next; 382 qinf->length++; 383 } 384 break; 385 case PUSH_NTH: 386 { 387 int pos = get_random_position (q, TRUE); 388 int x = g_random_int_range (0, 236546); 389 g_queue_push_nth (q, GINT_TO_POINTER (x), pos); 390 if (qinf->head && qinf->head->prev) 391 qinf->head = qinf->head->prev; 392 else 393 qinf->head = q->head; 394 if (qinf->tail && qinf->tail->next) 395 qinf->tail = qinf->tail->next; 396 else 397 qinf->tail = g_list_last (qinf->head); 398 qinf->length++; 399 } 400 break; 401 case POP_HEAD: 402 if (qinf->head) 403 qinf->head = qinf->head->next; 404 if (!qinf->head) 405 qinf->tail = NULL; 406 qinf->length = (qinf->length == 0)? 0 : qinf->length - 1; 407 g_queue_pop_head (q); 408 break; 409 case POP_TAIL: 410 if (qinf->tail) 411 qinf->tail = qinf->tail->prev; 412 if (!qinf->tail) 413 qinf->head = NULL; 414 qinf->length = (qinf->length == 0)? 0 : qinf->length - 1; 415 g_queue_pop_tail (q); 416 break; 417 case POP_NTH: 418 if (!g_queue_is_empty (q)) 419 { 420 int n = get_random_position (q, TRUE); 421 gpointer elm = g_queue_peek_nth (q, n); 422 423 if (n == q->length - 1) 424 qinf->tail = qinf->tail->prev; 425 426 if (n == 0) 427 qinf->head = qinf->head->next; 428 429 if (n >= 0 && n < q->length) 430 qinf->length--; 431 432 g_assert (elm == g_queue_pop_nth (q, n)); 433 } 434 break; 435 case PEEK_HEAD: 436 if (qinf->head) 437 g_assert (qinf->head->data == g_queue_peek_head (q)); 438 else 439 g_assert (g_queue_peek_head (q) == NULL); 440 break; 441 case PEEK_TAIL: 442 if (qinf->head) 443 g_assert (qinf->tail->data == g_queue_peek_tail (q)); 444 else 445 g_assert (g_queue_peek_tail (q) == NULL); 446 break; 447 case PEEK_NTH: 448 if (g_queue_is_empty (q)) 449 { 450 for (j = -10; j < 10; ++j) 451 g_assert (g_queue_peek_nth (q, j) == NULL); 452 } 453 else 454 { 455 GList *list; 456 int n = get_random_position (q, TRUE); 457 if (n < 0 || n >= q->length) 458 { 459 g_assert (g_queue_peek_nth (q, n) == NULL); 460 } 461 else 462 { 463 list = qinf->head; 464 for (j = 0; j < n; ++j) 465 list = list->next; 466 467 g_assert (list->data == g_queue_peek_nth (q, n)); 468 } 469 } 470 break; 471 case INDEX: 472 case LINK_INDEX: 473 { 474 int x = g_random_int_range (0, 386538); 475 int n; 476 GList *list; 477 478 g_queue_remove_all (q, GINT_TO_POINTER (x)); 479 check_integrity (q); 480 g_queue_push_tail (q, GINT_TO_POINTER (x)); 481 check_integrity (q); 482 g_queue_sort (q, compare_int, NULL); 483 check_integrity (q); 484 485 n = 0; 486 for (list = q->head; list != NULL; list = list->next) 487 { 488 if (list->data == GINT_TO_POINTER (x)) 489 break; 490 n++; 491 } 492 g_assert (list); 493 g_assert (g_queue_index (q, GINT_TO_POINTER (x)) == 494 g_queue_link_index (q, list)); 495 g_assert (g_queue_link_index (q, list) == n); 496 497 qinf->head = q->head; 498 qinf->tail = q->tail; 499 qinf->length = q->length; 500 } 501 break; 502 case REMOVE: 503 if (!g_queue_is_empty (q)) 504 g_queue_remove (q, qinf->tail->data); 505 if (!g_queue_is_empty (q)) 506 g_queue_remove (q, qinf->head->data); 507 if (!g_queue_is_empty (q)) 508 g_queue_remove (q, g_queue_peek_nth (q, get_random_position (q, TRUE))); 509 510 qinf->head = q->head; 511 qinf->tail = q->tail; 512 qinf->length = q->length; 513 break; 514 case REMOVE_ALL: 515 if (!g_queue_is_empty (q)) 516 g_queue_remove_all (q, qinf->tail->data); 517 if (!g_queue_is_empty (q)) 518 g_queue_remove_all (q, qinf->head->data); 519 if (!g_queue_is_empty (q)) 520 g_queue_remove_all (q, g_queue_peek_nth (q, get_random_position (q, TRUE))); 521 522 qinf->head = q->head; 523 qinf->tail = q->tail; 524 qinf->length = q->length; 525 break; 526 case INSERT_BEFORE: 527 if (!g_queue_is_empty (q)) 528 { 529 gpointer x = GINT_TO_POINTER (g_random_int_range (0, 386538)); 530 531 g_queue_insert_before (q, qinf->tail, x); 532 g_queue_insert_before (q, qinf->head, x); 533 g_queue_insert_before (q, g_queue_find (q, x), x); 534 } 535 qinf->head = q->head; 536 qinf->tail = q->tail; 537 qinf->length = q->length; 538 break; 539 case INSERT_AFTER: 540 if (!g_queue_is_empty (q)) 541 { 542 gpointer x = GINT_TO_POINTER (g_random_int_range (0, 386538)); 543 544 g_queue_insert_after (q, qinf->tail, x); 545 g_queue_insert_after (q, qinf->head, x); 546 g_queue_insert_after (q, g_queue_find (q, x), x); 547 } 548 qinf->head = q->head; 549 qinf->tail = q->tail; 550 qinf->length = q->length; 551 break; 552 case INSERT_SORTED: 553 { 554 int max = find_max (q); 555 int min = find_min (q); 556 557 if (g_queue_is_empty (q)) 558 { 559 max = 345; 560 min = -12; 561 } 562 563 g_queue_sort (q, compare_int, NULL); 564 check_integrity (q); 565 g_queue_insert_sorted (q, GINT_TO_POINTER (max + 1), compare_int, NULL); 566 check_integrity (q); 567 g_assert (GPOINTER_TO_INT (q->tail->data) == max + 1); 568 g_queue_insert_sorted (q, GINT_TO_POINTER (min - 1), compare_int, NULL); 569 check_integrity (q); 570 g_assert (GPOINTER_TO_INT (q->head->data) == min - 1); 571 qinf->head = q->head; 572 qinf->tail = q->tail; 573 qinf->length = q->length; 574 } 575 break; 576 case PUSH_HEAD_LINK: 577 { 578 GList *link = g_list_prepend (NULL, GINT_TO_POINTER (i)); 579 g_queue_push_head_link (q, link); 580 if (!qinf->tail) 581 qinf->tail = link; 582 qinf->head = link; 583 qinf->length++; 584 } 585 break; 586 case PUSH_TAIL_LINK: 587 { 588 GList *link = g_list_prepend (NULL, GINT_TO_POINTER (i)); 589 g_queue_push_tail_link (q, link); 590 if (!qinf->head) 591 qinf->head = link; 592 qinf->tail = link; 593 qinf->length++; 594 } 595 break; 596 case PUSH_NTH_LINK: 597 { 598 GList *link = g_list_prepend (NULL, GINT_TO_POINTER (i)); 599 gint n = get_random_position (q, TRUE); 600 g_queue_push_nth_link (q, n, link); 601 602 if (qinf->head && qinf->head->prev) 603 qinf->head = qinf->head->prev; 604 else 605 qinf->head = q->head; 606 if (qinf->tail && qinf->tail->next) 607 qinf->tail = qinf->tail->next; 608 else 609 qinf->tail = g_list_last (qinf->head); 610 qinf->length++; 611 } 612 break; 613 case POP_HEAD_LINK: 614 if (!g_queue_is_empty (q)) 615 { 616 qinf->head = qinf->head->next; 617 if (!qinf->head) 618 qinf->tail = NULL; 619 qinf->length--; 620 g_list_free (g_queue_pop_head_link (q)); 621 } 622 break; 623 case POP_TAIL_LINK: 624 if (!g_queue_is_empty (q)) 625 { 626 qinf->tail = qinf->tail->prev; 627 if (!qinf->tail) 628 qinf->head = NULL; 629 qinf->length--; 630 g_list_free (g_queue_pop_tail_link (q)); 631 } 632 break; 633 case POP_NTH_LINK: 634 if (g_queue_is_empty (q)) 635 g_assert (g_queue_pop_nth_link (q, 200) == NULL); 636 else 637 { 638 int n = get_random_position (q, FALSE); 639 640 if (n == g_queue_get_length (q) - 1) 641 qinf->tail = qinf->tail->prev; 642 643 if (n == 0) 644 qinf->head = qinf->head->next; 645 646 qinf->length--; 647 648 g_list_free (g_queue_pop_nth_link (q, n)); 649 } 650 break; 651 case PEEK_HEAD_LINK: 652 if (g_queue_is_empty (q)) 653 g_assert (g_queue_peek_head_link (q) == NULL); 654 else 655 g_assert (g_queue_peek_head_link (q) == qinf->head); 656 break; 657 case PEEK_TAIL_LINK: 658 if (g_queue_is_empty (q)) 659 g_assert (g_queue_peek_tail_link (q) == NULL); 660 else 661 g_assert (g_queue_peek_tail_link (q) == qinf->tail); 662 break; 663 case PEEK_NTH_LINK: 664 if (g_queue_is_empty(q)) 665 g_assert (g_queue_peek_nth_link (q, 1000) == NULL); 666 else 667 { 668 gint n = get_random_position (q, FALSE); 669 GList *link; 670 671 link = q->head; 672 for (j = 0; j < n; ++j) 673 link = link->next; 674 675 g_assert (g_queue_peek_nth_link (q, n) == link); 676 } 677 break; 678 case UNLINK: 679 if (!g_queue_is_empty (q)) 680 { 681 gint n = g_random_int_range (0, g_queue_get_length (q)); 682 GList *link; 683 684 link = q->head; 685 for (j = 0; j < n; ++j) 686 link = link->next; 687 688 g_queue_unlink (q, link); 689 check_integrity (q); 690 691 g_list_free (link); 692 693 qinf->head = q->head; 694 qinf->tail = q->tail; 695 qinf->length--; 696 } 697 break; 698 case DELETE_LINK: 699 if (!g_queue_is_empty (q)) 700 { 701 gint n = g_random_int_range (0, g_queue_get_length (q)); 702 GList *link; 703 704 link = q->head; 705 for (j = 0; j < n; ++j) 706 link = link->next; 707 708 g_queue_delete_link (q, link); 709 check_integrity (q); 710 711 qinf->head = q->head; 712 qinf->tail = q->tail; 713 qinf->length--; 714 } 715 break; 716 case LAST_OP: 717 default: 718 g_assert_not_reached(); 719 break; 720 } 721 722 if (qinf->head != q->head || 723 qinf->tail != q->tail || 724 qinf->length != q->length) 725 g_print ("op: %d\n", op); 726 727 g_assert (qinf->head == q->head); 728 g_assert (qinf->tail == q->tail); 729 g_assert (qinf->length == q->length); 730 731 for (j = 0; j < N_QUEUES; ++j) 732 check_integrity (queues[j].queue); 733 } 734 735 for (i = 0; i < N_QUEUES; ++i) 736 g_queue_free (queues[i].queue); 737 } 738 739 static void 740 remove_item (gpointer data, gpointer q) 741 { 742 GQueue *queue = q; 743 744 g_queue_remove (queue, data); 745 } 746 747 int main(int argc, gchar *args[]) 748 { 749 GQueue *q, *q2; 750 GList *node; 751 gpointer data; 752 int i; 753 754 if (argc > 1 && args[1][0] == '-' && args[1][1] == 'v') 755 verbose = TRUE; 756 757 q = g_queue_new (); 758 759 g_assert (g_queue_is_empty (q) == TRUE); 760 761 g_queue_push_head (q, GINT_TO_POINTER (2)); 762 check_integrity (q); 763 g_assert (g_queue_peek_head (q) == GINT_TO_POINTER (2)); 764 check_integrity (q); 765 g_assert (g_queue_is_empty (q) == FALSE); 766 check_integrity (q); 767 g_assert (g_list_length (q->head) == 1); 768 g_assert (q->head == q->tail); 769 g_queue_push_head (q, GINT_TO_POINTER (1)); 770 check_integrity (q); 771 g_assert (q->head->next == q->tail); 772 g_assert (q->tail->prev == q->head); 773 g_assert (g_list_length (q->head) == 2); 774 check_integrity (q); 775 g_assert (q->tail->data == GINT_TO_POINTER (2)); 776 g_assert (q->head->data == GINT_TO_POINTER (1)); 777 check_integrity (q); 778 g_queue_push_tail (q, GINT_TO_POINTER (3)); 779 g_assert (g_list_length (q->head) == 3); 780 g_assert (q->head->data == GINT_TO_POINTER (1)); 781 g_assert (q->head->next->data == GINT_TO_POINTER (2)); 782 g_assert (q->head->next->next == q->tail); 783 g_assert (q->head->next == q->tail->prev); 784 g_assert (q->tail->data == GINT_TO_POINTER (3)); 785 g_queue_push_tail (q, GINT_TO_POINTER (4)); 786 check_integrity (q); 787 g_assert (g_list_length (q->head) == 4); 788 g_assert (q->head->data == GINT_TO_POINTER (1)); 789 g_assert (g_queue_peek_tail (q) == GINT_TO_POINTER (4)); 790 g_queue_push_tail (q, GINT_TO_POINTER (5)); 791 check_integrity (q); 792 g_assert (g_list_length (q->head) == 5); 793 794 g_assert (g_queue_is_empty (q) == FALSE); 795 check_integrity (q); 796 797 g_assert (q->length == 5); 798 g_assert (q->head->prev == NULL); 799 g_assert (q->head->data == GINT_TO_POINTER (1)); 800 g_assert (q->head->next->data == GINT_TO_POINTER (2)); 801 g_assert (q->head->next->next->data == GINT_TO_POINTER (3)); 802 g_assert (q->head->next->next->next->data == GINT_TO_POINTER (4)); 803 g_assert (q->head->next->next->next->next->data == GINT_TO_POINTER (5)); 804 g_assert (q->head->next->next->next->next->next == NULL); 805 g_assert (q->head->next->next->next->next == q->tail); 806 g_assert (q->tail->data == GINT_TO_POINTER (5)); 807 g_assert (q->tail->prev->data == GINT_TO_POINTER (4)); 808 g_assert (q->tail->prev->prev->data == GINT_TO_POINTER (3)); 809 g_assert (q->tail->prev->prev->prev->data == GINT_TO_POINTER (2)); 810 g_assert (q->tail->prev->prev->prev->prev->data == GINT_TO_POINTER (1)); 811 g_assert (q->tail->prev->prev->prev->prev->prev == NULL); 812 g_assert (q->tail->prev->prev->prev->prev == q->head); 813 g_assert (g_queue_peek_tail (q) == GINT_TO_POINTER (5)); 814 g_assert (g_queue_peek_head (q) == GINT_TO_POINTER (1)); 815 816 g_assert (g_queue_pop_head (q) == GINT_TO_POINTER (1)); 817 check_integrity (q); 818 g_assert (g_list_length (q->head) == 4 && q->length == 4); 819 g_assert (g_queue_pop_tail (q) == GINT_TO_POINTER (5)); 820 check_integrity (q); 821 g_assert (g_list_length (q->head) == 3); 822 g_assert (g_queue_pop_head_link (q)->data == GINT_TO_POINTER (2)); 823 check_integrity (q); 824 g_assert (g_list_length (q->head) == 2); 825 g_assert (g_queue_pop_tail (q) == GINT_TO_POINTER (4)); 826 check_integrity (q); 827 g_assert (g_list_length (q->head) == 1); 828 g_assert (g_queue_pop_head_link (q)->data == GINT_TO_POINTER (3)); 829 check_integrity (q); 830 g_assert (g_list_length (q->head) == 0); 831 g_assert (g_queue_pop_tail (q) == NULL); 832 check_integrity (q); 833 g_assert (g_list_length (q->head) == 0); 834 g_assert (g_queue_pop_head (q) == NULL); 835 check_integrity (q); 836 g_assert (g_list_length (q->head) == 0); 837 838 g_assert (g_queue_is_empty (q) == TRUE); 839 check_integrity (q); 840 841 /************************/ 842 843 g_queue_push_head (q, GINT_TO_POINTER (1)); 844 check_integrity (q); 845 g_assert (g_list_length (q->head) == 1 && 1 == q->length); 846 g_queue_push_head (q, GINT_TO_POINTER (2)); 847 check_integrity (q); 848 g_assert (g_list_length (q->head) == 2 && 2 == q->length); 849 g_queue_push_head (q, GINT_TO_POINTER (3)); 850 check_integrity (q); 851 g_assert (g_list_length (q->head) == 3 && 3 == q->length); 852 g_queue_push_head (q, GINT_TO_POINTER (4)); 853 check_integrity (q); 854 g_assert (g_list_length (q->head) == 4 && 4 == q->length); 855 g_queue_push_head (q, GINT_TO_POINTER (5)); 856 check_integrity (q); 857 g_assert (g_list_length (q->head) == 5 && 5 == q->length); 858 859 g_assert (g_queue_pop_head (q) == GINT_TO_POINTER (5)); 860 check_integrity (q); 861 g_assert (g_list_length (q->head) == 4); 862 node = q->tail; 863 g_assert (node == g_queue_pop_tail_link (q)); 864 check_integrity (q); 865 g_assert (g_list_length (q->head) == 3); 866 data = q->head->data; 867 g_assert (data == g_queue_pop_head (q)); 868 check_integrity (q); 869 g_assert (g_list_length (q->head) == 2); 870 g_assert (g_queue_pop_tail (q) == GINT_TO_POINTER (2)); 871 check_integrity (q); 872 g_assert (g_list_length (q->head) == 1); 873 g_assert (q->head == q->tail); 874 g_assert (g_queue_pop_tail (q) == GINT_TO_POINTER (3)); 875 check_integrity (q); 876 g_assert (g_list_length (q->head) == 0); 877 g_assert (g_queue_pop_head (q) == NULL); 878 check_integrity (q); 879 g_assert (g_queue_pop_head_link (q) == NULL); 880 check_integrity (q); 881 g_assert (g_list_length (q->head) == 0); 882 g_assert (g_queue_pop_tail_link (q) == NULL); 883 check_integrity (q); 884 g_assert (g_list_length (q->head) == 0); 885 886 /* */ 887 g_queue_reverse (q); 888 check_integrity (q); 889 g_assert (g_list_length (q->head) == 0); 890 891 q2 = g_queue_copy (q); 892 check_integrity (q); 893 check_integrity (q2); 894 g_assert (g_list_length (q->head) == 0); 895 g_assert (g_list_length (q2->head) == 0); 896 g_queue_sort (q, compare_int, NULL); 897 check_integrity (q2); 898 check_integrity (q); 899 g_queue_sort (q2, compare_int, NULL); 900 check_integrity (q2); 901 check_integrity (q); 902 903 for (i = 0; i < 200; ++i) 904 { 905 g_queue_push_nth (q, GINT_TO_POINTER (i), i); 906 g_assert (g_queue_find (q, GINT_TO_POINTER (i))); 907 check_integrity (q); 908 check_integrity (q2); 909 } 910 911 for (i = 0; i < 200; ++i) 912 { 913 g_queue_remove (q, GINT_TO_POINTER (i)); 914 check_integrity (q); 915 check_integrity (q2); 916 } 917 918 for (i = 0; i < 200; ++i) 919 { 920 GList *l = g_list_prepend (NULL, GINT_TO_POINTER (i)); 921 922 g_queue_push_nth_link (q, i, l); 923 check_integrity (q); 924 check_integrity (q2); 925 g_queue_reverse (q); 926 check_integrity (q); 927 check_integrity (q2); 928 } 929 930 g_queue_free (q2); 931 q2 = g_queue_copy (q); 932 933 g_queue_foreach (q2, remove_item, q2); 934 check_integrity (q2); 935 check_integrity (q); 936 937 /* some checks for off by one errors */ 938 g_queue_push_tail (q, GINT_TO_POINTER (1234)); 939 check_integrity (q); 940 node = g_queue_peek_tail_link (q); 941 g_assert (node != NULL && node->data == GINT_TO_POINTER (1234)); 942 node = g_queue_peek_nth_link (q, g_queue_get_length (q)); 943 g_assert (node == NULL); 944 node = g_queue_peek_nth_link (q, g_queue_get_length (q) - 1); 945 g_assert (node->data == GINT_TO_POINTER (1234)); 946 node = g_queue_pop_nth_link (q, g_queue_get_length (q)); 947 g_assert (node == NULL); 948 node = g_queue_pop_nth_link (q, g_queue_get_length (q) - 1); 949 g_assert (node != NULL && node->data == GINT_TO_POINTER (1234)); 950 951 g_queue_free (q); 952 953 if (argc > 2 && args[1][0] == '-' && args[1][1] == 'v') 954 random_test (strtol (args[2], NULL, 0)); 955 if (argc > 1) 956 random_test (strtol (args[1], NULL, 0)); 957 else 958 random_test (time (0)); 959 960 return 0; 961 } 962 963