Skip to content

Commit 978afc1

Browse files
committed
Fix std::views::zip support (issue #40)
1 parent 929f8e7 commit 978afc1

File tree

3 files changed

+64
-5
lines changed

3 files changed

+64
-5
lines changed

include/gfx/timsort.hpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,13 @@ struct run {
8989
template <typename RandomAccessIterator>
9090
class TimSort {
9191
using iter_t = RandomAccessIterator;
92-
using value_t = typename std::iterator_traits<iter_t>::value_type;
93-
using diff_t = typename std::iterator_traits<iter_t>::difference_type;
92+
using diff_t = std::iter_difference_t<iter_t>;
9493

9594
static constexpr int MIN_MERGE = 32;
9695
static constexpr int MIN_GALLOP = 7;
9796

9897
int minGallop_ = MIN_GALLOP;
99-
std::vector<value_t> tmp_; // temp storage for merges
98+
std::vector<std::iter_value_t<iter_t>> tmp_; // temp storage for merges
10099
std::vector<run<RandomAccessIterator>> pending_;
101100

102101
template <typename Compare, typename Projection>
@@ -344,14 +343,14 @@ class TimSort {
344343
}
345344

346345
static void rotateLeft(iter_t first, iter_t last) {
347-
auto tmp = std::ranges::iter_move(first);
346+
std::iter_value_t<iter_t> tmp = std::ranges::iter_move(first);
348347
auto [_, last_1] = std::ranges::move(std::ranges::next(first), last, first);
349348
*last_1 = std::move(tmp);
350349
}
351350

352351
static void rotateRight(iter_t first, iter_t last) {
353352
auto last_1 = std::ranges::prev(last);
354-
auto tmp = std::ranges::iter_move(last_1);
353+
std::iter_value_t<iter_t> tmp = std::ranges::iter_move(last_1);
355354
std::ranges::move_backward(first, last_1, last);
356355
*first = std::move(tmp);
357356
}

tests/CMakeLists.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,16 @@ add_executable(cxx_20_tests
118118
configure_tests(cxx_20_tests)
119119
target_compile_features(cxx_20_tests PRIVATE cxx_std_20)
120120

121+
# Tests requiring C++23 support
122+
if ("cxx_std_23" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
123+
add_executable(cxx_23_tests
124+
cxx_23_tests.cpp
125+
verbose_abort.cpp
126+
)
127+
configure_tests(cxx_23_tests)
128+
target_compile_features(cxx_23_tests PRIVATE cxx_std_23)
129+
endif()
130+
121131
# Windows-specific tests
122132
if (WIN32)
123133
add_executable(windows_tests
@@ -135,6 +145,9 @@ catch_discover_tests(cxx_98_tests EXTRA_ARGS --rng-seed ${RNG_SEED})
135145
catch_discover_tests(cxx_11_tests EXTRA_ARGS --rng-seed ${RNG_SEED})
136146
catch_discover_tests(cxx_17_tests EXTRA_ARGS --rng-seed ${RNG_SEED})
137147
catch_discover_tests(cxx_20_tests EXTRA_ARGS --rng-seed ${RNG_SEED})
148+
if ("cxx_std_23" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
149+
catch_discover_tests(cxx_23_tests EXTRA_ARGS --rng-seed ${RNG_SEED})
150+
endif()
138151
if (WIN32)
139152
catch_discover_tests(windows_tests EXTRA_ARGS --rng-seed ${RNG_SEED})
140153
endif()

tests/cxx_23_tests.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright (c) 2024 Morwenn.
3+
* SPDX-License-Identifier: MIT
4+
*/
5+
#include <array>
6+
#include <deque>
7+
#include <iterator>
8+
#include <numeric>
9+
#include <ranges>
10+
#include <vector>
11+
#include <catch2/catch_test_macros.hpp>
12+
#include <gfx/timsort.hpp>
13+
#include "test_helpers.hpp"
14+
15+
TEST_CASE( "support for std::ranges::views::zip" )
16+
{
17+
SECTION( "zip two small collections" ) {
18+
// issue #40
19+
std::vector<int> vec = {4, 2, 3, 1};
20+
std::array<char, 4> arr = {'A', 'C', 'B', 'D'};
21+
auto zipped = std::views::zip(vec, arr);
22+
23+
gfx::timsort(
24+
zipped, {},
25+
[](std::tuple<int&, char&> const& pair) {
26+
return std::get<0>(pair);
27+
}
28+
);
29+
CHECK( std::ranges::is_sorted(vec) );
30+
CHECK( std::ranges::is_sorted(arr, std::ranges::greater{}) );
31+
}
32+
33+
SECTION( "zip two big collections" ) {
34+
std::vector<int> vec(3000);
35+
std::deque<long long int> deq(3000);
36+
std::iota(vec.begin(), vec.end(), -500);
37+
std::ranges::reverse(vec);
38+
std::iota(deq.begin(), deq.end(), -500);
39+
40+
auto zipped = std::views::zip(vec, deq);
41+
test_helpers::shuffle(zipped);
42+
43+
gfx::timsort(zipped);
44+
CHECK( std::ranges::is_sorted(vec) );
45+
CHECK( std::ranges::is_sorted(deq, std::ranges::greater{}) );
46+
}
47+
}

0 commit comments

Comments
 (0)