Skip to content

Commit bfca750

Browse files
committed
Make control flow clearer with goto
1 parent 91d35c9 commit bfca750

File tree

1 file changed

+18
-41
lines changed

1 file changed

+18
-41
lines changed

include/gfx/timsort.hpp

Lines changed: 18 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,6 @@ template <typename RandomAccessIterator, typename LessFunction> class TimSort {
457457
diff_t count1 = 0;
458458
diff_t count2 = 0;
459459

460-
bool break_outer = false;
461460
do {
462461
GFX_TIMSORT_ASSERT(len1 > 1 && len2 > 0);
463462

@@ -466,22 +465,17 @@ template <typename RandomAccessIterator, typename LessFunction> class TimSort {
466465
++count2;
467466
count1 = 0;
468467
if (--len2 == 0) {
469-
break_outer = true;
470-
break;
468+
goto epilogue;
471469
}
472470
} else {
473471
*(dest++) = GFX_TIMSORT_MOVE(*(cursor1++));
474472
++count1;
475473
count2 = 0;
476474
if (--len1 == 1) {
477-
break_outer = true;
478-
break;
475+
goto epilogue;
479476
}
480477
}
481478
} while ((count1 | count2) < minGallop);
482-
if (break_outer) {
483-
break;
484-
}
485479

486480
do {
487481
GFX_TIMSORT_ASSERT(len1 > 1 && len2 > 0);
@@ -494,14 +488,12 @@ template <typename RandomAccessIterator, typename LessFunction> class TimSort {
494488
len1 -= count1;
495489

496490
if (len1 <= 1) {
497-
break_outer = true;
498-
break;
491+
goto epilogue;
499492
}
500493
}
501494
*(dest++) = GFX_TIMSORT_MOVE(*(cursor2++));
502495
if (--len2 == 0) {
503-
break_outer = true;
504-
break;
496+
goto epilogue;
505497
}
506498

507499
count2 = gallopLeft(*cursor1, cursor2, len2, 0);
@@ -511,28 +503,25 @@ template <typename RandomAccessIterator, typename LessFunction> class TimSort {
511503
cursor2 += count2;
512504
len2 -= count2;
513505
if (len2 == 0) {
514-
break_outer = true;
515-
break;
506+
goto epilogue;
516507
}
517508
}
518509
*(dest++) = GFX_TIMSORT_MOVE(*(cursor1++));
519510
if (--len1 == 1) {
520-
break_outer = true;
521-
break;
511+
goto epilogue;
522512
}
523513

524514
--minGallop;
525515
} while ((count1 >= MIN_GALLOP) | (count2 >= MIN_GALLOP));
526-
if (break_outer) {
527-
break;
528-
}
529516

530517
if (minGallop < 0) {
531518
minGallop = 0;
532519
}
533520
minGallop += 2;
534521
} // end of "outer" loop
535522

523+
epilogue: // merge what is left from either cursor1 or cursor2
524+
536525
minGallop_ = std::min(minGallop, 1);
537526

538527
if (len1 == 1) {
@@ -582,7 +571,6 @@ template <typename RandomAccessIterator, typename LessFunction> class TimSort {
582571
// sure that it points to the next value again by the end of said loop
583572
--cursor1;
584573

585-
bool break_outer = false;
586574
do {
587575
GFX_TIMSORT_ASSERT(len1 > 0 && len2 > 1);
588576

@@ -591,26 +579,20 @@ template <typename RandomAccessIterator, typename LessFunction> class TimSort {
591579
++count1;
592580
count2 = 0;
593581
if (--len1 == 0) {
594-
break_outer = true;
595-
break;
582+
goto epilogue;
596583
}
597584
--cursor1;
598585
} else {
599586
*(dest--) = GFX_TIMSORT_MOVE(*(cursor2--));
600587
++count2;
601588
count1 = 0;
602589
if (--len2 == 1) {
603-
++cursor1;
604-
break_outer = true;
605-
break;
590+
++cursor1; // See comment before the loop
591+
goto epilogue;
606592
}
607593
}
608594
} while ((count1 | count2) < minGallop);
609-
if (break_outer) {
610-
break;
611-
} else {
612-
++cursor1; // See comment before the loop
613-
}
595+
++cursor1; // See comment before the loop
614596

615597
do {
616598
GFX_TIMSORT_ASSERT(len1 > 0 && len2 > 1);
@@ -623,14 +605,12 @@ template <typename RandomAccessIterator, typename LessFunction> class TimSort {
623605
GFX_TIMSORT_MOVE_BACKWARD(cursor1, cursor1 + count1, dest + (1 + count1));
624606

625607
if (len1 == 0) {
626-
break_outer = true;
627-
break;
608+
goto epilogue;
628609
}
629610
}
630611
*(dest--) = GFX_TIMSORT_MOVE(*(cursor2--));
631612
if (--len2 == 1) {
632-
break_outer = true;
633-
break;
613+
goto epilogue;
634614
}
635615

636616
count2 = len2 - gallopLeft(*(cursor1 - 1), tmp_.begin(), len2, len2 - 1);
@@ -640,28 +620,25 @@ template <typename RandomAccessIterator, typename LessFunction> class TimSort {
640620
len2 -= count2;
641621
GFX_TIMSORT_MOVE_RANGE(cursor2 + 1, cursor2 + (1 + count2), dest + 1);
642622
if (len2 <= 1) {
643-
break_outer = true;
644-
break;
623+
goto epilogue;
645624
}
646625
}
647626
*(dest--) = GFX_TIMSORT_MOVE(*(--cursor1));
648627
if (--len1 == 0) {
649-
break_outer = true;
650-
break;
628+
goto epilogue;
651629
}
652630

653631
minGallop--;
654632
} while ((count1 >= MIN_GALLOP) | (count2 >= MIN_GALLOP));
655-
if (break_outer) {
656-
break;
657-
}
658633

659634
if (minGallop < 0) {
660635
minGallop = 0;
661636
}
662637
minGallop += 2;
663638
} // end of "outer" loop
664639

640+
epilogue: // merge what is left from either cursor1 or cursor2
641+
665642
minGallop_ = std::min(minGallop, 1);
666643

667644
if (len2 == 1) {

0 commit comments

Comments
 (0)