Skip to content

Commit f1268e6

Browse files
committed
Support for proxy iterators
1 parent e108d6f commit f1268e6

File tree

2 files changed

+56
-57
lines changed

2 files changed

+56
-57
lines changed

include/gfx/timsort.hpp

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,11 @@ class TimSort {
114114
}
115115
for (; start < hi; ++start) {
116116
GFX_TIMSORT_ASSERT(lo <= start);
117-
value_t pivot = std::move(*start);
117+
auto pivot = std::ranges::iter_move(start);
118118

119119
auto pos = std::ranges::upper_bound(lo, start, std::invoke(proj, pivot), comp, proj);
120120
for (iter_t p = start; p > pos; --p) {
121-
*p = std::move(*(p - 1));
121+
*p = std::ranges::iter_move(p - 1);
122122
}
123123
*pos = std::move(pivot);
124124
}
@@ -139,7 +139,7 @@ class TimSort {
139139
} while (runHi < hi && std::invoke(comp,
140140
std::invoke(proj, *runHi),
141141
std::invoke(proj, *(runHi - 1))));
142-
std::reverse(lo, runHi);
142+
std::ranges::reverse(lo, runHi);
143143
} else { // non-decreasing
144144
do {
145145
++runHi;
@@ -355,15 +355,15 @@ class TimSort {
355355
}
356356

357357
static void rotateLeft(iter_t first, iter_t last) {
358-
value_t tmp = std::move(*first);
359-
iter_t last_1 = std::move(first + 1, last, first);
358+
auto tmp = std::ranges::iter_move(first);
359+
auto [_, last_1] = std::ranges::move(first + 1, last, first);
360360
*last_1 = std::move(tmp);
361361
}
362362

363363
static void rotateRight(iter_t first, iter_t last) {
364-
iter_t last_1 = last - 1;
365-
value_t tmp = std::move(*last_1);
366-
std::move_backward(first, last_1, last);
364+
auto last_1 = last - 1;
365+
auto tmp = std::ranges::iter_move(last_1);
366+
std::ranges::move_backward(first, last_1, last);
367367
*first = std::move(tmp);
368368
}
369369

@@ -386,7 +386,7 @@ class TimSort {
386386
iter_t cursor2 = base2;
387387
iter_t dest = base1;
388388

389-
*dest = std::move(*cursor2);
389+
*dest = std::ranges::iter_move(cursor2);
390390
++cursor2;
391391
++dest;
392392
--len2;
@@ -403,7 +403,7 @@ class TimSort {
403403
GFX_TIMSORT_ASSERT(len2 > 0);
404404

405405
if (std::invoke(comp, std::invoke(proj, *cursor2), std::invoke(proj, *cursor1))) {
406-
*dest = std::move(*cursor2);
406+
*dest = std::ranges::iter_move(cursor2);
407407
++cursor2;
408408
++dest;
409409
++count2;
@@ -412,7 +412,7 @@ class TimSort {
412412
goto epilogue;
413413
}
414414
} else {
415-
*dest = std::move(*cursor1);
415+
*dest = std::ranges::iter_move(cursor1);
416416
++cursor1;
417417
++dest;
418418
++count1;
@@ -429,7 +429,7 @@ class TimSort {
429429

430430
count1 = gallopRight(std::invoke(proj, *cursor2), cursor1, len1, 0, comp, proj);
431431
if (count1 != 0) {
432-
std::move_backward(cursor1, cursor1 + count1, dest + count1);
432+
std::ranges::move_backward(cursor1, cursor1 + count1, dest + count1);
433433
dest += count1;
434434
cursor1 += count1;
435435
len1 -= count1;
@@ -438,7 +438,7 @@ class TimSort {
438438
goto epilogue;
439439
}
440440
}
441-
*dest = std::move(*cursor2);
441+
*dest = std::ranges::iter_move(cursor2);
442442
++cursor2;
443443
++dest;
444444
if (--len2 == 0) {
@@ -447,15 +447,15 @@ class TimSort {
447447

448448
count2 = gallopLeft(std::invoke(proj, *cursor1), cursor2, len2, 0, comp, proj);
449449
if (count2 != 0) {
450-
std::move(cursor2, cursor2 + count2, dest);
450+
std::ranges::move(cursor2, cursor2 + count2, dest);
451451
dest += count2;
452452
cursor2 += count2;
453453
len2 -= count2;
454454
if (len2 == 0) {
455455
goto epilogue;
456456
}
457457
}
458-
*dest = std::move(*cursor1);
458+
*dest = std::ranges::iter_move(cursor1);
459459
++cursor1;
460460
++dest;
461461
if (--len1 == 1) {
@@ -477,13 +477,13 @@ class TimSort {
477477

478478
if (len1 == 1) {
479479
GFX_TIMSORT_ASSERT(len2 > 0);
480-
std::move(cursor2, cursor2 + len2, dest);
481-
*(dest + len2) = std::move(*cursor1);
480+
std::ranges::move(cursor2, cursor2 + len2, dest);
481+
*(dest + len2) = std::ranges::iter_move(cursor1);
482482
} else {
483483
GFX_TIMSORT_ASSERT(len1 != 0 && "Comparison function violates its general contract");
484484
GFX_TIMSORT_ASSERT(len2 == 0);
485485
GFX_TIMSORT_ASSERT(len1 > 1);
486-
std::move(cursor1, cursor1 + len1, dest);
486+
std::ranges::move(cursor1, cursor1 + len1, dest);
487487
}
488488
}
489489

@@ -506,7 +506,7 @@ class TimSort {
506506
tmp_iter_t cursor2 = tmp_.begin() + (len2 - 1);
507507
iter_t dest = base2 + (len2 - 1);
508508

509-
*dest = std::move(*(--cursor1));
509+
*dest = std::ranges::iter_move(--cursor1);
510510
--dest;
511511
--len1;
512512

@@ -528,7 +528,7 @@ class TimSort {
528528
GFX_TIMSORT_ASSERT(len2 > 1);
529529

530530
if (std::invoke(comp, std::invoke(proj, *cursor2), std::invoke(proj, *cursor1))) {
531-
*dest = std::move(*cursor1);
531+
*dest = std::ranges::iter_move(cursor1);
532532
--dest;
533533
++count1;
534534
count2 = 0;
@@ -537,7 +537,7 @@ class TimSort {
537537
}
538538
--cursor1;
539539
} else {
540-
*dest = std::move(*cursor2);
540+
*dest = std::ranges::iter_move(cursor2);
541541
--cursor2;
542542
--dest;
543543
++count2;
@@ -560,13 +560,13 @@ class TimSort {
560560
dest -= count1;
561561
cursor1 -= count1;
562562
len1 -= count1;
563-
std::move_backward(cursor1, cursor1 + count1, dest + (1 + count1));
563+
std::ranges::move_backward(cursor1, cursor1 + count1, dest + (1 + count1));
564564

565565
if (len1 == 0) {
566566
goto epilogue;
567567
}
568568
}
569-
*dest = std::move(*cursor2);
569+
*dest = std::ranges::iter_move(cursor2);
570570
--cursor2;
571571
--dest;
572572
if (--len2 == 1) {
@@ -579,12 +579,12 @@ class TimSort {
579579
dest -= count2;
580580
cursor2 -= count2;
581581
len2 -= count2;
582-
std::move(cursor2 + 1, cursor2 + (1 + count2), dest + 1);
582+
std::ranges::move(cursor2 + 1, cursor2 + (1 + count2), dest + 1);
583583
if (len2 <= 1) {
584584
goto epilogue;
585585
}
586586
}
587-
*dest = std::move(*(--cursor1));
587+
*dest = std::ranges::iter_move(--cursor1);
588588
--dest;
589589
if (--len1 == 0) {
590590
goto epilogue;
@@ -606,13 +606,13 @@ class TimSort {
606606
if (len2 == 1) {
607607
GFX_TIMSORT_ASSERT(len1 > 0);
608608
dest -= len1;
609-
std::move_backward(cursor1 - len1, cursor1, dest + (1 + len1));
610-
*dest = std::move(*cursor2);
609+
std::ranges::move_backward(cursor1 - len1, cursor1, dest + (1 + len1));
610+
*dest = std::ranges::iter_move(cursor2);
611611
} else {
612612
GFX_TIMSORT_ASSERT(len2 != 0 && "Comparison function violates its general contract");
613613
GFX_TIMSORT_ASSERT(len1 == 0);
614614
GFX_TIMSORT_ASSERT(len2 > 1);
615-
std::move(tmp_.begin(), tmp_.begin() + len2, dest - (len2 - 1));
615+
std::ranges::move(tmp_.begin(), tmp_.begin() + len2, dest - (len2 - 1));
616616
}
617617
}
618618

tests/cxx_20_tests.cpp

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@
1414
#include "test_helpers.hpp"
1515

1616
TEST_CASE( "support for temporary types" ) {
17+
SECTION( "timsort over std::span" ) {
18+
std::vector<int> vec(50);
19+
std::iota(vec.begin(), vec.end(), -25);
20+
test_helpers::shuffle(vec);
21+
22+
auto last_it = gfx::timsort(std::span(vec));
23+
CHECK(std::ranges::is_sorted(vec));
24+
CHECK(last_it == std::span(vec).end());
25+
}
26+
1727
SECTION( "timmerge over std::span" ) {
1828
std::vector<int> vec(100);
1929
std::iota(vec.begin(), vec.end(), -25);
@@ -28,58 +38,47 @@ TEST_CASE( "support for temporary types" ) {
2838
CHECK(std::ranges::is_sorted(vec));
2939
CHECK(last_it == view.end());
3040
}
31-
32-
SECTION( "timsort over std::span" ) {
33-
std::vector<int> vec(50);
34-
std::iota(vec.begin(), vec.end(), -25);
35-
test_helpers::shuffle(vec);
36-
37-
auto last_it = gfx::timsort(std::span(vec));
38-
CHECK(std::ranges::is_sorted(vec));
39-
CHECK(last_it == std::span(vec).end());
40-
}
4141
}
4242

4343
TEST_CASE( "dangling return type" ) {
44-
SECTION( "timmerge over temporary std::vector" ) {
45-
std::vector<int> vec(30, 5);
46-
auto last_it = gfx::timmerge(std::move(vec), vec.begin() + 14);
47-
STATIC_CHECK(std::is_same_v<decltype(last_it), std::ranges::dangling>);
48-
}
49-
5044
SECTION( "timsort over temporary std::vector" ) {
5145
std::vector<int> vec(50, 8);
5246
auto last_it = gfx::timsort(std::move(vec));
5347
STATIC_CHECK(std::is_same_v<decltype(last_it), std::ranges::dangling>);
5448
}
49+
50+
SECTION( "timmerge over temporary std::vector" ) {
51+
std::vector<int> vec(30, 5);
52+
auto last_it = gfx::timmerge(std::move(vec), vec.begin() + 14);
53+
STATIC_CHECK(std::is_same_v<decltype(last_it), std::ranges::dangling>);
54+
}
5555
}
5656

57-
TEST_CASE( "support for sentinels" )
58-
{
59-
SECTION( "timmerge with sentinel" ) {
57+
TEST_CASE( "support for sentinels" ) {
58+
SECTION( "timsort with sentinel" ) {
6059
std::vector<int> vec(100);
6160
std::iota(vec.begin(), vec.end(), -25);
6261
test_helpers::shuffle(vec);
6362

64-
auto middle = vec.begin() + 38;
65-
gfx::timsort(vec.begin(), middle);
66-
gfx::timsort(middle, vec.end());
67-
68-
auto last_it = gfx::timmerge(std::counted_iterator(vec.begin(), 85),
69-
std::counted_iterator(middle, 85 - 38),
70-
std::default_sentinel);
63+
auto last_it = gfx::timsort(std::counted_iterator(vec.begin(), 85),
64+
std::default_sentinel);
7165
CHECK(std::is_sorted(vec.begin(), vec.begin() + 85));
7266
CHECK(last_it == std::counted_iterator(vec.begin() + 85, 0));
7367
CHECK(last_it == std::default_sentinel);
7468
}
7569

76-
SECTION( "timsort with sentinel" ) {
70+
SECTION( "timmerge with sentinel" ) {
7771
std::vector<int> vec(100);
7872
std::iota(vec.begin(), vec.end(), -25);
7973
test_helpers::shuffle(vec);
8074

81-
auto last_it = gfx::timsort(std::counted_iterator(vec.begin(), 85),
82-
std::default_sentinel);
75+
auto middle = vec.begin() + 38;
76+
gfx::timsort(vec.begin(), middle);
77+
gfx::timsort(middle, vec.end());
78+
79+
auto last_it = gfx::timmerge(std::counted_iterator(vec.begin(), 85),
80+
std::counted_iterator(middle, 85 - 38),
81+
std::default_sentinel);
8382
CHECK(std::is_sorted(vec.begin(), vec.begin() + 85));
8483
CHECK(last_it == std::counted_iterator(vec.begin() + 85, 0));
8584
CHECK(last_it == std::default_sentinel);

0 commit comments

Comments
 (0)