Skip to content

Commit

Permalink
Fix std::views::zip support (issue #40)
Browse files Browse the repository at this point in the history
  • Loading branch information
Morwenn committed Nov 28, 2024
1 parent 929f8e7 commit f8bc0db
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 5 deletions.
9 changes: 4 additions & 5 deletions include/gfx/timsort.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,13 @@ struct run {
template <typename RandomAccessIterator>
class TimSort {
using iter_t = RandomAccessIterator;
using value_t = typename std::iterator_traits<iter_t>::value_type;
using diff_t = typename std::iterator_traits<iter_t>::difference_type;
using diff_t = std::iter_difference_t<iter_t>;

static constexpr int MIN_MERGE = 32;
static constexpr int MIN_GALLOP = 7;

int minGallop_ = MIN_GALLOP;
std::vector<value_t> tmp_; // temp storage for merges
std::vector<std::iter_value_t<iter_t>> tmp_; // temp storage for merges
std::vector<run<RandomAccessIterator>> pending_;

template <typename Compare, typename Projection>
Expand Down Expand Up @@ -344,14 +343,14 @@ class TimSort {
}

static void rotateLeft(iter_t first, iter_t last) {
auto tmp = std::ranges::iter_move(first);
std::iter_value_t<iter_t> tmp = std::ranges::iter_move(first);
auto [_, last_1] = std::ranges::move(std::ranges::next(first), last, first);
*last_1 = std::move(tmp);
}

static void rotateRight(iter_t first, iter_t last) {
auto last_1 = std::ranges::prev(last);
auto tmp = std::ranges::iter_move(last_1);
std::iter_value_t<iter_t> tmp = std::ranges::iter_move(last_1);
std::ranges::move_backward(first, last_1, last);
*first = std::move(tmp);
}
Expand Down
9 changes: 9 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,14 @@ add_executable(cxx_20_tests
configure_tests(cxx_20_tests)
target_compile_features(cxx_20_tests PRIVATE cxx_std_20)

# Tests requiring C++23 support
add_executable(cxx_23_tests
cxx_23_tests.cpp
verbose_abort.cpp
)
configure_tests(cxx_23_tests)
target_compile_features(cxx_23_tests PRIVATE cxx_std_23)

# Windows-specific tests
if (WIN32)
add_executable(windows_tests
Expand All @@ -135,6 +143,7 @@ catch_discover_tests(cxx_98_tests EXTRA_ARGS --rng-seed ${RNG_SEED})
catch_discover_tests(cxx_11_tests EXTRA_ARGS --rng-seed ${RNG_SEED})
catch_discover_tests(cxx_17_tests EXTRA_ARGS --rng-seed ${RNG_SEED})
catch_discover_tests(cxx_20_tests EXTRA_ARGS --rng-seed ${RNG_SEED})
catch_discover_tests(cxx_23_tests EXTRA_ARGS --rng-seed ${RNG_SEED})
if (WIN32)
catch_discover_tests(windows_tests EXTRA_ARGS --rng-seed ${RNG_SEED})
endif()
47 changes: 47 additions & 0 deletions tests/cxx_23_tests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2024 Morwenn.
* SPDX-License-Identifier: MIT
*/
#include <array>
#include <deque>
#include <iterator>
#include <numeric>
#include <ranges>
#include <vector>
#include <catch2/catch_test_macros.hpp>
#include <gfx/timsort.hpp>
#include "test_helpers.hpp"

TEST_CASE( "support for std::ranges::views::zip" )
{
SECTION( "zip two small collections" ) {
// issue #40
std::vector<int> vec = {4, 2, 3, 1};
std::array<char, 4> arr = {'A', 'C', 'B', 'D'};
auto zipped = std::views::zip(vec, arr);

gfx::timsort(
zipped, {},
[](std::tuple<int&, char&> const& pair) {
return std::get<0>(pair);
}
);
CHECK( std::ranges::is_sorted(vec) );
CHECK( std::ranges::is_sorted(arr, std::ranges::greater{}) );
}

SECTION( "zip two big collections" ) {
std::vector<int> vec(3000);
std::deque<long long int> deq(3000);
std::iota(vec.begin(), vec.end(), -500);
std::ranges::reverse(vec);
std::iota(deq.begin(), deq.end(), -500);

auto zipped = std::views::zip(vec, deq);
test_helpers::shuffle(zipped);

gfx::timsort(zipped);
CHECK( std::ranges::is_sorted(vec) );
CHECK( std::ranges::is_sorted(deq, std::ranges::greater{}) );
}
}

0 comments on commit f8bc0db

Please sign in to comment.