From f8bc0db4bbaa4c5a6f10e9481a218175e51f98ed Mon Sep 17 00:00:00 2001 From: Morwenn Date: Thu, 28 Nov 2024 22:42:39 +0100 Subject: [PATCH] Fix std::views::zip support (issue #40) --- include/gfx/timsort.hpp | 9 ++++---- tests/CMakeLists.txt | 9 ++++++++ tests/cxx_23_tests.cpp | 47 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 tests/cxx_23_tests.cpp diff --git a/include/gfx/timsort.hpp b/include/gfx/timsort.hpp index 9a51ebe..f7803a3 100644 --- a/include/gfx/timsort.hpp +++ b/include/gfx/timsort.hpp @@ -89,14 +89,13 @@ struct run { template class TimSort { using iter_t = RandomAccessIterator; - using value_t = typename std::iterator_traits::value_type; - using diff_t = typename std::iterator_traits::difference_type; + using diff_t = std::iter_difference_t; static constexpr int MIN_MERGE = 32; static constexpr int MIN_GALLOP = 7; int minGallop_ = MIN_GALLOP; - std::vector tmp_; // temp storage for merges + std::vector> tmp_; // temp storage for merges std::vector> pending_; template @@ -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 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 tmp = std::ranges::iter_move(last_1); std::ranges::move_backward(first, last_1, last); *first = std::move(tmp); } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6dab07c..babe326 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -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 @@ -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() diff --git a/tests/cxx_23_tests.cpp b/tests/cxx_23_tests.cpp new file mode 100644 index 0000000..b27562a --- /dev/null +++ b/tests/cxx_23_tests.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2024 Morwenn. + * SPDX-License-Identifier: MIT + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "test_helpers.hpp" + +TEST_CASE( "support for std::ranges::views::zip" ) +{ + SECTION( "zip two small collections" ) { + // issue #40 + std::vector vec = {4, 2, 3, 1}; + std::array arr = {'A', 'C', 'B', 'D'}; + auto zipped = std::views::zip(vec, arr); + + gfx::timsort( + zipped, {}, + [](std::tuple 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 vec(3000); + std::deque 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{}) ); + } +}