Skip to content

Commit

Permalink
Add range + iterator overload for timmerge
Browse files Browse the repository at this point in the history
Range overload supports temporaries.
Also change a missed std::less<> into std::ranges::less.
  • Loading branch information
Morwenn committed Jan 17, 2024
1 parent a141e03 commit d3ab5e1
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 1 deletion.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ template <
requires std::sortable<Iterator, Compare, Projection>
void timmerge(Iterator first, Iterator middle, Iterator last,
Compare compare={}, Projection projection={});

template <
std::ranges::random_access_range Range,
typename Compare = std::ranges::less,
typename Projection = std::identity
>
requires std::sortable<std::ranges::iterator_t<Range>, Compare, Projection>
void timmerge(Range &&range, std::ranges::iterator_t<Range> middle,
Compare compare={}, Projection projection={})
```
## EXAMPLE
Expand Down
18 changes: 17 additions & 1 deletion include/gfx/timsort.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,7 @@ template <typename RandomAccessIterator, typename Compare, typename Projection>
*/
template <
std::random_access_iterator Iterator,
typename Compare = std::less<>,
typename Compare = std::ranges::less,
typename Projection = std::identity
>
requires std::sortable<Iterator, Compare, Projection>
Expand All @@ -707,6 +707,22 @@ void timmerge(Iterator first, Iterator middle, Iterator last,
GFX_TIMSORT_AUDIT(std::is_sorted(first, last, comp, proj) && "Postcondition");
}

/**
* Stably merges two sorted halves [first, middle) and [middle, last) of a range into one
* sorted range [first, last) with a comparison function and a projection function.
*/
template <
std::ranges::random_access_range Range,
typename Compare = std::ranges::less,
typename Projection = std::identity
>
requires std::sortable<std::ranges::iterator_t<Range>, Compare, Projection>
void timmerge(Range &&range, std::ranges::iterator_t<Range> middle,
Compare comp={}, Projection proj={})
{
gfx::timmerge(std::begin(range), middle, std::end(range), comp, proj);
}

/**
* Stably sorts a range with a comparison function and a projection function.
*/
Expand Down
14 changes: 14 additions & 0 deletions tests/cxx_20_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,20 @@
#include "test_helpers.hpp"

TEST_CASE( "support for temporary types" ) {
SECTION( "timsmerge over std::span" ) {
std::vector<int> vec(100);
std::iota(vec.begin(), vec.end(), -25);
test_helpers::shuffle(vec);

auto middle = vec.begin() + 38;
gfx::timsort(vec.begin(), middle);
gfx::timsort(middle, vec.end());

auto view = std::span(vec);
gfx::timmerge(std::span(vec), view.begin() + 38);
CHECK(std::ranges::is_sorted(vec));
}

SECTION( "timsort over std::span" ) {
std::vector<int> vec(50);
std::iota(vec.begin(), vec.end(), -25);
Expand Down

0 comments on commit d3ab5e1

Please sign in to comment.