From 3235ec810c4101d3ddf217ca62149f67b6fcae65 Mon Sep 17 00:00:00 2001 From: Morwenn Date: Mon, 18 Apr 2022 21:35:28 +0200 Subject: [PATCH 01/51] Docs: sqrt/half/loh inherit from projection_base --- docs/Miscellaneous-utilities.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Miscellaneous-utilities.md b/docs/Miscellaneous-utilities.md index 5a4b1fae..d687b89c 100644 --- a/docs/Miscellaneous-utilities.md +++ b/docs/Miscellaneous-utilities.md @@ -159,7 +159,7 @@ This header also provides additional function objects implementing basic unary o * `log`: returns the base 10 logarithm of the passed value. * `sqrt`: returns the square root of the passed value. -All of those function objects can double as projections are are [*transparent function objects*][transparent-func]. +All of those function objects inherit from `projection_base` and are [*transparent function objects*][transparent-func]. Since C++17, the following utility is also available when some level of micro-optimization is needed: From 74c2ad4869cfa98cdc7497c7a9d38b2e60bddc1f Mon Sep 17 00:00:00 2001 From: Morwenn Date: Sun, 24 Apr 2022 14:43:34 +0200 Subject: [PATCH 02/51] Don't project key in gallopLeft/gallopRight It doesn't make much of a difference today, but not projecting the key in the functions makes them more flexible. This choice also makes them closer from the design of std::ranges::lower_bound and std::ranges::upper_bound. --- include/cpp-sort/detail/timsort.h | 37 ++++++++++++++----------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/include/cpp-sort/detail/timsort.h b/include/cpp-sort/detail/timsort.h index c761a9be..5cc25697 100644 --- a/include/cpp-sort/detail/timsort.h +++ b/include/cpp-sort/detail/timsort.h @@ -273,8 +273,9 @@ namespace detail CPPSORT_ASSERT(len1 > 0); CPPSORT_ASSERT(len2 > 0); CPPSORT_ASSERT(base1 + len1 == base2); + auto&& proj = utility::as_function(projection); - difference_type const k = gallopRight(*base2, base1, len1, 0, compare, projection); + difference_type const k = gallopRight(proj(*base2), base1, len1, 0, compare, projection); CPPSORT_ASSERT(k >= 0); base1 += k; @@ -284,7 +285,7 @@ namespace detail return; } - len2 = gallopLeft(base1[len1 - 1], base2, len2, len2 - 1, compare, projection); + len2 = gallopLeft(proj(base1[len1 - 1]), base2, len2, len2 - 1, compare, projection); CPPSORT_ASSERT(len2 >= 0); if (len2 == 0) { return; @@ -309,14 +310,13 @@ namespace detail auto&& comp = utility::as_function(compare); auto&& proj = utility::as_function(projection); - auto&& key_proj = proj(key); difference_type lastOfs = 0; difference_type ofs = 1; - if (comp(proj(base[hint]), key_proj)) { + if (comp(proj(base[hint]), key)) { difference_type const maxOfs = len - hint; - while (ofs < maxOfs && comp(proj(base[hint + ofs]), key_proj)) { + while (ofs < maxOfs && comp(proj(base[hint + ofs]), key)) { lastOfs = ofs; ofs = (ofs << 1) + 1; @@ -330,10 +330,9 @@ namespace detail lastOfs += hint; ofs += hint; - } - else { + } else { difference_type const maxOfs = hint + 1; - while (ofs < maxOfs && not comp(proj(base[hint - ofs]), key_proj)) { + while (ofs < maxOfs && not comp(proj(base[hint - ofs]), key)) { lastOfs = ofs; ofs = (ofs << 1) + 1; @@ -353,7 +352,7 @@ namespace detail CPPSORT_ASSERT(lastOfs < ofs); CPPSORT_ASSERT(ofs <= len); - return lower_bound(base+(lastOfs+1), base+ofs, key_proj, compare, projection) - base; + return lower_bound(base+(lastOfs+1), base+ofs, key, compare, projection) - base; } template @@ -367,14 +366,13 @@ namespace detail auto&& comp = utility::as_function(compare); auto&& proj = utility::as_function(projection); - auto&& key_proj = proj(key); difference_type ofs = 1; difference_type lastOfs = 0; - if (comp(key_proj, proj(base[hint]))) { + if (comp(key, proj(base[hint]))) { difference_type const maxOfs = hint + 1; - while (ofs < maxOfs && comp(key_proj, proj(base[hint - ofs]))) { + while (ofs < maxOfs && comp(key, proj(base[hint - ofs]))) { lastOfs = ofs; ofs = (ofs << 1) + 1; @@ -389,10 +387,9 @@ namespace detail difference_type const tmp = lastOfs; lastOfs = hint - ofs; ofs = hint - tmp; - } - else { + } else { difference_type const maxOfs = len - hint; - while (ofs < maxOfs && not comp(key_proj, proj(base[hint + ofs]))) { + while (ofs < maxOfs && not comp(key, proj(base[hint + ofs]))) { lastOfs = ofs; ofs = (ofs << 1) + 1; @@ -411,7 +408,7 @@ namespace detail CPPSORT_ASSERT(lastOfs < ofs); CPPSORT_ASSERT(ofs <= len); - return upper_bound(base+(lastOfs+1), base+ofs, key_proj, compare, projection) - base; + return upper_bound(base+(lastOfs+1), base+ofs, key, compare, projection) - base; } auto resize_buffer(std::ptrdiff_t new_size) @@ -509,7 +506,7 @@ namespace detail CPPSORT_ASSERT(len1 > 1); CPPSORT_ASSERT(len2 > 0); - count1 = gallopRight(*cursor2, cursor1, len1, 0, compare, projection); + count1 = gallopRight(proj(*cursor2), cursor1, len1, 0, compare, projection); if (count1 != 0) { detail::move_backward(cursor1, cursor1 + count1, dest + count1); dest += count1; @@ -529,7 +526,7 @@ namespace detail break; } - count2 = gallopLeft(*cursor1, cursor2, len2, 0, compare, projection); + count2 = gallopLeft(proj(*cursor1), cursor2, len2, 0, compare, projection); if (count2 != 0) { detail::move(cursor2, cursor2 + count2, dest); dest += count2; @@ -660,7 +657,7 @@ namespace detail CPPSORT_ASSERT(len1 > 0); CPPSORT_ASSERT(len2 > 1); - count1 = len1 - gallopRight(*cursor2, base1, len1, len1 - 1, compare, projection); + count1 = len1 - gallopRight(proj(*cursor2), base1, len1, len1 - 1, compare, projection); if (count1 != 0) { dest -= count1; cursor1 -= count1; @@ -680,7 +677,7 @@ namespace detail break; } - count2 = len2 - gallopLeft(*std::prev(cursor1), buffer.get(), len2, len2 - 1, compare, projection); + count2 = len2 - gallopLeft(proj(*std::prev(cursor1)), buffer.get(), len2, len2 - 1, compare, projection); if (count2 != 0) { dest -= count2; cursor2 -= count2; From 00189b75acad590a980c6598e309f00c99fc6c9c Mon Sep 17 00:00:00 2001 From: Morwenn Date: Mon, 2 May 2022 19:02:07 +0200 Subject: [PATCH 03/51] Replace bubble_sort with selection_sort as unstable fallback Replace bubble_sort with selection_sort as the fallback of introselect and quick_merge_sort for small collections. The number of performed comparisons stays the same, but the speed is improved for most patterns. Thanks @easyaspi314 for the suggestion. --- include/cpp-sort/detail/introselect.h | 18 +++++++----------- include/cpp-sort/detail/quick_merge_sort.h | 6 +++--- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/include/cpp-sort/detail/introselect.h b/include/cpp-sort/detail/introselect.h index 94d3b23d..e33a5306 100644 --- a/include/cpp-sort/detail/introselect.h +++ b/include/cpp-sort/detail/introselect.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2021 Morwenn + * Copyright (c) 2018-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_INTROSELECT_H_ @@ -13,12 +13,12 @@ #include #include #include "bitops.h" -#include "bubble_sort.h" #include "config.h" #include "insertion_sort.h" #include "iter_sort3.h" #include "iterator_traits.h" #include "partition.h" +#include "selection_sort.h" #include "swap_if.h" namespace cppsort @@ -26,20 +26,17 @@ namespace cppsort namespace detail { template - auto small_sort(ForwardIterator first, ForwardIterator, - difference_type_t size, + auto small_sort(ForwardIterator first, ForwardIterator last, Compare compare, Projection projection, std::forward_iterator_tag) -> void { - // TODO: find something better than bubble sort - bubble_sort(std::move(first), size, - std::move(compare), std::move(projection)); + selection_sort(std::move(first), std::move(last), + std::move(compare), std::move(projection)); } template auto small_sort(BidirectionalIterator first, BidirectionalIterator last, - difference_type_t, Compare compare, Projection projection, std::bidirectional_iterator_tag) -> void @@ -50,12 +47,11 @@ namespace detail template auto small_sort(ForwardIterator first, ForwardIterator last, - difference_type_t size, Compare compare, Projection projection) -> void { using category = iterator_category_t; - small_sort(first, last, size, std::move(compare), std::move(projection), + small_sort(first, last, std::move(compare), std::move(projection), category{}); } @@ -319,7 +315,7 @@ namespace detail --bad_allowed; } // Fallback when the collection is small enough - small_sort(first, last, size, std::move(compare), std::move(projection)); + small_sort(first, last, std::move(compare), std::move(projection)); return std::next(first, nth_pos); } }} diff --git a/include/cpp-sort/detail/quick_merge_sort.h b/include/cpp-sort/detail/quick_merge_sort.h index e5d1fdf9..fd853d04 100644 --- a/include/cpp-sort/detail/quick_merge_sort.h +++ b/include/cpp-sort/detail/quick_merge_sort.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2021 Morwenn + * Copyright (c) 2018-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_QUICK_MERGE_SORT_H_ @@ -90,7 +90,7 @@ namespace detail -> void { if (size <= qmsort_limit) { - small_sort(first, last, size, std::move(compare), std::move(projection)); + small_sort(first, last, std::move(compare), std::move(projection)); return; } @@ -148,7 +148,7 @@ namespace detail } size -= size_left; } - small_sort(first, last, size, std::move(compare), std::move(projection)); + small_sort(first, last, std::move(compare), std::move(projection)); } template From b7037ff4c3e483fafdc8270d69a500e3054d2e05 Mon Sep 17 00:00:00 2001 From: Morwenn Date: Thu, 12 May 2022 22:43:07 +0200 Subject: [PATCH 04/51] Use wg21.link for P0022 --- docs/Library-nomenclature.md | 2 +- docs/Writing-a-bubble_sorter.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/Library-nomenclature.md b/docs/Library-nomenclature.md index 04e98167..49cc28b0 100644 --- a/docs/Library-nomenclature.md +++ b/docs/Library-nomenclature.md @@ -70,7 +70,7 @@ [iterator-category]: Sorter-traits.md#iterator_category [iterator-tags]: https://en.cppreference.com/w/cpp/iterator/iterator_tags [measures-of-presortedness]: Measures-of-presortedness.md - [p0022]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0022r1.html + [p0022]: https://wg21.link/P0022 [radix-sort]: https://en.wikipedia.org/wiki/Radix_sort [sorter-adapters]: Sorter-adapters.md [sorters]: Sorters.md diff --git a/docs/Writing-a-bubble_sorter.md b/docs/Writing-a-bubble_sorter.md index 8aa0d9c6..eaa6fd77 100644 --- a/docs/Writing-a-bubble_sorter.md +++ b/docs/Writing-a-bubble_sorter.md @@ -444,7 +444,7 @@ That's it: we have covered pretty much every interesting aspect of writing a sim [hybrid-adapter]: Sorter-adapters.md#hybrid_adapter [is-projection]: Sorter-traits.md#is_projection-and-is_projection_iterator [projections]: https://ezoeryou.github.io/blog/article/2019-01-22-ranges-projection.html - [proxy-iterators]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0022r2.html + [proxy-iterators]: https://wg21.link/P0022 [sorter-adapters]: Sorter-adapters.md [sorter-facade]: Sorter-facade.md [sorter-traits]: Sorter-traits.md#sorter_traits From 0da8aa104ee76b38f881ceab9efb1386ae0d5f1b Mon Sep 17 00:00:00 2001 From: Morwenn Date: Thu, 26 May 2022 00:04:49 +0200 Subject: [PATCH 05/51] Add a tutorial showing how to write a sorter adapter (issue #154) --- docs/Writing-a-randomizing_adapter.md | 154 ++++++++++++++++++++++++++ docs/_Sidebar.md | 1 + examples/CMakeLists.txt | 4 +- examples/randomizing_adapter.cpp | 103 +++++++++++++++++ 4 files changed, 260 insertions(+), 2 deletions(-) create mode 100644 docs/Writing-a-randomizing_adapter.md create mode 100644 examples/randomizing_adapter.cpp diff --git a/docs/Writing-a-randomizing_adapter.md b/docs/Writing-a-randomizing_adapter.md new file mode 100644 index 00000000..7638cc77 --- /dev/null +++ b/docs/Writing-a-randomizing_adapter.md @@ -0,0 +1,154 @@ +In this tutorial, we will see how to write a `randomizing_adapter`, a [sorter adapter][sorter-adapters] that shuffles the collection to sort prior to sorting it with the *adapted sorter*. + +*Note: this tutorial assumes that you have already followed the one about [writing a `bubble_sorter`][writing-a-bubble-sorter] since most of the techniques described in it also apply to writing sorter adapters.* + +## Why shuffle the collection prior to sorting it? + +The main purpose of sorting is to bring order to a collection of elements, which might question the legitimacy of why anyone would want to shuffle said collection prior to sorting it. It turns out that there are several answers to that question. + +### Breaking quicksort-adverse patterns + +Depending on how it picks its pivot, a quicksort algorithm might run in quadratic time even on almost-sorted collections though these quicksort-adverse patterns generally don't occur on "random" data. The argument has been made that there is often pre-existing order in real life scenarios, so the collection passed to quicksort should be shuffled. + +The `randomizing_adapter` we are about to write allows to seamlessly wrap a naive `quick_sorter` to implement that trick: + +```cpp +using randomizing_quicksort = randomizing_adapter; +``` + +Obviously such a trick does not guarantee a O(n log n) runtime for the resulting sorter, but when applied to data with pre-existing order, it does make a quadratic runtime much less likely. + +*Note: the library's [`quick_sorter`][quick-sorter] already has a guaranteed O(n log n) worst case runtime, which would make such a trick unneeded anyway.* + +### Hyrum's law + +An arguably more useful use for a `randomizing_adapter` would be to avoid becoming a victim of [Hyrum's law][hyrums-law]. + +> With a sufficient number of users of an API, +> it does not matter what you promise in the contract: +> all observable behaviors of your system +> will be depended on by somebody. + +Danila Kutenin rightfully mentions that [changing `std::sort` is harder than meets the eye][changing-std-sort], the main reason being that pieces of code accidentally rely on the observable yet not guaranteed properties of [`std::sort`][std-sort], namely the order of elements that compare equivalent. The article gives [golden tests][golden-tests] as an example of things that might break when changing a sorting algorithm. + +In order to make it less likely for users to rely on the order of elements that compare equivalent, the author proposes to shuffle the collection prior to sorting it debug mode. This makes the order of equivalent elements non deterministic, which in turns can purposefuly break code accidentally relying on this order. + +It might seem at first that **cpp-sort**'s algorithms are not vulnerable to such changes since the name of the algorithm is part of sorter's name, but the truth is that their implementation still changes, and a user of the library might still want to swap a sorter for another one and suffer the same fate. + +The solution for libc++ was to guard `std::sort` with a `_LIBCPP_DEBUG_RANDOMIZE_RANGE` macro, a solution more in the spirit of **cpp-sort** is to provide an adapter for users who might want to add such a safeguard. + +## A basic `randomizing_adapter` + +Writing a sorter adapter is very similar to writing a sorter: +* Provide a suitable `operator()`. +* Document the [category of iterators][iterator-category] it accepts. +* Optionally document its stability guarantees. + +In the case of `randomizing_adapter`, all of those are quite simple: +* The algorithm is really just "shuffle the collection, then call the wrapped sorter". +* We are using `std::shuffle`, so it only accepts random-access iterators. +* Shuffling ensures that the sort is never stable. + +```cpp +template +struct randomizing_adapter +{ + template + auto operator()(RandomAccessIterator begin, RandomAccessIterator end, Args&&... args) const + -> decltype(Sorter{}(begin, end, std::forward(args)...)) + { + thread_local std::random_device device; + thread_local std::minstd_rand engine(device()); + std::shuffle(begin, end, engine); + return Sorter{}(begin, end, std::forward(args)...); + } + + using iterator_category = std::random_access_iterator_tag; + using is_always_stable = std::false_type; +}; +``` + +When possible, a proper *sorter adapter* is expected to be callable with the same combination of parameters than the *sorter* it wraps, which often calls for an implementation class later wrapped in [`sorter_facade`][sorter-facade] and adding the proper SFINAE constraints to `operator()`. For this simple adapter we don't need to go to such lengths and instead rely on [expression SFINAE][sfinae] in the return type expression to transitively benefit from the sorter. + +## Returned value + +There is currently no strict rule about what a sorter adapter should return (this is actually a [open design issue][issue-134]), though the general wisdom is that an adapter should transparently provide as many features as the sorter it adapts when it reasonably can. The idea is that replacing the sorter by its wrapped counterpart should be easy. + +We don't have a specific use for the return channel of `randomizing_adapter` and it is simple to make it transitively return whatever the wrapped sorter returns - and even convenient -, so I decided to do just that. + +## Construction + +A sorter adapter should be exmplicitly constructible from an instance of the sorter it adapts, so we need to give it appropriate constructors: + +```cpp +randomizing_adapter() = default; +constexpr explicit randomizing_adapter(Sorter) {} +``` + +It might seem useless since our adapter does not store an instance of the sorter it wraps, but it adds expressiveness with C++17 [class template argument deduction][ctad]: + +```cpp +auto sort = randomizing_adapter(cppsort::poplar_sorter); +``` + +## `utility::adapter_storage` + +As previously mentioned, our `randomizing_adapter` currently does not store the adapted sorter even though it might be desirable since sorters can be stateful. **cpp-sort** provides the class template [`utility::adapter_storage`][adapter-storage] that adapters can inherit from to take care of storing a sorter instance. + +```cpp +template +struct randomizing_adapter: + cppsort::utility::adapter_storage +{ + randomizing_adapter() = default; + + constexpr explicit randomizing_adapter(Sorter sorter): + cppsort::utility::adapter_storage(std::move(sorter)) + {} + + template + auto operator()(RandomAccessIterator begin, RandomAccessIterator end, Args&&... args) const + -> decltype(this->get()(begin, end, std::forward(args)...)) + { + thread_local std::random_device device; + thread_local std::minstd_rand engine(device()); + std::shuffle(begin, end, engine); + return this->get()(begin, end, std::forward(args)...); + } +}; +``` + +`adapter_storage` is constructed with an instance of `Sorter` and has value semantics: it holds a copy of the sorter, not a reference to it. The stored sorter can be accessed via the `get()` method. + +It is special-cased for empty sorters: when constructed with one, it doesn't store it and instead default-constructs a new instance when `get()` is called. The lack of storage allows the adapter to be converted to a function pointer when it stores an empty sorter. + +## Polishing it a bit + +`randomizing_adapter` is already usable as is, but it can still benefit from small improvements like those we gave to `bubble_sorter` [in the other tutorial][writing-a-bubble-sorter]: +* Add an `operator()` overload accepting an iterable to benefit from O(1) `.size()` functions. +* Add a `static_assert` to make it clear when it isn't given random-access iterators. + +## Conclusion + +We have seen how to write a simple sorter adapter which gives users the option to harden their code against Hyrum's law in a more granular fashion that simply sticking a macro in every sorter. + +This one was pretty straightforward, but writing adapters can occasionally be much more challenging. Good adapters can ideally replace the sorter they wrap without effort, and there's generally more to it than meets the eye. + +The full implementation can be found in the `examples` folder. + + + [adapter-storage]: Miscellaneous-utilities.md#adapter_storage + [changing-std-sort]: https://danlark.org/2022/04/20/changing-stdsort-at-googles-scale-and-beyond/ + [ctad]: https://en.cppreference.com/w/cpp/language/class_template_argument_deduction + [golden-tests]: https://en.wikipedia.org/wiki/Characterization_test + [hyrums-law]: https://www.hyrumslaw.com/ + [issue-134]: https://github.com/Morwenn/cpp-sort/issues/134 + [iterator-category]: https://en.cppreference.com/w/cpp/iterator + [proxy-iterators]: https://wg21.link/P0022 + [quick-sorter]: Sorters.md#quick_sorter + [sfinae]: https://en.cppreference.com/w/cpp/language/sfinae + [sorter-adapters]: Sorter-adapters.md + [sorter-facade]: Sorter-facade.md + [sorter-traits]: Sorter-traits.md#sorter_traits + [writing-a-sorter]: Writing-a-sorter.md + [writing-a-bubble-sorter]: Writing-a-bubble_sorter.md diff --git a/docs/_Sidebar.md b/docs/_Sidebar.md index efdea090..6bff272c 100644 --- a/docs/_Sidebar.md +++ b/docs/_Sidebar.md @@ -17,6 +17,7 @@ * Tutorials * [Writing a sorter](Writing-a-sorter.md) * [Writing a `bubble_sorter`](Writing-a-bubble_sorter.md) + * [Writing a `randomizing_adapter`](Writing-a-randomizing_adapter.md) * [Writing a container-aware algorithm](Writing-a-container-aware-algorithm.md) * [Tooling](Tooling.md) * [Benchmarks](Benchmarks.md) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 1e2bed46..fe7f2a76 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,10 +1,10 @@ -# Copyright (c) 2019-2021 Morwenn +# Copyright (c) 2019-2022 Morwenn # SPDX-License-Identifier: MIT include(cpp-sort-utils) # Quick & dirty script to compile the examples -foreach(filename bubble_sorter.cpp list_selection_sorter.cpp readme_example.cpp) +foreach(filename bubble_sorter.cpp list_selection_sorter.cpp randomizing_adapter.cpp readme_example.cpp) get_filename_component(name ${filename} NAME_WE) add_executable(${name} ${filename}) target_link_libraries(${name} PRIVATE cpp-sort::cpp-sort) diff --git a/examples/randomizing_adapter.cpp b/examples/randomizing_adapter.cpp new file mode 100644 index 00000000..bfaabe84 --- /dev/null +++ b/examples/randomizing_adapter.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2022 Morwenn + * SPDX-License-Identifier: MIT + */ +#include +#include +#include +#include +#include +#include +#include + +template +auto my_shuffle(RandomAccessIterator begin, RandomAccessIterator end) + -> void +{ + thread_local std::random_device device; + thread_local std::minstd_rand engine(device()); + std::shuffle(begin, end, engine); +} + +template +struct randomizing_adapter: + cppsort::utility::adapter_storage +{ + //////////////////////////////////////////////////////////// + // Construction + + randomizing_adapter() = default; + + constexpr explicit randomizing_adapter(Sorter sorter): + cppsort::utility::adapter_storage(std::move(sorter)) + {} + + //////////////////////////////////////////////////////////// + // operator() + + template + auto operator()(RandomAccessIterator begin, RandomAccessIterator end, Args&&... args) const + -> decltype(this->get()(begin, end, std::forward(args)...)) + { + static_assert( + std::is_base_of< + iterator_category, + typename std::iterator_traits::iterator_category + >::value, + "randomizing_adapter requires at least forward iterators" + ); + + my_shuffle(begin, end); + return this->get()(begin, end, std::forward(args)...); + } + + template + auto operator()(RandomAccessIterable&& iterable, Args&&... args) const + -> decltype(this->get()(std::forward(iterable), std::forward(args)...)) + { + static_assert( + std::is_base_of< + iterator_category, + typename std::iterator_traits::iterator_category + >::value, + "randomizing_adapter requires at least forward iterators" + ); + + my_shuffle(std::begin(iterable), std::end(iterable)); + return this->get()(std::forward(iterable), std::forward(args)...); + } + + //////////////////////////////////////////////////////////// + // Sorter traits + + using iterator_category = std::random_access_iterator_tag; + using is_always_stable = std::false_type; +}; + +#include +#include + +int main() +{ + // Vector of pairs: + // - First fields all contain the same value + // - Second fields have unique values + std::vector> vec; + for (int i = 0; i < 10; ++i) { + vec.emplace_back(5, i); + vec.emplace_back(6, i); + } + + // Sort on first field + auto my_sort = randomizing_adapter{}; + my_sort(vec, &std::pair::first); + + // Second field values should change between executions + for (const auto& pair: vec) { + std::cout << pair.first << '\t'; + } + std::cout << '\n';for (const auto& pair: vec) { + std::cout << pair.second << '\t'; + } + std::cout << '\n'; +} From 13ff7e6b49dd31ad967273c9a68a360dc424e134 Mon Sep 17 00:00:00 2001 From: Morwenn Date: Tue, 14 Jun 2022 16:46:16 +0200 Subject: [PATCH 06/51] Upgrade actions/checkout to v3 --- .github/workflows/build-macos.yml | 2 +- .github/workflows/build-mingw.yml | 2 +- .github/workflows/build-msvc.yml | 2 +- .github/workflows/build-ubuntu.yml | 2 +- .github/workflows/code-coverage.yml | 2 +- .github/workflows/deploy-to-wiki.yml | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml index 057437f2..faa3b0c2 100644 --- a/.github/workflows/build-macos.yml +++ b/.github/workflows/build-macos.yml @@ -41,7 +41,7 @@ jobs: sanitize: undefined steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: seanmiddleditch/gha-setup-ninja@master - name: Configure CMake diff --git a/.github/workflows/build-mingw.yml b/.github/workflows/build-mingw.yml index 2b3f7986..14e5b7b6 100644 --- a/.github/workflows/build-mingw.yml +++ b/.github/workflows/build-mingw.yml @@ -31,7 +31,7 @@ jobs: build_type: [Debug, Release] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Configure CMake shell: pwsh diff --git a/.github/workflows/build-msvc.yml b/.github/workflows/build-msvc.yml index 17c0cc3c..bd374932 100644 --- a/.github/workflows/build-msvc.yml +++ b/.github/workflows/build-msvc.yml @@ -31,7 +31,7 @@ jobs: build_type: [Debug, Release] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Configure CMake shell: pwsh diff --git a/.github/workflows/build-ubuntu.yml b/.github/workflows/build-ubuntu.yml index d4bc586f..cb193f48 100644 --- a/.github/workflows/build-ubuntu.yml +++ b/.github/workflows/build-ubuntu.yml @@ -43,7 +43,7 @@ jobs: sanitize: undefined steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install GCC if: ${{matrix.cxx == 'g++-5'}} diff --git a/.github/workflows/code-coverage.yml b/.github/workflows/code-coverage.yml index e8c7a4d4..6b5cba4b 100644 --- a/.github/workflows/code-coverage.yml +++ b/.github/workflows/code-coverage.yml @@ -23,7 +23,7 @@ jobs: steps: - name: Checkout project - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Install LCOV run: sudo apt-get install -y lcov diff --git a/.github/workflows/deploy-to-wiki.yml b/.github/workflows/deploy-to-wiki.yml index 62804cfb..d95c68b4 100644 --- a/.github/workflows/deploy-to-wiki.yml +++ b/.github/workflows/deploy-to-wiki.yml @@ -18,13 +18,13 @@ jobs: steps: - name: Checkout /docs - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: ${{github.repository}} path: main - name: Checkout wiki - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: ${{github.repository}}.wiki path: wiki From db29e5120a47121f159a15cc2713bb2719f524b3 Mon Sep 17 00:00:00 2001 From: Morwenn Date: Sun, 19 Jun 2022 13:57:49 +0200 Subject: [PATCH 07/51] MSVC STL: use _Swap_ranges_unchecked when possible --- docs/Changelog.md | 2 ++ include/cpp-sort/detail/swap_ranges.h | 31 ++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/docs/Changelog.md b/docs/Changelog.md index cc5559af..5179686f 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -89,6 +89,8 @@ When compiled with C++20, **cpp-sort** might gain a few additional features depe * Assumptions: some algorithms use assumptions in select places to make the compiler generate more efficient code. Whether such assumptions are available depends on the compiler. +* Vectorized algorithms: when compiled against the Microsoft STL, **cpp-sort** tries to take advantage of their vectorized algorithms when possible. This improves some algorithms when sorting contiguous collections of trivially copyable types. + * When using libstdc++, libc++ or the Microsoft STL, the return type of [`std::mem_fn`][std-mem-fn] is considered ["probably branchless"][branchless-traits] when it wraps a pointer to data member, which can improve the speed of [`pdq_sorter`][pdq-sorter] and everything that relies on it in some scenarios. diff --git a/include/cpp-sort/detail/swap_ranges.h b/include/cpp-sort/detail/swap_ranges.h index 9056283f..0aa37d94 100644 --- a/include/cpp-sort/detail/swap_ranges.h +++ b/include/cpp-sort/detail/swap_ranges.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 Morwenn + * Copyright (c) 2016-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SWAP_RANGES_H_ @@ -8,6 +8,7 @@ //////////////////////////////////////////////////////////// // Headers //////////////////////////////////////////////////////////// +#include #include #include #include @@ -71,11 +72,39 @@ namespace detail return swap_ranges_overlap(first1, last1, first2); } +#if defined(_USE_STD_VECTOR_ALGORITHMS) && _USE_STD_VECTOR_ALGORITHMS template auto swap_ranges_inner_impl(std::random_access_iterator_tag, RandomAccessIterator first1, RandomAccessIterator last1, RandomAccessIterator first2) + -> detail::enable_if_t< + not is_invocable_v, + RandomAccessIterator + > + { + CPPSORT_ASSERT(first1 <= last1); + + auto last2 = first2 + (last1 - first1); + (void)last2; + CPPSORT_ASSERT(not (first2 >= first1 && first2 < last1)); + CPPSORT_ASSERT(not (last2 > first1 && last2 <= last1)); + + return std::_Swap_ranges_unchecked(first1, last1, first2); + } +#endif + + template + auto swap_ranges_inner_impl(std::random_access_iterator_tag, + RandomAccessIterator first1, RandomAccessIterator last1, + RandomAccessIterator first2) +#if defined(_USE_STD_VECTOR_ALGORITHMS) && _USE_STD_VECTOR_ALGORITHMS + -> detail::enable_if_t< + is_invocable_v, + RandomAccessIterator + > +#else -> RandomAccessIterator +#endif { CPPSORT_ASSERT(first1 <= last1); From 5536c7fc843a6c3ffd3ccae224de83715731aad0 Mon Sep 17 00:00:00 2001 From: Morwenn Date: Sun, 19 Jun 2022 21:34:09 +0200 Subject: [PATCH 08/51] MSVC STL: used vectorized std::reverse when possible --- include/cpp-sort/detail/reverse.h | 34 ++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/include/cpp-sort/detail/reverse.h b/include/cpp-sort/detail/reverse.h index 7b4d7643..b11fdbab 100644 --- a/include/cpp-sort/detail/reverse.h +++ b/include/cpp-sort/detail/reverse.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Morwenn + * Copyright (c) 2016-2022 Morwenn * SPDX-License-Identifier: MIT */ @@ -17,10 +17,13 @@ //////////////////////////////////////////////////////////// // Headers //////////////////////////////////////////////////////////// +#include #include #include #include #include "iterator_traits.h" +#include "move.h" +#include "type_traits.h" namespace cppsort { @@ -33,23 +36,40 @@ namespace detail { using utility::iter_swap; - while (first != last) - { + while (first != last) { if (first == --last) break; iter_swap(first, last); ++first; } } +#if defined(_USE_STD_VECTOR_ALGORITHMS) && _USE_STD_VECTOR_ALGORITHMS template auto reverse_impl(RandomAccessIterator first, RandomAccessIterator last, std::random_access_iterator_tag) + -> detail::enable_if_t< + not is_invocable_v, + void + > + { + std::reverse(first, last); + } +#endif + + template + auto reverse_impl(RandomAccessIterator first, RandomAccessIterator last, + std::random_access_iterator_tag) +#if defined(_USE_STD_VECTOR_ALGORITHMS) && _USE_STD_VECTOR_ALGORITHMS + -> detail::enable_if_t< + is_invocable_v, + void + > +#else -> void +#endif { - if (first != last) - { - for (; first < --last ; ++first) - { + if (first != last) { + for (; first < --last ; ++first) { using utility::iter_swap; iter_swap(first, last); } From e7f5cbe675a73ede4fe414e5a25e5858a4e8403b Mon Sep 17 00:00:00 2001 From: Morwenn Date: Tue, 21 Jun 2022 23:36:22 +0200 Subject: [PATCH 09/51] Implement heap_sorter as a bottom-up heapsort Update the heapsort algorithm to match the latest version of the code in libc++. As a result heap_sort performs significantly fewer comparisons, even though it doesn't make much of a speed difference for simple scenarios. cartesian_tree_sorter is also impacted, although the reduction in the number of comparisons is mostly noticeable in its worst cas scenarios. --- docs/Sorters.md | 2 +- include/cpp-sort/detail/heapsort.h | 104 +++++++++++++++++++++-------- 2 files changed, 77 insertions(+), 29 deletions(-) diff --git a/docs/Sorters.md b/docs/Sorters.md index e53ca4f8..3b80f8dc 100644 --- a/docs/Sorters.md +++ b/docs/Sorters.md @@ -137,7 +137,7 @@ Whether this sorter works with types that are not default-constructible depends #include ``` -Implements a [heapsort][heapsort]. +Implements a bottom-up [heapsort][heapsort]. | Best | Average | Worst | Memory | Stable | Iterators | | ----------- | ----------- | ----------- | ----------- | ----------- | ------------- | diff --git a/include/cpp-sort/detail/heapsort.h b/include/cpp-sort/detail/heapsort.h index bcfa2ad9..91282439 100644 --- a/include/cpp-sort/detail/heapsort.h +++ b/include/cpp-sort/detail/heapsort.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ @@ -17,9 +17,11 @@ //////////////////////////////////////////////////////////// // Headers //////////////////////////////////////////////////////////// +#include #include #include #include +#include "config.h" #include "iterator_traits.h" namespace cppsort @@ -36,17 +38,17 @@ namespace detail using utility::iter_move; auto&& comp = utility::as_function(compare); auto&& proj = utility::as_function(projection); - using difference_type = difference_type_t; // left-child of start is at 2 * start + 1 // right-child of start is at 2 * start + 2 - difference_type child = start - first; + auto child = start - first; - if (len < 2 || (len - 2) / 2 < child) + if (len < 2 || (len - 2) / 2 < child) { return; + } child = 2 * child + 1; - RandomAccessIterator child_i = first + child; + auto child_i = first + child; if ((child + 1) < len && comp(proj(*child_i), proj(*(child_i + 1)))) { // right-child exists and is greater than left-child @@ -55,19 +57,20 @@ namespace detail } // check if we are in heap-order - if (comp(proj(*child_i), proj(*start))) + if (comp(proj(*child_i), proj(*start))) { // we are, start is larger than it's largest child return; + } auto top = iter_move(start); - do - { + do { // we are not in heap-order, swap the parent with it's largest child *start = iter_move(child_i); start = child_i; - if ((len - 2) / 2 < child) + if ((len - 2) / 2 < child) { break; + } // recompute the child based off of the updated parent child = 2 * child + 1; @@ -80,21 +83,43 @@ namespace detail } // check if we are in heap-order - } while (!comp(proj(*child_i), proj(top))); + } while (not comp(proj(*child_i), proj(top))); *start = std::move(top); } template - auto make_heap(RandomAccessIterator first, RandomAccessIterator last, - Compare compare, Projection projection) - -> void + auto floyd_sift_down(RandomAccessIterator first, Compare compare, Projection projection, + difference_type_t len) + -> RandomAccessIterator { + CPPSORT_ASSERT(len >= 2); + + using utility::iter_move; + auto&& comp = utility::as_function(compare); + auto&& proj = utility::as_function(projection); using difference_type = difference_type_t; - difference_type n = last - first; - if (n > 1) { - // start from the first parent, there is no need to consider children - for (difference_type start = (n - 2) / 2; start >= 0; --start) { - sift_down(first, last, compare, projection, n, first + start); + + auto hole = first; + auto child_i = first; + difference_type child = 0; + + while (true) { + child_i += difference_type(child + 1); + child = 2 * child + 1; + + if ((child + 1) < len && comp(proj(*child_i), proj(*std::next(child_i)))) { + // right-child exists and is greater than left-child + ++child_i; + ++child; + } + + // swap hole with its largest child + *hole = iter_move(child_i); + hole = child_i; + + // if hole is now a leaf, we're done + if (child > (len - 2) / 2) { + return hole; } } } @@ -128,27 +153,50 @@ namespace detail } } - template + template auto pop_heap(RandomAccessIterator first, RandomAccessIterator last, Compare compare, Projection projection, difference_type_t len) -> void { + using utility::iter_move; + if (len > 1) { - using utility::iter_swap; - iter_swap(first, --last); - sift_down(first, last, compare, std::move(projection), len - 1, first); + auto top = iter_move(first); // create a hole at first + auto hole = detail::floyd_sift_down(first, compare, projection, len); + if (hole == --last) { + *hole = std::move(top); + } else { + *hole = iter_move(last); + ++hole; + *last = std::move(top); + detail::push_heap(first, hole, compare, projection, hole - first); + } } } template - auto sort_heap(RandomAccessIterator first, RandomAccessIterator last, + auto make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare compare, Projection projection) -> void { using difference_type = difference_type_t; - for (difference_type n = last - first; n > 1; --last, (void) --n) { - pop_heap(first, last, compare, projection, n); + difference_type n = last - first; + if (n > 1) { + // start from the first parent, there is no need to consider children + for (difference_type start = (n - 2) / 2; start >= 0; --start) { + detail::sift_down(first, last, compare, projection, n, first + start); + } + } + } + + template + auto sort_heap(RandomAccessIterator first, RandomAccessIterator last, + Compare compare, Projection projection) + -> void + { + for (auto n = last - first; n > 1; --last, (void) --n) { + detail::pop_heap(first, last, compare, projection, n); } } @@ -157,9 +205,9 @@ namespace detail Compare compare, Projection projection) -> void { - make_heap(first, last, compare, projection); - sort_heap(std::move(first), std::move(last), - std::move(compare), std::move(projection)); + detail::make_heap(first, last, compare, projection); + detail::sort_heap(std::move(first), std::move(last), + std::move(compare), std::move(projection)); } }} From 2465db953f935402642184116ad20005a13e3eed Mon Sep 17 00:00:00 2001 From: Morwenn Date: Thu, 23 Jun 2022 16:50:10 +0200 Subject: [PATCH 10/51] Small fixes --- .../cpp-sort/detail/merge_insertion_sort.h | 2 +- include/cpp-sort/detail/partition.h | 40 +++++++++---------- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/include/cpp-sort/detail/merge_insertion_sort.h b/include/cpp-sort/detail/merge_insertion_sort.h index 414d1da0..7b448781 100644 --- a/include/cpp-sort/detail/merge_insertion_sort.h +++ b/include/cpp-sort/detail/merge_insertion_sort.h @@ -288,7 +288,7 @@ namespace detail auto end = has_stray ? std::prev(last) : last; for (auto it = first ; it != end ; it += 2) { - iter_swap_if(it, it + 1, compare, projection); + iter_swap_if(it, std::next(it), compare, projection); } //////////////////////////////////////////////////////////// diff --git a/include/cpp-sort/detail/partition.h b/include/cpp-sort/detail/partition.h index e6a2a011..47e26173 100644 --- a/include/cpp-sort/detail/partition.h +++ b/include/cpp-sort/detail/partition.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Morwenn + * Copyright (c) 2016-2022 Morwenn * SPDX-License-Identifier: MIT */ @@ -18,7 +18,6 @@ // Headers //////////////////////////////////////////////////////////// #include -#include #include #include #include "iterator_traits.h" @@ -32,18 +31,17 @@ namespace detail std::forward_iterator_tag) -> ForwardIterator { - while (true) - { - if (first == last) + while (true) { + if (first == last) { return first; - if (!pred(*first)) + } + if (not pred(*first)) { break; + } ++first; } - for (ForwardIterator p = first; ++p != last;) - { - if (pred(*p)) - { + for (auto p = first; ++p != last;) { + if (pred(*p)) { using utility::iter_swap; iter_swap(first, p); ++first; @@ -57,21 +55,21 @@ namespace detail std::bidirectional_iterator_tag) -> BidirectionalIterator { - while (true) - { - while (true) - { - if (first == last) + while (true) { + while (true) { + if (first == last) { return first; - if (!pred(*first)) + } + if (not pred(*first)) { break; + } ++first; } - do - { - if (first == --last) + do { + if (first == --last) { return first; - } while (!pred(*last)); + } + } while (not pred(*last)); using utility::iter_swap; iter_swap(first, last); ++first; @@ -82,7 +80,7 @@ namespace detail auto partition(ForwardIterator first, ForwardIterator last, Predicate pred) -> ForwardIterator { - return partition_impl>( + return partition_impl( std::move(first), std::move(last), pred, iterator_category_t{} ); From 69a839ca568b030de892cd807e08f8183d866ca4 Mon Sep 17 00:00:00 2001 From: Morwenn Date: Thu, 23 Jun 2022 18:05:45 +0200 Subject: [PATCH 11/51] Let immovable_vector::emplace_back return a pointer to the new elements --- include/cpp-sort/detail/cartesian_tree_sort.h | 9 ++++----- include/cpp-sort/detail/immovable_vector.h | 6 +++--- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/include/cpp-sort/detail/cartesian_tree_sort.h b/include/cpp-sort/detail/cartesian_tree_sort.h index 7f41cfd4..f2dc73d5 100644 --- a/include/cpp-sort/detail/cartesian_tree_sort.h +++ b/include/cpp-sort/detail/cartesian_tree_sort.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Morwenn + * Copyright (c) 2021-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_CARTESIAN_TREE_SORT_H_ @@ -86,11 +86,10 @@ namespace detail auto&& proj_value = proj(*first); node_type* new_parent = _find_insertion_parent(prev_node, proj_value, compare, projection); if (new_parent == nullptr) { - buffer_.emplace_back(iter_move(first), nullptr, root_); - root_ = &buffer_.back(); + root_ = buffer_.emplace_back(iter_move(first), nullptr, root_); } else { - buffer_.emplace_back(iter_move(first), new_parent, new_parent->right_child); - new_parent->right_child = &buffer_.back(); + new_parent->right_child = buffer_.emplace_back(iter_move(first), new_parent, + new_parent->right_child); } prev_node = &buffer_.back(); } diff --git a/include/cpp-sort/detail/immovable_vector.h b/include/cpp-sort/detail/immovable_vector.h index 274d8334..0cd6f1fe 100644 --- a/include/cpp-sort/detail/immovable_vector.h +++ b/include/cpp-sort/detail/immovable_vector.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Morwenn + * Copyright (c) 2021-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_IMMOVABLE_VECTOR_H_ @@ -123,11 +123,11 @@ namespace detail template auto emplace_back(Args&&... args) - -> void + -> T* { CPPSORT_ASSERT(end_ - memory_ < capacity_); ::new(end_) T(std::forward(args)...); - ++end_; + return std::exchange(end_, end_ + 1); } template From 834cac4c6c98aec67aa86a1ad30036144e613a9b Mon Sep 17 00:00:00 2001 From: Morwenn Date: Sat, 25 Jun 2022 12:38:50 +0200 Subject: [PATCH 12/51] Remove mention of std::atomic in the counting_adapter doc It was never tested and never worked in the first place. The library barely tackles parallel programming issues so the deleted part really didn't have its place there. --- docs/Sorter-adapters.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Sorter-adapters.md b/docs/Sorter-adapters.md index 8717b61a..78053c68 100644 --- a/docs/Sorter-adapters.md +++ b/docs/Sorter-adapters.md @@ -59,7 +59,7 @@ An interesting property of dedicated sorting algorithms is that one can craft an Unlike usual sorters, `counting_adapter::operator()` does not return `void` but the number of comparisons that have been needed to sort the iterable. It will adapt the comparison function so that it can count the number of comparisons made by any other sorter with a reasonable implementation. The actual number of comparisons needed to sort an iterable can be used as a heuristic in hybrid sorts and may constitute interesting information nevertheless. -The actual counter type can be configured with the template parameter `CountType`, which defaults to `std::size_t` if not specified. While this doesn't matter most of the times, this parameter may be changed to `std::atomic` to count the number of comparisons performed by parallel sorting algorithms (or to a reducer, which would probably be a better idea). +The actual counter type can be configured with the template parameter `CountType`, which defaults to `std::size_t` if not specified. ```cpp template< From c9e9a0fe7704dfcda9f6fd25e90cde69fc9d1ad4 Mon Sep 17 00:00:00 2001 From: Morwenn Date: Sat, 25 Jun 2022 12:41:07 +0200 Subject: [PATCH 13/51] Rework iter_move/iter_swap implementation --- include/cpp-sort/detail/move.h | 39 +---- include/cpp-sort/detail/reverse.h | 4 +- include/cpp-sort/detail/swap_if.h | 11 +- include/cpp-sort/detail/swap_ranges.h | 4 +- include/cpp-sort/utility/iter_move.h | 223 +++++++++++++++----------- 5 files changed, 139 insertions(+), 142 deletions(-) diff --git a/include/cpp-sort/detail/move.h b/include/cpp-sort/detail/move.h index b8ba06da..abe14032 100644 --- a/include/cpp-sort/detail/move.h +++ b/include/cpp-sort/detail/move.h @@ -20,44 +20,13 @@ namespace cppsort { namespace detail { - //////////////////////////////////////////////////////////// - // Check whether iter_move is specialized - // - // The idea behind this check is that if an iterator has a - // dedicated iter_move found by ADL, then we ought to use it, - // otherwise we can fallback to std::move which is supposedly - // more optimized than what we would write by hand (notably - // for standard library iterators) - // - - namespace hide_adl - { - template - auto iter_move(Iterator) = delete; - - struct dummy_callable - { - template - auto operator()(Iterator it) - -> decltype(iter_move(it)); - - template - auto operator()(const std::reverse_iterator& it) - -> decltype(iter_move(it.base())); // only there for type information - - template - auto operator()(const std::move_iterator& it) - -> decltype(iter_move(it.base())); - }; - } - //////////////////////////////////////////////////////////// // move template auto move(InputIterator first, InputIterator last, OutputIterator result) -> detail::enable_if_t< - not is_invocable_v, + not is_invocable_v, OutputIterator > { @@ -67,7 +36,7 @@ namespace detail template auto move(InputIterator first, InputIterator last, OutputIterator result) -> detail::enable_if_t< - is_invocable_v, + is_invocable_v, OutputIterator > { @@ -84,7 +53,7 @@ namespace detail template auto move_backward(InputIterator first, InputIterator last, OutputIterator result) -> detail::enable_if_t< - not is_invocable_v, + not is_invocable_v, OutputIterator > { @@ -94,7 +63,7 @@ namespace detail template auto move_backward(InputIterator first, InputIterator last, OutputIterator result) -> detail::enable_if_t< - is_invocable_v, + is_invocable_v, OutputIterator > { diff --git a/include/cpp-sort/detail/reverse.h b/include/cpp-sort/detail/reverse.h index b11fdbab..4a2360fb 100644 --- a/include/cpp-sort/detail/reverse.h +++ b/include/cpp-sort/detail/reverse.h @@ -48,7 +48,7 @@ namespace detail auto reverse_impl(RandomAccessIterator first, RandomAccessIterator last, std::random_access_iterator_tag) -> detail::enable_if_t< - not is_invocable_v, + not is_invocable_v, void > { @@ -61,7 +61,7 @@ namespace detail std::random_access_iterator_tag) #if defined(_USE_STD_VECTOR_ALGORITHMS) && _USE_STD_VECTOR_ALGORITHMS -> detail::enable_if_t< - is_invocable_v, + is_invocable_v, void > #else diff --git a/include/cpp-sort/detail/swap_if.h b/include/cpp-sort/detail/swap_if.h index 1d3a97e0..04168b30 100644 --- a/include/cpp-sort/detail/swap_if.h +++ b/include/cpp-sort/detail/swap_if.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SWAP_IF_H_ @@ -178,8 +178,8 @@ namespace detail typename Compare, typename Projection, typename = detail::enable_if_t< - is_detected_v || - is_detected_v + cppsort::detail::is_invocable_v || + cppsort::detail::is_invocable_v > > auto iter_swap_if(Iterator lhs, Iterator rhs, Compare compare, Projection projection) @@ -199,8 +199,8 @@ namespace detail typename Compare, typename Projection, typename = detail::enable_if_t< - not is_detected_v && - not is_detected_v + not cppsort::detail::is_invocable_v && + not cppsort::detail::is_invocable_v >, typename = void // dummy parameter for ODR > @@ -211,7 +211,6 @@ namespace detail // Take advantage of the swap_if optimizations // only when the iterators don't have dedicated // iter_move or iter_swap ADL-found functions - swap_if(*lhs, *rhs, std::move(compare), std::move(projection)); } }} diff --git a/include/cpp-sort/detail/swap_ranges.h b/include/cpp-sort/detail/swap_ranges.h index 0aa37d94..6dc11f5f 100644 --- a/include/cpp-sort/detail/swap_ranges.h +++ b/include/cpp-sort/detail/swap_ranges.h @@ -78,7 +78,7 @@ namespace detail RandomAccessIterator first1, RandomAccessIterator last1, RandomAccessIterator first2) -> detail::enable_if_t< - not is_invocable_v, + not is_invocable_v, RandomAccessIterator > { @@ -99,7 +99,7 @@ namespace detail RandomAccessIterator first2) #if defined(_USE_STD_VECTOR_ALGORITHMS) && _USE_STD_VECTOR_ALGORITHMS -> detail::enable_if_t< - is_invocable_v, + is_invocable_v, RandomAccessIterator > #else diff --git a/include/cpp-sort/utility/iter_move.h b/include/cpp-sort/utility/iter_move.h index c6c377a1..b15be22c 100644 --- a/include/cpp-sort/utility/iter_move.h +++ b/include/cpp-sort/utility/iter_move.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 Morwenn + * Copyright (c) 2016-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_UTILITY_ITER_MOVE_H_ @@ -15,122 +15,151 @@ namespace cppsort { -namespace utility -{ - //////////////////////////////////////////////////////////// - // Generic iter_move and iter_swap - namespace detail { + //////////////////////////////////////////////////////////// + // Check whether iter_move and iter_swap are specialized: + // the extra namespace and deleted overloads ensure that the + // call_* classes will only be callable when an iter_move or + // iter_swap overload is found via ADL. + + namespace hide_adl + { + template + auto iter_move(Iterator) = delete; + + template + auto iter_swap(Iterator, Iterator) = delete; + + struct call_iter_move + { + template + auto operator()(Iterator it) + -> decltype(iter_move(it)); + + template + auto operator()(const std::reverse_iterator& it) + -> decltype(iter_move(it.base())); + + template + auto operator()(const std::move_iterator& it) + -> decltype(iter_move(it.base())); + }; + + struct call_iter_swap + { + template + auto operator()(Iterator it1, Iterator it2) + -> decltype(iter_swap(it1, it2)); + + template + auto operator()(const std::reverse_iterator& it1, + const std::reverse_iterator& it2) + -> decltype(iter_swap(it1.base(), it2.base())); + + template + auto operator()(const std::move_iterator& it1, + const std::move_iterator& it2) + -> decltype(iter_swap(it1.base(), it2.base())); + }; + } + + //////////////////////////////////////////////////////////// + // Result type of a non-specialized iter_move call + template using iter_move_t = cppsort::detail::conditional_t< std::is_reference::reference>::value, std::remove_reference_t::reference>&&, std::decay_t::reference> >; - - template - using has_iter_move_t = decltype(iter_move(std::declval())); - - template - using has_iter_swap_t = decltype(iter_swap( - std::declval(), std::declval()) - ); - } - - template< - typename Iterator, - typename = cppsort::detail::enable_if_t< - cppsort::detail::is_detected_v - > - > - constexpr auto iter_swap(Iterator lhs, Iterator rhs) - -> void - { - auto tmp = iter_move(lhs); - *lhs = iter_move(rhs); - *rhs = std::move(tmp); - } - - template< - typename Iterator, - typename = cppsort::detail::enable_if_t< - not cppsort::detail::is_detected_v - >, - typename = void // dummy parameter for ODR - > - constexpr auto iter_swap(Iterator lhs, Iterator rhs) - -> void - { - // While this overload is not strictly needed, it - // ensures that an ADL-found swap is used when the - // iterator type does not have a dedicated iter_move - // ADL-found overload - - using std::swap; - swap(*lhs, *rhs); - } - - template - constexpr auto iter_move(Iterator it) - noexcept(noexcept(detail::iter_move_t(std::move(*it)))) - -> detail::iter_move_t - { - return std::move(*it); } - //////////////////////////////////////////////////////////// - // rvalue_reference_t type trait - - namespace adl_trick + namespace utility { - using utility::iter_move; + //////////////////////////////////////////////////////////// + // Generic iter_move and iter_swap template - auto do_iter_move() - -> decltype(iter_move(std::declval())); - } + constexpr auto iter_move(Iterator it) + noexcept(noexcept(cppsort::detail::iter_move_t(std::move(*it)))) + -> cppsort::detail::iter_move_t + { + return std::move(*it); + } + + template< + typename Iterator, + typename = cppsort::detail::enable_if_t< + cppsort::detail::is_invocable_v + > + > + constexpr auto iter_swap(Iterator lhs, Iterator rhs) + -> void + { + auto tmp = iter_move(lhs); + *lhs = iter_move(rhs); + *rhs = std::move(tmp); + } + + template< + typename Iterator, + typename = cppsort::detail::enable_if_t< + not cppsort::detail::is_invocable_v + >, + typename = void // dummy parameter for ODR + > + constexpr auto iter_swap(Iterator lhs, Iterator rhs) + -> void + { + // While this overload is not strictly needed, it + // ensures that an ADL-found swap is used when the + // iterator type does not have a dedicated iter_move + // ADL-found overload + using std::swap; + swap(*lhs, *rhs); + } + + //////////////////////////////////////////////////////////// + // std::reverse_iterator overloads - template - using rvalue_reference_t = decltype(adl_trick::do_iter_move()); + template + auto iter_move(const std::reverse_iterator& it) + -> decltype(iter_move(it.base())) + { + return iter_move(std::prev(it.base())); + } - //////////////////////////////////////////////////////////// - // std::reverse_iterator overloads + template + auto iter_swap(std::reverse_iterator lhs, std::reverse_iterator rhs) + -> void + { + iter_swap(std::prev(lhs.base()), std::prev(rhs.base())); + } - template - auto iter_move(const std::reverse_iterator& it) - -> rvalue_reference_t - { - using utility::iter_move; - return iter_move(std::prev(it.base())); - } + //////////////////////////////////////////////////////////// + // std::move_iterator overloads - template - auto iter_swap(std::reverse_iterator lhs, std::reverse_iterator rhs) - -> void - { - using utility::iter_swap; - iter_swap(std::prev(lhs.base()), std::prev(rhs.base())); - } + template + auto iter_move(const std::move_iterator& it) + -> decltype(iter_move(it.base())) + { + return iter_move(it.base()); + } - //////////////////////////////////////////////////////////// - // std::move_iterator overloads + template + auto iter_swap(std::move_iterator lhs, std::move_iterator rhs) + -> void + { + iter_swap(lhs.base(), rhs.base()); + } - template - auto iter_move(const std::move_iterator& it) - -> rvalue_reference_t - { - using utility::iter_move; - return iter_move(it.base()); - } + //////////////////////////////////////////////////////////// + // rvalue_reference_t type trait - template - auto iter_swap(std::move_iterator lhs, std::move_iterator rhs) - -> void - { - using utility::iter_swap; - iter_swap(lhs.base(), rhs.base()); + template + using rvalue_reference_t = decltype(iter_move(std::declval())); } -}} +} #endif // CPPSORT_UTILITY_ITER_MOVE_H_ From 7c2327b206565acdb6033c92fc6913fa568bb719 Mon Sep 17 00:00:00 2001 From: Morwenn Date: Thu, 30 Jun 2022 14:35:01 +0200 Subject: [PATCH 14/51] Fix iter_move/iter_swap shenanigans (#206) Try my best to get the expected behaviour in both C++14 and C++20 despite the changes brought to the perimeter by C++20 - fix the ambiguous overload issue, also change the iter_move/iter_swap ADL tests to rely on int* instead of std::vectro::iterator in order to avoid some of std:: overloads being found by ADL. --- include/cpp-sort/detail/move.h | 10 +-- include/cpp-sort/detail/reverse.h | 4 +- include/cpp-sort/detail/swap_if.h | 8 +- include/cpp-sort/detail/swap_ranges.h | 4 +- include/cpp-sort/utility/iter_move.h | 109 +++++++++++++++----------- tests/utility/iter_swap.cpp | 17 ++-- 6 files changed, 83 insertions(+), 69 deletions(-) diff --git a/include/cpp-sort/detail/move.h b/include/cpp-sort/detail/move.h index abe14032..3d12b5a0 100644 --- a/include/cpp-sort/detail/move.h +++ b/include/cpp-sort/detail/move.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2021 Morwenn + * Copyright (c) 2019-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_MOVE_H_ @@ -26,7 +26,7 @@ namespace detail template auto move(InputIterator first, InputIterator last, OutputIterator result) -> detail::enable_if_t< - not is_invocable_v, + not cppsort::detail::has_iter_move_v, OutputIterator > { @@ -36,7 +36,7 @@ namespace detail template auto move(InputIterator first, InputIterator last, OutputIterator result) -> detail::enable_if_t< - is_invocable_v, + cppsort::detail::has_iter_move_v, OutputIterator > { @@ -53,7 +53,7 @@ namespace detail template auto move_backward(InputIterator first, InputIterator last, OutputIterator result) -> detail::enable_if_t< - not is_invocable_v, + not cppsort::detail::has_iter_move_v, OutputIterator > { @@ -63,7 +63,7 @@ namespace detail template auto move_backward(InputIterator first, InputIterator last, OutputIterator result) -> detail::enable_if_t< - is_invocable_v, + cppsort::detail::has_iter_move_v, OutputIterator > { diff --git a/include/cpp-sort/detail/reverse.h b/include/cpp-sort/detail/reverse.h index 4a2360fb..8b9092fa 100644 --- a/include/cpp-sort/detail/reverse.h +++ b/include/cpp-sort/detail/reverse.h @@ -48,7 +48,7 @@ namespace detail auto reverse_impl(RandomAccessIterator first, RandomAccessIterator last, std::random_access_iterator_tag) -> detail::enable_if_t< - not is_invocable_v, + not detail::has_iter_move_v, void > { @@ -61,7 +61,7 @@ namespace detail std::random_access_iterator_tag) #if defined(_USE_STD_VECTOR_ALGORITHMS) && _USE_STD_VECTOR_ALGORITHMS -> detail::enable_if_t< - is_invocable_v, + detail::has_iter_move_v, void > #else diff --git a/include/cpp-sort/detail/swap_if.h b/include/cpp-sort/detail/swap_if.h index 04168b30..ff46cff8 100644 --- a/include/cpp-sort/detail/swap_if.h +++ b/include/cpp-sort/detail/swap_if.h @@ -178,8 +178,8 @@ namespace detail typename Compare, typename Projection, typename = detail::enable_if_t< - cppsort::detail::is_invocable_v || - cppsort::detail::is_invocable_v + cppsort::detail::has_iter_move_v || + cppsort::detail::has_iter_swap_v > > auto iter_swap_if(Iterator lhs, Iterator rhs, Compare compare, Projection projection) @@ -199,8 +199,8 @@ namespace detail typename Compare, typename Projection, typename = detail::enable_if_t< - not cppsort::detail::is_invocable_v && - not cppsort::detail::is_invocable_v + not cppsort::detail::has_iter_move_v && + not cppsort::detail::has_iter_swap_v >, typename = void // dummy parameter for ODR > diff --git a/include/cpp-sort/detail/swap_ranges.h b/include/cpp-sort/detail/swap_ranges.h index 6dc11f5f..547dc1cb 100644 --- a/include/cpp-sort/detail/swap_ranges.h +++ b/include/cpp-sort/detail/swap_ranges.h @@ -78,7 +78,7 @@ namespace detail RandomAccessIterator first1, RandomAccessIterator last1, RandomAccessIterator first2) -> detail::enable_if_t< - not is_invocable_v, + not detail::has_iter_move_v, RandomAccessIterator > { @@ -99,7 +99,7 @@ namespace detail RandomAccessIterator first2) #if defined(_USE_STD_VECTOR_ALGORITHMS) && _USE_STD_VECTOR_ALGORITHMS -> detail::enable_if_t< - is_invocable_v, + detail::has_iter_move_v, RandomAccessIterator > #else diff --git a/include/cpp-sort/utility/iter_move.h b/include/cpp-sort/utility/iter_move.h index b15be22c..ed1d2ac3 100644 --- a/include/cpp-sort/utility/iter_move.h +++ b/include/cpp-sort/utility/iter_move.h @@ -18,51 +18,46 @@ namespace cppsort namespace detail { //////////////////////////////////////////////////////////// - // Check whether iter_move and iter_swap are specialized: - // the extra namespace and deleted overloads ensure that the - // call_* classes will only be callable when an iter_move or - // iter_swap overload is found via ADL. + // Check whether iter_move and iter_swap are available for + // the given iterators. Having those checks outside of the + // utility namespace avoids its iter_move and iter_swap + // overloads getting in the way - namespace hide_adl + struct call_iter_move { template - auto iter_move(Iterator) = delete; + auto operator()(Iterator it) const + -> decltype(iter_move(it)); template - auto iter_swap(Iterator, Iterator) = delete; - - struct call_iter_move - { - template - auto operator()(Iterator it) - -> decltype(iter_move(it)); - - template - auto operator()(const std::reverse_iterator& it) - -> decltype(iter_move(it.base())); - - template - auto operator()(const std::move_iterator& it) - -> decltype(iter_move(it.base())); - }; - - struct call_iter_swap - { - template - auto operator()(Iterator it1, Iterator it2) - -> decltype(iter_swap(it1, it2)); - - template - auto operator()(const std::reverse_iterator& it1, - const std::reverse_iterator& it2) - -> decltype(iter_swap(it1.base(), it2.base())); - - template - auto operator()(const std::move_iterator& it1, - const std::move_iterator& it2) - -> decltype(iter_swap(it1.base(), it2.base())); - }; - } + auto operator()(std::move_iterator it) const + -> decltype(iter_move(it.base())); + + template + auto operator()(std::reverse_iterator it) const + -> decltype(iter_move(it.base())); + }; + + struct call_iter_swap + { + template + auto operator()(Iterator it1, Iterator it2) const + -> decltype(iter_swap(it1, it2)); + + template + auto operator()(std::move_iterator it1, std::move_iterator it2) const + -> decltype(iter_swap(it1.base(), it2.base())); + + template + auto operator()(std::reverse_iterator it1, std::reverse_iterator it2) const + -> decltype(iter_swap(it1.base(), it2.base())); + }; + + template + constexpr bool has_iter_move_v = detail::is_invocable_v; + + template + constexpr bool has_iter_swap_v = detail::is_invocable_v; //////////////////////////////////////////////////////////// // Result type of a non-specialized iter_move call @@ -91,7 +86,8 @@ namespace cppsort template< typename Iterator, typename = cppsort::detail::enable_if_t< - cppsort::detail::is_invocable_v + not cppsort::detail::has_iter_swap_v && + cppsort::detail::has_iter_move_v > > constexpr auto iter_swap(Iterator lhs, Iterator rhs) @@ -105,7 +101,8 @@ namespace cppsort template< typename Iterator, typename = cppsort::detail::enable_if_t< - not cppsort::detail::is_invocable_v + not cppsort::detail::has_iter_swap_v && + not cppsort::detail::has_iter_move_v >, typename = void // dummy parameter for ODR > @@ -123,14 +120,24 @@ namespace cppsort //////////////////////////////////////////////////////////// // std::reverse_iterator overloads - template + template< + typename Iterator, + typename = cppsort::detail::enable_if_t< + not cppsort::detail::has_iter_move_v> + > + > auto iter_move(const std::reverse_iterator& it) -> decltype(iter_move(it.base())) { return iter_move(std::prev(it.base())); } - template + template< + typename Iterator, + typename = cppsort::detail::enable_if_t< + not cppsort::detail::has_iter_swap_v> + > + > auto iter_swap(std::reverse_iterator lhs, std::reverse_iterator rhs) -> void { @@ -140,14 +147,24 @@ namespace cppsort //////////////////////////////////////////////////////////// // std::move_iterator overloads - template + template< + typename Iterator, + typename = cppsort::detail::enable_if_t< + not cppsort::detail::has_iter_move_v> + > + > auto iter_move(const std::move_iterator& it) -> decltype(iter_move(it.base())) { return iter_move(it.base()); } - template + template< + typename Iterator, + typename = cppsort::detail::enable_if_t< + not cppsort::detail::has_iter_swap_v> + > + > auto iter_swap(std::move_iterator lhs, std::move_iterator rhs) -> void { diff --git a/tests/utility/iter_swap.cpp b/tests/utility/iter_swap.cpp index 6294d86b..0315d8e8 100644 --- a/tests/utility/iter_swap.cpp +++ b/tests/utility/iter_swap.cpp @@ -109,7 +109,7 @@ TEST_CASE( "ADL tests for swap and iter_swap", std::vector vec = { {}, {} }; using cppsort::utility::iter_swap; - iter_swap(vec.begin(), vec.begin() + 1); + iter_swap(vec.data(), vec.data() + 1); CHECK( vec.front().swap_flag ); CHECK( not vec.front().iter_swap_flag ); CHECK( not vec.front().iter_move_flag ); @@ -118,12 +118,11 @@ TEST_CASE( "ADL tests for swap and iter_swap", SECTION( "custom iter_swap is found" ) { std::vector vec = { {}, {} }; - using it_t = std::vector::iterator; using cppsort::utility::iter_swap; iter_swap( - adl_iter_swap::iterator{vec.begin()}, - adl_iter_swap::iterator{vec.begin() + 1} + adl_iter_swap::iterator{vec.data()}, + adl_iter_swap::iterator{vec.data() + 1} ); CHECK( not vec.front().swap_flag ); CHECK( vec.front().iter_swap_flag ); @@ -133,12 +132,11 @@ TEST_CASE( "ADL tests for swap and iter_swap", SECTION( "custom iter_move is found" ) { std::vector vec = { {}, {} }; - using it_t = std::vector::iterator; using cppsort::utility::iter_swap; iter_swap( - adl_iter_move::iterator{vec.begin()}, - adl_iter_move::iterator{vec.begin() + 1} + adl_iter_move::iterator{vec.data()}, + adl_iter_move::iterator{vec.data() + 1} ); CHECK( not vec.front().swap_flag ); CHECK( not vec.front().iter_swap_flag ); @@ -148,12 +146,11 @@ TEST_CASE( "ADL tests for swap and iter_swap", SECTION( "custom iter_swap is found even when iter_move is there" ) { std::vector vec = { {}, {} }; - using it_t = std::vector::iterator; using cppsort::utility::iter_swap; iter_swap( - adl_iter_swap_and_move::iterator{vec.begin()}, - adl_iter_swap_and_move::iterator{vec.begin() + 1} + adl_iter_swap_and_move::iterator{vec.data()}, + adl_iter_swap_and_move::iterator{vec.data() + 1} ); CHECK( not vec.front().swap_flag ); CHECK( vec.front().iter_swap_flag ); From c0f8af3064eb78d0541e48472eca5eb230d96ce2 Mon Sep 17 00:00:00 2001 From: Morwenn Date: Thu, 30 Jun 2022 15:07:18 +0200 Subject: [PATCH 15/51] Fix MacOS build in CI --- .github/workflows/build-macos.yml | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml index faa3b0c2..877447fb 100644 --- a/.github/workflows/build-macos.yml +++ b/.github/workflows/build-macos.yml @@ -29,8 +29,8 @@ jobs: fail-fast: false matrix: cxx: - - g++-9 - - $(brew --prefix llvm)/bin/clang++ # Clang 11 + - g++-10 + - clang++ config: # Release build - build_type: Release @@ -44,10 +44,31 @@ jobs: - uses: actions/checkout@v3 - uses: seanmiddleditch/gha-setup-ninja@master + - name: Install LLVM and Clang + if: ${{matrix.cxx == 'clang++'}} + uses: KyleMayes/install-llvm-action@v1 + with: + version: "11.0" + + - name: Configure LLVM + if: ${{matrix.cxx == 'clang++'}} + run: | + LLVM_PATH=${{ env.LLVM_PATH }} + LLVM_VERSION=11 + echo "SDKROOT=$(xcrun --sdk macosx --show-sdk-path)" >> $GITHUB_ENV + echo "CPATH=$LLVM_PATH/lib/clang/$LLVM_VERSION/include/" >> $GITHUB_ENV + echo "LDFLAGS=-L$LLVM_PATH/lib" >> $GITHUB_ENV + echo "CPPFLAGS=-I$LLVM_PATH/include" >> $GITHUB_ENV + echo "CC=$LLVM_PATH/bin/clang" >> $GITHUB_ENV + echo "CXX=$LLVM_PATH/bin/clang++" >> $GITHUB_ENV + + - name: Configure GCC + if: ${{matrix.cxx != 'clang++'}} + run: echo "CXX=${{ matrix.cxx }}" >> $GITHUB_ENV + - name: Configure CMake working-directory: ${{runner.workspace}} run: | - export CXX=${{matrix.cxx}} cmake -H${{github.event.repository.name}} -Bbuild \ -DCMAKE_CONFIGURATION_TYPES=${{matrix.config.build_type}} \ -DCMAKE_BUILD_TYPE=${{matrix.config.build_type}} \ From 56f5daba31586745ec28d85374938707b367a1d7 Mon Sep 17 00:00:00 2001 From: Morwenn Date: Thu, 30 Jun 2022 17:38:51 +0200 Subject: [PATCH 16/51] Try to build the project with Clang 10 --- .github/workflows/build-macos.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml index 877447fb..eae1266a 100644 --- a/.github/workflows/build-macos.yml +++ b/.github/workflows/build-macos.yml @@ -48,13 +48,13 @@ jobs: if: ${{matrix.cxx == 'clang++'}} uses: KyleMayes/install-llvm-action@v1 with: - version: "11.0" + version: "10.0" - name: Configure LLVM if: ${{matrix.cxx == 'clang++'}} run: | LLVM_PATH=${{ env.LLVM_PATH }} - LLVM_VERSION=11 + LLVM_VERSION=10 echo "SDKROOT=$(xcrun --sdk macosx --show-sdk-path)" >> $GITHUB_ENV echo "CPATH=$LLVM_PATH/lib/clang/$LLVM_VERSION/include/" >> $GITHUB_ENV echo "LDFLAGS=-L$LLVM_PATH/lib" >> $GITHUB_ENV From e5d3dacab046c8c65f0707be3e9d5f0cc1e65658 Mon Sep 17 00:00:00 2001 From: Morwenn Date: Thu, 7 Jul 2022 11:18:53 +0200 Subject: [PATCH 17/51] Fix make_projection_copare with std::identity Due to a copy-paste error, make_projection_compare would fail to compile when passed std::identity. --- include/cpp-sort/comparators/projection_compare.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/cpp-sort/comparators/projection_compare.h b/include/cpp-sort/comparators/projection_compare.h index 219282a5..2bf1292a 100644 --- a/include/cpp-sort/comparators/projection_compare.h +++ b/include/cpp-sort/comparators/projection_compare.h @@ -157,13 +157,13 @@ namespace cppsort { using type = Compare; - static constexpr auto construct(const Compare& comp, const utility::identity&) + static constexpr auto construct(const Compare& comp, const std::identity&) -> type { return comp; } - static constexpr auto construct(Compare&& comp, const utility::identity&) + static constexpr auto construct(Compare&& comp, const std::identity&) -> type { return comp; From b8080f42957808e1b234d36ac4e73b900d565879 Mon Sep 17 00:00:00 2001 From: Morwenn Date: Fri, 8 Jul 2022 00:40:28 +0200 Subject: [PATCH 18/51] typo --- docs/Writing-a-bubble_sorter.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Writing-a-bubble_sorter.md b/docs/Writing-a-bubble_sorter.md index eaa6fd77..790d74fe 100644 --- a/docs/Writing-a-bubble_sorter.md +++ b/docs/Writing-a-bubble_sorter.md @@ -254,7 +254,7 @@ struct bubble_sorter_impl }; ``` -We can see several improvements compared to the previous version: first of all, we added an optional projection parameter which defauts to [`utility::identity`][utility-identity] (in C++20 we would use [`std::identity`][std-identity]). This is a function object that takes a value and returns it as is so that the default behaviour of the algorithm is to run *as if* projections didn't exist. It is very likely to be optimized aways by the compiler. +We can see several improvements compared to the previous version: first of all, we added an optional projection parameter which defauts to [`utility::identity`][utility-identity] (in C++20 we would use [`std::identity`][std-identity]). This is a function object that takes a value and returns it as is so that the default behaviour of the algorithm is to run *as if* projections didn't exist. It is very likely to be optimized away by the compiler. The second modification is one I wish we could do without (but will have to live with until concepts): [`is_projection_iterator_v`][is-projection] is a trait that checks whether a projection function can be used on a dereferenced iterator. It also optionally checks that a given comparison function can be called with the result of two such projections. This trait exists to ensure that a sorter's `operator()` won't be called when these conditions are not satisfied, which may be crucial when aggregating sorters with [`hybrid_adapter`][hybrid-adapter]. From 2f9e9133f1f2b03f9f87af23a979a4e58fb4b772 Mon Sep 17 00:00:00 2001 From: Morwenn Date: Fri, 8 Jul 2022 00:43:30 +0200 Subject: [PATCH 19/51] Remove unused #includes --- include/cpp-sort/detail/longest_non_descending_subsequence.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/include/cpp-sort/detail/longest_non_descending_subsequence.h b/include/cpp-sort/detail/longest_non_descending_subsequence.h index 0e9e56a7..4cd64ba7 100644 --- a/include/cpp-sort/detail/longest_non_descending_subsequence.h +++ b/include/cpp-sort/detail/longest_non_descending_subsequence.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Morwenn + * Copyright (c) 2021-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_LONGEST_NON_DESCENDING_SUBSEQUENCE_H_ @@ -13,9 +13,6 @@ #include #include #include -#include -#include -#include #include "functional.h" #include "iterator_traits.h" #include "upper_bound.h" From a8ff09003d3204c831734ab5f78357dfcf2354da Mon Sep 17 00:00:00 2001 From: Morwenn Date: Mon, 11 Jul 2022 20:21:32 +0200 Subject: [PATCH 20/51] adaptive_quickselect: fewer projections in pivot_partition Just a small change, but it allows to perform up to 1% fewer projections in slab_sort and quick_merge_sort. --- include/cpp-sort/detail/adaptive_quickselect.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/include/cpp-sort/detail/adaptive_quickselect.h b/include/cpp-sort/detail/adaptive_quickselect.h index 1736c337..c5b88bb5 100644 --- a/include/cpp-sort/detail/adaptive_quickselect.h +++ b/include/cpp-sort/detail/adaptive_quickselect.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Morwenn + * Copyright (c) 2021-2022 Morwenn * SPDX-License-Identifier: MIT */ @@ -47,17 +47,19 @@ namespace detail CPPSORT_ASSERT(k < length); iter_swap(r, r + k); + auto&& pivot_proj = proj(*r); + difference_type_t lo = 1, hi = length - 1; for (;; ++lo, --hi) { for (;; ++lo) { if (lo > hi) { goto loop_done; } - if (not comp(proj(r[lo]), proj(*r))) break; + if (not comp(proj(r[lo]), pivot_proj)) break; } // found the left bound: r[lo] >= r[0] CPPSORT_ASSERT(lo <= hi); - for (; comp(proj(*r), proj(r[hi])) ; --hi) {} + for (; comp(pivot_proj, proj(r[hi])) ; --hi) {} if (lo >= hi) break; // found the right bound: r[hi] <= r[0], swap & make progress iter_swap(r + lo, r + hi); From 243ff03da1a3d253e9da106745e892a796f87e2c Mon Sep 17 00:00:00 2001 From: Morwenn Date: Tue, 12 Jul 2022 14:26:21 +0200 Subject: [PATCH 21/51] Remove custom_std_partition from ska_sort Despite the claims on the original blog post, the only differences I found between that and the libc++ implementation were at best lost in the noise. --- include/cpp-sort/detail/ska_sort.h | 48 ++++++------------------------ 1 file changed, 9 insertions(+), 39 deletions(-) diff --git a/include/cpp-sort/detail/ska_sort.h b/include/cpp-sort/detail/ska_sort.h index 15bf2c5e..d96b710e 100644 --- a/include/cpp-sort/detail/ska_sort.h +++ b/include/cpp-sort/detail/ska_sort.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2021 Morwenn + * Copyright (c) 2017-2022 Morwenn * SPDX-License-Identifier: MIT */ @@ -13,13 +13,10 @@ //////////////////////////////////////////////////////////// // Headers //////////////////////////////////////////////////////////// -#include -#include #include #include #include #include -#include #include #include #include @@ -27,8 +24,9 @@ #include #include #include "attributes.h" -#include "iterator_traits.h" +#include "iterator_traits.h" // projected_t #include "memcpy_cast.h" +#include "partition.h" #include "pdqsort.h" #include "type_traits.h" @@ -214,34 +212,6 @@ namespace detail } } - template - auto custom_std_partition(RandomAccessIterator begin, RandomAccessIterator end, - Function function) - -> RandomAccessIterator - { - auto&& func = utility::as_function(function); - - for (;; ++begin) { - if (begin == end) { - return end; - } - if (not func(*begin)) { - break; - } - } - RandomAccessIterator it = begin; - for (++it ; it != end ; ++it) { - if (not func(*it)) { - continue; - } - - using utility::iter_swap; - iter_swap(begin, it); - ++begin; - } - return begin; - } - struct PartitionInfo { PartitionInfo(): @@ -706,8 +676,8 @@ namespace detail for (std::uint8_t *last_remaining = remaining_partitions + num_partitions, *end_partition = remaining_partitions + 1 ; last_remaining > end_partition ;) { - last_remaining = custom_std_partition(remaining_partitions, last_remaining, - [&](std::uint8_t partition) { + last_remaining = detail::partition(remaining_partitions, last_remaining, + [&](std::uint8_t partition) { std::size_t& begin_offset = partitions[partition].offset; std::size_t& end_offset = partitions[partition].next_offset; if (begin_offset == end_offset) { @@ -810,7 +780,7 @@ namespace detail return ElementSubKey::base::sub_key(elem, sort_data); }; sort_data->current_index = current_index = CommonPrefix(begin, end, current_index, current_key, element_key); - auto end_of_shorter_ones = std::partition(begin, end, [&](auto&& elem) { + auto end_of_shorter_ones = detail::partition(begin, end, [&](auto&& elem) { return current_key(elem).size() <= current_index; }); std::ptrdiff_t num_shorter_ones = end_of_shorter_ones - begin; @@ -871,9 +841,9 @@ namespace detail { auto&& proj = utility::as_function(projection); - auto middle = std::partition(begin, end, [&](auto&& a) { - return not CurrentSubKey::sub_key(proj(a), sort_data); - }); + auto middle = detail::partition(begin, end, [&](auto&& a) { + return not CurrentSubKey::sub_key(proj(a), sort_data); + }); if (next_sort) { next_sort(begin, middle, middle - begin, projection, sort_data); next_sort(middle, end, end - middle, projection, sort_data); From 7d40f7fefbd720e1413f746d3e0bb0b4e57e110a Mon Sep 17 00:00:00 2001 From: Morwenn Date: Tue, 12 Jul 2022 15:29:37 +0200 Subject: [PATCH 22/51] Reimplement partition_pivot in terms of partition This apparently slightly reduces the number of comparisons performed, mostly doesn't change anything to the running time of the algorithm, avoids code duplication and removes one of the library's remaining gotos. --- .../cpp-sort/detail/adaptive_quickselect.h | 28 +++++-------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/include/cpp-sort/detail/adaptive_quickselect.h b/include/cpp-sort/detail/adaptive_quickselect.h index c5b88bb5..1948bcbd 100644 --- a/include/cpp-sort/detail/adaptive_quickselect.h +++ b/include/cpp-sort/detail/adaptive_quickselect.h @@ -27,6 +27,7 @@ #include #include #include "config.h" +#include "partition.h" #include "type_traits.h" namespace cppsort @@ -46,28 +47,13 @@ namespace detail auto&& proj = utility::as_function(projection); CPPSORT_ASSERT(k < length); - iter_swap(r, r + k); + iter_swap(r, r + k); // Move pivot out of the way auto&& pivot_proj = proj(*r); - - difference_type_t lo = 1, hi = length - 1; - for (;; ++lo, --hi) { - for (;; ++lo) { - if (lo > hi) { - goto loop_done; - } - if (not comp(proj(r[lo]), pivot_proj)) break; - } - // found the left bound: r[lo] >= r[0] - CPPSORT_ASSERT(lo <= hi); - for (; comp(pivot_proj, proj(r[hi])) ; --hi) {} - if (lo >= hi) break; - // found the right bound: r[hi] <= r[0], swap & make progress - iter_swap(r + lo, r + hi); - } - loop_done: - --lo; - iter_swap(r + lo, r); - return r + lo; + auto pivot_pos = detail::partition(r, r + length, [&](auto&& elem) { + return not comp(pivot_proj, proj(elem)); + }); + iter_swap(r, --pivot_pos); // Put pivot back in its place + return pivot_pos; } template From f982c8cdd905563c2dc0b19f8110f71528b37d7e Mon Sep 17 00:00:00 2001 From: Morwenn Date: Tue, 12 Jul 2022 16:40:29 +0200 Subject: [PATCH 23/51] Tweak expand_partition_left and expand_partition_right Apply changes similar to those applied to pivot_partition: - Perform fewer redundant projections - Duplicate some code to get rid of goto Also remove some useless #include from the adaptive_quickselect.h header. --- .../cpp-sort/detail/adaptive_quickselect.h | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/include/cpp-sort/detail/adaptive_quickselect.h b/include/cpp-sort/detail/adaptive_quickselect.h index 1948bcbd..8c562f86 100644 --- a/include/cpp-sort/detail/adaptive_quickselect.h +++ b/include/cpp-sort/detail/adaptive_quickselect.h @@ -19,10 +19,6 @@ //////////////////////////////////////////////////////////// // Headers //////////////////////////////////////////////////////////// -#include -#include -#include -#include #include #include #include @@ -176,11 +172,13 @@ namespace detail CPPSORT_ASSERT(lo > 0 && lo <= pivot); difference_type_t left = 0; const auto oldPivot = pivot; + auto&& old_pivot_proj = proj(r[oldPivot]); for (; lo < pivot ; ++left) { if (left == lo) { - goto done; + iter_swap(r + oldPivot, r + pivot); + return pivot; } - if (not comp(proj(r[oldPivot]), proj(r[left]))) continue; + if (not comp(old_pivot_proj, proj(r[left]))) continue; --pivot; iter_swap(r + left, r + pivot); } @@ -188,20 +186,20 @@ namespace detail // Second loop: make left and pivot meet for (;; ++left) { if (left == pivot) break; - if (not comp(proj(r[oldPivot]), proj(r[left]))) continue; + if (not comp(old_pivot_proj, proj(r[left]))) continue; for (;;) { if (left == pivot) { - goto done; + iter_swap(r + oldPivot, r + pivot); + return pivot; } --pivot; - if (comp(proj(r[pivot]), proj(r[oldPivot]))) { + if (comp(proj(r[pivot]), old_pivot_proj)) { iter_swap(r + left, r + pivot); break; } } } - done: iter_swap(r + oldPivot, r + pivot); return pivot; } @@ -219,30 +217,31 @@ namespace detail difference_type_t pivot = 0; CPPSORT_ASSERT(pivot <= hi); CPPSORT_ASSERT(hi <= rite); + auto&& pivot_proj = proj(r[0]); // First loop: spend r[pivot .. hi] for (; pivot < hi ; --rite) { if (rite == hi) { - goto done; + iter_swap(r, r + pivot); + return pivot; } - if (not comp(proj(r[rite]), proj(r[0]))) continue; + if (not comp(proj(r[rite]), pivot_proj)) continue; ++pivot; iter_swap(r + rite, r + pivot); } // Second loop: make left and pivot meet for (; rite > pivot ; --rite) { - if (not comp(proj(r[rite]), proj(r[0]))) continue; + if (not comp(proj(r[rite]), pivot_proj)) continue; while (rite > pivot) { ++pivot; - if (comp(proj(r[0]), proj(r[pivot]))) { + if (comp(pivot_proj, proj(r[pivot]))) { iter_swap(r + rite, r + pivot); break; } } } - done: iter_swap(r, r + pivot); return pivot; } From 514c0c962af8cd5259cbaa213578c47a819894fc Mon Sep 17 00:00:00 2001 From: Morwenn Date: Fri, 15 Jul 2022 17:38:14 +0200 Subject: [PATCH 24/51] Add a test for counting_sort with std::greater --- tests/sorters/counting_sorter.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/sorters/counting_sorter.cpp b/tests/sorters/counting_sorter.cpp index 91f3c949..d3e5cf0e 100644 --- a/tests/sorters/counting_sorter.cpp +++ b/tests/sorters/counting_sorter.cpp @@ -4,6 +4,7 @@ */ #include #include +#include #include #include #include @@ -26,6 +27,14 @@ TEST_CASE( "counting_sorter tests", "[counting_sorter]" ) CHECK( std::is_sorted(vec.begin(), vec.end()) ); } + SECTION( "reverse sort with int iterable" ) + { + std::vector vec; vec.reserve(size); + distribution(std::back_inserter(vec), size, -1568); + cppsort::counting_sort(vec, std::greater<>{}); + CHECK( std::is_sorted(vec.begin(), vec.end(), std::greater<>{}) ); + } + SECTION( "sort with unsigned int iterators" ) { std::list li; From 5f7c7a0dd76d06376a9e277972e5047a9606ad3e Mon Sep 17 00:00:00 2001 From: Morwenn Date: Fri, 15 Jul 2022 18:41:04 +0200 Subject: [PATCH 25/51] Use immovable_vector to implement counting_sorter --- include/cpp-sort/detail/counting_sort.h | 39 +++++++++++++++---------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/include/cpp-sort/detail/counting_sort.h b/include/cpp-sort/detail/counting_sort.h index 9486befb..8c0b366b 100644 --- a/include/cpp-sort/detail/counting_sort.h +++ b/include/cpp-sort/detail/counting_sort.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2020 Morwenn + * Copyright (c) 2016-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_COUNTING_SORT_H_ @@ -10,7 +10,8 @@ //////////////////////////////////////////////////////////// #include #include -#include +#include +#include "immovable_vector.h" #include "iterator_traits.h" #include "minmax_element_and_is_sorted.h" @@ -22,21 +23,25 @@ namespace detail auto counting_sort(ForwardIterator first, ForwardIterator last) -> void { + using difference_type = difference_type_t; + auto info = minmax_element_and_is_sorted(first, last); if (info.is_sorted) return; - using difference_type = difference_type_t; auto min = *info.min; auto max = *info.max; - std::vector counts(max - min + 1, 0); + difference_type value_range = max - min + 1; + + immovable_vector counts(value_range); + for (difference_type n = 0; n < value_range; ++n) { + counts.emplace_back(0); + } - for (auto it = first ; it != last ; ++it) - { + for (auto it = first; it != last; ++it) { ++counts[*it - min]; } - for (auto count: counts) - { + for (auto count: counts) { first = std::fill_n(first, count, min++); } } @@ -45,22 +50,26 @@ namespace detail auto reverse_counting_sort(ForwardIterator first, ForwardIterator last) -> void { + using difference_type = difference_type_t; + auto info = minmax_element_and_is_sorted(first, last, std::greater<>{}); if (info.is_sorted) return; - using difference_type = difference_type_t; auto min = *info.max; auto max = *info.min; - std::vector counts(max - min + 1, 0); + difference_type value_range = max - min + 1; + + immovable_vector counts(value_range); + for (difference_type n = 0; n < value_range; ++n) { + counts.emplace_back(0); + } - for (auto it = first ; it != last ; ++it) - { + for (auto it = first; it != last; ++it) { ++counts[*it - min]; } - for (auto rit = counts.rbegin() ; rit != counts.rend() ; ++rit) - { - auto count = *rit; + for (auto rit = counts.end(); rit != counts.begin(); --rit) { + auto count = *std::prev(rit); first = std::fill_n(first, count, max--); } } From c29f3834bd834c7b21cd4eae6f486992ae43b2af Mon Sep 17 00:00:00 2001 From: Morwenn Date: Sun, 17 Jul 2022 22:45:07 +0200 Subject: [PATCH 26/51] Bump required Catch2 version to v3.1.0 --- tests/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index da3a53fc..8eca1d16 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -18,8 +18,8 @@ option(CPPSORT_STATIC_TESTS "Whether to turn some tests into static assertions" ######################################## # Find or download Catch2 -message(STATUS "Looking for Catch2 3.0.0+") -find_package(Catch2 3.0.0 QUIET) +message(STATUS "Looking for Catch2 3.1.0+") +find_package(Catch2 3.1.0 QUIET) if (TARGET Catch2::Catch2) get_target_property(Catch2_INCLUDE_DIRECTORY Catch2::Catch2 INTERFACE_INCLUDE_DIRECTORIES) message(STATUS "Catch2 found: ${Catch2_INCLUDE_DIRECTORY}") @@ -27,7 +27,7 @@ else() message(STATUS "Catch2 not found") download_project(PROJ Catch2 GIT_REPOSITORY https://github.com/catchorg/Catch2 - GIT_TAG v3.0.0-preview4 + GIT_TAG v3.1.0 UPDATE_DISCONNECTED 1 ) add_subdirectory(${Catch2_SOURCE_DIR} ${Catch2_BINARY_DIR}) From 96a2d51645eeb5463e5fa845e3c8d6045962c38b Mon Sep 17 00:00:00 2001 From: Morwenn Date: Thu, 21 Jul 2022 17:33:28 +0200 Subject: [PATCH 27/51] constexpr hybird_adapter (#58) --- include/cpp-sort/adapters/hybrid_adapter.h | 14 ++++++------- tests/sorter_facade_constexpr.cpp | 23 +++++++++++++++++----- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/include/cpp-sort/adapters/hybrid_adapter.h b/include/cpp-sort/adapters/hybrid_adapter.h index 33fec453..649ade18 100644 --- a/include/cpp-sort/adapters/hybrid_adapter.h +++ b/include/cpp-sort/adapters/hybrid_adapter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_ADAPTERS_HYBRID_ADAPTER_H_ @@ -107,14 +107,14 @@ namespace cppsort // position into the sorters template - auto operator()(choice, Args&&... args) const + constexpr auto operator()(choice, Args&&... args) const -> decltype(this->get()(std::forward(args)...)) { return this->get()(std::forward(args)...); } template - static auto _detail_stability(choice, Args&&... args) + static constexpr auto _detail_stability(choice, Args&&... args) -> detail::enable_if_t< is_invocable_v, is_stable @@ -272,7 +272,7 @@ namespace cppsort // Call operator template - auto operator()(Iterable&& iterable, Args&&... args) const + constexpr auto operator()(Iterable&& iterable, Args&&... args) const -> decltype(base_class::operator()( detail::choice_for_it{}, std::forward(iterable), @@ -287,7 +287,7 @@ namespace cppsort } template - auto operator()(Iterator first, Iterator last, Args&&... args) const + constexpr auto operator()(Iterator first, Iterator last, Args&&... args) const -> decltype(base_class::operator()( detail::choice_for_it{}, std::move(first), std::move(last), @@ -305,7 +305,7 @@ namespace cppsort // Stability of a call template - static auto _detail_stability(Iterable&& iterable, Args&&... args) + static constexpr auto _detail_stability(Iterable&& iterable, Args&&... args) -> decltype(base_class::_detail_stability( detail::choice_for_it{}, std::forward(iterable), @@ -313,7 +313,7 @@ namespace cppsort )); template - static auto _detail_stability(Iterator first, Iterator last, Args&&... args) + static constexpr auto _detail_stability(Iterator first, Iterator last, Args&&... args) -> decltype(base_class::_detail_stability( detail::choice_for_it{}, std::move(first), std::move(last), diff --git a/tests/sorter_facade_constexpr.cpp b/tests/sorter_facade_constexpr.cpp index d4dfc26f..71bb0c55 100644 --- a/tests/sorter_facade_constexpr.cpp +++ b/tests/sorter_facade_constexpr.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -63,12 +64,13 @@ namespace cppsort::sorter_facade {}; + template constexpr auto test_sorter() -> bool { constexpr std::size_t size = 13; int collection[size] = { 15, 6, 0, 2, 2, 3, 8, 12, 10, 5, 9, 7, 10 }; - constexpr_insertion_sorter sorter; + Sorter sorter; sorter(collection, collection + size); return helpers::is_sorted(collection, collection + size); } @@ -76,8 +78,19 @@ namespace TEST_CASE( "test basic constexpr support", "[sorter_facade][constexpr]" ) { - // Check that sorter_facade can be useful in a constexpr constext - // if the sorter implementation is constexpr-friendly itself - constexpr bool is_sorted = test_sorter(); - STATIC_CHECK( is_sorted ); + SECTION( "simple test" ) + { + // Check that sorter_facade can be useful in a constexpr constext + // if the sorter implementation is constexpr-friendly itself + constexpr bool is_sorted = test_sorter(); + STATIC_CHECK( is_sorted ); + } + + SECTION( "hybrid_adapter test" ) + { + constexpr bool is_sorted = test_sorter< + cppsort::hybrid_adapter + >(); + STATIC_CHECK( is_sorted ); + } } From ad037c7f8687ba028f13c2dc1aa37aa59e7370cf Mon Sep 17 00:00:00 2001 From: Morwenn Date: Thu, 21 Jul 2022 18:13:38 +0200 Subject: [PATCH 28/51] CI: switch from macos-10.15 to macos-11 The macos-10.15 image is deprecated and will soon be removed. --- .github/workflows/build-macos.yml | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml index eae1266a..355645de 100644 --- a/.github/workflows/build-macos.yml +++ b/.github/workflows/build-macos.yml @@ -23,7 +23,7 @@ on: jobs: build: - runs-on: macos-10.15 + runs-on: macos-11 strategy: fail-fast: false @@ -42,38 +42,15 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: seanmiddleditch/gha-setup-ninja@master - - - name: Install LLVM and Clang - if: ${{matrix.cxx == 'clang++'}} - uses: KyleMayes/install-llvm-action@v1 - with: - version: "10.0" - - - name: Configure LLVM - if: ${{matrix.cxx == 'clang++'}} - run: | - LLVM_PATH=${{ env.LLVM_PATH }} - LLVM_VERSION=10 - echo "SDKROOT=$(xcrun --sdk macosx --show-sdk-path)" >> $GITHUB_ENV - echo "CPATH=$LLVM_PATH/lib/clang/$LLVM_VERSION/include/" >> $GITHUB_ENV - echo "LDFLAGS=-L$LLVM_PATH/lib" >> $GITHUB_ENV - echo "CPPFLAGS=-I$LLVM_PATH/include" >> $GITHUB_ENV - echo "CC=$LLVM_PATH/bin/clang" >> $GITHUB_ENV - echo "CXX=$LLVM_PATH/bin/clang++" >> $GITHUB_ENV - - - name: Configure GCC - if: ${{matrix.cxx != 'clang++'}} - run: echo "CXX=${{ matrix.cxx }}" >> $GITHUB_ENV - name: Configure CMake working-directory: ${{runner.workspace}} run: | + export CXX=${{matrix.cxx}} cmake -H${{github.event.repository.name}} -Bbuild \ -DCMAKE_CONFIGURATION_TYPES=${{matrix.config.build_type}} \ -DCMAKE_BUILD_TYPE=${{matrix.config.build_type}} \ -DCPPSORT_SANITIZE=${{matrix.config.sanitize}} \ - -GNinja \ -DCPPSORT_BUILD_EXAMPLES=ON - name: Build the test suite From 69e7cd74979d23e7f227a409d100b59e65138e53 Mon Sep 17 00:00:00 2001 From: Morwenn Date: Sun, 31 Jul 2022 15:02:33 +0200 Subject: [PATCH 29/51] Replace is_hybrid_adapter with is_specialization_of --- include/cpp-sort/adapters/hybrid_adapter.h | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/include/cpp-sort/adapters/hybrid_adapter.h b/include/cpp-sort/adapters/hybrid_adapter.h index 649ade18..a20b60ff 100644 --- a/include/cpp-sort/adapters/hybrid_adapter.h +++ b/include/cpp-sort/adapters/hybrid_adapter.h @@ -29,22 +29,6 @@ namespace cppsort namespace detail { - //////////////////////////////////////////////////////////// - // Trait to detect hybrid_adapter - - template - struct is_hybrid_adapter_impl: - std::false_type - {}; - - template - struct is_hybrid_adapter_impl>: - std::true_type - {}; - - template - using is_hybrid_adapter = is_hybrid_adapter_impl>; - //////////////////////////////////////////////////////////// // Overload resolution tool @@ -395,7 +379,7 @@ namespace cppsort template static constexpr auto get_flat_tuple(Sorter&& value) -> detail::enable_if_t< - not detail::is_hybrid_adapter::value, + not detail::is_specialization_of_v, cppsort::hybrid_adapter>, std::tuple&&> > { @@ -405,7 +389,7 @@ namespace cppsort template static constexpr auto get_flat_tuple(Sorter&& value) -> detail::enable_if_t< - detail::is_hybrid_adapter::value, + detail::is_specialization_of_v, cppsort::hybrid_adapter>, decltype(get_sorters_from_impl(std::move(value))) > { From 5841d3273059b4d5493de3412874bda9cd55ff5b Mon Sep 17 00:00:00 2001 From: Morwenn Date: Sat, 13 Aug 2022 13:43:46 +0200 Subject: [PATCH 30/51] Replace is_as_comparison/projection with is_specialization_of --- include/cpp-sort/utility/functional.h | 28 ++++----------------------- 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/include/cpp-sort/utility/functional.h b/include/cpp-sort/utility/functional.h index 42396cd6..1d62d690 100644 --- a/include/cpp-sort/utility/functional.h +++ b/include/cpp-sort/utility/functional.h @@ -164,16 +164,6 @@ namespace utility } }; - template - struct is_as_projection_fn: - std::false_type - {}; - - template - struct is_as_projection_fn>: - std::true_type - {}; - template struct as_comparison_fn: cppsort::detail::raw_check_is_transparent @@ -230,22 +220,12 @@ namespace utility return std::move(as_function(_func))(std::forward(lhs), std::forward(rhs)); } }; - - template - struct is_as_comparison_fn: - std::false_type - {}; - - template - struct is_as_comparison_fn>: - std::true_type - {}; } template constexpr auto as_projection(Function&& func) -> cppsort::detail::enable_if_t< - not detail::is_as_projection_fn>::value, + not cppsort::detail::is_specialization_of_v, detail::as_projection_fn>, detail::as_projection_fn> > { @@ -255,7 +235,7 @@ namespace utility template constexpr auto as_projection(Function&& func) -> cppsort::detail::enable_if_t< - detail::is_as_projection_fn>::value, + cppsort::detail::is_specialization_of_v, detail::as_projection_fn>, decltype(std::forward(func)) > { @@ -265,7 +245,7 @@ namespace utility template constexpr auto as_comparison(Function&& func) -> cppsort::detail::enable_if_t< - not detail::is_as_comparison_fn>::value, + not cppsort::detail::is_specialization_of_v, detail::as_comparison_fn>, detail::as_comparison_fn> > { @@ -275,7 +255,7 @@ namespace utility template constexpr auto as_comparison(Function&& func) -> cppsort::detail::enable_if_t< - detail::is_as_comparison_fn>::value, + cppsort::detail::is_specialization_of_v, detail::as_comparison_fn>, decltype(std::forward(func)) > { From b05c0200195b561bf0a9e52d2aca78c1f9f45586 Mon Sep 17 00:00:00 2001 From: Morwenn Date: Sat, 13 Aug 2022 23:11:21 +0200 Subject: [PATCH 31/51] [u]int128 support for total/weak/partial comparators --- docs/Comparators.md | 6 ++++++ include/cpp-sort/comparators/total_greater.h | 4 ++-- include/cpp-sort/comparators/total_less.h | 4 ++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/Comparators.md b/docs/Comparators.md index 05221f31..246c1266 100644 --- a/docs/Comparators.md +++ b/docs/Comparators.md @@ -29,6 +29,8 @@ Total order comparators are considered as [generating branchless code][branchles *Changed in version 1.5.0:* `total_greater` and `total_less` are respectively of type `total_greater_t` and `total_less_t`. +*Changed in version 1.13.1:* support for `[un]signed __int128`. + ### Weak order comparators ```cpp @@ -51,6 +53,8 @@ Weak order comparators are considered as [generating branchless code][branchless *Changed in version 1.5.0:* `weak_greater` and `weak_less` are respectively of type `weak_greater_t` and `weak_less_t`. +*Changed in version 1.13.1:* support for `[un]signed __int128`. + ### Partial order comparators ```cpp @@ -66,6 +70,8 @@ Partial order comparators are considered as [generating branchless code][branchl *Changed in version 1.5.0:* `partial_greater` and `partial_less` are respectively of type `partial_greater_t` and `partial_less_t`. +*Changed in version 1.13.1:* support for `[un]signed __int128`. + ### Natural order comparator ```cpp diff --git a/include/cpp-sort/comparators/total_greater.h b/include/cpp-sort/comparators/total_greater.h index 80c6bc72..ffe62a7f 100644 --- a/include/cpp-sort/comparators/total_greater.h +++ b/include/cpp-sort/comparators/total_greater.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 Morwenn + * Copyright (c) 2016-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_COMPARATORS_TOTAL_GREATER_H_ @@ -25,7 +25,7 @@ namespace cppsort template constexpr auto total_greater(T lhs, T rhs) noexcept - -> detail::enable_if_t::value, bool> + -> detail::enable_if_t::value, bool> { return lhs > rhs; } diff --git a/include/cpp-sort/comparators/total_less.h b/include/cpp-sort/comparators/total_less.h index 6e09ae82..76e9bafb 100644 --- a/include/cpp-sort/comparators/total_less.h +++ b/include/cpp-sort/comparators/total_less.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 Morwenn + * Copyright (c) 2016-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_COMPARATORS_TOTAL_LESS_H_ @@ -25,7 +25,7 @@ namespace cppsort template constexpr auto total_less(T lhs, T rhs) noexcept - -> detail::enable_if_t::value, bool> + -> detail::enable_if_t::value, bool> { return lhs < rhs; } From 3068849783e562000269401bf712b0599b7f1bdd Mon Sep 17 00:00:00 2001 From: Morwenn Date: Sun, 14 Aug 2022 18:38:51 +0200 Subject: [PATCH 32/51] Add missing include to string_spread_sort --- include/cpp-sort/detail/spreadsort/detail/string_sort.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/cpp-sort/detail/spreadsort/detail/string_sort.h b/include/cpp-sort/detail/spreadsort/detail/string_sort.h index 06cd0029..94ef94f2 100644 --- a/include/cpp-sort/detail/spreadsort/detail/string_sort.h +++ b/include/cpp-sort/detail/spreadsort/detail/string_sort.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ @@ -33,6 +33,7 @@ Phil Endecott and Frank Gennari #include #include "common.h" #include "constants.h" +#include "../../pdqsort.h" #include "../../type_traits.h" namespace cppsort From 639571964bb3b96300278383781854f2c56e3fb6 Mon Sep 17 00:00:00 2001 From: Morwenn Date: Mon, 15 Aug 2022 12:20:49 +0200 Subject: [PATCH 33/51] Reduce the amount of projections in string_spread_sort --- .../detail/spreadsort/detail/string_sort.h | 46 +++++++++---------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/include/cpp-sort/detail/spreadsort/detail/string_sort.h b/include/cpp-sort/detail/spreadsort/detail/string_sort.h index 94ef94f2..2894b339 100644 --- a/include/cpp-sort/detail/spreadsort/detail/string_sort.h +++ b/include/cpp-sort/detail/spreadsort/detail/string_sort.h @@ -102,23 +102,22 @@ namespace spreadsort -> bool { auto&& proj = utility::as_function(std::get<1>(data)); + auto&& proj_x = proj(x); + auto&& proj_y = proj(y); - std::size_t minSize = (std::min)(proj(x).size(), proj(y).size()); - for (std::size_t u = std::get<0>(data) ; u < minSize ; ++u) - { - static_assert(sizeof(proj(x)[u]) == sizeof(Unsigned_char_type), ""); - if (static_cast(proj(x)[u]) != - static_cast(proj(y)[u])) - { - return static_cast(proj(x)[u]) < - static_cast(proj(y)[u]); + std::size_t minSize = (std::min)(proj_x.size(), proj_y.size()); + for (std::size_t u = std::get<0>(data); u < minSize; ++u) { + static_assert(sizeof(proj_x[u]) == sizeof(Unsigned_char_type), ""); + if (static_cast(proj_x[u]) != static_cast(proj_y[u])) { + return static_cast(proj_x[u]) < + static_cast(proj_y[u]); } } - return proj(x).size() < proj(y).size(); + return proj_x.size() < proj_y.size(); } - // Pack fchar_offset and projection - std::tuple data; + // Pack char_offset and projection + std::tuple data; }; //Compares strings assuming they are identical up to char_offset @@ -134,23 +133,22 @@ namespace spreadsort -> bool { auto&& proj = utility::as_function(std::get<1>(data)); + auto&& proj_x = proj(x); + auto&& proj_y = proj(y); - std::size_t minSize = (std::min)(proj(x).size(), proj(y).size()); - for (std::size_t u = std::get<0>(data) ; u < minSize ; ++u) - { - static_assert(sizeof(proj(x)[u]) == sizeof(Unsigned_char_type), ""); - if (static_cast(proj(x)[u]) != - static_cast(proj(y)[u])) - { - return static_cast(proj(x)[u]) > - static_cast(proj(y)[u]); + std::size_t minSize = (std::min)(proj_x.size(), proj_y.size()); + for (std::size_t u = std::get<0>(data); u < minSize; ++u) { + static_assert(sizeof(proj_x[u]) == sizeof(Unsigned_char_type), ""); + if (static_cast(proj_x[u]) != static_cast(proj_y[u])) { + return static_cast(proj_x[u]) > + static_cast(proj_y[u]); } } - return proj(x).size() > proj(y).size(); + return proj_x.size() > proj_y.size(); } - // Pack fchar_offset and projection - std::tuple data; + // Pack char_offset and projection + std::tuple data; }; //String sorting recursive implementation From 5cec9f897f08295aa802a918c68b08e6aa1724af Mon Sep 17 00:00:00 2001 From: Morwenn Date: Mon, 15 Aug 2022 17:02:40 +0200 Subject: [PATCH 34/51] More constexpr for spreadsort --- .../detail/spreadsort/detail/common.h | 23 ++++---- .../detail/spreadsort/detail/constants.h | 56 ++++++++++--------- .../detail/spreadsort/detail/string_sort.h | 20 +++---- 3 files changed, 51 insertions(+), 48 deletions(-) diff --git a/include/cpp-sort/detail/spreadsort/detail/common.h b/include/cpp-sort/detail/spreadsort/detail/common.h index 58a4ab1e..d45d81cf 100644 --- a/include/cpp-sort/detail/spreadsort/detail/common.h +++ b/include/cpp-sort/detail/spreadsort/detail/common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ @@ -24,7 +24,6 @@ Phil Endecott and Frank Gennari // Headers //////////////////////////////////////////////////////////// #include -#include #include #include "constants.h" #include "../../type_traits.h" @@ -43,7 +42,7 @@ namespace detail //This only works on unsigned data types template - auto rough_log_2_size(const T& input) + constexpr auto rough_log_2_size(const T& input) -> unsigned { unsigned result = 0; @@ -58,14 +57,16 @@ namespace detail //runtime overhead. //This could be replaced by a lookup table of sizeof(Div_type)*8 but this //function is more general. - template - auto get_min_count(unsigned log_range) + template< + unsigned log_mean_bin_size, + unsigned log_min_split_count, + unsigned log_finishing_count + > + constexpr auto get_min_count(unsigned log_range) -> std::size_t { - const std::size_t typed_one = 1; - const unsigned min_size = log_mean_bin_size + log_min_split_count; + constexpr std::size_t typed_one = 1; + constexpr unsigned min_size = log_mean_bin_size + log_min_split_count; //Assuring that constants have valid settings static_assert(log_min_split_count <= max_splits && log_min_split_count > 0, ""); @@ -85,9 +86,9 @@ namespace detail return typed_one << log_range; } } - const unsigned base_iterations = max_splits - log_min_split_count; + constexpr unsigned base_iterations = max_splits - log_min_split_count; //sum of n to n + x = ((x + 1) * (n + (n + x)))/2 + log_mean_bin_size - const unsigned base_range = + constexpr unsigned base_range = ((base_iterations + 1) * (max_splits + log_min_split_count))/2 + log_mean_bin_size; //Calculating the required number of iterations, and returning diff --git a/include/cpp-sort/detail/spreadsort/detail/constants.h b/include/cpp-sort/detail/spreadsort/detail/constants.h index 664e4bd6..0ecbd5ba 100644 --- a/include/cpp-sort/detail/spreadsort/detail/constants.h +++ b/include/cpp-sort/detail/spreadsort/detail/constants.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ @@ -24,32 +24,34 @@ namespace spreadsort namespace detail { //Tuning constants - //This should be tuned to your processor cache; - //if you go too large you get cache misses on bins - //The smaller this number, the less worst-case memory usage. - //If too small, too many recursions slow down spreadsort - enum { max_splits = 11, - //It's better to have a few cache misses and finish sorting - //than to run another iteration - max_finishing_splits = max_splits + 1, - //Sets the minimum number of items per bin. - int_log_mean_bin_size = 2, - //Used to force a comparison-based sorting for small bins, if it's faster. - //Minimum value 1 - int_log_min_split_count = 9, - //This is the minimum split count to use spreadsort when it will finish in one - //iteration. Make this larger the faster std::sort is relative to integer_sort. - int_log_finishing_count = 31, - //Sets the minimum number of items per bin for floating point. - float_log_mean_bin_size = 2, - //Used to force a comparison-based sorting for small bins, if it's faster. - //Minimum value 1 - float_log_min_split_count = 8, - //This is the minimum split count to use spreadsort when it will finish in one - //iteration. Make this larger the faster std::sort is relative to float_sort. - float_log_finishing_count = 4, - //There is a minimum size below which it is not worth using spreadsort - min_sort_size = 1000 }; + enum { + //This should be tuned to your processor cache; + //if you go too large you get cache misses on bins + //The smaller this number, the less worst-case memory usage. + //If too small, too many recursions slow down spreadsort + max_splits = 11, + //It's better to have a few cache misses and finish sorting + //than to run another iteration + max_finishing_splits = max_splits + 1, + //Sets the minimum number of items per bin. + int_log_mean_bin_size = 2, + //Used to force a comparison-based sorting for small bins, if it's faster. + //Minimum value 1 + int_log_min_split_count = 9, + //This is the minimum split count to use spreadsort when it will finish in one + //iteration. Make this larger the faster std::sort is relative to integer_sort. + int_log_finishing_count = 31, + //Sets the minimum number of items per bin for floating point. + float_log_mean_bin_size = 2, + //Used to force a comparison-based sorting for small bins, if it's faster. + //Minimum value 1 + float_log_min_split_count = 8, + //This is the minimum split count to use spreadsort when it will finish in one + //iteration. Make this larger the faster std::sort is relative to float_sort. + float_log_finishing_count = 4, + //There is a minimum size below which it is not worth using spreadsort + min_sort_size = 1000 + }; }}}} #endif // CPPSORT_DETAIL_SPREADSORT_DETAIL_CONSTANTS_H_ diff --git a/include/cpp-sort/detail/spreadsort/detail/string_sort.h b/include/cpp-sort/detail/spreadsort/detail/string_sort.h index 2894b339..d9852edb 100644 --- a/include/cpp-sort/detail/spreadsort/detail/string_sort.h +++ b/include/cpp-sort/detail/spreadsort/detail/string_sort.h @@ -43,8 +43,6 @@ namespace detail namespace spreadsort { namespace detail { - static constexpr int max_step_size = 64; - //Offsetting on identical characters. This function works a chunk of //characters at a time for cache efficiency and optimal worst-case //performance. @@ -55,7 +53,9 @@ namespace spreadsort { auto&& proj = utility::as_function(projection); - const int char_size = sizeof(Unsigned_char_type); + constexpr int max_step_size = 64; + constexpr int char_size = sizeof(Unsigned_char_type); + std::size_t nextOffset = char_offset; int step_size = max_step_size / char_size; while (true) { @@ -177,10 +177,10 @@ namespace spreadsort //a few characters at a time for optimal worst-case performance. update_offset(first, finish, char_offset, projection); - const unsigned bin_count = (1 << (sizeof(Unsigned_char_type)*8)); + constexpr unsigned bin_count = (1 << (sizeof(Unsigned_char_type)*8)); //Equal worst-case of radix and comparison is when bin_count = n*log(n). - const unsigned max_size = bin_count; - const unsigned membin_count = bin_count + 1; + constexpr unsigned max_size = bin_count; + constexpr unsigned membin_count = bin_count + 1; unsigned cache_end; RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count) + 1; @@ -288,11 +288,11 @@ namespace spreadsort update_offset(curr, last, char_offset, projection); RandomAccessIter * target_bin; - const unsigned bin_count = (1 << (sizeof(Unsigned_char_type)*8)); + constexpr unsigned bin_count = (1 << (sizeof(Unsigned_char_type)*8)); //Equal worst-case of radix and comparison when bin_count = n*log(n). - const unsigned max_size = bin_count; - const unsigned membin_count = bin_count + 1; - const unsigned max_bin = bin_count - 1; + constexpr unsigned max_size = bin_count; + constexpr unsigned membin_count = bin_count + 1; + constexpr unsigned max_bin = bin_count - 1; unsigned cache_end; RandomAccessIter * bins = size_bins(bin_sizes, bin_cache, cache_offset, cache_end, membin_count); From b11f5f3730b73e5562034b1ed0c9a776fbfea897 Mon Sep 17 00:00:00 2001 From: Morwenn Date: Sun, 28 Aug 2022 16:57:17 +0200 Subject: [PATCH 35/51] Add Python script to generate sorting networks code --- tools/generate.py | 26 ------ tools/generate_sorting_network.py | 127 ++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+), 26 deletions(-) delete mode 100644 tools/generate.py create mode 100644 tools/generate_sorting_network.py diff --git a/tools/generate.py b/tools/generate.py deleted file mode 100644 index 1f59b0c1..00000000 --- a/tools/generate.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2015-2022 Morwenn -# SPDX-License-Identifier: MIT - -import sys - - -def transform(line): - line = line.strip('[],\nSWAP();{}') - if line: - x, y = map(int, line.split(',')) - return 'iter_swap_if(first + {0}u, first + {1}u, compare, projection);'.format(x, y) - - -if __name__ == '__main__': - with open(sys.argv[1]) as source: - for line in source: - line = line.replace(' ', '') - line = line.replace('(', '[') - line = line.replace(')', ']') - pairs = line.split('],[') - for pair in pairs: - res = transform(pair) - if res: - print(res) diff --git a/tools/generate_sorting_network.py b/tools/generate_sorting_network.py new file mode 100644 index 00000000..81ac116f --- /dev/null +++ b/tools/generate_sorting_network.py @@ -0,0 +1,127 @@ +# -*- coding: utf-8 -*- + +import ast +import sys +import textwrap + +import z3 + + +def parse_network(path) -> list[list[tuple]]: + """ + Reads a file and returns for each line of list of tuples representing the indices + of elements on which to perform compare-and-swap operations. + """ + res: list[list[tuple]] = [] + with open(path) as fd: + for line in fd: + res.append(ast.literal_eval(line)) + return res + + +def swap_if(a, b): + # When a, b are in {0, 1} this function returns min(a, b), max(a, b), AKA a + # compare-and-swap unit in a sorting network. + + # Note that min(a, b) is a & b and max(a, b) is a | b. + return z3.And(a, b), z3.Or(a, b) + + +def verify_network(pairs: list[tuple]): + # Zero-one principle: if the sorting network is valid for all boolean inputs + # then it is valid for all inputs. + n = max(max(i, j) for i, j in pairs) + 1 + inputs = [z3.Bool("x" + str(k)) for k in range(n)] + + network = inputs[:] + for i, j in pairs: + network[i], network[j] = swap_if(network[i], network[j]) + + # Attempt to find counterexample. + solver = z3.Solver() + solver.add(z3.Or(*[z3.And(network[i-1], z3.Not(network[i])) for i in range(1, n)])) + if solver.check() == z3.sat: + model = solver.model() + return False, [int(bool(model[inp])) for inp in inputs] + return True, None + + +def generate_cxx(network: list[list[tuple]]): + template = textwrap.dedent(""" + namespace cppsort + {{ + namespace detail + {{ + template<> + struct sorting_network_sorter_impl<{nb_inputs}> + {{ + template< + typename RandomAccessIterator, + typename Compare = std::less<>, + typename Projection = utility::identity, + typename = detail::enable_if_t> + > + auto operator()(RandomAccessIterator first, RandomAccessIterator, + Compare compare={{}}, Projection projection={{}}) const + -> void + {{ + {swaps} + }} + + template + static constexpr auto index_pairs() + -> std::array, {nb_indices}> + {{ + return {{{{ + {indices} + }}}}; + }} + }}; + }}}} + """) + + pairs = sum(network, []) + + # Find highest index in pairs + highest_index = max( + max(pair[0] for pair in pairs), + max(pair[1] for pair in pairs) + ) + + # Generate pairs of swaps + swaps = [] + for pair in pairs: + lhs = "first" if pair[0] == 0 else f"first + {pair[0]}" + rhs = "first" if pair[1] == 0 else f"first + {pair[1]}" + swaps.append(f"iter_swap_if({lhs}, {rhs}, compare, projection);") + + # Generate list of indices + indices = [] + for line in network: + indices.append(", ".join(f"{{{pair[0]}, {pair[1]}}}" for pair in line) + ",") + + return template.format( + nb_inputs=highest_index + 1, + swaps="\n ".join(swaps), + indices="\n ".join(indices), + nb_indices=len(pairs), + ) + + +def main(): + network = parse_network(sys.argv[1]) + pairs = sum(network, []) + print(f"Number of pairs: {len(pairs)}") + + valid, failing_input = verify_network(pairs) + if not valid: + print("Network failed to sort: {failing_input}") + exit(1) + + print(generate_cxx(network)) + + +if __name__ == '__main__': + main() From b42ef6225a16774213ad63ae12d36e5dd29468cb Mon Sep 17 00:00:00 2001 From: Morwenn Date: Tue, 6 Sep 2022 12:28:16 +0200 Subject: [PATCH 36/51] Regenerate all sorting networks Regenerate from the most recent size-optimal networks from the SorterHunter project. This brings a few changes: - Sorting 25 inputs now takes 130 CEs instead of 131 - Sorting 30 inputs reuses the 15 inputs network --- docs/Fixed-size-sorters.md | 4 +- .../cpp-sort/detail/sorting_network/sort10.h | 62 +-- .../cpp-sort/detail/sorting_network/sort11.h | 74 ++-- .../cpp-sort/detail/sorting_network/sort12.h | 82 ++-- .../cpp-sort/detail/sorting_network/sort13.h | 94 ++--- .../cpp-sort/detail/sorting_network/sort14.h | 124 +++--- .../cpp-sort/detail/sorting_network/sort15.h | 116 +++--- .../cpp-sort/detail/sorting_network/sort16.h | 124 +++--- .../cpp-sort/detail/sorting_network/sort17.h | 146 +++---- .../cpp-sort/detail/sorting_network/sort18.h | 181 +++++---- .../cpp-sort/detail/sorting_network/sort19.h | 174 ++++----- .../cpp-sort/detail/sorting_network/sort2.h | 6 +- .../cpp-sort/detail/sorting_network/sort20.h | 186 ++++----- .../cpp-sort/detail/sorting_network/sort21.h | 219 ++++++----- .../cpp-sort/detail/sorting_network/sort22.h | 237 ++++++------ .../cpp-sort/detail/sorting_network/sort23.h | 230 +++++------ .../cpp-sort/detail/sorting_network/sort24.h | 244 ++++++------ .../cpp-sort/detail/sorting_network/sort25.h | 294 +++++++-------- .../cpp-sort/detail/sorting_network/sort26.h | 309 ++++++++------- .../cpp-sort/detail/sorting_network/sort27.h | 298 +++++++-------- .../cpp-sort/detail/sorting_network/sort28.h | 314 +++++++-------- .../cpp-sort/detail/sorting_network/sort29.h | 356 +++++++++--------- .../cpp-sort/detail/sorting_network/sort3.h | 10 +- .../cpp-sort/detail/sorting_network/sort30.h | 241 ++++-------- .../cpp-sort/detail/sorting_network/sort31.h | 251 ++++++++---- .../cpp-sort/detail/sorting_network/sort32.h | 255 +++++++++---- .../cpp-sort/detail/sorting_network/sort4.h | 14 +- .../cpp-sort/detail/sorting_network/sort5.h | 30 +- .../cpp-sort/detail/sorting_network/sort6.h | 28 +- .../cpp-sort/detail/sorting_network/sort7.h | 36 +- .../cpp-sort/detail/sorting_network/sort8.h | 42 +-- .../cpp-sort/detail/sorting_network/sort9.h | 54 +-- 32 files changed, 2476 insertions(+), 2359 deletions(-) diff --git a/docs/Fixed-size-sorters.md b/docs/Fixed-size-sorters.md index 43c5dfdc..5a327513 100644 --- a/docs/Fixed-size-sorters.md +++ b/docs/Fixed-size-sorters.md @@ -147,7 +147,7 @@ Size | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: **CEs** | 0 | 1 | 3 | 5 | 9 | 12 | 16 | 19 | 25 | 29 | 35 | 39 | 45 | 51 | 56 | 60 **Size** | **17** | **18** | **19** | **20** | **21** | **22** | **23** | **24** | **25** | **26** | **27** | **28** | **29** | **30** | **31** | **32** -**CEs** | 71 | 77 | 85 | 91 | 99 | 106 | 114 | 120 | 131 | 139 | 148 | 155 | 164 | 172 | 180 | 185 +**CEs** | 71 | 77 | 85 | 91 | 99 | 106 | 114 | 120 | 130 | 139 | 148 | 155 | 164 | 172 | 180 | 185 One of the main advantages of sorting networks is the fixed number of CEs required to sort a collection: this means that sorting networks are far more resistant to time and cache attacks since the number of performed comparisons does not depend on the contents of the collection. However, additional care (not provided by the library) is required to ensure that the algorithms always perform the same amount of memory loads and stores. For example, one could create a `constant_time_iterator` with a dedicated `iter_swap` tuned to perform a constant-time compare-exchange operation. @@ -171,6 +171,8 @@ static constexpr auto index_pairs() *Changed in version 1.13.0:* sorting 21, 22, 23, 25, 27 and 29 inputs respectively require 99, 106, 114, 131, 149 and 164 CEs instead of 100, 107, 115, 132, 150 and 165. +*Changed in version 1.13.1:* sorting 25 inputs requires 130 CEs instead of 131. + [double-insertion-sort]: Original-research.md#double-insertion-sort [fixed-sorter-traits]: Sorter-traits.md#fixed_sorter_traits diff --git a/include/cpp-sort/detail/sorting_network/sort10.h b/include/cpp-sort/detail/sorting_network/sort10.h index b34e712f..0985d02d 100644 --- a/include/cpp-sort/detail/sorting_network/sort10.h +++ b/include/cpp-sort/detail/sorting_network/sort10.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SORTING_NETWORK_SORT10_H_ @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<10u> + struct sorting_network_sorter_impl<10> { template< typename RandomAccessIterator, @@ -24,35 +24,35 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - iter_swap_if(first + 4u, first + 9u, compare, projection); - iter_swap_if(first + 3u, first + 8u, compare, projection); - iter_swap_if(first + 2u, first + 7u, compare, projection); - iter_swap_if(first + 1u, first + 6u, compare, projection); - iter_swap_if(first, first + 5u, compare, projection); - iter_swap_if(first + 1u, first + 4u, compare, projection); - iter_swap_if(first + 6u, first + 9u, compare, projection); - iter_swap_if(first, first + 3u, compare, projection); - iter_swap_if(first + 5u, first + 8u, compare, projection); - iter_swap_if(first, first + 2u, compare, projection); - iter_swap_if(first + 3u, first + 6u, compare, projection); - iter_swap_if(first + 7u, first + 9u, compare, projection); - iter_swap_if(first, first + 1u, compare, projection); - iter_swap_if(first + 2u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first + 4u, first + 6u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); - iter_swap_if(first + 3u, first + 5u, compare, projection); - iter_swap_if(first + 2u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 8u, compare, projection); - iter_swap_if(first + 1u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 7u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); + iter_swap_if(first, first + 8, compare, projection); + iter_swap_if(first + 1, first + 9, compare, projection); + iter_swap_if(first + 2, first + 7, compare, projection); + iter_swap_if(first + 3, first + 5, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first, first + 2, compare, projection); + iter_swap_if(first + 1, first + 4, compare, projection); + iter_swap_if(first + 5, first + 8, compare, projection); + iter_swap_if(first + 7, first + 9, compare, projection); + iter_swap_if(first, first + 3, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 5, first + 7, compare, projection); + iter_swap_if(first + 6, first + 9, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 3, first + 6, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 1, first + 5, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 8, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 3, first + 5, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); } template diff --git a/include/cpp-sort/detail/sorting_network/sort11.h b/include/cpp-sort/detail/sorting_network/sort11.h index 0dc582c0..743c3e0f 100644 --- a/include/cpp-sort/detail/sorting_network/sort11.h +++ b/include/cpp-sort/detail/sorting_network/sort11.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SORTING_NETWORK_SORT11_H_ @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<11u> + struct sorting_network_sorter_impl<11> { template< typename RandomAccessIterator, @@ -24,41 +24,41 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - iter_swap_if(first, first + 1u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 1u, first + 3u, compare, projection); - iter_swap_if(first + 5u, first + 7u, compare, projection); - iter_swap_if(first, first + 2u, compare, projection); - iter_swap_if(first + 4u, first + 6u, compare, projection); - iter_swap_if(first + 8u, first + 10u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 9u, first + 10u, compare, projection); - iter_swap_if(first + 1u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 10u, compare, projection); - iter_swap_if(first + 5u, first + 9u, compare, projection); - iter_swap_if(first + 2u, first + 6u, compare, projection); - iter_swap_if(first + 1u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 10u, compare, projection); - iter_swap_if(first, first + 4u, compare, projection); - iter_swap_if(first + 3u, first + 7u, compare, projection); - iter_swap_if(first + 4u, first + 8u, compare, projection); - iter_swap_if(first, first + 4u, compare, projection); - iter_swap_if(first + 1u, first + 4u, compare, projection); - iter_swap_if(first + 7u, first + 10u, compare, projection); - iter_swap_if(first + 3u, first + 8u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 2u, first + 4u, compare, projection); - iter_swap_if(first + 7u, first + 9u, compare, projection); - iter_swap_if(first + 3u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 8u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); + iter_swap_if(first, first + 9, compare, projection); + iter_swap_if(first + 1, first + 6, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 3, first + 7, compare, projection); + iter_swap_if(first + 5, first + 8, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 3, first + 5, compare, projection); + iter_swap_if(first + 4, first + 10, compare, projection); + iter_swap_if(first + 6, first + 9, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 1, first + 3, compare, projection); + iter_swap_if(first + 2, first + 5, compare, projection); + iter_swap_if(first + 4, first + 7, compare, projection); + iter_swap_if(first + 8, first + 10, compare, projection); + iter_swap_if(first, first + 4, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 3, first + 7, compare, projection); + iter_swap_if(first + 5, first + 9, compare, projection); + iter_swap_if(first + 6, first + 8, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 2, first + 6, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 9, first + 10, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 3, first + 6, compare, projection); + iter_swap_if(first + 5, first + 7, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); } template diff --git a/include/cpp-sort/detail/sorting_network/sort12.h b/include/cpp-sort/detail/sorting_network/sort12.h index 39d05c19..c3325545 100644 --- a/include/cpp-sort/detail/sorting_network/sort12.h +++ b/include/cpp-sort/detail/sorting_network/sort12.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SORTING_NETWORK_SORT12_H_ @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<12u> + struct sorting_network_sorter_impl<12> { template< typename RandomAccessIterator, @@ -24,45 +24,45 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - iter_swap_if(first, first + 1u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 1u, first + 3u, compare, projection); - iter_swap_if(first + 5u, first + 7u, compare, projection); - iter_swap_if(first + 9u, first + 11u, compare, projection); - iter_swap_if(first, first + 2u, compare, projection); - iter_swap_if(first + 4u, first + 6u, compare, projection); - iter_swap_if(first + 8u, first + 10u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 9u, first + 10u, compare, projection); - iter_swap_if(first + 1u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 10u, compare, projection); - iter_swap_if(first + 5u, first + 9u, compare, projection); - iter_swap_if(first + 2u, first + 6u, compare, projection); - iter_swap_if(first + 1u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 10u, compare, projection); - iter_swap_if(first, first + 4u, compare, projection); - iter_swap_if(first + 7u, first + 11u, compare, projection); - iter_swap_if(first + 3u, first + 7u, compare, projection); - iter_swap_if(first + 4u, first + 8u, compare, projection); - iter_swap_if(first, first + 4u, compare, projection); - iter_swap_if(first + 7u, first + 11u, compare, projection); - iter_swap_if(first + 1u, first + 4u, compare, projection); - iter_swap_if(first + 7u, first + 10u, compare, projection); - iter_swap_if(first + 3u, first + 8u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 2u, first + 4u, compare, projection); - iter_swap_if(first + 7u, first + 9u, compare, projection); - iter_swap_if(first + 3u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 8u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); + iter_swap_if(first, first + 8, compare, projection); + iter_swap_if(first + 1, first + 7, compare, projection); + iter_swap_if(first + 2, first + 6, compare, projection); + iter_swap_if(first + 3, first + 11, compare, projection); + iter_swap_if(first + 4, first + 10, compare, projection); + iter_swap_if(first + 5, first + 9, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 2, first + 5, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 6, first + 9, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first, first + 2, compare, projection); + iter_swap_if(first + 1, first + 6, compare, projection); + iter_swap_if(first + 5, first + 10, compare, projection); + iter_swap_if(first + 9, first + 11, compare, projection); + iter_swap_if(first, first + 3, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first + 5, first + 7, compare, projection); + iter_swap_if(first + 8, first + 11, compare, projection); + iter_swap_if(first + 9, first + 10, compare, projection); + iter_swap_if(first + 1, first + 4, compare, projection); + iter_swap_if(first + 3, first + 5, compare, projection); + iter_swap_if(first + 6, first + 8, compare, projection); + iter_swap_if(first + 7, first + 10, compare, projection); + iter_swap_if(first + 1, first + 3, compare, projection); + iter_swap_if(first + 2, first + 5, compare, projection); + iter_swap_if(first + 6, first + 9, compare, projection); + iter_swap_if(first + 8, first + 10, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first + 5, first + 7, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); } template diff --git a/include/cpp-sort/detail/sorting_network/sort13.h b/include/cpp-sort/detail/sorting_network/sort13.h index 444959a0..dd7a7cb9 100644 --- a/include/cpp-sort/detail/sorting_network/sort13.h +++ b/include/cpp-sort/detail/sorting_network/sort13.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SORTING_NETWORK_SORT13_H_ @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<13u> + struct sorting_network_sorter_impl<13> { template< typename RandomAccessIterator, @@ -24,51 +24,51 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - iter_swap_if(first + 1u, first + 7u, compare, projection); - iter_swap_if(first + 9u, first + 11u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 8u, compare, projection); - iter_swap_if(first, first + 12u, compare, projection); - iter_swap_if(first + 2u, first + 6u, compare, projection); - iter_swap_if(first, first + 1u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 6u, compare, projection); - iter_swap_if(first + 8u, first + 11u, compare, projection); - iter_swap_if(first + 7u, first + 12u, compare, projection); - iter_swap_if(first + 5u, first + 9u, compare, projection); - iter_swap_if(first, first + 2u, compare, projection); - iter_swap_if(first + 3u, first + 7u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 1u, first + 4u, compare, projection); - iter_swap_if(first + 6u, first + 12u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); - iter_swap_if(first + 11u, first + 12u, compare, projection); - iter_swap_if(first + 4u, first + 9u, compare, projection); - iter_swap_if(first + 6u, first + 10u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 1u, first + 7u, compare, projection); - iter_swap_if(first + 2u, first + 6u, compare, projection); - iter_swap_if(first + 9u, first + 11u, compare, projection); - iter_swap_if(first + 1u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 10u, compare, projection); - iter_swap_if(first, first + 5u, compare, projection); - iter_swap_if(first + 2u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 8u, compare, projection); - iter_swap_if(first + 9u, first + 10u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first + 3u, first + 5u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); - iter_swap_if(first + 4u, first + 6u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); + iter_swap_if(first, first + 12, compare, projection); + iter_swap_if(first + 1, first + 10, compare, projection); + iter_swap_if(first + 2, first + 9, compare, projection); + iter_swap_if(first + 3, first + 7, compare, projection); + iter_swap_if(first + 5, first + 11, compare, projection); + iter_swap_if(first + 6, first + 8, compare, projection); + iter_swap_if(first + 1, first + 6, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 11, compare, projection); + iter_swap_if(first + 7, first + 9, compare, projection); + iter_swap_if(first + 8, first + 10, compare, projection); + iter_swap_if(first, first + 4, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 3, first + 6, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 9, first + 10, compare, projection); + iter_swap_if(first + 11, first + 12, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first + 5, first + 9, compare, projection); + iter_swap_if(first + 8, first + 11, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first, first + 5, compare, projection); + iter_swap_if(first + 3, first + 8, compare, projection); + iter_swap_if(first + 4, first + 7, compare, projection); + iter_swap_if(first + 6, first + 11, compare, projection); + iter_swap_if(first + 9, first + 10, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 2, first + 5, compare, projection); + iter_swap_if(first + 6, first + 9, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 1, first + 3, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 9, first + 10, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 7, compare, projection); + iter_swap_if(first + 6, first + 8, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); } template diff --git a/include/cpp-sort/detail/sorting_network/sort14.h b/include/cpp-sort/detail/sorting_network/sort14.h index 11ca07c0..2f1a0a03 100644 --- a/include/cpp-sort/detail/sorting_network/sort14.h +++ b/include/cpp-sort/detail/sorting_network/sort14.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SORTING_NETWORK_SORT14_H_ @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<14u> + struct sorting_network_sorter_impl<14> { template< typename RandomAccessIterator, @@ -24,57 +24,57 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - iter_swap_if(first, first + 1u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 13u, compare, projection); - iter_swap_if(first, first + 2u, compare, projection); - iter_swap_if(first + 4u, first + 6u, compare, projection); - iter_swap_if(first + 8u, first + 10u, compare, projection); - iter_swap_if(first + 1u, first + 3u, compare, projection); - iter_swap_if(first + 5u, first + 7u, compare, projection); - iter_swap_if(first + 9u, first + 11u, compare, projection); - iter_swap_if(first, first + 4u, compare, projection); - iter_swap_if(first + 8u, first + 12u, compare, projection); - iter_swap_if(first + 1u, first + 5u, compare, projection); - iter_swap_if(first + 9u, first + 13u, compare, projection); - iter_swap_if(first + 2u, first + 6u, compare, projection); - iter_swap_if(first + 3u, first + 7u, compare, projection); - iter_swap_if(first, first + 8u, compare, projection); - iter_swap_if(first + 1u, first + 9u, compare, projection); - iter_swap_if(first + 2u, first + 10u, compare, projection); - iter_swap_if(first + 3u, first + 11u, compare, projection); - iter_swap_if(first + 4u, first + 12u, compare, projection); - iter_swap_if(first + 5u, first + 13u, compare, projection); - iter_swap_if(first + 5u, first + 10u, compare, projection); - iter_swap_if(first + 6u, first + 9u, compare, projection); - iter_swap_if(first + 3u, first + 12u, compare, projection); - iter_swap_if(first + 7u, first + 11u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first + 4u, first + 8u, compare, projection); - iter_swap_if(first + 1u, first + 4u, compare, projection); - iter_swap_if(first + 7u, first + 13u, compare, projection); - iter_swap_if(first + 2u, first + 8u, compare, projection); - iter_swap_if(first + 2u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 9u, first + 10u, compare, projection); - iter_swap_if(first + 11u, first + 13u, compare, projection); - iter_swap_if(first + 3u, first + 8u, compare, projection); - iter_swap_if(first + 7u, first + 12u, compare, projection); - iter_swap_if(first + 6u, first + 8u, compare, projection); - iter_swap_if(first + 10u, first + 12u, compare, projection); - iter_swap_if(first + 3u, first + 5u, compare, projection); - iter_swap_if(first + 7u, first + 9u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); - iter_swap_if(first + 9u, first + 10u, compare, projection); - iter_swap_if(first + 11u, first + 12u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 12, first + 13, compare, projection); + iter_swap_if(first, first + 2, compare, projection); + iter_swap_if(first + 1, first + 3, compare, projection); + iter_swap_if(first + 4, first + 8, compare, projection); + iter_swap_if(first + 5, first + 9, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 11, first + 13, compare, projection); + iter_swap_if(first, first + 4, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 3, first + 7, compare, projection); + iter_swap_if(first + 5, first + 8, compare, projection); + iter_swap_if(first + 6, first + 10, compare, projection); + iter_swap_if(first + 9, first + 13, compare, projection); + iter_swap_if(first + 11, first + 12, compare, projection); + iter_swap_if(first, first + 6, compare, projection); + iter_swap_if(first + 1, first + 5, compare, projection); + iter_swap_if(first + 3, first + 9, compare, projection); + iter_swap_if(first + 4, first + 10, compare, projection); + iter_swap_if(first + 7, first + 13, compare, projection); + iter_swap_if(first + 8, first + 12, compare, projection); + iter_swap_if(first + 2, first + 10, compare, projection); + iter_swap_if(first + 3, first + 11, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first + 7, first + 9, compare, projection); + iter_swap_if(first + 1, first + 3, compare, projection); + iter_swap_if(first + 2, first + 8, compare, projection); + iter_swap_if(first + 5, first + 11, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 1, first + 4, compare, projection); + iter_swap_if(first + 2, first + 6, compare, projection); + iter_swap_if(first + 3, first + 5, compare, projection); + iter_swap_if(first + 7, first + 11, compare, projection); + iter_swap_if(first + 8, first + 10, compare, projection); + iter_swap_if(first + 9, first + 12, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 3, first + 6, compare, projection); + iter_swap_if(first + 5, first + 8, compare, projection); + iter_swap_if(first + 7, first + 10, compare, projection); + iter_swap_if(first + 9, first + 11, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 9, first + 10, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); } template @@ -82,16 +82,16 @@ namespace detail -> std::array, 51> { return {{ - {0, 6}, {1, 11}, {2, 12}, {3, 10}, {4, 5}, {7, 13}, {8, 9}, - {1, 2}, {3, 7}, {4, 8}, {5, 9}, {6, 10}, {11, 12}, - {0, 4}, {1, 3}, {5, 6}, {7, 8}, {9, 13}, {10, 12}, - {0, 1}, {2, 9}, {3, 7}, {4, 11}, {6, 10}, {12, 13}, - {2, 5}, {4, 7}, {6, 9}, {8, 11}, - {1, 2}, {3, 4}, {6, 7}, {9, 10}, {11, 12}, - {1, 3}, {2, 4}, {5, 6}, {7, 8}, {9, 11}, {10, 12}, - {2, 3}, {4, 7}, {6, 9}, {10, 11}, - {4, 5}, {6, 7}, {8, 9}, + {0, 1}, {2, 3}, {4, 5}, {6, 7}, {8, 9}, {10, 11}, {12, 13}, + {0, 2}, {1, 3}, {4, 8}, {5, 9}, {10, 12}, {11, 13}, + {0, 4}, {1, 2}, {3, 7}, {5, 8}, {6, 10}, {9, 13}, {11, 12}, + {0, 6}, {1, 5}, {3, 9}, {4, 10}, {7, 13}, {8, 12}, + {2, 10}, {3, 11}, {4, 6}, {7, 9}, + {1, 3}, {2, 8}, {5, 11}, {6, 7}, {10, 12}, + {1, 4}, {2, 6}, {3, 5}, {7, 11}, {8, 10}, {9, 12}, + {2, 4}, {3, 6}, {5, 8}, {7, 10}, {9, 11}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, + {6, 7}, }}; } }; diff --git a/include/cpp-sort/detail/sorting_network/sort15.h b/include/cpp-sort/detail/sorting_network/sort15.h index 539dadd7..8feb1941 100644 --- a/include/cpp-sort/detail/sorting_network/sort15.h +++ b/include/cpp-sort/detail/sorting_network/sort15.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SORTING_NETWORK_SORT15_H_ @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<15u> + struct sorting_network_sorter_impl<15> { template< typename RandomAccessIterator, @@ -24,62 +24,62 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - iter_swap_if(first, first + 1u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 13u, compare, projection); - iter_swap_if(first, first + 2u, compare, projection); - iter_swap_if(first + 4u, first + 6u, compare, projection); - iter_swap_if(first + 8u, first + 10u, compare, projection); - iter_swap_if(first + 12u, first + 14u, compare, projection); - iter_swap_if(first + 1u, first + 3u, compare, projection); - iter_swap_if(first + 5u, first + 7u, compare, projection); - iter_swap_if(first + 9u, first + 11u, compare, projection); - iter_swap_if(first, first + 4u, compare, projection); - iter_swap_if(first + 8u, first + 12u, compare, projection); - iter_swap_if(first + 1u, first + 5u, compare, projection); - iter_swap_if(first + 9u, first + 13u, compare, projection); - iter_swap_if(first + 2u, first + 6u, compare, projection); - iter_swap_if(first + 10u, first + 14u, compare, projection); - iter_swap_if(first + 3u, first + 7u, compare, projection); - iter_swap_if(first, first + 8u, compare, projection); - iter_swap_if(first + 1u, first + 9u, compare, projection); - iter_swap_if(first + 2u, first + 10u, compare, projection); - iter_swap_if(first + 3u, first + 11u, compare, projection); - iter_swap_if(first + 4u, first + 12u, compare, projection); - iter_swap_if(first + 5u, first + 13u, compare, projection); - iter_swap_if(first + 6u, first + 14u, compare, projection); - iter_swap_if(first + 5u, first + 10u, compare, projection); - iter_swap_if(first + 6u, first + 9u, compare, projection); - iter_swap_if(first + 3u, first + 12u, compare, projection); - iter_swap_if(first + 13u, first + 14u, compare, projection); - iter_swap_if(first + 7u, first + 11u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first + 4u, first + 8u, compare, projection); - iter_swap_if(first + 1u, first + 4u, compare, projection); - iter_swap_if(first + 7u, first + 13u, compare, projection); - iter_swap_if(first + 2u, first + 8u, compare, projection); - iter_swap_if(first + 11u, first + 14u, compare, projection); - iter_swap_if(first + 2u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 9u, first + 10u, compare, projection); - iter_swap_if(first + 11u, first + 13u, compare, projection); - iter_swap_if(first + 3u, first + 8u, compare, projection); - iter_swap_if(first + 7u, first + 12u, compare, projection); - iter_swap_if(first + 6u, first + 8u, compare, projection); - iter_swap_if(first + 10u, first + 12u, compare, projection); - iter_swap_if(first + 3u, first + 5u, compare, projection); - iter_swap_if(first + 7u, first + 9u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); - iter_swap_if(first + 9u, first + 10u, compare, projection); - iter_swap_if(first + 11u, first + 12u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 3, first + 10, compare, projection); + iter_swap_if(first + 4, first + 14, compare, projection); + iter_swap_if(first + 5, first + 8, compare, projection); + iter_swap_if(first + 6, first + 13, compare, projection); + iter_swap_if(first + 7, first + 12, compare, projection); + iter_swap_if(first + 9, first + 11, compare, projection); + iter_swap_if(first, first + 14, compare, projection); + iter_swap_if(first + 1, first + 5, compare, projection); + iter_swap_if(first + 2, first + 8, compare, projection); + iter_swap_if(first + 3, first + 7, compare, projection); + iter_swap_if(first + 6, first + 9, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 11, first + 13, compare, projection); + iter_swap_if(first, first + 7, compare, projection); + iter_swap_if(first + 1, first + 6, compare, projection); + iter_swap_if(first + 2, first + 9, compare, projection); + iter_swap_if(first + 4, first + 10, compare, projection); + iter_swap_if(first + 5, first + 11, compare, projection); + iter_swap_if(first + 8, first + 13, compare, projection); + iter_swap_if(first + 12, first + 14, compare, projection); + iter_swap_if(first, first + 6, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 3, first + 5, compare, projection); + iter_swap_if(first + 7, first + 11, compare, projection); + iter_swap_if(first + 8, first + 10, compare, projection); + iter_swap_if(first + 9, first + 12, compare, projection); + iter_swap_if(first + 13, first + 14, compare, projection); + iter_swap_if(first, first + 3, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 4, first + 7, compare, projection); + iter_swap_if(first + 5, first + 9, compare, projection); + iter_swap_if(first + 6, first + 8, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 12, first + 13, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first + 7, first + 9, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 11, first + 13, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 3, first + 5, compare, projection); + iter_swap_if(first + 8, first + 10, compare, projection); + iter_swap_if(first + 11, first + 12, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 9, first + 10, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); } template diff --git a/include/cpp-sort/detail/sorting_network/sort16.h b/include/cpp-sort/detail/sorting_network/sort16.h index cf1be55c..dd613673 100644 --- a/include/cpp-sort/detail/sorting_network/sort16.h +++ b/include/cpp-sort/detail/sorting_network/sort16.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SORTING_NETWORK_SORT16_H_ @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<16u> + struct sorting_network_sorter_impl<16> { template< typename RandomAccessIterator, @@ -24,66 +24,66 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - iter_swap_if(first, first + 1u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 13u, compare, projection); - iter_swap_if(first + 14u, first + 15u, compare, projection); - iter_swap_if(first, first + 2u, compare, projection); - iter_swap_if(first + 4u, first + 6u, compare, projection); - iter_swap_if(first + 8u, first + 10u, compare, projection); - iter_swap_if(first + 12u, first + 14u, compare, projection); - iter_swap_if(first + 1u, first + 3u, compare, projection); - iter_swap_if(first + 5u, first + 7u, compare, projection); - iter_swap_if(first + 9u, first + 11u, compare, projection); - iter_swap_if(first + 13u, first + 15u, compare, projection); - iter_swap_if(first, first + 4u, compare, projection); - iter_swap_if(first + 8u, first + 12u, compare, projection); - iter_swap_if(first + 1u, first + 5u, compare, projection); - iter_swap_if(first + 9u, first + 13u, compare, projection); - iter_swap_if(first + 2u, first + 6u, compare, projection); - iter_swap_if(first + 10u, first + 14u, compare, projection); - iter_swap_if(first + 3u, first + 7u, compare, projection); - iter_swap_if(first + 11u, first + 15u, compare, projection); - iter_swap_if(first, first + 8u, compare, projection); - iter_swap_if(first + 1u, first + 9u, compare, projection); - iter_swap_if(first + 2u, first + 10u, compare, projection); - iter_swap_if(first + 3u, first + 11u, compare, projection); - iter_swap_if(first + 4u, first + 12u, compare, projection); - iter_swap_if(first + 5u, first + 13u, compare, projection); - iter_swap_if(first + 6u, first + 14u, compare, projection); - iter_swap_if(first + 7u, first + 15u, compare, projection); - iter_swap_if(first + 5u, first + 10u, compare, projection); - iter_swap_if(first + 6u, first + 9u, compare, projection); - iter_swap_if(first + 3u, first + 12u, compare, projection); - iter_swap_if(first + 13u, first + 14u, compare, projection); - iter_swap_if(first + 7u, first + 11u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first + 4u, first + 8u, compare, projection); - iter_swap_if(first + 1u, first + 4u, compare, projection); - iter_swap_if(first + 7u, first + 13u, compare, projection); - iter_swap_if(first + 2u, first + 8u, compare, projection); - iter_swap_if(first + 11u, first + 14u, compare, projection); - iter_swap_if(first + 2u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 9u, first + 10u, compare, projection); - iter_swap_if(first + 11u, first + 13u, compare, projection); - iter_swap_if(first + 3u, first + 8u, compare, projection); - iter_swap_if(first + 7u, first + 12u, compare, projection); - iter_swap_if(first + 6u, first + 8u, compare, projection); - iter_swap_if(first + 10u, first + 12u, compare, projection); - iter_swap_if(first + 3u, first + 5u, compare, projection); - iter_swap_if(first + 7u, first + 9u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); - iter_swap_if(first + 9u, first + 10u, compare, projection); - iter_swap_if(first + 11u, first + 12u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); + iter_swap_if(first, first + 13, compare, projection); + iter_swap_if(first + 1, first + 12, compare, projection); + iter_swap_if(first + 2, first + 15, compare, projection); + iter_swap_if(first + 3, first + 14, compare, projection); + iter_swap_if(first + 4, first + 8, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 7, first + 11, compare, projection); + iter_swap_if(first + 9, first + 10, compare, projection); + iter_swap_if(first, first + 5, compare, projection); + iter_swap_if(first + 1, first + 7, compare, projection); + iter_swap_if(first + 2, first + 9, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 6, first + 13, compare, projection); + iter_swap_if(first + 8, first + 14, compare, projection); + iter_swap_if(first + 10, first + 15, compare, projection); + iter_swap_if(first + 11, first + 12, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 6, first + 8, compare, projection); + iter_swap_if(first + 7, first + 9, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 12, first + 13, compare, projection); + iter_swap_if(first + 14, first + 15, compare, projection); + iter_swap_if(first, first + 2, compare, projection); + iter_swap_if(first + 1, first + 3, compare, projection); + iter_swap_if(first + 4, first + 10, compare, projection); + iter_swap_if(first + 5, first + 11, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 12, first + 14, compare, projection); + iter_swap_if(first + 13, first + 15, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 3, first + 12, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first + 5, first + 7, compare, projection); + iter_swap_if(first + 8, first + 10, compare, projection); + iter_swap_if(first + 9, first + 11, compare, projection); + iter_swap_if(first + 13, first + 14, compare, projection); + iter_swap_if(first + 1, first + 4, compare, projection); + iter_swap_if(first + 2, first + 6, compare, projection); + iter_swap_if(first + 5, first + 8, compare, projection); + iter_swap_if(first + 7, first + 10, compare, projection); + iter_swap_if(first + 9, first + 13, compare, projection); + iter_swap_if(first + 11, first + 14, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 3, first + 6, compare, projection); + iter_swap_if(first + 9, first + 12, compare, projection); + iter_swap_if(first + 11, first + 13, compare, projection); + iter_swap_if(first + 3, first + 5, compare, projection); + iter_swap_if(first + 6, first + 8, compare, projection); + iter_swap_if(first + 7, first + 9, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 9, first + 10, compare, projection); + iter_swap_if(first + 11, first + 12, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); } template diff --git a/include/cpp-sort/detail/sorting_network/sort17.h b/include/cpp-sort/detail/sorting_network/sort17.h index ae1e35c5..fd81ceb0 100644 --- a/include/cpp-sort/detail/sorting_network/sort17.h +++ b/include/cpp-sort/detail/sorting_network/sort17.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SORTING_NETWORK_SORT17_H_ @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<17u> + struct sorting_network_sorter_impl<17> { template< typename RandomAccessIterator, @@ -24,77 +24,77 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - iter_swap_if(first + 5u, first + 11u, compare, projection); - iter_swap_if(first + 4u, first + 9u, compare, projection); - iter_swap_if(first + 7u, first + 12u, compare, projection); - iter_swap_if(first, first + 14u, compare, projection); - iter_swap_if(first + 2u, first + 16u, compare, projection); - iter_swap_if(first + 1u, first + 15u, compare, projection); - iter_swap_if(first + 3u, first + 8u, compare, projection); - iter_swap_if(first + 6u, first + 13u, compare, projection); - iter_swap_if(first + 3u, first + 10u, compare, projection); - iter_swap_if(first + 8u, first + 13u, compare, projection); - iter_swap_if(first + 4u, first + 7u, compare, projection); - iter_swap_if(first + 9u, first + 12u, compare, projection); - iter_swap_if(first, first + 2u, compare, projection); - iter_swap_if(first + 14u, first + 16u, compare, projection); - iter_swap_if(first + 1u, first + 6u, compare, projection); - iter_swap_if(first + 10u, first + 15u, compare, projection); - iter_swap_if(first + 3u, first + 5u, compare, projection); - iter_swap_if(first + 11u, first + 13u, compare, projection); - iter_swap_if(first, first + 4u, compare, projection); - iter_swap_if(first + 12u, first + 16u, compare, projection); - iter_swap_if(first + 1u, first + 3u, compare, projection); - iter_swap_if(first + 13u, first + 15u, compare, projection); - iter_swap_if(first, first + 1u, compare, projection); - iter_swap_if(first + 15u, first + 16u, compare, projection); - iter_swap_if(first + 2u, first + 9u, compare, projection); - iter_swap_if(first + 7u, first + 14u, compare, projection); - iter_swap_if(first + 5u, first + 10u, compare, projection); - iter_swap_if(first + 6u, first + 11u, compare, projection); - iter_swap_if(first + 5u, first + 7u, compare, projection); - iter_swap_if(first + 6u, first + 8u, compare, projection); - iter_swap_if(first + 8u, first + 10u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 8u, first + 14u, compare, projection); - iter_swap_if(first + 9u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 13u, compare, projection); - iter_swap_if(first + 4u, first + 6u, compare, projection); - iter_swap_if(first + 10u, first + 14u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 7u, first + 9u, compare, projection); - iter_swap_if(first + 11u, first + 13u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first + 14u, first + 15u, compare, projection); - iter_swap_if(first + 1u, first + 8u, compare, projection); - iter_swap_if(first + 13u, first + 15u, compare, projection); - iter_swap_if(first + 1u, first + 4u, compare, projection); - iter_swap_if(first + 2u, first + 5u, compare, projection); - iter_swap_if(first + 11u, first + 14u, compare, projection); - iter_swap_if(first + 13u, first + 14u, compare, projection); - iter_swap_if(first + 2u, first + 4u, compare, projection); - iter_swap_if(first + 6u, first + 12u, compare, projection); - iter_swap_if(first + 9u, first + 12u, compare, projection); - iter_swap_if(first + 3u, first + 10u, compare, projection); - iter_swap_if(first + 3u, first + 8u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 10u, first + 12u, compare, projection); - iter_swap_if(first + 3u, first + 6u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 12u, first + 13u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 11u, first + 12u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 6u, first + 8u, compare, projection); - iter_swap_if(first + 9u, first + 11u, compare, projection); - iter_swap_if(first + 5u, first + 7u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 9u, first + 10u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); + iter_swap_if(first, first + 11, compare, projection); + iter_swap_if(first + 1, first + 15, compare, projection); + iter_swap_if(first + 2, first + 10, compare, projection); + iter_swap_if(first + 3, first + 5, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first + 8, first + 12, compare, projection); + iter_swap_if(first + 9, first + 16, compare, projection); + iter_swap_if(first + 13, first + 14, compare, projection); + iter_swap_if(first, first + 6, compare, projection); + iter_swap_if(first + 1, first + 13, compare, projection); + iter_swap_if(first + 2, first + 8, compare, projection); + iter_swap_if(first + 4, first + 14, compare, projection); + iter_swap_if(first + 5, first + 15, compare, projection); + iter_swap_if(first + 7, first + 11, compare, projection); + iter_swap_if(first, first + 8, compare, projection); + iter_swap_if(first + 3, first + 7, compare, projection); + iter_swap_if(first + 4, first + 9, compare, projection); + iter_swap_if(first + 6, first + 16, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 12, first + 14, compare, projection); + iter_swap_if(first, first + 2, compare, projection); + iter_swap_if(first + 1, first + 4, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 7, first + 13, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 11, first + 14, compare, projection); + iter_swap_if(first + 15, first + 16, compare, projection); + iter_swap_if(first, first + 3, compare, projection); + iter_swap_if(first + 2, first + 5, compare, projection); + iter_swap_if(first + 6, first + 11, compare, projection); + iter_swap_if(first + 7, first + 10, compare, projection); + iter_swap_if(first + 9, first + 13, compare, projection); + iter_swap_if(first + 12, first + 15, compare, projection); + iter_swap_if(first + 14, first + 16, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 10, compare, projection); + iter_swap_if(first + 6, first + 9, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 11, first + 15, compare, projection); + iter_swap_if(first + 13, first + 14, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 3, first + 7, compare, projection); + iter_swap_if(first + 4, first + 8, compare, projection); + iter_swap_if(first + 6, first + 12, compare, projection); + iter_swap_if(first + 11, first + 13, compare, projection); + iter_swap_if(first + 14, first + 15, compare, projection); + iter_swap_if(first + 1, first + 3, compare, projection); + iter_swap_if(first + 2, first + 7, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 9, first + 11, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 13, first + 14, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first + 5, first + 7, compare, projection); + iter_swap_if(first + 8, first + 10, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 6, first + 8, compare, projection); + iter_swap_if(first + 7, first + 9, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 9, first + 10, compare, projection); + iter_swap_if(first + 11, first + 12, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 12, first + 13, compare, projection); } template diff --git a/include/cpp-sort/detail/sorting_network/sort18.h b/include/cpp-sort/detail/sorting_network/sort18.h index 7520709c..bc942526 100644 --- a/include/cpp-sort/detail/sorting_network/sort18.h +++ b/include/cpp-sort/detail/sorting_network/sort18.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SORTING_NETWORK_SORT18_H_ @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<18u> + struct sorting_network_sorter_impl<18> { template< typename RandomAccessIterator, @@ -24,83 +24,83 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - iter_swap_if(first, first + 1u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 13u, compare, projection); - iter_swap_if(first + 14u, first + 15u, compare, projection); - iter_swap_if(first + 16u, first + 17u, compare, projection); - iter_swap_if(first + 1u, first + 5u, compare, projection); - iter_swap_if(first + 2u, first + 6u, compare, projection); - iter_swap_if(first + 3u, first + 7u, compare, projection); - iter_swap_if(first + 4u, first + 10u, compare, projection); - iter_swap_if(first + 8u, first + 16u, compare, projection); - iter_swap_if(first + 9u, first + 17u, compare, projection); - iter_swap_if(first + 12u, first + 14u, compare, projection); - iter_swap_if(first + 13u, first + 15u, compare, projection); - iter_swap_if(first, first + 8u, compare, projection); - iter_swap_if(first + 1u, first + 10u, compare, projection); - iter_swap_if(first + 2u, first + 12u, compare, projection); - iter_swap_if(first + 3u, first + 14u, compare, projection); - iter_swap_if(first + 6u, first + 13u, compare, projection); - iter_swap_if(first + 7u, first + 15u, compare, projection); - iter_swap_if(first + 9u, first + 16u, compare, projection); - iter_swap_if(first + 11u, first + 17u, compare, projection); - iter_swap_if(first, first + 4u, compare, projection); - iter_swap_if(first + 1u, first + 9u, compare, projection); - iter_swap_if(first + 5u, first + 17u, compare, projection); - iter_swap_if(first + 8u, first + 11u, compare, projection); - iter_swap_if(first + 10u, first + 16u, compare, projection); - iter_swap_if(first, first + 2u, compare, projection); - iter_swap_if(first + 1u, first + 6u, compare, projection); - iter_swap_if(first + 4u, first + 10u, compare, projection); - iter_swap_if(first + 5u, first + 9u, compare, projection); - iter_swap_if(first + 14u, first + 16u, compare, projection); - iter_swap_if(first + 15u, first + 17u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first + 3u, first + 10u, compare, projection); - iter_swap_if(first + 4u, first + 12u, compare, projection); - iter_swap_if(first + 5u, first + 7u, compare, projection); - iter_swap_if(first + 6u, first + 14u, compare, projection); - iter_swap_if(first + 9u, first + 13u, compare, projection); - iter_swap_if(first + 15u, first + 16u, compare, projection); - iter_swap_if(first + 3u, first + 8u, compare, projection); - iter_swap_if(first + 5u, first + 12u, compare, projection); - iter_swap_if(first + 7u, first + 11u, compare, projection); - iter_swap_if(first + 9u, first + 10u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 6u, first + 8u, compare, projection); - iter_swap_if(first + 7u, first + 14u, compare, projection); - iter_swap_if(first + 9u, first + 12u, compare, projection); - iter_swap_if(first + 11u, first + 13u, compare, projection); - iter_swap_if(first + 1u, first + 3u, compare, projection); - iter_swap_if(first + 2u, first + 4u, compare, projection); - iter_swap_if(first + 7u, first + 9u, compare, projection); - iter_swap_if(first + 8u, first + 12u, compare, projection); - iter_swap_if(first + 11u, first + 15u, compare, projection); - iter_swap_if(first + 13u, first + 16u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 14u, compare, projection); - iter_swap_if(first + 13u, first + 15u, compare, projection); - iter_swap_if(first + 4u, first + 6u, compare, projection); - iter_swap_if(first + 5u, first + 8u, compare, projection); - iter_swap_if(first + 9u, first + 10u, compare, projection); - iter_swap_if(first + 11u, first + 14u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 12u, compare, projection); - iter_swap_if(first + 13u, first + 14u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); - iter_swap_if(first + 9u, first + 10u, compare, projection); - iter_swap_if(first + 11u, first + 12u, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 12, first + 13, compare, projection); + iter_swap_if(first + 14, first + 15, compare, projection); + iter_swap_if(first + 16, first + 17, compare, projection); + iter_swap_if(first, first + 2, compare, projection); + iter_swap_if(first + 1, first + 3, compare, projection); + iter_swap_if(first + 4, first + 12, compare, projection); + iter_swap_if(first + 5, first + 13, compare, projection); + iter_swap_if(first + 6, first + 8, compare, projection); + iter_swap_if(first + 9, first + 11, compare, projection); + iter_swap_if(first + 14, first + 16, compare, projection); + iter_swap_if(first + 15, first + 17, compare, projection); + iter_swap_if(first, first + 14, compare, projection); + iter_swap_if(first + 1, first + 16, compare, projection); + iter_swap_if(first + 2, first + 15, compare, projection); + iter_swap_if(first + 3, first + 17, compare, projection); + iter_swap_if(first, first + 6, compare, projection); + iter_swap_if(first + 1, first + 10, compare, projection); + iter_swap_if(first + 2, first + 9, compare, projection); + iter_swap_if(first + 7, first + 16, compare, projection); + iter_swap_if(first + 8, first + 15, compare, projection); + iter_swap_if(first + 11, first + 17, compare, projection); + iter_swap_if(first + 1, first + 4, compare, projection); + iter_swap_if(first + 3, first + 9, compare, projection); + iter_swap_if(first + 5, first + 7, compare, projection); + iter_swap_if(first + 8, first + 14, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 13, first + 16, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 2, first + 5, compare, projection); + iter_swap_if(first + 3, first + 13, compare, projection); + iter_swap_if(first + 4, first + 14, compare, projection); + iter_swap_if(first + 7, first + 9, compare, projection); + iter_swap_if(first + 8, first + 10, compare, projection); + iter_swap_if(first + 12, first + 15, compare, projection); + iter_swap_if(first + 16, first + 17, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 3, first + 5, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first + 11, first + 13, compare, projection); + iter_swap_if(first + 12, first + 14, compare, projection); + iter_swap_if(first + 15, first + 16, compare, projection); + iter_swap_if(first + 4, first + 8, compare, projection); + iter_swap_if(first + 5, first + 12, compare, projection); + iter_swap_if(first + 6, first + 10, compare, projection); + iter_swap_if(first + 7, first + 11, compare, projection); + iter_swap_if(first + 9, first + 13, compare, projection); + iter_swap_if(first + 1, first + 4, compare, projection); + iter_swap_if(first + 2, first + 8, compare, projection); + iter_swap_if(first + 3, first + 6, compare, projection); + iter_swap_if(first + 5, first + 7, compare, projection); + iter_swap_if(first + 9, first + 15, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 11, first + 14, compare, projection); + iter_swap_if(first + 13, first + 16, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 5, first + 8, compare, projection); + iter_swap_if(first + 6, first + 10, compare, projection); + iter_swap_if(first + 7, first + 11, compare, projection); + iter_swap_if(first + 9, first + 12, compare, projection); + iter_swap_if(first + 13, first + 15, compare, projection); + iter_swap_if(first + 3, first + 5, compare, projection); + iter_swap_if(first + 6, first + 8, compare, projection); + iter_swap_if(first + 7, first + 10, compare, projection); + iter_swap_if(first + 9, first + 11, compare, projection); + iter_swap_if(first + 12, first + 14, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 9, first + 10, compare, projection); + iter_swap_if(first + 11, first + 12, compare, projection); + iter_swap_if(first + 13, first + 14, compare, projection); } template @@ -109,18 +109,17 @@ namespace detail { return {{ {0, 1}, {2, 3}, {4, 5}, {6, 7}, {8, 9}, {10, 11}, {12, 13}, {14, 15}, {16, 17}, - {1, 5}, {2, 6}, {3, 7}, {4, 10}, {8, 16}, {9, 17}, {12, 14}, {13, 15}, - {0, 8}, {1, 10}, {2, 12}, {3, 14}, {6, 13}, {7, 15}, {9, 16}, {11, 17}, - {0, 4}, {1, 9}, {5, 17}, {8, 11}, {10, 16}, - {0, 2}, {1, 6}, {4, 10}, {5, 9}, {14, 16}, {15, 17}, - {1, 2}, {3, 10}, {4, 12}, {5, 7}, {6, 14}, {9, 13}, {15, 16}, - {3, 8}, {5, 12}, {7, 11}, {9, 10}, - {3, 4}, {6, 8}, {7, 14}, {9, 12}, {11, 13}, - {1, 3}, {2, 4}, {7, 9}, {8, 12}, {11, 15}, {13, 16}, - {2, 3}, {4, 5}, {6, 7}, {10, 11}, {12, 14}, {13, 15}, - {4, 6}, {5, 8}, {9, 10}, {11, 14}, - {3, 4}, {5, 7}, {8, 9}, {10, 12}, {13, 14}, - {5, 6}, {7, 8}, {9, 10}, {11, 12}, + {0, 2}, {1, 3}, {4, 12}, {5, 13}, {6, 8}, {9, 11}, {14, 16}, {15, 17}, + {0, 14}, {1, 16}, {2, 15}, {3, 17}, + {0, 6}, {1, 10}, {2, 9}, {7, 16}, {8, 15}, {11, 17}, + {1, 4}, {3, 9}, {5, 7}, {8, 14}, {10, 12}, {13, 16}, + {0, 1}, {2, 5}, {3, 13}, {4, 14}, {7, 9}, {8, 10}, {12, 15}, {16, 17}, + {1, 2}, {3, 5}, {4, 6}, {11, 13}, {12, 14}, {15, 16}, + {4, 8}, {5, 12}, {6, 10}, {7, 11}, {9, 13}, + {1, 4}, {2, 8}, {3, 6}, {5, 7}, {9, 15}, {10, 12}, {11, 14}, {13, 16}, + {2, 4}, {5, 8}, {6, 10}, {7, 11}, {9, 12}, {13, 15}, + {3, 5}, {6, 8}, {7, 10}, {9, 11}, {12, 14}, + {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}, {13, 14}, }}; } }; diff --git a/include/cpp-sort/detail/sorting_network/sort19.h b/include/cpp-sort/detail/sorting_network/sort19.h index b606b109..03744aa4 100644 --- a/include/cpp-sort/detail/sorting_network/sort19.h +++ b/include/cpp-sort/detail/sorting_network/sort19.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SORTING_NETWORK_SORT19_H_ @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<19u> + struct sorting_network_sorter_impl<19> { template< typename RandomAccessIterator, @@ -24,91 +24,91 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - iter_swap_if(first, first + 12u, compare, projection); - iter_swap_if(first + 1u, first + 4u, compare, projection); - iter_swap_if(first + 2u, first + 8u, compare, projection); - iter_swap_if(first + 3u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 17u, compare, projection); - iter_swap_if(first + 7u, first + 11u, compare, projection); - iter_swap_if(first + 9u, first + 14u, compare, projection); - iter_swap_if(first + 10u, first + 13u, compare, projection); - iter_swap_if(first + 15u, first + 16u, compare, projection); - iter_swap_if(first, first + 2u, compare, projection); - iter_swap_if(first + 1u, first + 7u, compare, projection); - iter_swap_if(first + 3u, first + 6u, compare, projection); - iter_swap_if(first + 4u, first + 11u, compare, projection); - iter_swap_if(first + 5u, first + 17u, compare, projection); - iter_swap_if(first + 8u, first + 12u, compare, projection); - iter_swap_if(first + 10u, first + 15u, compare, projection); - iter_swap_if(first + 13u, first + 16u, compare, projection); - iter_swap_if(first + 14u, first + 18u, compare, projection); - iter_swap_if(first + 3u, first + 10u, compare, projection); - iter_swap_if(first + 4u, first + 14u, compare, projection); - iter_swap_if(first + 5u, first + 15u, compare, projection); - iter_swap_if(first + 6u, first + 13u, compare, projection); - iter_swap_if(first + 7u, first + 9u, compare, projection); - iter_swap_if(first + 11u, first + 17u, compare, projection); - iter_swap_if(first + 16u, first + 18u, compare, projection); - iter_swap_if(first, first + 7u, compare, projection); - iter_swap_if(first + 1u, first + 10u, compare, projection); - iter_swap_if(first + 4u, first + 6u, compare, projection); - iter_swap_if(first + 9u, first + 15u, compare, projection); - iter_swap_if(first + 11u, first + 16u, compare, projection); - iter_swap_if(first + 12u, first + 17u, compare, projection); - iter_swap_if(first + 13u, first + 14u, compare, projection); - iter_swap_if(first, first + 3u, compare, projection); - iter_swap_if(first + 2u, first + 6u, compare, projection); - iter_swap_if(first + 5u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 16u, compare, projection); - iter_swap_if(first + 1u, first + 8u, compare, projection); - iter_swap_if(first + 2u, first + 9u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 6u, first + 15u, compare, projection); - iter_swap_if(first + 7u, first + 13u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 18u, compare, projection); - iter_swap_if(first + 1u, first + 3u, compare, projection); - iter_swap_if(first + 2u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 9u, compare, projection); - iter_swap_if(first + 7u, first + 12u, compare, projection); - iter_swap_if(first + 8u, first + 10u, compare, projection); - iter_swap_if(first + 11u, first + 14u, compare, projection); - iter_swap_if(first + 17u, first + 18u, compare, projection); - iter_swap_if(first, first + 1u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 8u, compare, projection); - iter_swap_if(first + 6u, first + 10u, compare, projection); - iter_swap_if(first + 9u, first + 12u, compare, projection); - iter_swap_if(first + 14u, first + 15u, compare, projection); - iter_swap_if(first + 16u, first + 17u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first + 5u, first + 8u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 9u, first + 11u, compare, projection); - iter_swap_if(first + 10u, first + 13u, compare, projection); - iter_swap_if(first + 14u, first + 16u, compare, projection); - iter_swap_if(first + 15u, first + 17u, compare, projection); - iter_swap_if(first + 3u, first + 6u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 7u, first + 9u, compare, projection); - iter_swap_if(first + 8u, first + 10u, compare, projection); - iter_swap_if(first + 11u, first + 12u, compare, projection); - iter_swap_if(first + 13u, first + 14u, compare, projection); - iter_swap_if(first + 15u, first + 16u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); - iter_swap_if(first + 9u, first + 10u, compare, projection); - iter_swap_if(first + 11u, first + 13u, compare, projection); - iter_swap_if(first + 12u, first + 14u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 13u, compare, projection); - iter_swap_if(first + 14u, first + 15u, compare, projection); + iter_swap_if(first, first + 12, compare, projection); + iter_swap_if(first + 1, first + 4, compare, projection); + iter_swap_if(first + 2, first + 8, compare, projection); + iter_swap_if(first + 3, first + 5, compare, projection); + iter_swap_if(first + 6, first + 17, compare, projection); + iter_swap_if(first + 7, first + 11, compare, projection); + iter_swap_if(first + 9, first + 14, compare, projection); + iter_swap_if(first + 10, first + 13, compare, projection); + iter_swap_if(first + 15, first + 16, compare, projection); + iter_swap_if(first, first + 2, compare, projection); + iter_swap_if(first + 1, first + 7, compare, projection); + iter_swap_if(first + 3, first + 6, compare, projection); + iter_swap_if(first + 4, first + 11, compare, projection); + iter_swap_if(first + 5, first + 17, compare, projection); + iter_swap_if(first + 8, first + 12, compare, projection); + iter_swap_if(first + 10, first + 15, compare, projection); + iter_swap_if(first + 13, first + 16, compare, projection); + iter_swap_if(first + 14, first + 18, compare, projection); + iter_swap_if(first + 3, first + 10, compare, projection); + iter_swap_if(first + 4, first + 14, compare, projection); + iter_swap_if(first + 5, first + 15, compare, projection); + iter_swap_if(first + 6, first + 13, compare, projection); + iter_swap_if(first + 7, first + 9, compare, projection); + iter_swap_if(first + 11, first + 17, compare, projection); + iter_swap_if(first + 16, first + 18, compare, projection); + iter_swap_if(first, first + 7, compare, projection); + iter_swap_if(first + 1, first + 10, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first + 9, first + 15, compare, projection); + iter_swap_if(first + 11, first + 16, compare, projection); + iter_swap_if(first + 12, first + 17, compare, projection); + iter_swap_if(first + 13, first + 14, compare, projection); + iter_swap_if(first, first + 3, compare, projection); + iter_swap_if(first + 2, first + 6, compare, projection); + iter_swap_if(first + 5, first + 7, compare, projection); + iter_swap_if(first + 8, first + 11, compare, projection); + iter_swap_if(first + 12, first + 16, compare, projection); + iter_swap_if(first + 1, first + 8, compare, projection); + iter_swap_if(first + 2, first + 9, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 6, first + 15, compare, projection); + iter_swap_if(first + 7, first + 13, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 12, first + 18, compare, projection); + iter_swap_if(first + 1, first + 3, compare, projection); + iter_swap_if(first + 2, first + 5, compare, projection); + iter_swap_if(first + 6, first + 9, compare, projection); + iter_swap_if(first + 7, first + 12, compare, projection); + iter_swap_if(first + 8, first + 10, compare, projection); + iter_swap_if(first + 11, first + 14, compare, projection); + iter_swap_if(first + 17, first + 18, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 8, compare, projection); + iter_swap_if(first + 6, first + 10, compare, projection); + iter_swap_if(first + 9, first + 12, compare, projection); + iter_swap_if(first + 14, first + 15, compare, projection); + iter_swap_if(first + 16, first + 17, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 5, first + 8, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 9, first + 11, compare, projection); + iter_swap_if(first + 10, first + 13, compare, projection); + iter_swap_if(first + 14, first + 16, compare, projection); + iter_swap_if(first + 15, first + 17, compare, projection); + iter_swap_if(first + 3, first + 6, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 7, first + 9, compare, projection); + iter_swap_if(first + 8, first + 10, compare, projection); + iter_swap_if(first + 11, first + 12, compare, projection); + iter_swap_if(first + 13, first + 14, compare, projection); + iter_swap_if(first + 15, first + 16, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 9, first + 10, compare, projection); + iter_swap_if(first + 11, first + 13, compare, projection); + iter_swap_if(first + 12, first + 14, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 12, first + 13, compare, projection); + iter_swap_if(first + 14, first + 15, compare, projection); } template diff --git a/include/cpp-sort/detail/sorting_network/sort2.h b/include/cpp-sort/detail/sorting_network/sort2.h index 621d01a2..3f3f0ccb 100644 --- a/include/cpp-sort/detail/sorting_network/sort2.h +++ b/include/cpp-sort/detail/sorting_network/sort2.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SORTING_NETWORK_SORT2_H_ @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<2u> + struct sorting_network_sorter_impl<2> { template< typename RandomAccessIterator, @@ -24,7 +24,7 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - iter_swap_if(first, first + 1u, compare, projection); + iter_swap_if(first, first + 1, compare, projection); } template diff --git a/include/cpp-sort/detail/sorting_network/sort20.h b/include/cpp-sort/detail/sorting_network/sort20.h index 4d6b1082..f0f8319b 100644 --- a/include/cpp-sort/detail/sorting_network/sort20.h +++ b/include/cpp-sort/detail/sorting_network/sort20.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SORTING_NETWORK_SORT20_H_ @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<20u> + struct sorting_network_sorter_impl<20> { template< typename RandomAccessIterator, @@ -24,97 +24,97 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - iter_swap_if(first, first + 3u, compare, projection); - iter_swap_if(first + 1u, first + 7u, compare, projection); - iter_swap_if(first + 2u, first + 5u, compare, projection); - iter_swap_if(first + 4u, first + 8u, compare, projection); - iter_swap_if(first + 6u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 13u, compare, projection); - iter_swap_if(first + 11u, first + 15u, compare, projection); - iter_swap_if(first + 12u, first + 18u, compare, projection); - iter_swap_if(first + 14u, first + 17u, compare, projection); - iter_swap_if(first + 16u, first + 19u, compare, projection); - iter_swap_if(first, first + 14u, compare, projection); - iter_swap_if(first + 1u, first + 11u, compare, projection); - iter_swap_if(first + 2u, first + 16u, compare, projection); - iter_swap_if(first + 3u, first + 17u, compare, projection); - iter_swap_if(first + 4u, first + 12u, compare, projection); - iter_swap_if(first + 5u, first + 19u, compare, projection); - iter_swap_if(first + 6u, first + 10u, compare, projection); - iter_swap_if(first + 7u, first + 15u, compare, projection); - iter_swap_if(first + 8u, first + 18u, compare, projection); - iter_swap_if(first + 9u, first + 13u, compare, projection); - iter_swap_if(first, first + 4u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first + 3u, first + 8u, compare, projection); - iter_swap_if(first + 5u, first + 7u, compare, projection); - iter_swap_if(first + 11u, first + 16u, compare, projection); - iter_swap_if(first + 12u, first + 14u, compare, projection); - iter_swap_if(first + 15u, first + 19u, compare, projection); - iter_swap_if(first + 17u, first + 18u, compare, projection); - iter_swap_if(first + 1u, first + 6u, compare, projection); - iter_swap_if(first + 2u, first + 12u, compare, projection); - iter_swap_if(first + 3u, first + 5u, compare, projection); - iter_swap_if(first + 4u, first + 11u, compare, projection); - iter_swap_if(first + 7u, first + 17u, compare, projection); - iter_swap_if(first + 8u, first + 15u, compare, projection); - iter_swap_if(first + 13u, first + 18u, compare, projection); - iter_swap_if(first + 14u, first + 16u, compare, projection); - iter_swap_if(first, first + 1u, compare, projection); - iter_swap_if(first + 2u, first + 6u, compare, projection); - iter_swap_if(first + 7u, first + 10u, compare, projection); - iter_swap_if(first + 9u, first + 12u, compare, projection); - iter_swap_if(first + 13u, first + 17u, compare, projection); - iter_swap_if(first + 18u, first + 19u, compare, projection); - iter_swap_if(first + 1u, first + 6u, compare, projection); - iter_swap_if(first + 5u, first + 9u, compare, projection); - iter_swap_if(first + 7u, first + 11u, compare, projection); - iter_swap_if(first + 8u, first + 12u, compare, projection); - iter_swap_if(first + 10u, first + 14u, compare, projection); - iter_swap_if(first + 13u, first + 18u, compare, projection); - iter_swap_if(first + 3u, first + 5u, compare, projection); - iter_swap_if(first + 4u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 10u, compare, projection); - iter_swap_if(first + 9u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 15u, compare, projection); - iter_swap_if(first + 14u, first + 16u, compare, projection); - iter_swap_if(first + 1u, first + 3u, compare, projection); - iter_swap_if(first + 2u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 7u, compare, projection); - iter_swap_if(first + 6u, first + 10u, compare, projection); - iter_swap_if(first + 9u, first + 13u, compare, projection); - iter_swap_if(first + 12u, first + 14u, compare, projection); - iter_swap_if(first + 15u, first + 17u, compare, projection); - iter_swap_if(first + 16u, first + 18u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 13u, compare, projection); - iter_swap_if(first + 15u, first + 16u, compare, projection); - iter_swap_if(first + 17u, first + 18u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 6u, compare, projection); - iter_swap_if(first + 5u, first + 8u, compare, projection); - iter_swap_if(first + 7u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 12u, compare, projection); - iter_swap_if(first + 11u, first + 14u, compare, projection); - iter_swap_if(first + 13u, first + 15u, compare, projection); - iter_swap_if(first + 16u, first + 17u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 8u, compare, projection); - iter_swap_if(first + 7u, first + 10u, compare, projection); - iter_swap_if(first + 9u, first + 12u, compare, projection); - iter_swap_if(first + 11u, first + 13u, compare, projection); - iter_swap_if(first + 14u, first + 15u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); - iter_swap_if(first + 9u, first + 10u, compare, projection); - iter_swap_if(first + 11u, first + 12u, compare, projection); - iter_swap_if(first + 13u, first + 14u, compare, projection); - iter_swap_if(first + 15u, first + 16u, compare, projection); + iter_swap_if(first, first + 3, compare, projection); + iter_swap_if(first + 1, first + 7, compare, projection); + iter_swap_if(first + 2, first + 5, compare, projection); + iter_swap_if(first + 4, first + 8, compare, projection); + iter_swap_if(first + 6, first + 9, compare, projection); + iter_swap_if(first + 10, first + 13, compare, projection); + iter_swap_if(first + 11, first + 15, compare, projection); + iter_swap_if(first + 12, first + 18, compare, projection); + iter_swap_if(first + 14, first + 17, compare, projection); + iter_swap_if(first + 16, first + 19, compare, projection); + iter_swap_if(first, first + 14, compare, projection); + iter_swap_if(first + 1, first + 11, compare, projection); + iter_swap_if(first + 2, first + 16, compare, projection); + iter_swap_if(first + 3, first + 17, compare, projection); + iter_swap_if(first + 4, first + 12, compare, projection); + iter_swap_if(first + 5, first + 19, compare, projection); + iter_swap_if(first + 6, first + 10, compare, projection); + iter_swap_if(first + 7, first + 15, compare, projection); + iter_swap_if(first + 8, first + 18, compare, projection); + iter_swap_if(first + 9, first + 13, compare, projection); + iter_swap_if(first, first + 4, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 3, first + 8, compare, projection); + iter_swap_if(first + 5, first + 7, compare, projection); + iter_swap_if(first + 11, first + 16, compare, projection); + iter_swap_if(first + 12, first + 14, compare, projection); + iter_swap_if(first + 15, first + 19, compare, projection); + iter_swap_if(first + 17, first + 18, compare, projection); + iter_swap_if(first + 1, first + 6, compare, projection); + iter_swap_if(first + 2, first + 12, compare, projection); + iter_swap_if(first + 3, first + 5, compare, projection); + iter_swap_if(first + 4, first + 11, compare, projection); + iter_swap_if(first + 7, first + 17, compare, projection); + iter_swap_if(first + 8, first + 15, compare, projection); + iter_swap_if(first + 13, first + 18, compare, projection); + iter_swap_if(first + 14, first + 16, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 2, first + 6, compare, projection); + iter_swap_if(first + 7, first + 10, compare, projection); + iter_swap_if(first + 9, first + 12, compare, projection); + iter_swap_if(first + 13, first + 17, compare, projection); + iter_swap_if(first + 18, first + 19, compare, projection); + iter_swap_if(first + 1, first + 6, compare, projection); + iter_swap_if(first + 5, first + 9, compare, projection); + iter_swap_if(first + 7, first + 11, compare, projection); + iter_swap_if(first + 8, first + 12, compare, projection); + iter_swap_if(first + 10, first + 14, compare, projection); + iter_swap_if(first + 13, first + 18, compare, projection); + iter_swap_if(first + 3, first + 5, compare, projection); + iter_swap_if(first + 4, first + 7, compare, projection); + iter_swap_if(first + 8, first + 10, compare, projection); + iter_swap_if(first + 9, first + 11, compare, projection); + iter_swap_if(first + 12, first + 15, compare, projection); + iter_swap_if(first + 14, first + 16, compare, projection); + iter_swap_if(first + 1, first + 3, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 5, first + 7, compare, projection); + iter_swap_if(first + 6, first + 10, compare, projection); + iter_swap_if(first + 9, first + 13, compare, projection); + iter_swap_if(first + 12, first + 14, compare, projection); + iter_swap_if(first + 15, first + 17, compare, projection); + iter_swap_if(first + 16, first + 18, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 12, first + 13, compare, projection); + iter_swap_if(first + 15, first + 16, compare, projection); + iter_swap_if(first + 17, first + 18, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first + 5, first + 8, compare, projection); + iter_swap_if(first + 7, first + 9, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 11, first + 14, compare, projection); + iter_swap_if(first + 13, first + 15, compare, projection); + iter_swap_if(first + 16, first + 17, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 6, first + 8, compare, projection); + iter_swap_if(first + 7, first + 10, compare, projection); + iter_swap_if(first + 9, first + 12, compare, projection); + iter_swap_if(first + 11, first + 13, compare, projection); + iter_swap_if(first + 14, first + 15, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 9, first + 10, compare, projection); + iter_swap_if(first + 11, first + 12, compare, projection); + iter_swap_if(first + 13, first + 14, compare, projection); + iter_swap_if(first + 15, first + 16, compare, projection); } template diff --git a/include/cpp-sort/detail/sorting_network/sort21.h b/include/cpp-sort/detail/sorting_network/sort21.h index 422fa47a..ef2acdf8 100644 --- a/include/cpp-sort/detail/sorting_network/sort21.h +++ b/include/cpp-sort/detail/sorting_network/sort21.h @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<21u> + struct sorting_network_sorter_impl<21> { template< typename RandomAccessIterator, @@ -24,105 +24,105 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - iter_swap_if(first + 0u, first + 1u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 13u, compare, projection); - iter_swap_if(first + 14u, first + 15u, compare, projection); - iter_swap_if(first + 16u, first + 17u, compare, projection); - iter_swap_if(first + 18u, first + 19u, compare, projection); - iter_swap_if(first + 0u, first + 2u, compare, projection); - iter_swap_if(first + 1u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 6u, compare, projection); - iter_swap_if(first + 5u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 10u, compare, projection); - iter_swap_if(first + 9u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 14u, compare, projection); - iter_swap_if(first + 13u, first + 15u, compare, projection); - iter_swap_if(first + 16u, first + 18u, compare, projection); - iter_swap_if(first + 17u, first + 19u, compare, projection); - iter_swap_if(first + 0u, first + 4u, compare, projection); - iter_swap_if(first + 1u, first + 5u, compare, projection); - iter_swap_if(first + 2u, first + 6u, compare, projection); - iter_swap_if(first + 3u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 12u, compare, projection); - iter_swap_if(first + 9u, first + 13u, compare, projection); - iter_swap_if(first + 10u, first + 14u, compare, projection); - iter_swap_if(first + 11u, first + 15u, compare, projection); - iter_swap_if(first + 0u, first + 8u, compare, projection); - iter_swap_if(first + 1u, first + 9u, compare, projection); - iter_swap_if(first + 2u, first + 10u, compare, projection); - iter_swap_if(first + 3u, first + 11u, compare, projection); - iter_swap_if(first + 4u, first + 12u, compare, projection); - iter_swap_if(first + 5u, first + 13u, compare, projection); - iter_swap_if(first + 6u, first + 14u, compare, projection); - iter_swap_if(first + 7u, first + 15u, compare, projection); - iter_swap_if(first + 3u, first + 18u, compare, projection); - iter_swap_if(first + 7u, first + 20u, compare, projection); - iter_swap_if(first + 2u, first + 7u, compare, projection); - iter_swap_if(first + 3u, first + 6u, compare, projection); - iter_swap_if(first + 14u, first + 18u, compare, projection); - iter_swap_if(first + 19u, first + 20u, compare, projection); - iter_swap_if(first + 2u, first + 16u, compare, projection); - iter_swap_if(first + 3u, first + 8u, compare, projection); - iter_swap_if(first + 6u, first + 14u, compare, projection); - iter_swap_if(first + 7u, first + 17u, compare, projection); - iter_swap_if(first + 11u, first + 19u, compare, projection); - iter_swap_if(first + 15u, first + 20u, compare, projection); - iter_swap_if(first + 0u, first + 2u, compare, projection); - iter_swap_if(first + 7u, first + 10u, compare, projection); - iter_swap_if(first + 9u, first + 16u, compare, projection); - iter_swap_if(first + 13u, first + 17u, compare, projection); - iter_swap_if(first + 15u, first + 19u, compare, projection); - iter_swap_if(first + 1u, first + 7u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 9u, compare, projection); - iter_swap_if(first + 5u, first + 10u, compare, projection); - iter_swap_if(first + 11u, first + 16u, compare, projection); - iter_swap_if(first + 12u, first + 13u, compare, projection); - iter_swap_if(first + 17u, first + 18u, compare, projection); - iter_swap_if(first + 1u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 11u, compare, projection); - iter_swap_if(first + 6u, first + 12u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); - iter_swap_if(first + 10u, first + 13u, compare, projection); - iter_swap_if(first + 14u, first + 16u, compare, projection); - iter_swap_if(first + 15u, first + 17u, compare, projection); - iter_swap_if(first + 18u, first + 19u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 10u, first + 14u, compare, projection); - iter_swap_if(first + 11u, first + 12u, compare, projection); - iter_swap_if(first + 13u, first + 16u, compare, projection); - iter_swap_if(first + 17u, first + 18u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 13u, compare, projection); - iter_swap_if(first + 14u, first + 15u, compare, projection); - iter_swap_if(first + 16u, first + 17u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 13u, first + 15u, compare, projection); - iter_swap_if(first + 4u, first + 6u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); - iter_swap_if(first + 9u, first + 12u, compare, projection); - iter_swap_if(first + 15u, first + 16u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 10u, compare, projection); - iter_swap_if(first + 9u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 14u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); - iter_swap_if(first + 9u, first + 10u, compare, projection); - iter_swap_if(first + 11u, first + 12u, compare, projection); - iter_swap_if(first + 13u, first + 14u, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 12, first + 13, compare, projection); + iter_swap_if(first + 14, first + 15, compare, projection); + iter_swap_if(first + 16, first + 17, compare, projection); + iter_swap_if(first + 18, first + 19, compare, projection); + iter_swap_if(first, first + 2, compare, projection); + iter_swap_if(first + 1, first + 3, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first + 5, first + 7, compare, projection); + iter_swap_if(first + 8, first + 10, compare, projection); + iter_swap_if(first + 9, first + 11, compare, projection); + iter_swap_if(first + 12, first + 14, compare, projection); + iter_swap_if(first + 13, first + 15, compare, projection); + iter_swap_if(first + 16, first + 18, compare, projection); + iter_swap_if(first + 17, first + 19, compare, projection); + iter_swap_if(first, first + 8, compare, projection); + iter_swap_if(first + 1, first + 9, compare, projection); + iter_swap_if(first + 2, first + 10, compare, projection); + iter_swap_if(first + 3, first + 11, compare, projection); + iter_swap_if(first + 4, first + 12, compare, projection); + iter_swap_if(first + 5, first + 13, compare, projection); + iter_swap_if(first + 6, first + 14, compare, projection); + iter_swap_if(first + 7, first + 15, compare, projection); + iter_swap_if(first, first + 4, compare, projection); + iter_swap_if(first + 1, first + 5, compare, projection); + iter_swap_if(first + 3, first + 7, compare, projection); + iter_swap_if(first + 6, first + 20, compare, projection); + iter_swap_if(first + 8, first + 12, compare, projection); + iter_swap_if(first + 9, first + 13, compare, projection); + iter_swap_if(first + 10, first + 14, compare, projection); + iter_swap_if(first + 15, first + 19, compare, projection); + iter_swap_if(first + 2, first + 6, compare, projection); + iter_swap_if(first + 3, first + 18, compare, projection); + iter_swap_if(first + 7, first + 20, compare, projection); + iter_swap_if(first + 2, first + 16, compare, projection); + iter_swap_if(first + 3, first + 6, compare, projection); + iter_swap_if(first + 5, first + 18, compare, projection); + iter_swap_if(first + 7, first + 17, compare, projection); + iter_swap_if(first + 11, first + 20, compare, projection); + iter_swap_if(first, first + 2, compare, projection); + iter_swap_if(first + 3, first + 8, compare, projection); + iter_swap_if(first + 6, first + 12, compare, projection); + iter_swap_if(first + 7, first + 10, compare, projection); + iter_swap_if(first + 9, first + 16, compare, projection); + iter_swap_if(first + 11, first + 15, compare, projection); + iter_swap_if(first + 13, first + 17, compare, projection); + iter_swap_if(first + 14, first + 18, compare, projection); + iter_swap_if(first + 19, first + 20, compare, projection); + iter_swap_if(first + 1, first + 7, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 9, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 13, first + 16, compare, projection); + iter_swap_if(first + 15, first + 18, compare, projection); + iter_swap_if(first + 17, first + 19, compare, projection); + iter_swap_if(first + 1, first + 4, compare, projection); + iter_swap_if(first + 5, first + 10, compare, projection); + iter_swap_if(first + 6, first + 13, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 11, first + 14, compare, projection); + iter_swap_if(first + 12, first + 16, compare, projection); + iter_swap_if(first + 15, first + 17, compare, projection); + iter_swap_if(first + 18, first + 19, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 11, first + 13, compare, projection); + iter_swap_if(first + 14, first + 16, compare, projection); + iter_swap_if(first + 17, first + 18, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 6, first + 9, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 12, first + 13, compare, projection); + iter_swap_if(first + 14, first + 15, compare, projection); + iter_swap_if(first + 16, first + 17, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 15, first + 16, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 9, first + 12, compare, projection); + iter_swap_if(first + 13, first + 15, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 7, compare, projection); + iter_swap_if(first + 8, first + 10, compare, projection); + iter_swap_if(first + 9, first + 11, compare, projection); + iter_swap_if(first + 12, first + 14, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 9, first + 10, compare, projection); + iter_swap_if(first + 11, first + 12, compare, projection); + iter_swap_if(first + 13, first + 14, compare, projection); } template @@ -132,18 +132,17 @@ namespace detail return {{ {0, 1}, {2, 3}, {4, 5}, {6, 7}, {8, 9}, {10, 11}, {12, 13}, {14, 15}, {16, 17}, {18, 19}, {0, 2}, {1, 3}, {4, 6}, {5, 7}, {8, 10}, {9, 11}, {12, 14}, {13, 15}, {16, 18}, {17, 19}, - {0, 4}, {1, 5}, {2, 6}, {3, 7}, {8, 12}, {9, 13}, {10, 14}, {11, 15}, {0, 8}, {1, 9}, {2, 10}, {3, 11}, {4, 12}, {5, 13}, {6, 14}, {7, 15}, - {3, 18}, {7, 20}, - {2, 7}, {3, 6}, {14, 18}, {19, 20}, - {2, 16}, {3, 8}, {6, 14}, {7, 17}, {11, 19}, {15, 20}, - {0, 2}, {7, 10}, {9, 16}, {13, 17}, {15, 19}, - {1, 7}, {2, 3}, {4, 9}, {5, 10}, {11, 16}, {12, 13}, {17, 18}, - {1, 4}, {5, 11}, {6, 12}, {7, 8}, {10, 13}, {14, 16}, {15, 17}, {18, 19}, - {1, 2}, {3, 4}, {5, 6}, {10, 14}, {11, 12}, {13, 16}, {17, 18}, + {0, 4}, {1, 5}, {3, 7}, {6, 20}, {8, 12}, {9, 13}, {10, 14}, {15, 19}, + {2, 6}, {3, 18}, {7, 20}, + {2, 16}, {3, 6}, {5, 18}, {7, 17}, {11, 20}, + {0, 2}, {3, 8}, {6, 12}, {7, 10}, {9, 16}, {11, 15}, {13, 17}, {14, 18}, {19, 20}, + {1, 7}, {2, 3}, {4, 9}, {10, 11}, {13, 16}, {15, 18}, {17, 19}, + {1, 4}, {5, 10}, {6, 13}, {7, 8}, {11, 14}, {12, 16}, {15, 17}, {18, 19}, + {1, 2}, {3, 4}, {5, 6}, {10, 12}, {11, 13}, {14, 16}, {17, 18}, {2, 3}, {4, 5}, {6, 9}, {10, 11}, {12, 13}, {14, 15}, {16, 17}, - {6, 7}, {8, 9}, {13, 15}, - {4, 6}, {7, 8}, {9, 12}, {15, 16}, + {6, 7}, {8, 9}, {15, 16}, + {4, 6}, {7, 8}, {9, 12}, {13, 15}, {3, 4}, {5, 7}, {8, 10}, {9, 11}, {12, 14}, {5, 6}, {7, 8}, {9, 10}, {11, 12}, {13, 14}, }}; diff --git a/include/cpp-sort/detail/sorting_network/sort22.h b/include/cpp-sort/detail/sorting_network/sort22.h index aaa7e020..adbad987 100644 --- a/include/cpp-sort/detail/sorting_network/sort22.h +++ b/include/cpp-sort/detail/sorting_network/sort22.h @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<22u> + struct sorting_network_sorter_impl<22> { template< typename RandomAccessIterator, @@ -24,112 +24,112 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - iter_swap_if(first + 0u, first + 1u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 13u, compare, projection); - iter_swap_if(first + 14u, first + 15u, compare, projection); - iter_swap_if(first + 16u, first + 17u, compare, projection); - iter_swap_if(first + 18u, first + 19u, compare, projection); - iter_swap_if(first + 20u, first + 21u, compare, projection); - iter_swap_if(first + 0u, first + 2u, compare, projection); - iter_swap_if(first + 1u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 6u, compare, projection); - iter_swap_if(first + 5u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 10u, compare, projection); - iter_swap_if(first + 9u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 14u, compare, projection); - iter_swap_if(first + 13u, first + 15u, compare, projection); - iter_swap_if(first + 16u, first + 18u, compare, projection); - iter_swap_if(first + 17u, first + 19u, compare, projection); - iter_swap_if(first + 0u, first + 4u, compare, projection); - iter_swap_if(first + 1u, first + 5u, compare, projection); - iter_swap_if(first + 2u, first + 6u, compare, projection); - iter_swap_if(first + 3u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 12u, compare, projection); - iter_swap_if(first + 9u, first + 13u, compare, projection); - iter_swap_if(first + 10u, first + 14u, compare, projection); - iter_swap_if(first + 11u, first + 15u, compare, projection); - iter_swap_if(first + 17u, first + 18u, compare, projection); - iter_swap_if(first + 0u, first + 8u, compare, projection); - iter_swap_if(first + 1u, first + 9u, compare, projection); - iter_swap_if(first + 2u, first + 10u, compare, projection); - iter_swap_if(first + 3u, first + 11u, compare, projection); - iter_swap_if(first + 4u, first + 12u, compare, projection); - iter_swap_if(first + 5u, first + 13u, compare, projection); - iter_swap_if(first + 6u, first + 14u, compare, projection); - iter_swap_if(first + 7u, first + 15u, compare, projection); - iter_swap_if(first + 17u, first + 21u, compare, projection); - iter_swap_if(first + 1u, first + 8u, compare, projection); - iter_swap_if(first + 6u, first + 20u, compare, projection); - iter_swap_if(first + 7u, first + 17u, compare, projection); - iter_swap_if(first + 19u, first + 21u, compare, projection); - iter_swap_if(first + 3u, first + 19u, compare, projection); - iter_swap_if(first + 4u, first + 7u, compare, projection); - iter_swap_if(first + 6u, first + 16u, compare, projection); - iter_swap_if(first + 14u, first + 21u, compare, projection); - iter_swap_if(first + 18u, first + 20u, compare, projection); - iter_swap_if(first + 0u, first + 6u, compare, projection); - iter_swap_if(first + 1u, first + 4u, compare, projection); - iter_swap_if(first + 3u, first + 12u, compare, projection); - iter_swap_if(first + 5u, first + 18u, compare, projection); - iter_swap_if(first + 7u, first + 10u, compare, projection); - iter_swap_if(first + 9u, first + 16u, compare, projection); - iter_swap_if(first + 11u, first + 20u, compare, projection); - iter_swap_if(first + 13u, first + 19u, compare, projection); - iter_swap_if(first + 14u, first + 17u, compare, projection); - iter_swap_if(first + 15u, first + 21u, compare, projection); - iter_swap_if(first + 2u, first + 5u, compare, projection); - iter_swap_if(first + 3u, first + 7u, compare, projection); - iter_swap_if(first + 6u, first + 8u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 13u, compare, projection); - iter_swap_if(first + 15u, first + 20u, compare, projection); - iter_swap_if(first + 16u, first + 18u, compare, projection); - iter_swap_if(first + 17u, first + 19u, compare, projection); - iter_swap_if(first + 5u, first + 8u, compare, projection); - iter_swap_if(first + 7u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 12u, compare, projection); - iter_swap_if(first + 14u, first + 16u, compare, projection); - iter_swap_if(first + 15u, first + 17u, compare, projection); - iter_swap_if(first + 19u, first + 20u, compare, projection); - iter_swap_if(first + 2u, first + 7u, compare, projection); - iter_swap_if(first + 3u, first + 5u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 14u, compare, projection); - iter_swap_if(first + 11u, first + 16u, compare, projection); - iter_swap_if(first + 12u, first + 18u, compare, projection); - iter_swap_if(first + 17u, first + 19u, compare, projection); - iter_swap_if(first + 2u, first + 6u, compare, projection); - iter_swap_if(first + 4u, first + 7u, compare, projection); - iter_swap_if(first + 5u, first + 8u, compare, projection); - iter_swap_if(first + 11u, first + 13u, compare, projection); - iter_swap_if(first + 12u, first + 14u, compare, projection); - iter_swap_if(first + 15u, first + 18u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first + 4u, first + 6u, compare, projection); - iter_swap_if(first + 7u, first + 10u, compare, projection); - iter_swap_if(first + 9u, first + 11u, compare, projection); - iter_swap_if(first + 13u, first + 16u, compare, projection); - iter_swap_if(first + 2u, first + 4u, compare, projection); - iter_swap_if(first + 3u, first + 6u, compare, projection); - iter_swap_if(first + 5u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 10u, compare, projection); - iter_swap_if(first + 9u, first + 12u, compare, projection); - iter_swap_if(first + 11u, first + 14u, compare, projection); - iter_swap_if(first + 13u, first + 15u, compare, projection); - iter_swap_if(first + 16u, first + 18u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); - iter_swap_if(first + 9u, first + 10u, compare, projection); - iter_swap_if(first + 11u, first + 12u, compare, projection); - iter_swap_if(first + 13u, first + 14u, compare, projection); - iter_swap_if(first + 15u, first + 16u, compare, projection); - iter_swap_if(first + 17u, first + 18u, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 12, first + 13, compare, projection); + iter_swap_if(first + 14, first + 15, compare, projection); + iter_swap_if(first + 16, first + 17, compare, projection); + iter_swap_if(first + 18, first + 19, compare, projection); + iter_swap_if(first + 20, first + 21, compare, projection); + iter_swap_if(first, first + 2, compare, projection); + iter_swap_if(first + 1, first + 3, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first + 5, first + 7, compare, projection); + iter_swap_if(first + 8, first + 12, compare, projection); + iter_swap_if(first + 9, first + 13, compare, projection); + iter_swap_if(first + 14, first + 16, compare, projection); + iter_swap_if(first + 15, first + 17, compare, projection); + iter_swap_if(first + 18, first + 20, compare, projection); + iter_swap_if(first + 19, first + 21, compare, projection); + iter_swap_if(first, first + 4, compare, projection); + iter_swap_if(first + 1, first + 5, compare, projection); + iter_swap_if(first + 2, first + 6, compare, projection); + iter_swap_if(first + 3, first + 7, compare, projection); + iter_swap_if(first + 8, first + 10, compare, projection); + iter_swap_if(first + 9, first + 12, compare, projection); + iter_swap_if(first + 11, first + 13, compare, projection); + iter_swap_if(first + 14, first + 18, compare, projection); + iter_swap_if(first + 15, first + 19, compare, projection); + iter_swap_if(first + 16, first + 20, compare, projection); + iter_swap_if(first + 17, first + 21, compare, projection); + iter_swap_if(first, first + 14, compare, projection); + iter_swap_if(first + 1, first + 15, compare, projection); + iter_swap_if(first + 2, first + 18, compare, projection); + iter_swap_if(first + 3, first + 19, compare, projection); + iter_swap_if(first + 4, first + 16, compare, projection); + iter_swap_if(first + 5, first + 17, compare, projection); + iter_swap_if(first + 6, first + 20, compare, projection); + iter_swap_if(first + 7, first + 21, compare, projection); + iter_swap_if(first + 9, first + 11, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 2, first + 8, compare, projection); + iter_swap_if(first + 3, first + 11, compare, projection); + iter_swap_if(first + 6, first + 9, compare, projection); + iter_swap_if(first + 10, first + 18, compare, projection); + iter_swap_if(first + 12, first + 15, compare, projection); + iter_swap_if(first + 13, first + 19, compare, projection); + iter_swap_if(first, first + 2, compare, projection); + iter_swap_if(first + 1, first + 10, compare, projection); + iter_swap_if(first + 3, first + 16, compare, projection); + iter_swap_if(first + 5, first + 18, compare, projection); + iter_swap_if(first + 6, first + 14, compare, projection); + iter_swap_if(first + 7, first + 15, compare, projection); + iter_swap_if(first + 8, first + 12, compare, projection); + iter_swap_if(first + 9, first + 13, compare, projection); + iter_swap_if(first + 11, first + 20, compare, projection); + iter_swap_if(first + 19, first + 21, compare, projection); + iter_swap_if(first + 2, first + 6, compare, projection); + iter_swap_if(first + 3, first + 10, compare, projection); + iter_swap_if(first + 4, first + 8, compare, projection); + iter_swap_if(first + 5, first + 12, compare, projection); + iter_swap_if(first + 9, first + 16, compare, projection); + iter_swap_if(first + 11, first + 18, compare, projection); + iter_swap_if(first + 13, first + 17, compare, projection); + iter_swap_if(first + 15, first + 19, compare, projection); + iter_swap_if(first + 1, first + 4, compare, projection); + iter_swap_if(first + 7, first + 13, compare, projection); + iter_swap_if(first + 8, first + 14, compare, projection); + iter_swap_if(first + 9, first + 12, compare, projection); + iter_swap_if(first + 17, first + 20, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 3, first + 8, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first + 7, first + 11, compare, projection); + iter_swap_if(first + 10, first + 14, compare, projection); + iter_swap_if(first + 13, first + 18, compare, projection); + iter_swap_if(first + 15, first + 17, compare, projection); + iter_swap_if(first + 19, first + 20, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 5, first + 10, compare, projection); + iter_swap_if(first + 7, first + 9, compare, projection); + iter_swap_if(first + 11, first + 16, compare, projection); + iter_swap_if(first + 12, first + 14, compare, projection); + iter_swap_if(first + 17, first + 19, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 9, first + 11, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 13, first + 14, compare, projection); + iter_swap_if(first + 15, first + 16, compare, projection); + iter_swap_if(first + 3, first + 5, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 8, first + 10, compare, projection); + iter_swap_if(first + 9, first + 12, compare, projection); + iter_swap_if(first + 11, first + 13, compare, projection); + iter_swap_if(first + 14, first + 15, compare, projection); + iter_swap_if(first + 16, first + 18, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 9, first + 10, compare, projection); + iter_swap_if(first + 11, first + 12, compare, projection); + iter_swap_if(first + 13, first + 14, compare, projection); + iter_swap_if(first + 15, first + 16, compare, projection); + iter_swap_if(first + 17, first + 18, compare, projection); } template @@ -138,18 +138,17 @@ namespace detail { return {{ {0, 1}, {2, 3}, {4, 5}, {6, 7}, {8, 9}, {10, 11}, {12, 13}, {14, 15}, {16, 17}, {18, 19}, {20, 21}, - {0, 2}, {1, 3}, {4, 6}, {5, 7}, {8, 10}, {9, 11}, {12, 14}, {13, 15}, {16, 18}, {17, 19}, - {0, 4}, {1, 5}, {2, 6}, {3, 7}, {8, 12}, {9, 13}, {10, 14}, {11, 15}, {17, 18}, - {0, 8}, {1, 9}, {2, 10}, {3, 11}, {4, 12}, {5, 13}, {6, 14}, {7, 15}, {17, 21}, - {1, 8}, {6, 20}, {7, 17}, {19, 21}, - {3, 19}, {4, 7}, {6, 16}, {14, 21}, {18, 20}, - {0, 6}, {1, 4}, {3, 12}, {5, 18}, {7, 10}, {9, 16}, {11, 20}, {13, 19}, {14, 17}, {15, 21}, - {2, 5}, {3, 7}, {6, 8}, {10, 11}, {12, 13}, {15, 20}, {16, 18}, {17, 19}, - {5, 8}, {7, 9}, {10, 12}, {14, 16}, {15, 17}, {19, 20}, - {2, 7}, {3, 5}, {8, 9}, {10, 14}, {11, 16}, {12, 18}, {17, 19}, - {2, 6}, {4, 7}, {5, 8}, {11, 13}, {12, 14}, {15, 18}, - {1, 2}, {4, 6}, {7, 10}, {9, 11}, {13, 16}, - {2, 4}, {3, 6}, {5, 7}, {8, 10}, {9, 12}, {11, 14}, {13, 15}, {16, 18}, + {0, 2}, {1, 3}, {4, 6}, {5, 7}, {8, 12}, {9, 13}, {14, 16}, {15, 17}, {18, 20}, {19, 21}, + {0, 4}, {1, 5}, {2, 6}, {3, 7}, {8, 10}, {9, 12}, {11, 13}, {14, 18}, {15, 19}, {16, 20}, {17, 21}, + {0, 14}, {1, 15}, {2, 18}, {3, 19}, {4, 16}, {5, 17}, {6, 20}, {7, 21}, {9, 11}, {10, 12}, + {2, 8}, {3, 11}, {6, 9}, {10, 18}, {12, 15}, {13, 19}, + {0, 2}, {1, 10}, {3, 16}, {5, 18}, {6, 14}, {7, 15}, {8, 12}, {9, 13}, {11, 20}, {19, 21}, + {2, 6}, {3, 10}, {4, 8}, {5, 12}, {9, 16}, {11, 18}, {13, 17}, {15, 19}, + {1, 4}, {7, 13}, {8, 14}, {9, 12}, {17, 20}, + {1, 2}, {3, 8}, {4, 6}, {7, 11}, {10, 14}, {13, 18}, {15, 17}, {19, 20}, + {2, 4}, {5, 10}, {7, 9}, {11, 16}, {12, 14}, {17, 19}, + {5, 6}, {7, 8}, {9, 11}, {10, 12}, {13, 14}, {15, 16}, + {3, 5}, {6, 7}, {8, 10}, {9, 12}, {11, 13}, {14, 15}, {16, 18}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}, {13, 14}, {15, 16}, {17, 18}, }}; } diff --git a/include/cpp-sort/detail/sorting_network/sort23.h b/include/cpp-sort/detail/sorting_network/sort23.h index 9f284af7..f0f546d0 100644 --- a/include/cpp-sort/detail/sorting_network/sort23.h +++ b/include/cpp-sort/detail/sorting_network/sort23.h @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<23u> + struct sorting_network_sorter_impl<23> { template< typename RandomAccessIterator, @@ -24,120 +24,120 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - iter_swap_if(first + 0u, first + 1u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 13u, compare, projection); - iter_swap_if(first + 14u, first + 15u, compare, projection); - iter_swap_if(first + 16u, first + 17u, compare, projection); - iter_swap_if(first + 18u, first + 19u, compare, projection); - iter_swap_if(first + 20u, first + 21u, compare, projection); - iter_swap_if(first + 0u, first + 2u, compare, projection); - iter_swap_if(first + 1u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 6u, compare, projection); - iter_swap_if(first + 5u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 10u, compare, projection); - iter_swap_if(first + 9u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 14u, compare, projection); - iter_swap_if(first + 13u, first + 15u, compare, projection); - iter_swap_if(first + 16u, first + 18u, compare, projection); - iter_swap_if(first + 17u, first + 19u, compare, projection); - iter_swap_if(first + 21u, first + 22u, compare, projection); - iter_swap_if(first + 0u, first + 4u, compare, projection); - iter_swap_if(first + 1u, first + 5u, compare, projection); - iter_swap_if(first + 2u, first + 6u, compare, projection); - iter_swap_if(first + 3u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 12u, compare, projection); - iter_swap_if(first + 9u, first + 13u, compare, projection); - iter_swap_if(first + 10u, first + 14u, compare, projection); - iter_swap_if(first + 11u, first + 15u, compare, projection); - iter_swap_if(first + 17u, first + 21u, compare, projection); - iter_swap_if(first + 18u, first + 20u, compare, projection); - iter_swap_if(first + 19u, first + 22u, compare, projection); - iter_swap_if(first + 0u, first + 8u, compare, projection); - iter_swap_if(first + 1u, first + 9u, compare, projection); - iter_swap_if(first + 2u, first + 10u, compare, projection); - iter_swap_if(first + 3u, first + 11u, compare, projection); - iter_swap_if(first + 4u, first + 12u, compare, projection); - iter_swap_if(first + 5u, first + 13u, compare, projection); - iter_swap_if(first + 6u, first + 14u, compare, projection); - iter_swap_if(first + 7u, first + 15u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first + 5u, first + 18u, compare, projection); - iter_swap_if(first + 7u, first + 19u, compare, projection); - iter_swap_if(first + 9u, first + 16u, compare, projection); - iter_swap_if(first + 10u, first + 21u, compare, projection); - iter_swap_if(first + 12u, first + 20u, compare, projection); - iter_swap_if(first + 15u, first + 22u, compare, projection); - iter_swap_if(first + 5u, first + 9u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 10u, first + 18u, compare, projection); - iter_swap_if(first + 11u, first + 21u, compare, projection); - iter_swap_if(first + 12u, first + 17u, compare, projection); - iter_swap_if(first + 13u, first + 20u, compare, projection); - iter_swap_if(first + 14u, first + 15u, compare, projection); - iter_swap_if(first + 3u, first + 17u, compare, projection); - iter_swap_if(first + 6u, first + 16u, compare, projection); - iter_swap_if(first + 7u, first + 14u, compare, projection); - iter_swap_if(first + 8u, first + 12u, compare, projection); - iter_swap_if(first + 15u, first + 19u, compare, projection); - iter_swap_if(first + 20u, first + 21u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 8u, compare, projection); - iter_swap_if(first + 6u, first + 10u, compare, projection); - iter_swap_if(first + 9u, first + 12u, compare, projection); - iter_swap_if(first + 13u, first + 16u, compare, projection); - iter_swap_if(first + 14u, first + 15u, compare, projection); - iter_swap_if(first + 17u, first + 18u, compare, projection); - iter_swap_if(first + 19u, first + 21u, compare, projection); - iter_swap_if(first + 0u, first + 5u, compare, projection); - iter_swap_if(first + 1u, first + 8u, compare, projection); - iter_swap_if(first + 2u, first + 12u, compare, projection); - iter_swap_if(first + 3u, first + 9u, compare, projection); - iter_swap_if(first + 4u, first + 10u, compare, projection); - iter_swap_if(first + 7u, first + 13u, compare, projection); - iter_swap_if(first + 11u, first + 17u, compare, projection); - iter_swap_if(first + 14u, first + 16u, compare, projection); - iter_swap_if(first + 18u, first + 20u, compare, projection); - iter_swap_if(first + 2u, first + 6u, compare, projection); - iter_swap_if(first + 3u, first + 5u, compare, projection); - iter_swap_if(first + 4u, first + 8u, compare, projection); - iter_swap_if(first + 7u, first + 11u, compare, projection); - iter_swap_if(first + 10u, first + 12u, compare, projection); - iter_swap_if(first + 13u, first + 18u, compare, projection); - iter_swap_if(first + 14u, first + 17u, compare, projection); - iter_swap_if(first + 15u, first + 20u, compare, projection); - iter_swap_if(first + 1u, first + 3u, compare, projection); - iter_swap_if(first + 2u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 9u, compare, projection); - iter_swap_if(first + 7u, first + 10u, compare, projection); - iter_swap_if(first + 11u, first + 13u, compare, projection); - iter_swap_if(first + 12u, first + 14u, compare, projection); - iter_swap_if(first + 15u, first + 18u, compare, projection); - iter_swap_if(first + 16u, first + 17u, compare, projection); - iter_swap_if(first + 19u, first + 20u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 6u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 11u, first + 12u, compare, projection); - iter_swap_if(first + 13u, first + 14u, compare, projection); - iter_swap_if(first + 15u, first + 16u, compare, projection); - iter_swap_if(first + 17u, first + 19u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); - iter_swap_if(first + 9u, first + 10u, compare, projection); - iter_swap_if(first + 12u, first + 13u, compare, projection); - iter_swap_if(first + 14u, first + 15u, compare, projection); - iter_swap_if(first + 17u, first + 18u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 16u, first + 17u, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 12, first + 13, compare, projection); + iter_swap_if(first + 14, first + 15, compare, projection); + iter_swap_if(first + 16, first + 17, compare, projection); + iter_swap_if(first + 18, first + 19, compare, projection); + iter_swap_if(first + 20, first + 21, compare, projection); + iter_swap_if(first, first + 2, compare, projection); + iter_swap_if(first + 1, first + 3, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first + 5, first + 7, compare, projection); + iter_swap_if(first + 8, first + 10, compare, projection); + iter_swap_if(first + 9, first + 11, compare, projection); + iter_swap_if(first + 12, first + 14, compare, projection); + iter_swap_if(first + 13, first + 15, compare, projection); + iter_swap_if(first + 16, first + 18, compare, projection); + iter_swap_if(first + 17, first + 19, compare, projection); + iter_swap_if(first + 21, first + 22, compare, projection); + iter_swap_if(first, first + 4, compare, projection); + iter_swap_if(first + 1, first + 5, compare, projection); + iter_swap_if(first + 2, first + 6, compare, projection); + iter_swap_if(first + 3, first + 7, compare, projection); + iter_swap_if(first + 8, first + 12, compare, projection); + iter_swap_if(first + 9, first + 13, compare, projection); + iter_swap_if(first + 10, first + 14, compare, projection); + iter_swap_if(first + 11, first + 15, compare, projection); + iter_swap_if(first + 17, first + 21, compare, projection); + iter_swap_if(first + 18, first + 20, compare, projection); + iter_swap_if(first + 19, first + 22, compare, projection); + iter_swap_if(first, first + 8, compare, projection); + iter_swap_if(first + 1, first + 9, compare, projection); + iter_swap_if(first + 2, first + 10, compare, projection); + iter_swap_if(first + 3, first + 11, compare, projection); + iter_swap_if(first + 4, first + 12, compare, projection); + iter_swap_if(first + 5, first + 13, compare, projection); + iter_swap_if(first + 6, first + 14, compare, projection); + iter_swap_if(first + 7, first + 15, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 5, first + 18, compare, projection); + iter_swap_if(first + 7, first + 19, compare, projection); + iter_swap_if(first + 9, first + 16, compare, projection); + iter_swap_if(first + 10, first + 21, compare, projection); + iter_swap_if(first + 12, first + 20, compare, projection); + iter_swap_if(first + 15, first + 22, compare, projection); + iter_swap_if(first + 5, first + 9, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 10, first + 18, compare, projection); + iter_swap_if(first + 11, first + 21, compare, projection); + iter_swap_if(first + 12, first + 17, compare, projection); + iter_swap_if(first + 13, first + 20, compare, projection); + iter_swap_if(first + 14, first + 15, compare, projection); + iter_swap_if(first + 3, first + 17, compare, projection); + iter_swap_if(first + 6, first + 16, compare, projection); + iter_swap_if(first + 7, first + 14, compare, projection); + iter_swap_if(first + 8, first + 12, compare, projection); + iter_swap_if(first + 15, first + 19, compare, projection); + iter_swap_if(first + 20, first + 21, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 8, compare, projection); + iter_swap_if(first + 6, first + 10, compare, projection); + iter_swap_if(first + 9, first + 12, compare, projection); + iter_swap_if(first + 13, first + 16, compare, projection); + iter_swap_if(first + 14, first + 15, compare, projection); + iter_swap_if(first + 17, first + 18, compare, projection); + iter_swap_if(first + 19, first + 21, compare, projection); + iter_swap_if(first, first + 5, compare, projection); + iter_swap_if(first + 1, first + 8, compare, projection); + iter_swap_if(first + 2, first + 12, compare, projection); + iter_swap_if(first + 3, first + 9, compare, projection); + iter_swap_if(first + 4, first + 10, compare, projection); + iter_swap_if(first + 7, first + 13, compare, projection); + iter_swap_if(first + 11, first + 17, compare, projection); + iter_swap_if(first + 14, first + 16, compare, projection); + iter_swap_if(first + 18, first + 20, compare, projection); + iter_swap_if(first + 2, first + 6, compare, projection); + iter_swap_if(first + 3, first + 5, compare, projection); + iter_swap_if(first + 4, first + 8, compare, projection); + iter_swap_if(first + 7, first + 11, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 13, first + 18, compare, projection); + iter_swap_if(first + 14, first + 17, compare, projection); + iter_swap_if(first + 15, first + 20, compare, projection); + iter_swap_if(first + 1, first + 3, compare, projection); + iter_swap_if(first + 2, first + 5, compare, projection); + iter_swap_if(first + 6, first + 9, compare, projection); + iter_swap_if(first + 7, first + 10, compare, projection); + iter_swap_if(first + 11, first + 13, compare, projection); + iter_swap_if(first + 12, first + 14, compare, projection); + iter_swap_if(first + 15, first + 18, compare, projection); + iter_swap_if(first + 16, first + 17, compare, projection); + iter_swap_if(first + 19, first + 20, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 11, first + 12, compare, projection); + iter_swap_if(first + 13, first + 14, compare, projection); + iter_swap_if(first + 15, first + 16, compare, projection); + iter_swap_if(first + 17, first + 19, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 9, first + 10, compare, projection); + iter_swap_if(first + 12, first + 13, compare, projection); + iter_swap_if(first + 14, first + 15, compare, projection); + iter_swap_if(first + 17, first + 18, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 16, first + 17, compare, projection); } template diff --git a/include/cpp-sort/detail/sorting_network/sort24.h b/include/cpp-sort/detail/sorting_network/sort24.h index 24977333..b59e1450 100644 --- a/include/cpp-sort/detail/sorting_network/sort24.h +++ b/include/cpp-sort/detail/sorting_network/sort24.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SORTING_NETWORK_SORT24_H_ @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<24u> + struct sorting_network_sorter_impl<24> { template< typename RandomAccessIterator, @@ -24,126 +24,126 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - iter_swap_if(first, first + 20u, compare, projection); - iter_swap_if(first + 1u, first + 12u, compare, projection); - iter_swap_if(first + 2u, first + 16u, compare, projection); - iter_swap_if(first + 3u, first + 23u, compare, projection); - iter_swap_if(first + 4u, first + 6u, compare, projection); - iter_swap_if(first + 5u, first + 10u, compare, projection); - iter_swap_if(first + 7u, first + 21u, compare, projection); - iter_swap_if(first + 8u, first + 14u, compare, projection); - iter_swap_if(first + 9u, first + 15u, compare, projection); - iter_swap_if(first + 11u, first + 22u, compare, projection); - iter_swap_if(first + 13u, first + 18u, compare, projection); - iter_swap_if(first + 17u, first + 19u, compare, projection); - iter_swap_if(first, first + 3u, compare, projection); - iter_swap_if(first + 1u, first + 11u, compare, projection); - iter_swap_if(first + 2u, first + 7u, compare, projection); - iter_swap_if(first + 4u, first + 17u, compare, projection); - iter_swap_if(first + 5u, first + 13u, compare, projection); - iter_swap_if(first + 6u, first + 19u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 18u, compare, projection); - iter_swap_if(first + 12u, first + 22u, compare, projection); - iter_swap_if(first + 14u, first + 15u, compare, projection); - iter_swap_if(first + 16u, first + 21u, compare, projection); - iter_swap_if(first + 20u, first + 23u, compare, projection); - iter_swap_if(first, first + 1u, compare, projection); - iter_swap_if(first + 2u, first + 4u, compare, projection); - iter_swap_if(first + 3u, first + 12u, compare, projection); - iter_swap_if(first + 5u, first + 8u, compare, projection); - iter_swap_if(first + 6u, first + 9u, compare, projection); - iter_swap_if(first + 7u, first + 10u, compare, projection); - iter_swap_if(first + 11u, first + 20u, compare, projection); - iter_swap_if(first + 13u, first + 16u, compare, projection); - iter_swap_if(first + 14u, first + 17u, compare, projection); - iter_swap_if(first + 15u, first + 18u, compare, projection); - iter_swap_if(first + 19u, first + 21u, compare, projection); - iter_swap_if(first + 22u, first + 23u, compare, projection); - iter_swap_if(first + 2u, first + 5u, compare, projection); - iter_swap_if(first + 4u, first + 8u, compare, projection); - iter_swap_if(first + 6u, first + 11u, compare, projection); - iter_swap_if(first + 7u, first + 14u, compare, projection); - iter_swap_if(first + 9u, first + 16u, compare, projection); - iter_swap_if(first + 12u, first + 17u, compare, projection); - iter_swap_if(first + 15u, first + 19u, compare, projection); - iter_swap_if(first + 18u, first + 21u, compare, projection); - iter_swap_if(first + 1u, first + 8u, compare, projection); - iter_swap_if(first + 3u, first + 14u, compare, projection); - iter_swap_if(first + 4u, first + 7u, compare, projection); - iter_swap_if(first + 9u, first + 20u, compare, projection); - iter_swap_if(first + 10u, first + 12u, compare, projection); - iter_swap_if(first + 11u, first + 13u, compare, projection); - iter_swap_if(first + 15u, first + 22u, compare, projection); - iter_swap_if(first + 16u, first + 19u, compare, projection); - iter_swap_if(first, first + 7u, compare, projection); - iter_swap_if(first + 1u, first + 5u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 6u, first + 11u, compare, projection); - iter_swap_if(first + 8u, first + 15u, compare, projection); - iter_swap_if(first + 9u, first + 14u, compare, projection); - iter_swap_if(first + 10u, first + 13u, compare, projection); - iter_swap_if(first + 12u, first + 17u, compare, projection); - iter_swap_if(first + 16u, first + 23u, compare, projection); - iter_swap_if(first + 18u, first + 22u, compare, projection); - iter_swap_if(first + 19u, first + 20u, compare, projection); - iter_swap_if(first, first + 2u, compare, projection); - iter_swap_if(first + 1u, first + 6u, compare, projection); - iter_swap_if(first + 4u, first + 7u, compare, projection); - iter_swap_if(first + 5u, first + 9u, compare, projection); - iter_swap_if(first + 8u, first + 10u, compare, projection); - iter_swap_if(first + 13u, first + 15u, compare, projection); - iter_swap_if(first + 14u, first + 18u, compare, projection); - iter_swap_if(first + 16u, first + 19u, compare, projection); - iter_swap_if(first + 17u, first + 22u, compare, projection); - iter_swap_if(first + 21u, first + 23u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 8u, compare, projection); - iter_swap_if(first + 7u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 13u, compare, projection); - iter_swap_if(first + 14u, first + 16u, compare, projection); - iter_swap_if(first + 15u, first + 17u, compare, projection); - iter_swap_if(first + 18u, first + 19u, compare, projection); - iter_swap_if(first + 20u, first + 21u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first + 3u, first + 6u, compare, projection); - iter_swap_if(first + 4u, first + 10u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); - iter_swap_if(first + 9u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 14u, compare, projection); - iter_swap_if(first + 13u, first + 19u, compare, projection); - iter_swap_if(first + 15u, first + 16u, compare, projection); - iter_swap_if(first + 17u, first + 20u, compare, projection); - iter_swap_if(first + 21u, first + 22u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 5u, first + 10u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 13u, first + 18u, compare, projection); - iter_swap_if(first + 14u, first + 15u, compare, projection); - iter_swap_if(first + 16u, first + 17u, compare, projection); - iter_swap_if(first + 20u, first + 21u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 7u, compare, projection); - iter_swap_if(first + 10u, first + 12u, compare, projection); - iter_swap_if(first + 11u, first + 13u, compare, projection); - iter_swap_if(first + 16u, first + 18u, compare, projection); - iter_swap_if(first + 19u, first + 20u, compare, projection); - iter_swap_if(first + 4u, first + 6u, compare, projection); - iter_swap_if(first + 8u, first + 10u, compare, projection); - iter_swap_if(first + 9u, first + 12u, compare, projection); - iter_swap_if(first + 11u, first + 14u, compare, projection); - iter_swap_if(first + 13u, first + 15u, compare, projection); - iter_swap_if(first + 17u, first + 19u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); - iter_swap_if(first + 9u, first + 10u, compare, projection); - iter_swap_if(first + 11u, first + 12u, compare, projection); - iter_swap_if(first + 13u, first + 14u, compare, projection); - iter_swap_if(first + 15u, first + 16u, compare, projection); - iter_swap_if(first + 17u, first + 18u, compare, projection); + iter_swap_if(first, first + 20, compare, projection); + iter_swap_if(first + 1, first + 12, compare, projection); + iter_swap_if(first + 2, first + 16, compare, projection); + iter_swap_if(first + 3, first + 23, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first + 5, first + 10, compare, projection); + iter_swap_if(first + 7, first + 21, compare, projection); + iter_swap_if(first + 8, first + 14, compare, projection); + iter_swap_if(first + 9, first + 15, compare, projection); + iter_swap_if(first + 11, first + 22, compare, projection); + iter_swap_if(first + 13, first + 18, compare, projection); + iter_swap_if(first + 17, first + 19, compare, projection); + iter_swap_if(first, first + 3, compare, projection); + iter_swap_if(first + 1, first + 11, compare, projection); + iter_swap_if(first + 2, first + 7, compare, projection); + iter_swap_if(first + 4, first + 17, compare, projection); + iter_swap_if(first + 5, first + 13, compare, projection); + iter_swap_if(first + 6, first + 19, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 10, first + 18, compare, projection); + iter_swap_if(first + 12, first + 22, compare, projection); + iter_swap_if(first + 14, first + 15, compare, projection); + iter_swap_if(first + 16, first + 21, compare, projection); + iter_swap_if(first + 20, first + 23, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 3, first + 12, compare, projection); + iter_swap_if(first + 5, first + 8, compare, projection); + iter_swap_if(first + 6, first + 9, compare, projection); + iter_swap_if(first + 7, first + 10, compare, projection); + iter_swap_if(first + 11, first + 20, compare, projection); + iter_swap_if(first + 13, first + 16, compare, projection); + iter_swap_if(first + 14, first + 17, compare, projection); + iter_swap_if(first + 15, first + 18, compare, projection); + iter_swap_if(first + 19, first + 21, compare, projection); + iter_swap_if(first + 22, first + 23, compare, projection); + iter_swap_if(first + 2, first + 5, compare, projection); + iter_swap_if(first + 4, first + 8, compare, projection); + iter_swap_if(first + 6, first + 11, compare, projection); + iter_swap_if(first + 7, first + 14, compare, projection); + iter_swap_if(first + 9, first + 16, compare, projection); + iter_swap_if(first + 12, first + 17, compare, projection); + iter_swap_if(first + 15, first + 19, compare, projection); + iter_swap_if(first + 18, first + 21, compare, projection); + iter_swap_if(first + 1, first + 8, compare, projection); + iter_swap_if(first + 3, first + 14, compare, projection); + iter_swap_if(first + 4, first + 7, compare, projection); + iter_swap_if(first + 9, first + 20, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 11, first + 13, compare, projection); + iter_swap_if(first + 15, first + 22, compare, projection); + iter_swap_if(first + 16, first + 19, compare, projection); + iter_swap_if(first, first + 7, compare, projection); + iter_swap_if(first + 1, first + 5, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 6, first + 11, compare, projection); + iter_swap_if(first + 8, first + 15, compare, projection); + iter_swap_if(first + 9, first + 14, compare, projection); + iter_swap_if(first + 10, first + 13, compare, projection); + iter_swap_if(first + 12, first + 17, compare, projection); + iter_swap_if(first + 16, first + 23, compare, projection); + iter_swap_if(first + 18, first + 22, compare, projection); + iter_swap_if(first + 19, first + 20, compare, projection); + iter_swap_if(first, first + 2, compare, projection); + iter_swap_if(first + 1, first + 6, compare, projection); + iter_swap_if(first + 4, first + 7, compare, projection); + iter_swap_if(first + 5, first + 9, compare, projection); + iter_swap_if(first + 8, first + 10, compare, projection); + iter_swap_if(first + 13, first + 15, compare, projection); + iter_swap_if(first + 14, first + 18, compare, projection); + iter_swap_if(first + 16, first + 19, compare, projection); + iter_swap_if(first + 17, first + 22, compare, projection); + iter_swap_if(first + 21, first + 23, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 6, first + 8, compare, projection); + iter_swap_if(first + 7, first + 9, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 12, first + 13, compare, projection); + iter_swap_if(first + 14, first + 16, compare, projection); + iter_swap_if(first + 15, first + 17, compare, projection); + iter_swap_if(first + 18, first + 19, compare, projection); + iter_swap_if(first + 20, first + 21, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 3, first + 6, compare, projection); + iter_swap_if(first + 4, first + 10, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 9, first + 11, compare, projection); + iter_swap_if(first + 12, first + 14, compare, projection); + iter_swap_if(first + 13, first + 19, compare, projection); + iter_swap_if(first + 15, first + 16, compare, projection); + iter_swap_if(first + 17, first + 20, compare, projection); + iter_swap_if(first + 21, first + 22, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 5, first + 10, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 13, first + 18, compare, projection); + iter_swap_if(first + 14, first + 15, compare, projection); + iter_swap_if(first + 16, first + 17, compare, projection); + iter_swap_if(first + 20, first + 21, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 7, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 11, first + 13, compare, projection); + iter_swap_if(first + 16, first + 18, compare, projection); + iter_swap_if(first + 19, first + 20, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first + 8, first + 10, compare, projection); + iter_swap_if(first + 9, first + 12, compare, projection); + iter_swap_if(first + 11, first + 14, compare, projection); + iter_swap_if(first + 13, first + 15, compare, projection); + iter_swap_if(first + 17, first + 19, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 9, first + 10, compare, projection); + iter_swap_if(first + 11, first + 12, compare, projection); + iter_swap_if(first + 13, first + 14, compare, projection); + iter_swap_if(first + 15, first + 16, compare, projection); + iter_swap_if(first + 17, first + 18, compare, projection); } template diff --git a/include/cpp-sort/detail/sorting_network/sort25.h b/include/cpp-sort/detail/sorting_network/sort25.h index 6708c60b..5442f5e0 100644 --- a/include/cpp-sort/detail/sorting_network/sort25.h +++ b/include/cpp-sort/detail/sorting_network/sort25.h @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<25u> + struct sorting_network_sorter_impl<25> { template< typename RandomAccessIterator, @@ -24,159 +24,159 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - iter_swap_if(first + 0u, first + 1u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 13u, compare, projection); - iter_swap_if(first + 14u, first + 15u, compare, projection); - iter_swap_if(first + 16u, first + 17u, compare, projection); - iter_swap_if(first + 18u, first + 19u, compare, projection); - iter_swap_if(first + 20u, first + 21u, compare, projection); - iter_swap_if(first + 22u, first + 23u, compare, projection); - iter_swap_if(first + 0u, first + 2u, compare, projection); - iter_swap_if(first + 1u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 6u, compare, projection); - iter_swap_if(first + 5u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 10u, compare, projection); - iter_swap_if(first + 9u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 14u, compare, projection); - iter_swap_if(first + 13u, first + 15u, compare, projection); - iter_swap_if(first + 16u, first + 18u, compare, projection); - iter_swap_if(first + 17u, first + 19u, compare, projection); - iter_swap_if(first + 20u, first + 22u, compare, projection); - iter_swap_if(first + 21u, first + 23u, compare, projection); - iter_swap_if(first + 0u, first + 4u, compare, projection); - iter_swap_if(first + 1u, first + 5u, compare, projection); - iter_swap_if(first + 2u, first + 6u, compare, projection); - iter_swap_if(first + 3u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 12u, compare, projection); - iter_swap_if(first + 9u, first + 13u, compare, projection); - iter_swap_if(first + 10u, first + 14u, compare, projection); - iter_swap_if(first + 11u, first + 15u, compare, projection); - iter_swap_if(first + 16u, first + 20u, compare, projection); - iter_swap_if(first + 17u, first + 21u, compare, projection); - iter_swap_if(first + 18u, first + 22u, compare, projection); - iter_swap_if(first + 19u, first + 23u, compare, projection); - iter_swap_if(first + 0u, first + 8u, compare, projection); - iter_swap_if(first + 1u, first + 9u, compare, projection); - iter_swap_if(first + 2u, first + 10u, compare, projection); - iter_swap_if(first + 3u, first + 11u, compare, projection); - iter_swap_if(first + 4u, first + 12u, compare, projection); - iter_swap_if(first + 5u, first + 13u, compare, projection); - iter_swap_if(first + 6u, first + 14u, compare, projection); - iter_swap_if(first + 7u, first + 15u, compare, projection); - iter_swap_if(first + 16u, first + 24u, compare, projection); - iter_swap_if(first + 17u, first + 18u, compare, projection); - iter_swap_if(first + 21u, first + 22u, compare, projection); - iter_swap_if(first + 0u, first + 16u, compare, projection); - iter_swap_if(first + 2u, first + 8u, compare, projection); - iter_swap_if(first + 3u, first + 12u, compare, projection); - iter_swap_if(first + 4u, first + 20u, compare, projection); - iter_swap_if(first + 5u, first + 19u, compare, projection); - iter_swap_if(first + 9u, first + 22u, compare, projection); - iter_swap_if(first + 10u, first + 24u, compare, projection); - iter_swap_if(first + 1u, first + 8u, compare, projection); - iter_swap_if(first + 6u, first + 9u, compare, projection); - iter_swap_if(first + 7u, first + 22u, compare, projection); - iter_swap_if(first + 10u, first + 18u, compare, projection); - iter_swap_if(first + 14u, first + 19u, compare, projection); - iter_swap_if(first + 21u, first + 24u, compare, projection); - iter_swap_if(first + 1u, first + 17u, compare, projection); - iter_swap_if(first + 2u, first + 10u, compare, projection); - iter_swap_if(first + 5u, first + 21u, compare, projection); - iter_swap_if(first + 11u, first + 24u, compare, projection); - iter_swap_if(first + 18u, first + 20u, compare, projection); - iter_swap_if(first + 1u, first + 4u, compare, projection); - iter_swap_if(first + 2u, first + 16u, compare, projection); - iter_swap_if(first + 3u, first + 21u, compare, projection); - iter_swap_if(first + 6u, first + 10u, compare, projection); - iter_swap_if(first + 8u, first + 18u, compare, projection); - iter_swap_if(first + 9u, first + 17u, compare, projection); - iter_swap_if(first + 11u, first + 14u, compare, projection); - iter_swap_if(first + 12u, first + 20u, compare, projection); - iter_swap_if(first + 23u, first + 24u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first + 3u, first + 5u, compare, projection); - iter_swap_if(first + 4u, first + 16u, compare, projection); - iter_swap_if(first + 12u, first + 18u, compare, projection); - iter_swap_if(first + 13u, first + 23u, compare, projection); - iter_swap_if(first + 14u, first + 19u, compare, projection); - iter_swap_if(first + 15u, first + 24u, compare, projection); - iter_swap_if(first + 17u, first + 21u, compare, projection); - iter_swap_if(first + 4u, first + 8u, compare, projection); - iter_swap_if(first + 7u, first + 13u, compare, projection); - iter_swap_if(first + 9u, first + 16u, compare, projection); - iter_swap_if(first + 10u, first + 12u, compare, projection); - iter_swap_if(first + 11u, first + 18u, compare, projection); - iter_swap_if(first + 14u, first + 20u, compare, projection); - iter_swap_if(first + 15u, first + 23u, compare, projection); - iter_swap_if(first + 19u, first + 22u, compare, projection); - iter_swap_if(first + 2u, first + 4u, compare, projection); - iter_swap_if(first + 3u, first + 8u, compare, projection); - iter_swap_if(first + 5u, first + 16u, compare, projection); - iter_swap_if(first + 6u, first + 9u, compare, projection); - iter_swap_if(first + 7u, first + 17u, compare, projection); - iter_swap_if(first + 13u, first + 21u, compare, projection); - iter_swap_if(first + 15u, first + 19u, compare, projection); - iter_swap_if(first + 22u, first + 23u, compare, projection); - iter_swap_if(first + 3u, first + 6u, compare, projection); - iter_swap_if(first + 5u, first + 10u, compare, projection); - iter_swap_if(first + 7u, first + 11u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 12u, first + 16u, compare, projection); - iter_swap_if(first + 13u, first + 18u, compare, projection); - iter_swap_if(first + 14u, first + 17u, compare, projection); - iter_swap_if(first + 19u, first + 22u, compare, projection); - iter_swap_if(first + 20u, first + 21u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 6u, first + 8u, compare, projection); - iter_swap_if(first + 7u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 12u, compare, projection); - iter_swap_if(first + 11u, first + 14u, compare, projection); - iter_swap_if(first + 13u, first + 16u, compare, projection); - iter_swap_if(first + 15u, first + 17u, compare, projection); - iter_swap_if(first + 18u, first + 20u, compare, projection); - iter_swap_if(first + 19u, first + 21u, compare, projection); - iter_swap_if(first + 5u, first + 8u, compare, projection); - iter_swap_if(first + 7u, first + 10u, compare, projection); - iter_swap_if(first + 9u, first + 12u, compare, projection); - iter_swap_if(first + 11u, first + 13u, compare, projection); - iter_swap_if(first + 14u, first + 16u, compare, projection); - iter_swap_if(first + 15u, first + 18u, compare, projection); - iter_swap_if(first + 17u, first + 20u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); - iter_swap_if(first + 9u, first + 10u, compare, projection); - iter_swap_if(first + 11u, first + 12u, compare, projection); - iter_swap_if(first + 13u, first + 14u, compare, projection); - iter_swap_if(first + 15u, first + 16u, compare, projection); - iter_swap_if(first + 17u, first + 18u, compare, projection); - iter_swap_if(first + 19u, first + 20u, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 12, first + 13, compare, projection); + iter_swap_if(first + 14, first + 15, compare, projection); + iter_swap_if(first + 16, first + 17, compare, projection); + iter_swap_if(first + 18, first + 19, compare, projection); + iter_swap_if(first + 20, first + 21, compare, projection); + iter_swap_if(first + 22, first + 23, compare, projection); + iter_swap_if(first, first + 2, compare, projection); + iter_swap_if(first + 1, first + 3, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first + 5, first + 7, compare, projection); + iter_swap_if(first + 8, first + 10, compare, projection); + iter_swap_if(first + 9, first + 11, compare, projection); + iter_swap_if(first + 12, first + 14, compare, projection); + iter_swap_if(first + 13, first + 15, compare, projection); + iter_swap_if(first + 16, first + 18, compare, projection); + iter_swap_if(first + 17, first + 19, compare, projection); + iter_swap_if(first + 20, first + 22, compare, projection); + iter_swap_if(first + 21, first + 24, compare, projection); + iter_swap_if(first, first + 4, compare, projection); + iter_swap_if(first + 1, first + 5, compare, projection); + iter_swap_if(first + 2, first + 6, compare, projection); + iter_swap_if(first + 3, first + 7, compare, projection); + iter_swap_if(first + 8, first + 12, compare, projection); + iter_swap_if(first + 9, first + 13, compare, projection); + iter_swap_if(first + 10, first + 14, compare, projection); + iter_swap_if(first + 11, first + 15, compare, projection); + iter_swap_if(first + 16, first + 20, compare, projection); + iter_swap_if(first + 21, first + 22, compare, projection); + iter_swap_if(first + 23, first + 24, compare, projection); + iter_swap_if(first, first + 8, compare, projection); + iter_swap_if(first + 1, first + 12, compare, projection); + iter_swap_if(first + 2, first + 10, compare, projection); + iter_swap_if(first + 3, first + 14, compare, projection); + iter_swap_if(first + 4, first + 9, compare, projection); + iter_swap_if(first + 5, first + 13, compare, projection); + iter_swap_if(first + 6, first + 11, compare, projection); + iter_swap_if(first + 7, first + 15, compare, projection); + iter_swap_if(first + 17, first + 22, compare, projection); + iter_swap_if(first + 18, first + 21, compare, projection); + iter_swap_if(first + 19, first + 24, compare, projection); + iter_swap_if(first + 1, first + 18, compare, projection); + iter_swap_if(first + 5, first + 9, compare, projection); + iter_swap_if(first + 7, first + 14, compare, projection); + iter_swap_if(first + 11, first + 19, compare, projection); + iter_swap_if(first + 15, first + 24, compare, projection); + iter_swap_if(first + 21, first + 23, compare, projection); + iter_swap_if(first + 1, first + 16, compare, projection); + iter_swap_if(first + 7, first + 20, compare, projection); + iter_swap_if(first + 12, first + 21, compare, projection); + iter_swap_if(first + 13, first + 23, compare, projection); + iter_swap_if(first + 15, first + 19, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 3, first + 13, compare, projection); + iter_swap_if(first + 7, first + 18, compare, projection); + iter_swap_if(first + 8, first + 16, compare, projection); + iter_swap_if(first + 12, first + 17, compare, projection); + iter_swap_if(first + 15, first + 20, compare, projection); + iter_swap_if(first + 19, first + 23, compare, projection); + iter_swap_if(first + 21, first + 22, compare, projection); + iter_swap_if(first + 1, first + 8, compare, projection); + iter_swap_if(first + 2, first + 12, compare, projection); + iter_swap_if(first + 3, first + 5, compare, projection); + iter_swap_if(first + 4, first + 7, compare, projection); + iter_swap_if(first + 6, first + 21, compare, projection); + iter_swap_if(first + 9, first + 18, compare, projection); + iter_swap_if(first + 10, first + 17, compare, projection); + iter_swap_if(first + 14, first + 22, compare, projection); + iter_swap_if(first + 19, first + 20, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 3, first + 10, compare, projection); + iter_swap_if(first + 6, first + 9, compare, projection); + iter_swap_if(first + 7, first + 16, compare, projection); + iter_swap_if(first + 11, first + 17, compare, projection); + iter_swap_if(first + 13, first + 14, compare, projection); + iter_swap_if(first + 18, first + 21, compare, projection); + iter_swap_if(first + 19, first + 22, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 4, first + 8, compare, projection); + iter_swap_if(first + 5, first + 11, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 9, first + 16, compare, projection); + iter_swap_if(first + 14, first + 19, compare, projection); + iter_swap_if(first + 15, first + 17, compare, projection); + iter_swap_if(first + 22, first + 23, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 5, first + 12, compare, projection); + iter_swap_if(first + 11, first + 13, compare, projection); + iter_swap_if(first + 15, first + 18, compare, projection); + iter_swap_if(first + 17, first + 21, compare, projection); + iter_swap_if(first + 20, first + 22, compare, projection); + iter_swap_if(first + 3, first + 5, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 11, first + 15, compare, projection); + iter_swap_if(first + 13, first + 17, compare, projection); + iter_swap_if(first + 14, first + 18, compare, projection); + iter_swap_if(first + 19, first + 21, compare, projection); + iter_swap_if(first + 3, first + 6, compare, projection); + iter_swap_if(first + 5, first + 9, compare, projection); + iter_swap_if(first + 7, first + 10, compare, projection); + iter_swap_if(first + 12, first + 16, compare, projection); + iter_swap_if(first + 14, first + 15, compare, projection); + iter_swap_if(first + 18, first + 19, compare, projection); + iter_swap_if(first + 20, first + 21, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 8, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 9, first + 11, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 13, first + 16, compare, projection); + iter_swap_if(first + 17, first + 19, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 9, first + 10, compare, projection); + iter_swap_if(first + 11, first + 12, compare, projection); + iter_swap_if(first + 13, first + 14, compare, projection); + iter_swap_if(first + 15, first + 16, compare, projection); + iter_swap_if(first + 17, first + 18, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 12, first + 13, compare, projection); + iter_swap_if(first + 14, first + 15, compare, projection); + iter_swap_if(first + 16, first + 17, compare, projection); } template static constexpr auto index_pairs() - -> std::array, 131> + -> std::array, 130> { return {{ {0, 1}, {2, 3}, {4, 5}, {6, 7}, {8, 9}, {10, 11}, {12, 13}, {14, 15}, {16, 17}, {18, 19}, {20, 21}, {22, 23}, - {0, 2}, {1, 3}, {4, 6}, {5, 7}, {8, 10}, {9, 11}, {12, 14}, {13, 15}, {16, 18}, {17, 19}, {20, 22}, {21, 23}, - {0, 4}, {1, 5}, {2, 6}, {3, 7}, {8, 12}, {9, 13}, {10, 14}, {11, 15}, {16, 20}, {17, 21}, {18, 22}, {19, 23}, - {0, 8}, {1, 9}, {2, 10}, {3, 11}, {4, 12}, {5, 13}, {6, 14}, {7, 15}, {16, 24}, {17, 18}, {21, 22}, - {0, 16}, {2, 8}, {3, 12}, {4, 20}, {5, 19}, {9, 22}, {10, 24}, - {1, 8}, {6, 9}, {7, 22}, {10, 18}, {14, 19}, {21, 24}, - {1, 17}, {2, 10}, {5, 21}, {11, 24}, {18, 20}, - {1, 4}, {2, 16}, {3, 21}, {6, 10}, {8, 18}, {9, 17}, {11, 14}, {12, 20}, {23, 24}, - {1, 2}, {3, 5}, {4, 16}, {12, 18}, {13, 23}, {14, 19}, {15, 24}, {17, 21}, - {4, 8}, {7, 13}, {9, 16}, {10, 12}, {11, 18}, {14, 20}, {15, 23}, {19, 22}, - {2, 4}, {3, 8}, {5, 16}, {6, 9}, {7, 17}, {13, 21}, {15, 19}, {22, 23}, - {3, 6}, {5, 10}, {7, 11}, {8, 9}, {12, 16}, {13, 18}, {14, 17}, {19, 22}, {20, 21}, - {3, 4}, {6, 8}, {7, 9}, {10, 12}, {11, 14}, {13, 16}, {15, 17}, {18, 20}, {19, 21}, - {5, 8}, {7, 10}, {9, 12}, {11, 13}, {14, 16}, {15, 18}, {17, 20}, - {5, 6}, {7, 8}, {9, 10}, {11, 12}, {13, 14}, {15, 16}, {17, 18}, {19, 20}, + {0, 2}, {1, 3}, {4, 6}, {5, 7}, {8, 10}, {9, 11}, {12, 14}, {13, 15}, {16, 18}, {17, 19}, {20, 22}, {21, 24}, + {0, 4}, {1, 5}, {2, 6}, {3, 7}, {8, 12}, {9, 13}, {10, 14}, {11, 15}, {16, 20}, {21, 22}, {23, 24}, + {0, 8}, {1, 12}, {2, 10}, {3, 14}, {4, 9}, {5, 13}, {6, 11}, {7, 15}, {17, 22}, {18, 21}, {19, 24}, + {1, 18}, {5, 9}, {7, 14}, {11, 19}, {15, 24}, {21, 23}, + {1, 16}, {7, 20}, {12, 21}, {13, 23}, {15, 19}, + {0, 1}, {3, 13}, {7, 18}, {8, 16}, {12, 17}, {15, 20}, {19, 23}, {21, 22}, + {1, 8}, {2, 12}, {3, 5}, {4, 7}, {6, 21}, {9, 18}, {10, 17}, {14, 22}, {19, 20}, + {2, 4}, {3, 10}, {6, 9}, {7, 16}, {11, 17}, {13, 14}, {18, 21}, {19, 22}, + {1, 2}, {4, 8}, {5, 11}, {6, 7}, {9, 16}, {14, 19}, {15, 17}, {22, 23}, + {2, 4}, {5, 12}, {11, 13}, {15, 18}, {17, 21}, {20, 22}, + {3, 5}, {10, 12}, {11, 15}, {13, 17}, {14, 18}, {19, 21}, + {3, 6}, {5, 9}, {7, 10}, {12, 16}, {14, 15}, {18, 19}, {20, 21}, + {3, 4}, {5, 8}, {6, 7}, {9, 11}, {10, 12}, {13, 16}, {17, 19}, + {5, 6}, {7, 8}, {9, 10}, {11, 12}, {13, 14}, {15, 16}, {17, 18}, + {4, 5}, {6, 7}, {8, 9}, {10, 11}, {12, 13}, {14, 15}, {16, 17}, }}; } }; diff --git a/include/cpp-sort/detail/sorting_network/sort26.h b/include/cpp-sort/detail/sorting_network/sort26.h index 20f93ae8..3e0734a0 100644 --- a/include/cpp-sort/detail/sorting_network/sort26.h +++ b/include/cpp-sort/detail/sorting_network/sort26.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SORTING_NETWORK_SORT26_H_ @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<26u> + struct sorting_network_sorter_impl<26> { template< typename RandomAccessIterator, @@ -24,145 +24,145 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - iter_swap_if(first, first + 25u, compare, projection); - iter_swap_if(first + 1u, first + 3u, compare, projection); - iter_swap_if(first + 2u, first + 9u, compare, projection); - iter_swap_if(first + 4u, first + 19u, compare, projection); - iter_swap_if(first + 5u, first + 18u, compare, projection); - iter_swap_if(first + 6u, first + 21u, compare, projection); - iter_swap_if(first + 7u, first + 20u, compare, projection); - iter_swap_if(first + 8u, first + 10u, compare, projection); - iter_swap_if(first + 11u, first + 12u, compare, projection); - iter_swap_if(first + 13u, first + 14u, compare, projection); - iter_swap_if(first + 15u, first + 17u, compare, projection); - iter_swap_if(first + 16u, first + 23u, compare, projection); - iter_swap_if(first + 22u, first + 24u, compare, projection); - iter_swap_if(first + 1u, first + 4u, compare, projection); - iter_swap_if(first + 2u, first + 16u, compare, projection); - iter_swap_if(first + 3u, first + 19u, compare, projection); - iter_swap_if(first + 5u, first + 13u, compare, projection); - iter_swap_if(first + 6u, first + 22u, compare, projection); - iter_swap_if(first + 7u, first + 11u, compare, projection); - iter_swap_if(first + 8u, first + 15u, compare, projection); - iter_swap_if(first + 9u, first + 23u, compare, projection); - iter_swap_if(first + 10u, first + 17u, compare, projection); - iter_swap_if(first + 12u, first + 20u, compare, projection); - iter_swap_if(first + 14u, first + 18u, compare, projection); - iter_swap_if(first + 21u, first + 24u, compare, projection); - iter_swap_if(first + 1u, first + 5u, compare, projection); - iter_swap_if(first + 2u, first + 8u, compare, projection); - iter_swap_if(first + 3u, first + 14u, compare, projection); - iter_swap_if(first + 4u, first + 13u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 9u, first + 15u, compare, projection); - iter_swap_if(first + 10u, first + 16u, compare, projection); - iter_swap_if(first + 11u, first + 22u, compare, projection); - iter_swap_if(first + 12u, first + 21u, compare, projection); - iter_swap_if(first + 17u, first + 23u, compare, projection); - iter_swap_if(first + 18u, first + 19u, compare, projection); - iter_swap_if(first + 20u, first + 24u, compare, projection); - iter_swap_if(first, first + 10u, compare, projection); - iter_swap_if(first + 1u, first + 6u, compare, projection); - iter_swap_if(first + 3u, first + 7u, compare, projection); - iter_swap_if(first + 4u, first + 11u, compare, projection); - iter_swap_if(first + 5u, first + 12u, compare, projection); - iter_swap_if(first + 13u, first + 20u, compare, projection); - iter_swap_if(first + 14u, first + 21u, compare, projection); - iter_swap_if(first + 15u, first + 25u, compare, projection); - iter_swap_if(first + 18u, first + 22u, compare, projection); - iter_swap_if(first + 19u, first + 24u, compare, projection); - iter_swap_if(first, first + 4u, compare, projection); - iter_swap_if(first + 8u, first + 10u, compare, projection); - iter_swap_if(first + 12u, first + 13u, compare, projection); - iter_swap_if(first + 15u, first + 17u, compare, projection); - iter_swap_if(first + 21u, first + 25u, compare, projection); - iter_swap_if(first, first + 2u, compare, projection); - iter_swap_if(first + 4u, first + 8u, compare, projection); - iter_swap_if(first + 10u, first + 12u, compare, projection); - iter_swap_if(first + 13u, first + 15u, compare, projection); - iter_swap_if(first + 17u, first + 21u, compare, projection); - iter_swap_if(first + 23u, first + 25u, compare, projection); - iter_swap_if(first, first + 1u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 8u, first + 14u, compare, projection); - iter_swap_if(first + 9u, first + 13u, compare, projection); - iter_swap_if(first + 11u, first + 17u, compare, projection); - iter_swap_if(first + 12u, first + 16u, compare, projection); - iter_swap_if(first + 20u, first + 21u, compare, projection); - iter_swap_if(first + 22u, first + 23u, compare, projection); - iter_swap_if(first + 24u, first + 25u, compare, projection); - iter_swap_if(first + 1u, first + 4u, compare, projection); - iter_swap_if(first + 3u, first + 10u, compare, projection); - iter_swap_if(first + 6u, first + 9u, compare, projection); - iter_swap_if(first + 7u, first + 13u, compare, projection); - iter_swap_if(first + 8u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 18u, compare, projection); - iter_swap_if(first + 14u, first + 17u, compare, projection); - iter_swap_if(first + 15u, first + 22u, compare, projection); - iter_swap_if(first + 16u, first + 19u, compare, projection); - iter_swap_if(first + 21u, first + 24u, compare, projection); - iter_swap_if(first + 2u, first + 6u, compare, projection); - iter_swap_if(first + 3u, first + 8u, compare, projection); - iter_swap_if(first + 5u, first + 7u, compare, projection); - iter_swap_if(first + 9u, first + 12u, compare, projection); - iter_swap_if(first + 13u, first + 16u, compare, projection); - iter_swap_if(first + 17u, first + 22u, compare, projection); - iter_swap_if(first + 18u, first + 20u, compare, projection); - iter_swap_if(first + 19u, first + 23u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first + 4u, first + 6u, compare, projection); - iter_swap_if(first + 5u, first + 9u, compare, projection); - iter_swap_if(first + 7u, first + 10u, compare, projection); - iter_swap_if(first + 11u, first + 12u, compare, projection); - iter_swap_if(first + 13u, first + 14u, compare, projection); - iter_swap_if(first + 15u, first + 18u, compare, projection); - iter_swap_if(first + 16u, first + 20u, compare, projection); - iter_swap_if(first + 19u, first + 21u, compare, projection); - iter_swap_if(first + 23u, first + 24u, compare, projection); - iter_swap_if(first + 2u, first + 4u, compare, projection); - iter_swap_if(first + 3u, first + 5u, compare, projection); - iter_swap_if(first + 7u, first + 13u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 14u, compare, projection); - iter_swap_if(first + 11u, first + 15u, compare, projection); - iter_swap_if(first + 12u, first + 18u, compare, projection); - iter_swap_if(first + 16u, first + 17u, compare, projection); - iter_swap_if(first + 20u, first + 22u, compare, projection); - iter_swap_if(first + 21u, first + 23u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 6u, first + 9u, compare, projection); - iter_swap_if(first + 7u, first + 11u, compare, projection); - iter_swap_if(first + 10u, first + 12u, compare, projection); - iter_swap_if(first + 13u, first + 15u, compare, projection); - iter_swap_if(first + 14u, first + 18u, compare, projection); - iter_swap_if(first + 16u, first + 19u, compare, projection); - iter_swap_if(first + 21u, first + 22u, compare, projection); - iter_swap_if(first + 5u, first + 7u, compare, projection); - iter_swap_if(first + 6u, first + 8u, compare, projection); - iter_swap_if(first + 9u, first + 13u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 16u, compare, projection); - iter_swap_if(first + 14u, first + 15u, compare, projection); - iter_swap_if(first + 17u, first + 19u, compare, projection); - iter_swap_if(first + 18u, first + 20u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); - iter_swap_if(first + 9u, first + 10u, compare, projection); - iter_swap_if(first + 11u, first + 13u, compare, projection); - iter_swap_if(first + 12u, first + 14u, compare, projection); - iter_swap_if(first + 15u, first + 16u, compare, projection); - iter_swap_if(first + 17u, first + 18u, compare, projection); - iter_swap_if(first + 19u, first + 20u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 13u, compare, projection); - iter_swap_if(first + 14u, first + 15u, compare, projection); - iter_swap_if(first + 16u, first + 17u, compare, projection); - iter_swap_if(first + 18u, first + 19u, compare, projection); - iter_swap_if(first + 20u, first + 21u, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 21, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 9, first + 10, compare, projection); + iter_swap_if(first + 11, first + 12, compare, projection); + iter_swap_if(first + 13, first + 14, compare, projection); + iter_swap_if(first + 15, first + 16, compare, projection); + iter_swap_if(first + 17, first + 18, compare, projection); + iter_swap_if(first + 19, first + 20, compare, projection); + iter_swap_if(first + 22, first + 23, compare, projection); + iter_swap_if(first + 24, first + 25, compare, projection); + iter_swap_if(first, first + 24, compare, projection); + iter_swap_if(first + 1, first + 25, compare, projection); + iter_swap_if(first + 3, first + 21, compare, projection); + iter_swap_if(first + 4, first + 22, compare, projection); + iter_swap_if(first + 5, first + 7, compare, projection); + iter_swap_if(first + 6, first + 8, compare, projection); + iter_swap_if(first + 9, first + 11, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 13, first + 15, compare, projection); + iter_swap_if(first + 14, first + 16, compare, projection); + iter_swap_if(first + 17, first + 19, compare, projection); + iter_swap_if(first + 18, first + 20, compare, projection); + iter_swap_if(first, first + 4, compare, projection); + iter_swap_if(first + 2, first + 22, compare, projection); + iter_swap_if(first + 3, first + 23, compare, projection); + iter_swap_if(first + 5, first + 9, compare, projection); + iter_swap_if(first + 6, first + 10, compare, projection); + iter_swap_if(first + 7, first + 11, compare, projection); + iter_swap_if(first + 8, first + 12, compare, projection); + iter_swap_if(first + 13, first + 17, compare, projection); + iter_swap_if(first + 14, first + 18, compare, projection); + iter_swap_if(first + 15, first + 19, compare, projection); + iter_swap_if(first + 16, first + 20, compare, projection); + iter_swap_if(first + 21, first + 25, compare, projection); + iter_swap_if(first, first + 2, compare, projection); + iter_swap_if(first + 1, first + 3, compare, projection); + iter_swap_if(first + 4, first + 21, compare, projection); + iter_swap_if(first + 5, first + 13, compare, projection); + iter_swap_if(first + 6, first + 14, compare, projection); + iter_swap_if(first + 7, first + 15, compare, projection); + iter_swap_if(first + 8, first + 16, compare, projection); + iter_swap_if(first + 9, first + 17, compare, projection); + iter_swap_if(first + 10, first + 18, compare, projection); + iter_swap_if(first + 11, first + 19, compare, projection); + iter_swap_if(first + 12, first + 20, compare, projection); + iter_swap_if(first + 22, first + 24, compare, projection); + iter_swap_if(first + 23, first + 25, compare, projection); + iter_swap_if(first, first + 5, compare, projection); + iter_swap_if(first + 1, first + 7, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 3, first + 10, compare, projection); + iter_swap_if(first + 15, first + 22, compare, projection); + iter_swap_if(first + 18, first + 24, compare, projection); + iter_swap_if(first + 20, first + 25, compare, projection); + iter_swap_if(first + 21, first + 23, compare, projection); + iter_swap_if(first + 2, first + 9, compare, projection); + iter_swap_if(first + 3, first + 7, compare, projection); + iter_swap_if(first + 4, first + 14, compare, projection); + iter_swap_if(first + 5, first + 13, compare, projection); + iter_swap_if(first + 6, first + 15, compare, projection); + iter_swap_if(first + 10, first + 19, compare, projection); + iter_swap_if(first + 11, first + 21, compare, projection); + iter_swap_if(first + 12, first + 20, compare, projection); + iter_swap_if(first + 16, first + 23, compare, projection); + iter_swap_if(first + 18, first + 22, compare, projection); + iter_swap_if(first + 1, first + 5, compare, projection); + iter_swap_if(first + 2, first + 6, compare, projection); + iter_swap_if(first + 3, first + 15, compare, projection); + iter_swap_if(first + 7, first + 17, compare, projection); + iter_swap_if(first + 8, first + 18, compare, projection); + iter_swap_if(first + 10, first + 22, compare, projection); + iter_swap_if(first + 11, first + 13, compare, projection); + iter_swap_if(first + 12, first + 14, compare, projection); + iter_swap_if(first + 19, first + 23, compare, projection); + iter_swap_if(first + 20, first + 24, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 4, first + 7, compare, projection); + iter_swap_if(first + 5, first + 11, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 13, first + 15, compare, projection); + iter_swap_if(first + 14, first + 20, compare, projection); + iter_swap_if(first + 16, first + 17, compare, projection); + iter_swap_if(first + 18, first + 21, compare, projection); + iter_swap_if(first + 23, first + 24, compare, projection); + iter_swap_if(first + 3, first + 8, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first + 7, first + 16, compare, projection); + iter_swap_if(first + 9, first + 18, compare, projection); + iter_swap_if(first + 10, first + 13, compare, projection); + iter_swap_if(first + 12, first + 15, compare, projection); + iter_swap_if(first + 17, first + 22, compare, projection); + iter_swap_if(first + 19, first + 21, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 6, first + 11, compare, projection); + iter_swap_if(first + 7, first + 9, compare, projection); + iter_swap_if(first + 14, first + 19, compare, projection); + iter_swap_if(first + 16, first + 18, compare, projection); + iter_swap_if(first + 20, first + 21, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 3, first + 6, compare, projection); + iter_swap_if(first + 7, first + 10, compare, projection); + iter_swap_if(first + 8, first + 11, compare, projection); + iter_swap_if(first + 9, first + 12, compare, projection); + iter_swap_if(first + 13, first + 16, compare, projection); + iter_swap_if(first + 14, first + 17, compare, projection); + iter_swap_if(first + 15, first + 18, compare, projection); + iter_swap_if(first + 19, first + 22, compare, projection); + iter_swap_if(first + 21, first + 23, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 8, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 9, first + 10, compare, projection); + iter_swap_if(first + 11, first + 13, compare, projection); + iter_swap_if(first + 12, first + 14, compare, projection); + iter_swap_if(first + 15, first + 16, compare, projection); + iter_swap_if(first + 17, first + 20, compare, projection); + iter_swap_if(first + 18, first + 19, compare, projection); + iter_swap_if(first + 21, first + 22, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 9, first + 11, compare, projection); + iter_swap_if(first + 10, first + 13, compare, projection); + iter_swap_if(first + 12, first + 15, compare, projection); + iter_swap_if(first + 14, first + 16, compare, projection); + iter_swap_if(first + 17, first + 18, compare, projection); + iter_swap_if(first + 19, first + 20, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 12, first + 13, compare, projection); + iter_swap_if(first + 14, first + 15, compare, projection); + iter_swap_if(first + 16, first + 17, compare, projection); + iter_swap_if(first + 18, first + 19, compare, projection); + iter_swap_if(first + 20, first + 21, compare, projection); } template @@ -170,20 +170,19 @@ namespace detail -> std::array, 139> { return {{ - {0, 25}, {1, 3}, {2, 9}, {4, 19}, {5, 18}, {6, 21}, {7, 20}, {8, 10}, {11, 12}, {13, 14}, {15, 17}, {16, 23}, {22, 24}, - {1, 4}, {2, 16}, {3, 19}, {5, 13}, {6, 22}, {7, 11}, {8, 15}, {9, 23}, {10, 17}, {12, 20}, {14, 18}, {21, 24}, - {1, 5}, {2, 8}, {3, 14}, {4, 13}, {6, 7}, {9, 15}, {10, 16}, {11, 22}, {12, 21}, {17, 23}, {18, 19}, {20, 24}, - {0, 10}, {1, 6}, {3, 7}, {4, 11}, {5, 12}, {13, 20}, {14, 21}, {15, 25}, {18, 22}, {19, 24}, - {0, 4}, {8, 10}, {12, 13}, {15, 17}, {21, 25}, - {0, 2}, {4, 8}, {10, 12}, {13, 15}, {17, 21}, {23, 25}, - {0, 1}, {2, 3}, {4, 5}, {8, 14}, {9, 13}, {11, 17}, {12, 16}, {20, 21}, {22, 23}, {24, 25}, - {1, 4}, {3, 10}, {6, 9}, {7, 13}, {8, 11}, {12, 18}, {14, 17}, {15, 22}, {16, 19}, {21, 24}, - {2, 6}, {3, 8}, {5, 7}, {9, 12}, {13, 16}, {17, 22}, {18, 20}, {19, 23}, - {1, 2}, {4, 6}, {5, 9}, {7, 10}, {11, 12}, {13, 14}, {15, 18}, {16, 20}, {19, 21}, {23, 24}, - {2, 4}, {3, 5}, {7, 13}, {8, 9}, {10, 14}, {11, 15}, {12, 18}, {16, 17}, {20, 22}, {21, 23}, - {3, 4}, {6, 9}, {7, 11}, {10, 12}, {13, 15}, {14, 18}, {16, 19}, {21, 22}, - {5, 7}, {6, 8}, {9, 13}, {10, 11}, {12, 16}, {14, 15}, {17, 19}, {18, 20}, - {5, 6}, {7, 8}, {9, 10}, {11, 13}, {12, 14}, {15, 16}, {17, 18}, {19, 20}, + {0, 1}, {2, 3}, {4, 21}, {5, 6}, {7, 8}, {9, 10}, {11, 12}, {13, 14}, {15, 16}, {17, 18}, {19, 20}, {22, 23}, {24, 25}, + {0, 24}, {1, 25}, {3, 21}, {4, 22}, {5, 7}, {6, 8}, {9, 11}, {10, 12}, {13, 15}, {14, 16}, {17, 19}, {18, 20}, + {0, 4}, {2, 22}, {3, 23}, {5, 9}, {6, 10}, {7, 11}, {8, 12}, {13, 17}, {14, 18}, {15, 19}, {16, 20}, {21, 25}, + {0, 2}, {1, 3}, {4, 21}, {5, 13}, {6, 14}, {7, 15}, {8, 16}, {9, 17}, {10, 18}, {11, 19}, {12, 20}, {22, 24}, {23, 25}, + {0, 5}, {1, 7}, {2, 4}, {3, 10}, {15, 22}, {18, 24}, {20, 25}, {21, 23}, + {2, 9}, {3, 7}, {4, 14}, {5, 13}, {6, 15}, {10, 19}, {11, 21}, {12, 20}, {16, 23}, {18, 22}, + {1, 5}, {2, 6}, {3, 15}, {7, 17}, {8, 18}, {10, 22}, {11, 13}, {12, 14}, {19, 23}, {20, 24}, + {1, 2}, {4, 7}, {5, 11}, {8, 9}, {10, 12}, {13, 15}, {14, 20}, {16, 17}, {18, 21}, {23, 24}, + {3, 8}, {4, 6}, {7, 16}, {9, 18}, {10, 13}, {12, 15}, {17, 22}, {19, 21}, + {4, 5}, {6, 11}, {7, 9}, {14, 19}, {16, 18}, {20, 21}, + {2, 4}, {3, 6}, {7, 10}, {8, 11}, {9, 12}, {13, 16}, {14, 17}, {15, 18}, {19, 22}, {21, 23}, + {3, 4}, {5, 8}, {6, 7}, {9, 10}, {11, 13}, {12, 14}, {15, 16}, {17, 20}, {18, 19}, {21, 22}, + {5, 6}, {7, 8}, {9, 11}, {10, 13}, {12, 15}, {14, 16}, {17, 18}, {19, 20}, {4, 5}, {6, 7}, {8, 9}, {10, 11}, {12, 13}, {14, 15}, {16, 17}, {18, 19}, {20, 21}, }}; } diff --git a/include/cpp-sort/detail/sorting_network/sort27.h b/include/cpp-sort/detail/sorting_network/sort27.h index eddcad59..e09e7b4c 100644 --- a/include/cpp-sort/detail/sorting_network/sort27.h +++ b/include/cpp-sort/detail/sorting_network/sort27.h @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<27u> + struct sorting_network_sorter_impl<27> { template< typename RandomAccessIterator, @@ -24,154 +24,154 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - iter_swap_if(first + 0u, first + 1u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 13u, compare, projection); - iter_swap_if(first + 14u, first + 15u, compare, projection); - iter_swap_if(first + 16u, first + 17u, compare, projection); - iter_swap_if(first + 18u, first + 19u, compare, projection); - iter_swap_if(first + 20u, first + 21u, compare, projection); - iter_swap_if(first + 22u, first + 23u, compare, projection); - iter_swap_if(first + 24u, first + 25u, compare, projection); - iter_swap_if(first + 0u, first + 2u, compare, projection); - iter_swap_if(first + 1u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 6u, compare, projection); - iter_swap_if(first + 5u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 10u, compare, projection); - iter_swap_if(first + 9u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 14u, compare, projection); - iter_swap_if(first + 13u, first + 15u, compare, projection); - iter_swap_if(first + 16u, first + 18u, compare, projection); - iter_swap_if(first + 17u, first + 19u, compare, projection); - iter_swap_if(first + 20u, first + 22u, compare, projection); - iter_swap_if(first + 21u, first + 23u, compare, projection); - iter_swap_if(first + 24u, first + 26u, compare, projection); - iter_swap_if(first + 0u, first + 4u, compare, projection); - iter_swap_if(first + 1u, first + 5u, compare, projection); - iter_swap_if(first + 2u, first + 6u, compare, projection); - iter_swap_if(first + 3u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 12u, compare, projection); - iter_swap_if(first + 9u, first + 13u, compare, projection); - iter_swap_if(first + 10u, first + 14u, compare, projection); - iter_swap_if(first + 11u, first + 15u, compare, projection); - iter_swap_if(first + 16u, first + 20u, compare, projection); - iter_swap_if(first + 17u, first + 21u, compare, projection); - iter_swap_if(first + 18u, first + 22u, compare, projection); - iter_swap_if(first + 19u, first + 23u, compare, projection); - iter_swap_if(first + 25u, first + 26u, compare, projection); - iter_swap_if(first + 0u, first + 8u, compare, projection); - iter_swap_if(first + 1u, first + 9u, compare, projection); - iter_swap_if(first + 2u, first + 10u, compare, projection); - iter_swap_if(first + 3u, first + 11u, compare, projection); - iter_swap_if(first + 4u, first + 12u, compare, projection); - iter_swap_if(first + 5u, first + 13u, compare, projection); - iter_swap_if(first + 6u, first + 14u, compare, projection); - iter_swap_if(first + 7u, first + 15u, compare, projection); - iter_swap_if(first + 18u, first + 24u, compare, projection); - iter_swap_if(first + 20u, first + 26u, compare, projection); - iter_swap_if(first + 22u, first + 25u, compare, projection); - iter_swap_if(first + 2u, first + 8u, compare, projection); - iter_swap_if(first + 3u, first + 12u, compare, projection); - iter_swap_if(first + 5u, first + 10u, compare, projection); - iter_swap_if(first + 6u, first + 9u, compare, projection); - iter_swap_if(first + 7u, first + 13u, compare, projection); - iter_swap_if(first + 11u, first + 14u, compare, projection); - iter_swap_if(first + 16u, first + 18u, compare, projection); - iter_swap_if(first + 17u, first + 22u, compare, projection); - iter_swap_if(first + 19u, first + 26u, compare, projection); - iter_swap_if(first + 21u, first + 25u, compare, projection); - iter_swap_if(first + 0u, first + 16u, compare, projection); - iter_swap_if(first + 1u, first + 8u, compare, projection); - iter_swap_if(first + 5u, first + 22u, compare, projection); - iter_swap_if(first + 10u, first + 24u, compare, projection); - iter_swap_if(first + 11u, first + 25u, compare, projection); - iter_swap_if(first + 23u, first + 26u, compare, projection); - iter_swap_if(first + 1u, first + 18u, compare, projection); - iter_swap_if(first + 4u, first + 8u, compare, projection); - iter_swap_if(first + 5u, first + 19u, compare, projection); - iter_swap_if(first + 9u, first + 26u, compare, projection); - iter_swap_if(first + 10u, first + 20u, compare, projection); - iter_swap_if(first + 12u, first + 23u, compare, projection); - iter_swap_if(first + 21u, first + 24u, compare, projection); - iter_swap_if(first + 2u, first + 10u, compare, projection); - iter_swap_if(first + 3u, first + 21u, compare, projection); - iter_swap_if(first + 4u, first + 17u, compare, projection); - iter_swap_if(first + 6u, first + 20u, compare, projection); - iter_swap_if(first + 7u, first + 24u, compare, projection); - iter_swap_if(first + 8u, first + 19u, compare, projection); - iter_swap_if(first + 12u, first + 18u, compare, projection); - iter_swap_if(first + 14u, first + 23u, compare, projection); - iter_swap_if(first + 15u, first + 26u, compare, projection); - iter_swap_if(first + 2u, first + 4u, compare, projection); - iter_swap_if(first + 6u, first + 10u, compare, projection); - iter_swap_if(first + 7u, first + 11u, compare, projection); - iter_swap_if(first + 8u, first + 16u, compare, projection); - iter_swap_if(first + 9u, first + 17u, compare, projection); - iter_swap_if(first + 13u, first + 19u, compare, projection); - iter_swap_if(first + 14u, first + 22u, compare, projection); - iter_swap_if(first + 15u, first + 23u, compare, projection); - iter_swap_if(first + 20u, first + 21u, compare, projection); - iter_swap_if(first + 1u, first + 8u, compare, projection); - iter_swap_if(first + 3u, first + 10u, compare, projection); - iter_swap_if(first + 5u, first + 9u, compare, projection); - iter_swap_if(first + 12u, first + 16u, compare, projection); - iter_swap_if(first + 13u, first + 18u, compare, projection); - iter_swap_if(first + 14u, first + 17u, compare, projection); - iter_swap_if(first + 15u, first + 24u, compare, projection); - iter_swap_if(first + 19u, first + 25u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first + 3u, first + 12u, compare, projection); - iter_swap_if(first + 4u, first + 8u, compare, projection); - iter_swap_if(first + 7u, first + 13u, compare, projection); - iter_swap_if(first + 9u, first + 16u, compare, projection); - iter_swap_if(first + 11u, first + 18u, compare, projection); - iter_swap_if(first + 14u, first + 20u, compare, projection); - iter_swap_if(first + 17u, first + 21u, compare, projection); - iter_swap_if(first + 19u, first + 22u, compare, projection); - iter_swap_if(first + 23u, first + 25u, compare, projection); - iter_swap_if(first + 2u, first + 4u, compare, projection); - iter_swap_if(first + 3u, first + 8u, compare, projection); - iter_swap_if(first + 5u, first + 12u, compare, projection); - iter_swap_if(first + 6u, first + 9u, compare, projection); - iter_swap_if(first + 7u, first + 14u, compare, projection); - iter_swap_if(first + 10u, first + 16u, compare, projection); - iter_swap_if(first + 11u, first + 17u, compare, projection); - iter_swap_if(first + 13u, first + 20u, compare, projection); - iter_swap_if(first + 15u, first + 19u, compare, projection); - iter_swap_if(first + 18u, first + 21u, compare, projection); - iter_swap_if(first + 23u, first + 24u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 7u, first + 10u, compare, projection); - iter_swap_if(first + 9u, first + 12u, compare, projection); - iter_swap_if(first + 11u, first + 13u, compare, projection); - iter_swap_if(first + 14u, first + 16u, compare, projection); - iter_swap_if(first + 15u, first + 18u, compare, projection); - iter_swap_if(first + 17u, first + 20u, compare, projection); - iter_swap_if(first + 21u, first + 22u, compare, projection); - iter_swap_if(first + 3u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 8u, compare, projection); - iter_swap_if(first + 7u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 12u, compare, projection); - iter_swap_if(first + 11u, first + 14u, compare, projection); - iter_swap_if(first + 13u, first + 16u, compare, projection); - iter_swap_if(first + 15u, first + 17u, compare, projection); - iter_swap_if(first + 18u, first + 20u, compare, projection); - iter_swap_if(first + 19u, first + 21u, compare, projection); - iter_swap_if(first + 22u, first + 23u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); - iter_swap_if(first + 9u, first + 10u, compare, projection); - iter_swap_if(first + 11u, first + 12u, compare, projection); - iter_swap_if(first + 13u, first + 14u, compare, projection); - iter_swap_if(first + 15u, first + 16u, compare, projection); - iter_swap_if(first + 17u, first + 18u, compare, projection); - iter_swap_if(first + 19u, first + 20u, compare, projection); - iter_swap_if(first + 21u, first + 22u, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 12, first + 13, compare, projection); + iter_swap_if(first + 14, first + 15, compare, projection); + iter_swap_if(first + 16, first + 17, compare, projection); + iter_swap_if(first + 18, first + 19, compare, projection); + iter_swap_if(first + 20, first + 21, compare, projection); + iter_swap_if(first + 22, first + 23, compare, projection); + iter_swap_if(first + 24, first + 25, compare, projection); + iter_swap_if(first, first + 2, compare, projection); + iter_swap_if(first + 1, first + 3, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first + 5, first + 7, compare, projection); + iter_swap_if(first + 8, first + 10, compare, projection); + iter_swap_if(first + 9, first + 11, compare, projection); + iter_swap_if(first + 12, first + 14, compare, projection); + iter_swap_if(first + 13, first + 15, compare, projection); + iter_swap_if(first + 16, first + 18, compare, projection); + iter_swap_if(first + 17, first + 19, compare, projection); + iter_swap_if(first + 20, first + 22, compare, projection); + iter_swap_if(first + 21, first + 23, compare, projection); + iter_swap_if(first + 24, first + 26, compare, projection); + iter_swap_if(first, first + 4, compare, projection); + iter_swap_if(first + 1, first + 5, compare, projection); + iter_swap_if(first + 2, first + 6, compare, projection); + iter_swap_if(first + 3, first + 7, compare, projection); + iter_swap_if(first + 8, first + 12, compare, projection); + iter_swap_if(first + 9, first + 13, compare, projection); + iter_swap_if(first + 10, first + 14, compare, projection); + iter_swap_if(first + 11, first + 15, compare, projection); + iter_swap_if(first + 16, first + 20, compare, projection); + iter_swap_if(first + 17, first + 21, compare, projection); + iter_swap_if(first + 18, first + 22, compare, projection); + iter_swap_if(first + 19, first + 23, compare, projection); + iter_swap_if(first + 25, first + 26, compare, projection); + iter_swap_if(first, first + 8, compare, projection); + iter_swap_if(first + 1, first + 9, compare, projection); + iter_swap_if(first + 2, first + 10, compare, projection); + iter_swap_if(first + 3, first + 11, compare, projection); + iter_swap_if(first + 4, first + 12, compare, projection); + iter_swap_if(first + 5, first + 13, compare, projection); + iter_swap_if(first + 6, first + 14, compare, projection); + iter_swap_if(first + 7, first + 15, compare, projection); + iter_swap_if(first + 18, first + 24, compare, projection); + iter_swap_if(first + 20, first + 26, compare, projection); + iter_swap_if(first + 22, first + 25, compare, projection); + iter_swap_if(first + 2, first + 8, compare, projection); + iter_swap_if(first + 3, first + 12, compare, projection); + iter_swap_if(first + 5, first + 10, compare, projection); + iter_swap_if(first + 6, first + 9, compare, projection); + iter_swap_if(first + 7, first + 13, compare, projection); + iter_swap_if(first + 11, first + 14, compare, projection); + iter_swap_if(first + 16, first + 18, compare, projection); + iter_swap_if(first + 17, first + 22, compare, projection); + iter_swap_if(first + 19, first + 26, compare, projection); + iter_swap_if(first + 21, first + 25, compare, projection); + iter_swap_if(first, first + 16, compare, projection); + iter_swap_if(first + 1, first + 8, compare, projection); + iter_swap_if(first + 5, first + 22, compare, projection); + iter_swap_if(first + 10, first + 24, compare, projection); + iter_swap_if(first + 11, first + 25, compare, projection); + iter_swap_if(first + 23, first + 26, compare, projection); + iter_swap_if(first + 1, first + 18, compare, projection); + iter_swap_if(first + 4, first + 8, compare, projection); + iter_swap_if(first + 5, first + 19, compare, projection); + iter_swap_if(first + 9, first + 26, compare, projection); + iter_swap_if(first + 10, first + 20, compare, projection); + iter_swap_if(first + 12, first + 23, compare, projection); + iter_swap_if(first + 21, first + 24, compare, projection); + iter_swap_if(first + 2, first + 10, compare, projection); + iter_swap_if(first + 3, first + 21, compare, projection); + iter_swap_if(first + 4, first + 17, compare, projection); + iter_swap_if(first + 6, first + 20, compare, projection); + iter_swap_if(first + 7, first + 24, compare, projection); + iter_swap_if(first + 8, first + 19, compare, projection); + iter_swap_if(first + 12, first + 18, compare, projection); + iter_swap_if(first + 14, first + 23, compare, projection); + iter_swap_if(first + 15, first + 26, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 6, first + 10, compare, projection); + iter_swap_if(first + 7, first + 11, compare, projection); + iter_swap_if(first + 8, first + 16, compare, projection); + iter_swap_if(first + 9, first + 17, compare, projection); + iter_swap_if(first + 13, first + 19, compare, projection); + iter_swap_if(first + 14, first + 22, compare, projection); + iter_swap_if(first + 15, first + 23, compare, projection); + iter_swap_if(first + 20, first + 21, compare, projection); + iter_swap_if(first + 1, first + 8, compare, projection); + iter_swap_if(first + 3, first + 10, compare, projection); + iter_swap_if(first + 5, first + 9, compare, projection); + iter_swap_if(first + 12, first + 16, compare, projection); + iter_swap_if(first + 13, first + 18, compare, projection); + iter_swap_if(first + 14, first + 17, compare, projection); + iter_swap_if(first + 15, first + 24, compare, projection); + iter_swap_if(first + 19, first + 25, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 3, first + 12, compare, projection); + iter_swap_if(first + 4, first + 8, compare, projection); + iter_swap_if(first + 7, first + 13, compare, projection); + iter_swap_if(first + 9, first + 16, compare, projection); + iter_swap_if(first + 11, first + 18, compare, projection); + iter_swap_if(first + 14, first + 20, compare, projection); + iter_swap_if(first + 17, first + 21, compare, projection); + iter_swap_if(first + 19, first + 22, compare, projection); + iter_swap_if(first + 23, first + 25, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 3, first + 8, compare, projection); + iter_swap_if(first + 5, first + 12, compare, projection); + iter_swap_if(first + 6, first + 9, compare, projection); + iter_swap_if(first + 7, first + 14, compare, projection); + iter_swap_if(first + 10, first + 16, compare, projection); + iter_swap_if(first + 11, first + 17, compare, projection); + iter_swap_if(first + 13, first + 20, compare, projection); + iter_swap_if(first + 15, first + 19, compare, projection); + iter_swap_if(first + 18, first + 21, compare, projection); + iter_swap_if(first + 23, first + 24, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 7, first + 10, compare, projection); + iter_swap_if(first + 9, first + 12, compare, projection); + iter_swap_if(first + 11, first + 13, compare, projection); + iter_swap_if(first + 14, first + 16, compare, projection); + iter_swap_if(first + 15, first + 18, compare, projection); + iter_swap_if(first + 17, first + 20, compare, projection); + iter_swap_if(first + 21, first + 22, compare, projection); + iter_swap_if(first + 3, first + 5, compare, projection); + iter_swap_if(first + 6, first + 8, compare, projection); + iter_swap_if(first + 7, first + 9, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 11, first + 14, compare, projection); + iter_swap_if(first + 13, first + 16, compare, projection); + iter_swap_if(first + 15, first + 17, compare, projection); + iter_swap_if(first + 18, first + 20, compare, projection); + iter_swap_if(first + 19, first + 21, compare, projection); + iter_swap_if(first + 22, first + 23, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 9, first + 10, compare, projection); + iter_swap_if(first + 11, first + 12, compare, projection); + iter_swap_if(first + 13, first + 14, compare, projection); + iter_swap_if(first + 15, first + 16, compare, projection); + iter_swap_if(first + 17, first + 18, compare, projection); + iter_swap_if(first + 19, first + 20, compare, projection); + iter_swap_if(first + 21, first + 22, compare, projection); } template diff --git a/include/cpp-sort/detail/sorting_network/sort28.h b/include/cpp-sort/detail/sorting_network/sort28.h index 1654aac5..0ad9c84f 100644 --- a/include/cpp-sort/detail/sorting_network/sort28.h +++ b/include/cpp-sort/detail/sorting_network/sort28.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SORTING_NETWORK_SORT28_H_ @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<28u> + struct sorting_network_sorter_impl<28> { template< typename RandomAccessIterator, @@ -24,161 +24,161 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - iter_swap_if(first, first + 9u, compare, projection); - iter_swap_if(first + 1u, first + 20u, compare, projection); - iter_swap_if(first + 2u, first + 21u, compare, projection); - iter_swap_if(first + 3u, first + 22u, compare, projection); - iter_swap_if(first + 4u, first + 19u, compare, projection); - iter_swap_if(first + 5u, first + 24u, compare, projection); - iter_swap_if(first + 6u, first + 25u, compare, projection); - iter_swap_if(first + 7u, first + 26u, compare, projection); - iter_swap_if(first + 8u, first + 23u, compare, projection); - iter_swap_if(first + 10u, first + 15u, compare, projection); - iter_swap_if(first + 11u, first + 13u, compare, projection); - iter_swap_if(first + 12u, first + 17u, compare, projection); - iter_swap_if(first + 14u, first + 16u, compare, projection); - iter_swap_if(first + 18u, first + 27u, compare, projection); - iter_swap_if(first, first + 18u, compare, projection); - iter_swap_if(first + 1u, first + 7u, compare, projection); - iter_swap_if(first + 2u, first + 6u, compare, projection); - iter_swap_if(first + 3u, first + 5u, compare, projection); - iter_swap_if(first + 4u, first + 8u, compare, projection); - iter_swap_if(first + 9u, first + 27u, compare, projection); - iter_swap_if(first + 10u, first + 12u, compare, projection); - iter_swap_if(first + 11u, first + 14u, compare, projection); - iter_swap_if(first + 13u, first + 16u, compare, projection); - iter_swap_if(first + 15u, first + 17u, compare, projection); - iter_swap_if(first + 19u, first + 23u, compare, projection); - iter_swap_if(first + 20u, first + 26u, compare, projection); - iter_swap_if(first + 21u, first + 25u, compare, projection); - iter_swap_if(first + 22u, first + 24u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 19u, compare, projection); - iter_swap_if(first + 6u, first + 20u, compare, projection); - iter_swap_if(first + 7u, first + 21u, compare, projection); - iter_swap_if(first + 8u, first + 22u, compare, projection); - iter_swap_if(first + 9u, first + 18u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 14u, compare, projection); - iter_swap_if(first + 13u, first + 15u, compare, projection); - iter_swap_if(first + 16u, first + 17u, compare, projection); - iter_swap_if(first + 23u, first + 24u, compare, projection); - iter_swap_if(first + 25u, first + 26u, compare, projection); - iter_swap_if(first, first + 3u, compare, projection); - iter_swap_if(first + 1u, first + 10u, compare, projection); - iter_swap_if(first + 5u, first + 8u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 11u, first + 13u, compare, projection); - iter_swap_if(first + 14u, first + 16u, compare, projection); - iter_swap_if(first + 17u, first + 26u, compare, projection); - iter_swap_if(first + 19u, first + 22u, compare, projection); - iter_swap_if(first + 20u, first + 21u, compare, projection); - iter_swap_if(first + 24u, first + 27u, compare, projection); - iter_swap_if(first, first + 1u, compare, projection); - iter_swap_if(first + 2u, first + 7u, compare, projection); - iter_swap_if(first + 3u, first + 10u, compare, projection); - iter_swap_if(first + 4u, first + 8u, compare, projection); - iter_swap_if(first + 12u, first + 13u, compare, projection); - iter_swap_if(first + 14u, first + 15u, compare, projection); - iter_swap_if(first + 17u, first + 24u, compare, projection); - iter_swap_if(first + 19u, first + 23u, compare, projection); - iter_swap_if(first + 20u, first + 25u, compare, projection); - iter_swap_if(first + 26u, first + 27u, compare, projection); - iter_swap_if(first + 1u, first + 3u, compare, projection); - iter_swap_if(first + 2u, first + 6u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 7u, first + 19u, compare, projection); - iter_swap_if(first + 8u, first + 20u, compare, projection); - iter_swap_if(first + 11u, first + 12u, compare, projection); - iter_swap_if(first + 13u, first + 14u, compare, projection); - iter_swap_if(first + 15u, first + 16u, compare, projection); - iter_swap_if(first + 21u, first + 25u, compare, projection); - iter_swap_if(first + 22u, first + 23u, compare, projection); - iter_swap_if(first + 24u, first + 26u, compare, projection); - iter_swap_if(first + 2u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 12u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); - iter_swap_if(first + 9u, first + 11u, compare, projection); - iter_swap_if(first + 10u, first + 14u, compare, projection); - iter_swap_if(first + 13u, first + 17u, compare, projection); - iter_swap_if(first + 15u, first + 22u, compare, projection); - iter_swap_if(first + 16u, first + 18u, compare, projection); - iter_swap_if(first + 19u, first + 20u, compare, projection); - iter_swap_if(first + 23u, first + 25u, compare, projection); - iter_swap_if(first + 2u, first + 9u, compare, projection); - iter_swap_if(first + 4u, first + 11u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 7u, first + 13u, compare, projection); - iter_swap_if(first + 8u, first + 10u, compare, projection); - iter_swap_if(first + 14u, first + 20u, compare, projection); - iter_swap_if(first + 16u, first + 23u, compare, projection); - iter_swap_if(first + 17u, first + 19u, compare, projection); - iter_swap_if(first + 18u, first + 25u, compare, projection); - iter_swap_if(first + 21u, first + 22u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first + 3u, first + 16u, compare, projection); - iter_swap_if(first + 4u, first + 9u, compare, projection); - iter_swap_if(first + 6u, first + 12u, compare, projection); - iter_swap_if(first + 10u, first + 14u, compare, projection); - iter_swap_if(first + 11u, first + 24u, compare, projection); - iter_swap_if(first + 13u, first + 17u, compare, projection); - iter_swap_if(first + 15u, first + 21u, compare, projection); - iter_swap_if(first + 18u, first + 23u, compare, projection); - iter_swap_if(first + 25u, first + 26u, compare, projection); - iter_swap_if(first + 2u, first + 8u, compare, projection); - iter_swap_if(first + 3u, first + 5u, compare, projection); - iter_swap_if(first + 4u, first + 7u, compare, projection); - iter_swap_if(first + 6u, first + 16u, compare, projection); - iter_swap_if(first + 9u, first + 15u, compare, projection); - iter_swap_if(first + 11u, first + 21u, compare, projection); - iter_swap_if(first + 12u, first + 18u, compare, projection); - iter_swap_if(first + 19u, first + 25u, compare, projection); - iter_swap_if(first + 20u, first + 23u, compare, projection); - iter_swap_if(first + 22u, first + 24u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 5u, first + 8u, compare, projection); - iter_swap_if(first + 7u, first + 9u, compare, projection); - iter_swap_if(first + 11u, first + 15u, compare, projection); - iter_swap_if(first + 12u, first + 16u, compare, projection); - iter_swap_if(first + 18u, first + 20u, compare, projection); - iter_swap_if(first + 19u, first + 22u, compare, projection); - iter_swap_if(first + 24u, first + 25u, compare, projection); - iter_swap_if(first + 6u, first + 8u, compare, projection); - iter_swap_if(first + 10u, first + 12u, compare, projection); - iter_swap_if(first + 11u, first + 13u, compare, projection); - iter_swap_if(first + 14u, first + 16u, compare, projection); - iter_swap_if(first + 15u, first + 17u, compare, projection); - iter_swap_if(first + 19u, first + 21u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 8u, first + 10u, compare, projection); - iter_swap_if(first + 9u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 13u, compare, projection); - iter_swap_if(first + 14u, first + 15u, compare, projection); - iter_swap_if(first + 16u, first + 18u, compare, projection); - iter_swap_if(first + 17u, first + 19u, compare, projection); - iter_swap_if(first + 21u, first + 22u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 14u, compare, projection); - iter_swap_if(first + 13u, first + 15u, compare, projection); - iter_swap_if(first + 16u, first + 17u, compare, projection); - iter_swap_if(first + 18u, first + 19u, compare, projection); - iter_swap_if(first + 20u, first + 21u, compare, projection); - iter_swap_if(first + 22u, first + 23u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); - iter_swap_if(first + 9u, first + 10u, compare, projection); - iter_swap_if(first + 11u, first + 12u, compare, projection); - iter_swap_if(first + 13u, first + 14u, compare, projection); - iter_swap_if(first + 15u, first + 16u, compare, projection); - iter_swap_if(first + 17u, first + 18u, compare, projection); - iter_swap_if(first + 19u, first + 20u, compare, projection); - iter_swap_if(first + 21u, first + 22u, compare, projection); - iter_swap_if(first + 23u, first + 24u, compare, projection); + iter_swap_if(first, first + 9, compare, projection); + iter_swap_if(first + 1, first + 20, compare, projection); + iter_swap_if(first + 2, first + 21, compare, projection); + iter_swap_if(first + 3, first + 22, compare, projection); + iter_swap_if(first + 4, first + 19, compare, projection); + iter_swap_if(first + 5, first + 24, compare, projection); + iter_swap_if(first + 6, first + 25, compare, projection); + iter_swap_if(first + 7, first + 26, compare, projection); + iter_swap_if(first + 8, first + 23, compare, projection); + iter_swap_if(first + 10, first + 15, compare, projection); + iter_swap_if(first + 11, first + 13, compare, projection); + iter_swap_if(first + 12, first + 17, compare, projection); + iter_swap_if(first + 14, first + 16, compare, projection); + iter_swap_if(first + 18, first + 27, compare, projection); + iter_swap_if(first, first + 18, compare, projection); + iter_swap_if(first + 1, first + 7, compare, projection); + iter_swap_if(first + 2, first + 6, compare, projection); + iter_swap_if(first + 3, first + 5, compare, projection); + iter_swap_if(first + 4, first + 8, compare, projection); + iter_swap_if(first + 9, first + 27, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 11, first + 14, compare, projection); + iter_swap_if(first + 13, first + 16, compare, projection); + iter_swap_if(first + 15, first + 17, compare, projection); + iter_swap_if(first + 19, first + 23, compare, projection); + iter_swap_if(first + 20, first + 26, compare, projection); + iter_swap_if(first + 21, first + 25, compare, projection); + iter_swap_if(first + 22, first + 24, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 19, compare, projection); + iter_swap_if(first + 6, first + 20, compare, projection); + iter_swap_if(first + 7, first + 21, compare, projection); + iter_swap_if(first + 8, first + 22, compare, projection); + iter_swap_if(first + 9, first + 18, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 12, first + 14, compare, projection); + iter_swap_if(first + 13, first + 15, compare, projection); + iter_swap_if(first + 16, first + 17, compare, projection); + iter_swap_if(first + 23, first + 24, compare, projection); + iter_swap_if(first + 25, first + 26, compare, projection); + iter_swap_if(first, first + 3, compare, projection); + iter_swap_if(first + 1, first + 10, compare, projection); + iter_swap_if(first + 5, first + 8, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 11, first + 13, compare, projection); + iter_swap_if(first + 14, first + 16, compare, projection); + iter_swap_if(first + 17, first + 26, compare, projection); + iter_swap_if(first + 19, first + 22, compare, projection); + iter_swap_if(first + 20, first + 21, compare, projection); + iter_swap_if(first + 24, first + 27, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 2, first + 7, compare, projection); + iter_swap_if(first + 3, first + 10, compare, projection); + iter_swap_if(first + 4, first + 8, compare, projection); + iter_swap_if(first + 12, first + 13, compare, projection); + iter_swap_if(first + 14, first + 15, compare, projection); + iter_swap_if(first + 17, first + 24, compare, projection); + iter_swap_if(first + 19, first + 23, compare, projection); + iter_swap_if(first + 20, first + 25, compare, projection); + iter_swap_if(first + 26, first + 27, compare, projection); + iter_swap_if(first + 1, first + 3, compare, projection); + iter_swap_if(first + 2, first + 6, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 7, first + 19, compare, projection); + iter_swap_if(first + 8, first + 20, compare, projection); + iter_swap_if(first + 11, first + 12, compare, projection); + iter_swap_if(first + 13, first + 14, compare, projection); + iter_swap_if(first + 15, first + 16, compare, projection); + iter_swap_if(first + 21, first + 25, compare, projection); + iter_swap_if(first + 22, first + 23, compare, projection); + iter_swap_if(first + 24, first + 26, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 5, first + 12, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 9, first + 11, compare, projection); + iter_swap_if(first + 10, first + 14, compare, projection); + iter_swap_if(first + 13, first + 17, compare, projection); + iter_swap_if(first + 15, first + 22, compare, projection); + iter_swap_if(first + 16, first + 18, compare, projection); + iter_swap_if(first + 19, first + 20, compare, projection); + iter_swap_if(first + 23, first + 25, compare, projection); + iter_swap_if(first + 2, first + 9, compare, projection); + iter_swap_if(first + 4, first + 11, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 7, first + 13, compare, projection); + iter_swap_if(first + 8, first + 10, compare, projection); + iter_swap_if(first + 14, first + 20, compare, projection); + iter_swap_if(first + 16, first + 23, compare, projection); + iter_swap_if(first + 17, first + 19, compare, projection); + iter_swap_if(first + 18, first + 25, compare, projection); + iter_swap_if(first + 21, first + 22, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 3, first + 16, compare, projection); + iter_swap_if(first + 4, first + 9, compare, projection); + iter_swap_if(first + 6, first + 12, compare, projection); + iter_swap_if(first + 10, first + 14, compare, projection); + iter_swap_if(first + 11, first + 24, compare, projection); + iter_swap_if(first + 13, first + 17, compare, projection); + iter_swap_if(first + 15, first + 21, compare, projection); + iter_swap_if(first + 18, first + 23, compare, projection); + iter_swap_if(first + 25, first + 26, compare, projection); + iter_swap_if(first + 2, first + 8, compare, projection); + iter_swap_if(first + 3, first + 5, compare, projection); + iter_swap_if(first + 4, first + 7, compare, projection); + iter_swap_if(first + 6, first + 16, compare, projection); + iter_swap_if(first + 9, first + 15, compare, projection); + iter_swap_if(first + 11, first + 21, compare, projection); + iter_swap_if(first + 12, first + 18, compare, projection); + iter_swap_if(first + 19, first + 25, compare, projection); + iter_swap_if(first + 20, first + 23, compare, projection); + iter_swap_if(first + 22, first + 24, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 5, first + 8, compare, projection); + iter_swap_if(first + 7, first + 9, compare, projection); + iter_swap_if(first + 11, first + 15, compare, projection); + iter_swap_if(first + 12, first + 16, compare, projection); + iter_swap_if(first + 18, first + 20, compare, projection); + iter_swap_if(first + 19, first + 22, compare, projection); + iter_swap_if(first + 24, first + 25, compare, projection); + iter_swap_if(first + 6, first + 8, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 11, first + 13, compare, projection); + iter_swap_if(first + 14, first + 16, compare, projection); + iter_swap_if(first + 15, first + 17, compare, projection); + iter_swap_if(first + 19, first + 21, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 8, first + 10, compare, projection); + iter_swap_if(first + 9, first + 11, compare, projection); + iter_swap_if(first + 12, first + 13, compare, projection); + iter_swap_if(first + 14, first + 15, compare, projection); + iter_swap_if(first + 16, first + 18, compare, projection); + iter_swap_if(first + 17, first + 19, compare, projection); + iter_swap_if(first + 21, first + 22, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 12, first + 14, compare, projection); + iter_swap_if(first + 13, first + 15, compare, projection); + iter_swap_if(first + 16, first + 17, compare, projection); + iter_swap_if(first + 18, first + 19, compare, projection); + iter_swap_if(first + 20, first + 21, compare, projection); + iter_swap_if(first + 22, first + 23, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 9, first + 10, compare, projection); + iter_swap_if(first + 11, first + 12, compare, projection); + iter_swap_if(first + 13, first + 14, compare, projection); + iter_swap_if(first + 15, first + 16, compare, projection); + iter_swap_if(first + 17, first + 18, compare, projection); + iter_swap_if(first + 19, first + 20, compare, projection); + iter_swap_if(first + 21, first + 22, compare, projection); + iter_swap_if(first + 23, first + 24, compare, projection); } template diff --git a/include/cpp-sort/detail/sorting_network/sort29.h b/include/cpp-sort/detail/sorting_network/sort29.h index b46680dc..ec877aac 100644 --- a/include/cpp-sort/detail/sorting_network/sort29.h +++ b/include/cpp-sort/detail/sorting_network/sort29.h @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<29u> + struct sorting_network_sorter_impl<29> { template< typename RandomAccessIterator, @@ -24,170 +24,170 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - iter_swap_if(first + 0u, first + 1u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 13u, compare, projection); - iter_swap_if(first + 14u, first + 15u, compare, projection); - iter_swap_if(first + 16u, first + 28u, compare, projection); - iter_swap_if(first + 17u, first + 26u, compare, projection); - iter_swap_if(first + 18u, first + 25u, compare, projection); - iter_swap_if(first + 19u, first + 23u, compare, projection); - iter_swap_if(first + 21u, first + 27u, compare, projection); - iter_swap_if(first + 22u, first + 24u, compare, projection); - iter_swap_if(first + 0u, first + 2u, compare, projection); - iter_swap_if(first + 1u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 6u, compare, projection); - iter_swap_if(first + 5u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 10u, compare, projection); - iter_swap_if(first + 9u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 14u, compare, projection); - iter_swap_if(first + 13u, first + 15u, compare, projection); - iter_swap_if(first + 17u, first + 22u, compare, projection); - iter_swap_if(first + 18u, first + 19u, compare, projection); - iter_swap_if(first + 20u, first + 27u, compare, projection); - iter_swap_if(first + 23u, first + 25u, compare, projection); - iter_swap_if(first + 24u, first + 26u, compare, projection); - iter_swap_if(first + 0u, first + 4u, compare, projection); - iter_swap_if(first + 1u, first + 5u, compare, projection); - iter_swap_if(first + 2u, first + 6u, compare, projection); - iter_swap_if(first + 3u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 12u, compare, projection); - iter_swap_if(first + 9u, first + 13u, compare, projection); - iter_swap_if(first + 10u, first + 14u, compare, projection); - iter_swap_if(first + 11u, first + 15u, compare, projection); - iter_swap_if(first + 16u, first + 20u, compare, projection); - iter_swap_if(first + 17u, first + 18u, compare, projection); - iter_swap_if(first + 19u, first + 22u, compare, projection); - iter_swap_if(first + 23u, first + 24u, compare, projection); - iter_swap_if(first + 25u, first + 26u, compare, projection); - iter_swap_if(first + 27u, first + 28u, compare, projection); - iter_swap_if(first + 0u, first + 8u, compare, projection); - iter_swap_if(first + 1u, first + 9u, compare, projection); - iter_swap_if(first + 2u, first + 10u, compare, projection); - iter_swap_if(first + 3u, first + 11u, compare, projection); - iter_swap_if(first + 4u, first + 12u, compare, projection); - iter_swap_if(first + 5u, first + 13u, compare, projection); - iter_swap_if(first + 6u, first + 14u, compare, projection); - iter_swap_if(first + 7u, first + 15u, compare, projection); - iter_swap_if(first + 20u, first + 22u, compare, projection); - iter_swap_if(first + 21u, first + 25u, compare, projection); - iter_swap_if(first + 24u, first + 27u, compare, projection); - iter_swap_if(first + 26u, first + 28u, compare, projection); - iter_swap_if(first + 3u, first + 20u, compare, projection); - iter_swap_if(first + 5u, first + 24u, compare, projection); - iter_swap_if(first + 6u, first + 21u, compare, projection); - iter_swap_if(first + 7u, first + 26u, compare, projection); - iter_swap_if(first + 10u, first + 23u, compare, projection); - iter_swap_if(first + 11u, first + 13u, compare, projection); - iter_swap_if(first + 12u, first + 19u, compare, projection); - iter_swap_if(first + 14u, first + 25u, compare, projection); - iter_swap_if(first + 15u, first + 28u, compare, projection); - iter_swap_if(first + 22u, first + 27u, compare, projection); - iter_swap_if(first + 2u, first + 5u, compare, projection); - iter_swap_if(first + 3u, first + 10u, compare, projection); - iter_swap_if(first + 6u, first + 16u, compare, projection); - iter_swap_if(first + 7u, first + 14u, compare, projection); - iter_swap_if(first + 11u, first + 22u, compare, projection); - iter_swap_if(first + 13u, first + 27u, compare, projection); - iter_swap_if(first + 15u, first + 25u, compare, projection); - iter_swap_if(first + 19u, first + 23u, compare, projection); - iter_swap_if(first + 20u, first + 24u, compare, projection); - iter_swap_if(first + 2u, first + 12u, compare, projection); - iter_swap_if(first + 6u, first + 17u, compare, projection); - iter_swap_if(first + 11u, first + 20u, compare, projection); - iter_swap_if(first + 13u, first + 24u, compare, projection); - iter_swap_if(first + 14u, first + 21u, compare, projection); - iter_swap_if(first + 15u, first + 26u, compare, projection); - iter_swap_if(first + 16u, first + 18u, compare, projection); - iter_swap_if(first + 0u, first + 6u, compare, projection); - iter_swap_if(first + 1u, first + 17u, compare, projection); - iter_swap_if(first + 5u, first + 12u, compare, projection); - iter_swap_if(first + 7u, first + 20u, compare, projection); - iter_swap_if(first + 8u, first + 16u, compare, projection); - iter_swap_if(first + 9u, first + 18u, compare, projection); - iter_swap_if(first + 13u, first + 14u, compare, projection); - iter_swap_if(first + 15u, first + 21u, compare, projection); - iter_swap_if(first + 25u, first + 26u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first + 6u, first + 8u, compare, projection); - iter_swap_if(first + 15u, first + 22u, compare, projection); - iter_swap_if(first + 16u, first + 17u, compare, projection); - iter_swap_if(first + 18u, first + 19u, compare, projection); - iter_swap_if(first + 26u, first + 27u, compare, projection); - iter_swap_if(first + 1u, first + 6u, compare, projection); - iter_swap_if(first + 2u, first + 8u, compare, projection); - iter_swap_if(first + 4u, first + 17u, compare, projection); - iter_swap_if(first + 9u, first + 16u, compare, projection); - iter_swap_if(first + 11u, first + 18u, compare, projection); - iter_swap_if(first + 19u, first + 23u, compare, projection); - iter_swap_if(first + 22u, first + 25u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 16u, compare, projection); - iter_swap_if(first + 10u, first + 17u, compare, projection); - iter_swap_if(first + 13u, first + 18u, compare, projection); - iter_swap_if(first + 14u, first + 19u, compare, projection); - iter_swap_if(first + 23u, first + 24u, compare, projection); - iter_swap_if(first + 25u, first + 26u, compare, projection); - iter_swap_if(first + 3u, first + 6u, compare, projection); - iter_swap_if(first + 4u, first + 10u, compare, projection); - iter_swap_if(first + 5u, first + 9u, compare, projection); - iter_swap_if(first + 7u, first + 13u, compare, projection); - iter_swap_if(first + 12u, first + 16u, compare, projection); - iter_swap_if(first + 14u, first + 17u, compare, projection); - iter_swap_if(first + 15u, first + 23u, compare, projection); - iter_swap_if(first + 18u, first + 20u, compare, projection); - iter_swap_if(first + 21u, first + 24u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 9u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 7u, first + 12u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 13u, first + 16u, compare, projection); - iter_swap_if(first + 15u, first + 18u, compare, projection); - iter_swap_if(first + 19u, first + 23u, compare, projection); - iter_swap_if(first + 20u, first + 21u, compare, projection); - iter_swap_if(first + 24u, first + 25u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 7u, first + 10u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 11u, first + 13u, compare, projection); - iter_swap_if(first + 12u, first + 14u, compare, projection); - iter_swap_if(first + 16u, first + 17u, compare, projection); - iter_swap_if(first + 18u, first + 19u, compare, projection); - iter_swap_if(first + 21u, first + 23u, compare, projection); - iter_swap_if(first + 22u, first + 24u, compare, projection); - iter_swap_if(first + 3u, first + 5u, compare, projection); - iter_swap_if(first + 4u, first + 7u, compare, projection); - iter_swap_if(first + 6u, first + 8u, compare, projection); - iter_swap_if(first + 9u, first + 12u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 13u, first + 16u, compare, projection); - iter_swap_if(first + 14u, first + 15u, compare, projection); - iter_swap_if(first + 17u, first + 20u, compare, projection); - iter_swap_if(first + 22u, first + 23u, compare, projection); - iter_swap_if(first + 4u, first + 6u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); - iter_swap_if(first + 9u, first + 10u, compare, projection); - iter_swap_if(first + 11u, first + 12u, compare, projection); - iter_swap_if(first + 13u, first + 14u, compare, projection); - iter_swap_if(first + 15u, first + 16u, compare, projection); - iter_swap_if(first + 17u, first + 18u, compare, projection); - iter_swap_if(first + 19u, first + 20u, compare, projection); - iter_swap_if(first + 21u, first + 22u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 13u, compare, projection); - iter_swap_if(first + 14u, first + 15u, compare, projection); - iter_swap_if(first + 16u, first + 17u, compare, projection); - iter_swap_if(first + 18u, first + 19u, compare, projection); - iter_swap_if(first + 20u, first + 21u, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 12, first + 13, compare, projection); + iter_swap_if(first + 14, first + 15, compare, projection); + iter_swap_if(first + 16, first + 28, compare, projection); + iter_swap_if(first + 17, first + 26, compare, projection); + iter_swap_if(first + 18, first + 25, compare, projection); + iter_swap_if(first + 19, first + 23, compare, projection); + iter_swap_if(first + 21, first + 27, compare, projection); + iter_swap_if(first + 22, first + 24, compare, projection); + iter_swap_if(first, first + 2, compare, projection); + iter_swap_if(first + 1, first + 3, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first + 5, first + 7, compare, projection); + iter_swap_if(first + 8, first + 10, compare, projection); + iter_swap_if(first + 9, first + 11, compare, projection); + iter_swap_if(first + 12, first + 14, compare, projection); + iter_swap_if(first + 13, first + 15, compare, projection); + iter_swap_if(first + 17, first + 22, compare, projection); + iter_swap_if(first + 18, first + 19, compare, projection); + iter_swap_if(first + 20, first + 27, compare, projection); + iter_swap_if(first + 23, first + 25, compare, projection); + iter_swap_if(first + 24, first + 26, compare, projection); + iter_swap_if(first, first + 4, compare, projection); + iter_swap_if(first + 1, first + 5, compare, projection); + iter_swap_if(first + 2, first + 6, compare, projection); + iter_swap_if(first + 3, first + 7, compare, projection); + iter_swap_if(first + 8, first + 12, compare, projection); + iter_swap_if(first + 9, first + 13, compare, projection); + iter_swap_if(first + 10, first + 14, compare, projection); + iter_swap_if(first + 11, first + 15, compare, projection); + iter_swap_if(first + 16, first + 20, compare, projection); + iter_swap_if(first + 17, first + 18, compare, projection); + iter_swap_if(first + 19, first + 22, compare, projection); + iter_swap_if(first + 23, first + 24, compare, projection); + iter_swap_if(first + 25, first + 26, compare, projection); + iter_swap_if(first + 27, first + 28, compare, projection); + iter_swap_if(first, first + 8, compare, projection); + iter_swap_if(first + 1, first + 9, compare, projection); + iter_swap_if(first + 2, first + 10, compare, projection); + iter_swap_if(first + 3, first + 11, compare, projection); + iter_swap_if(first + 4, first + 12, compare, projection); + iter_swap_if(first + 5, first + 13, compare, projection); + iter_swap_if(first + 6, first + 14, compare, projection); + iter_swap_if(first + 7, first + 15, compare, projection); + iter_swap_if(first + 16, first + 18, compare, projection); + iter_swap_if(first + 20, first + 22, compare, projection); + iter_swap_if(first + 21, first + 25, compare, projection); + iter_swap_if(first + 24, first + 27, compare, projection); + iter_swap_if(first + 26, first + 28, compare, projection); + iter_swap_if(first + 1, first + 8, compare, projection); + iter_swap_if(first + 2, first + 24, compare, projection); + iter_swap_if(first + 4, first + 19, compare, projection); + iter_swap_if(first + 5, first + 20, compare, projection); + iter_swap_if(first + 6, first + 21, compare, projection); + iter_swap_if(first + 7, first + 27, compare, projection); + iter_swap_if(first + 9, first + 18, compare, projection); + iter_swap_if(first + 10, first + 23, compare, projection); + iter_swap_if(first + 11, first + 26, compare, projection); + iter_swap_if(first + 13, first + 22, compare, projection); + iter_swap_if(first + 14, first + 25, compare, projection); + iter_swap_if(first + 15, first + 28, compare, projection); + iter_swap_if(first + 16, first + 17, compare, projection); + iter_swap_if(first, first + 6, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 3, first + 24, compare, projection); + iter_swap_if(first + 5, first + 10, compare, projection); + iter_swap_if(first + 12, first + 19, compare, projection); + iter_swap_if(first + 13, first + 18, compare, projection); + iter_swap_if(first + 14, first + 21, compare, projection); + iter_swap_if(first + 15, first + 25, compare, projection); + iter_swap_if(first + 20, first + 23, compare, projection); + iter_swap_if(first + 26, first + 27, compare, projection); + iter_swap_if(first, first + 16, compare, projection); + iter_swap_if(first + 1, first + 6, compare, projection); + iter_swap_if(first + 3, first + 12, compare, projection); + iter_swap_if(first + 4, first + 8, compare, projection); + iter_swap_if(first + 5, first + 17, compare, projection); + iter_swap_if(first + 7, first + 24, compare, projection); + iter_swap_if(first + 14, first + 20, compare, projection); + iter_swap_if(first + 15, first + 26, compare, projection); + iter_swap_if(first + 18, first + 21, compare, projection); + iter_swap_if(first + 19, first + 23, compare, projection); + iter_swap_if(first + 25, first + 27, compare, projection); + iter_swap_if(first + 1, first + 5, compare, projection); + iter_swap_if(first + 2, first + 16, compare, projection); + iter_swap_if(first + 3, first + 10, compare, projection); + iter_swap_if(first + 6, first + 9, compare, projection); + iter_swap_if(first + 7, first + 18, compare, projection); + iter_swap_if(first + 8, first + 17, compare, projection); + iter_swap_if(first + 11, first + 19, compare, projection); + iter_swap_if(first + 13, first + 14, compare, projection); + iter_swap_if(first + 15, first + 22, compare, projection); + iter_swap_if(first + 21, first + 23, compare, projection); + iter_swap_if(first + 25, first + 26, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 3, first + 5, compare, projection); + iter_swap_if(first + 4, first + 8, compare, projection); + iter_swap_if(first + 6, first + 16, compare, projection); + iter_swap_if(first + 7, first + 11, compare, projection); + iter_swap_if(first + 9, first + 17, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 14, first + 20, compare, projection); + iter_swap_if(first + 15, first + 18, compare, projection); + iter_swap_if(first + 19, first + 24, compare, projection); + iter_swap_if(first + 22, first + 27, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first + 9, first + 16, compare, projection); + iter_swap_if(first + 10, first + 13, compare, projection); + iter_swap_if(first + 11, first + 19, compare, projection); + iter_swap_if(first + 12, first + 14, compare, projection); + iter_swap_if(first + 20, first + 21, compare, projection); + iter_swap_if(first + 22, first + 26, compare, projection); + iter_swap_if(first + 23, first + 24, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 3, first + 6, compare, projection); + iter_swap_if(first + 7, first + 16, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 11, first + 17, compare, projection); + iter_swap_if(first + 15, first + 19, compare, projection); + iter_swap_if(first + 18, first + 23, compare, projection); + iter_swap_if(first + 24, first + 25, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 9, compare, projection); + iter_swap_if(first + 7, first + 10, compare, projection); + iter_swap_if(first + 11, first + 13, compare, projection); + iter_swap_if(first + 12, first + 16, compare, projection); + iter_swap_if(first + 14, first + 17, compare, projection); + iter_swap_if(first + 15, first + 20, compare, projection); + iter_swap_if(first + 19, first + 21, compare, projection); + iter_swap_if(first + 22, first + 24, compare, projection); + iter_swap_if(first + 5, first + 8, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 9, first + 12, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 13, first + 14, compare, projection); + iter_swap_if(first + 15, first + 16, compare, projection); + iter_swap_if(first + 17, first + 20, compare, projection); + iter_swap_if(first + 18, first + 19, compare, projection); + iter_swap_if(first + 21, first + 23, compare, projection); + iter_swap_if(first + 24, first + 25, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 9, first + 10, compare, projection); + iter_swap_if(first + 11, first + 12, compare, projection); + iter_swap_if(first + 13, first + 15, compare, projection); + iter_swap_if(first + 14, first + 16, compare, projection); + iter_swap_if(first + 17, first + 18, compare, projection); + iter_swap_if(first + 19, first + 20, compare, projection); + iter_swap_if(first + 21, first + 22, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 12, first + 13, compare, projection); + iter_swap_if(first + 14, first + 15, compare, projection); + iter_swap_if(first + 16, first + 17, compare, projection); + iter_swap_if(first + 18, first + 19, compare, projection); + iter_swap_if(first + 20, first + 21, compare, projection); + iter_swap_if(first + 22, first + 23, compare, projection); } template @@ -198,20 +198,18 @@ namespace detail {0, 1}, {2, 3}, {4, 5}, {6, 7}, {8, 9}, {10, 11}, {12, 13}, {14, 15}, {16, 28}, {17, 26}, {18, 25}, {19, 23}, {21, 27}, {22, 24}, {0, 2}, {1, 3}, {4, 6}, {5, 7}, {8, 10}, {9, 11}, {12, 14}, {13, 15}, {17, 22}, {18, 19}, {20, 27}, {23, 25}, {24, 26}, {0, 4}, {1, 5}, {2, 6}, {3, 7}, {8, 12}, {9, 13}, {10, 14}, {11, 15}, {16, 20}, {17, 18}, {19, 22}, {23, 24}, {25, 26}, {27, 28}, - {0, 8}, {1, 9}, {2, 10}, {3, 11}, {4, 12}, {5, 13}, {6, 14}, {7, 15}, {20, 22}, {21, 25}, {24, 27}, {26, 28}, - {3, 20}, {5, 24}, {6, 21}, {7, 26}, {10, 23}, {11, 13}, {12, 19}, {14, 25}, {15, 28}, {22, 27}, - {2, 5}, {3, 10}, {6, 16}, {7, 14}, {11, 22}, {13, 27}, {15, 25}, {19, 23}, {20, 24}, - {2, 12}, {6, 17}, {11, 20}, {13, 24}, {14, 21}, {15, 26}, {16, 18}, - {0, 6}, {1, 17}, {5, 12}, {7, 20}, {8, 16}, {9, 18}, {13, 14}, {15, 21}, {25, 26}, - {1, 2}, {6, 8}, {15, 22}, {16, 17}, {18, 19}, {26, 27}, - {1, 6}, {2, 8}, {4, 17}, {9, 16}, {11, 18}, {19, 23}, {22, 25}, - {3, 4}, {5, 16}, {10, 17}, {13, 18}, {14, 19}, {23, 24}, {25, 26}, - {3, 6}, {4, 10}, {5, 9}, {7, 13}, {12, 16}, {14, 17}, {15, 23}, {18, 20}, {21, 24}, - {2, 3}, {4, 9}, {5, 6}, {7, 12}, {10, 11}, {13, 16}, {15, 18}, {19, 23}, {20, 21}, {24, 25}, - {1, 2}, {3, 4}, {7, 10}, {8, 9}, {11, 13}, {12, 14}, {16, 17}, {18, 19}, {21, 23}, {22, 24}, - {3, 5}, {4, 7}, {6, 8}, {9, 12}, {10, 11}, {13, 16}, {14, 15}, {17, 20}, {22, 23}, - {4, 6}, {7, 8}, {9, 10}, {11, 12}, {13, 14}, {15, 16}, {17, 18}, {19, 20}, {21, 22}, - {4, 5}, {6, 7}, {8, 9}, {10, 11}, {12, 13}, {14, 15}, {16, 17}, {18, 19}, {20, 21}, + {0, 8}, {1, 9}, {2, 10}, {3, 11}, {4, 12}, {5, 13}, {6, 14}, {7, 15}, {16, 18}, {20, 22}, {21, 25}, {24, 27}, {26, 28}, + {1, 8}, {2, 24}, {4, 19}, {5, 20}, {6, 21}, {7, 27}, {9, 18}, {10, 23}, {11, 26}, {13, 22}, {14, 25}, {15, 28}, {16, 17}, + {0, 6}, {2, 4}, {3, 24}, {5, 10}, {12, 19}, {13, 18}, {14, 21}, {15, 25}, {20, 23}, {26, 27}, + {0, 16}, {1, 6}, {3, 12}, {4, 8}, {5, 17}, {7, 24}, {14, 20}, {15, 26}, {18, 21}, {19, 23}, {25, 27}, + {1, 5}, {2, 16}, {3, 10}, {6, 9}, {7, 18}, {8, 17}, {11, 19}, {13, 14}, {15, 22}, {21, 23}, {25, 26}, + {1, 2}, {3, 5}, {4, 8}, {6, 16}, {7, 11}, {9, 17}, {10, 12}, {14, 20}, {15, 18}, {19, 24}, {22, 27}, + {4, 6}, {9, 16}, {10, 13}, {11, 19}, {12, 14}, {20, 21}, {22, 26}, {23, 24}, + {2, 4}, {3, 6}, {7, 16}, {8, 9}, {11, 17}, {15, 19}, {18, 23}, {24, 25}, + {3, 4}, {5, 9}, {7, 10}, {11, 13}, {12, 16}, {14, 17}, {15, 20}, {19, 21}, {22, 24}, + {5, 8}, {6, 7}, {9, 12}, {10, 11}, {13, 14}, {15, 16}, {17, 20}, {18, 19}, {21, 23}, {24, 25}, + {5, 6}, {7, 8}, {9, 10}, {11, 12}, {13, 15}, {14, 16}, {17, 18}, {19, 20}, {21, 22}, + {4, 5}, {6, 7}, {8, 9}, {10, 11}, {12, 13}, {14, 15}, {16, 17}, {18, 19}, {20, 21}, {22, 23}, }}; } }; diff --git a/include/cpp-sort/detail/sorting_network/sort3.h b/include/cpp-sort/detail/sorting_network/sort3.h index 085db9a7..193025e5 100644 --- a/include/cpp-sort/detail/sorting_network/sort3.h +++ b/include/cpp-sort/detail/sorting_network/sort3.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SORTING_NETWORK_SORT3_H_ @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<3u> + struct sorting_network_sorter_impl<3> { template< typename RandomAccessIterator, @@ -24,9 +24,9 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first, first + 2u, compare, projection); - iter_swap_if(first, first + 1u, compare, projection); + iter_swap_if(first, first + 2, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); } template diff --git a/include/cpp-sort/detail/sorting_network/sort30.h b/include/cpp-sort/detail/sorting_network/sort30.h index 4cf2257a..06568ef0 100644 --- a/include/cpp-sort/detail/sorting_network/sort30.h +++ b/include/cpp-sort/detail/sorting_network/sort30.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SORTING_NETWORK_SORT30_H_ @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<30u> + struct sorting_network_sorter_impl<30> { template< typename RandomAccessIterator, @@ -20,182 +20,73 @@ namespace detail Projection, RandomAccessIterator, Compare >> > - auto operator()(RandomAccessIterator first, RandomAccessIterator, + auto operator()(RandomAccessIterator first, RandomAccessIterator last, Compare compare={}, Projection projection={}) const -> void { - iter_swap_if(first, first + 2u, compare, projection); - iter_swap_if(first + 4u, first + 6u, compare, projection); - iter_swap_if(first + 8u, first + 10u, compare, projection); - iter_swap_if(first + 12u, first + 14u, compare, projection); - iter_swap_if(first + 16u, first + 18u, compare, projection); - iter_swap_if(first + 20u, first + 22u, compare, projection); - iter_swap_if(first + 24u, first + 26u, compare, projection); - iter_swap_if(first, first + 4u, compare, projection); - iter_swap_if(first + 8u, first + 12u, compare, projection); - iter_swap_if(first + 16u, first + 20u, compare, projection); - iter_swap_if(first + 24u, first + 28u, compare, projection); - iter_swap_if(first + 2u, first + 6u, compare, projection); - iter_swap_if(first + 10u, first + 14u, compare, projection); - iter_swap_if(first + 18u, first + 22u, compare, projection); - iter_swap_if(first, first + 8u, compare, projection); - iter_swap_if(first + 16u, first + 24u, compare, projection); - iter_swap_if(first + 2u, first + 10u, compare, projection); - iter_swap_if(first + 18u, first + 26u, compare, projection); - iter_swap_if(first + 4u, first + 12u, compare, projection); - iter_swap_if(first + 20u, first + 28u, compare, projection); - iter_swap_if(first + 6u, first + 14u, compare, projection); - iter_swap_if(first, first + 16u, compare, projection); - iter_swap_if(first + 2u, first + 18u, compare, projection); - iter_swap_if(first + 4u, first + 20u, compare, projection); - iter_swap_if(first + 6u, first + 22u, compare, projection); - iter_swap_if(first + 8u, first + 24u, compare, projection); - iter_swap_if(first + 10u, first + 26u, compare, projection); - iter_swap_if(first + 12u, first + 28u, compare, projection); - iter_swap_if(first + 10u, first + 20u, compare, projection); - iter_swap_if(first + 12u, first + 18u, compare, projection); - iter_swap_if(first + 6u, first + 24u, compare, projection); - iter_swap_if(first + 26u, first + 28u, compare, projection); - iter_swap_if(first + 14u, first + 22u, compare, projection); - iter_swap_if(first + 2u, first + 4u, compare, projection); - iter_swap_if(first + 8u, first + 16u, compare, projection); - iter_swap_if(first + 2u, first + 8u, compare, projection); - iter_swap_if(first + 14u, first + 26u, compare, projection); - iter_swap_if(first + 4u, first + 16u, compare, projection); - iter_swap_if(first + 22u, first + 28u, compare, projection); - iter_swap_if(first + 4u, first + 8u, compare, projection); - iter_swap_if(first + 10u, first + 12u, compare, projection); - iter_swap_if(first + 18u, first + 20u, compare, projection); - iter_swap_if(first + 22u, first + 26u, compare, projection); - iter_swap_if(first + 6u, first + 16u, compare, projection); - iter_swap_if(first + 14u, first + 24u, compare, projection); - iter_swap_if(first + 12u, first + 16u, compare, projection); - iter_swap_if(first + 20u, first + 24u, compare, projection); - iter_swap_if(first + 6u, first + 10u, compare, projection); - iter_swap_if(first + 14u, first + 18u, compare, projection); - iter_swap_if(first + 6u, first + 8u, compare, projection); - iter_swap_if(first + 10u, first + 12u, compare, projection); - iter_swap_if(first + 14u, first + 16u, compare, projection); - iter_swap_if(first + 18u, first + 20u, compare, projection); - iter_swap_if(first + 22u, first + 24u, compare, projection); - iter_swap_if(first + 12u, first + 14u, compare, projection); - iter_swap_if(first + 16u, first + 18u, compare, projection); - iter_swap_if(first + 1u, first + 3u, compare, projection); - iter_swap_if(first + 5u, first + 7u, compare, projection); - iter_swap_if(first + 9u, first + 11u, compare, projection); - iter_swap_if(first + 13u, first + 15u, compare, projection); - iter_swap_if(first + 17u, first + 19u, compare, projection); - iter_swap_if(first + 21u, first + 23u, compare, projection); - iter_swap_if(first + 25u, first + 27u, compare, projection); - iter_swap_if(first + 1u, first + 5u, compare, projection); - iter_swap_if(first + 9u, first + 13u, compare, projection); - iter_swap_if(first + 17u, first + 21u, compare, projection); - iter_swap_if(first + 25u, first + 29u, compare, projection); - iter_swap_if(first + 3u, first + 7u, compare, projection); - iter_swap_if(first + 11u, first + 15u, compare, projection); - iter_swap_if(first + 19u, first + 23u, compare, projection); - iter_swap_if(first + 1u, first + 9u, compare, projection); - iter_swap_if(first + 17u, first + 25u, compare, projection); - iter_swap_if(first + 3u, first + 11u, compare, projection); - iter_swap_if(first + 19u, first + 27u, compare, projection); - iter_swap_if(first + 5u, first + 13u, compare, projection); - iter_swap_if(first + 21u, first + 29u, compare, projection); - iter_swap_if(first + 7u, first + 15u, compare, projection); - iter_swap_if(first + 1u, first + 17u, compare, projection); - iter_swap_if(first + 3u, first + 19u, compare, projection); - iter_swap_if(first + 5u, first + 21u, compare, projection); - iter_swap_if(first + 7u, first + 23u, compare, projection); - iter_swap_if(first + 9u, first + 25u, compare, projection); - iter_swap_if(first + 11u, first + 27u, compare, projection); - iter_swap_if(first + 13u, first + 29u, compare, projection); - iter_swap_if(first + 11u, first + 21u, compare, projection); - iter_swap_if(first + 13u, first + 19u, compare, projection); - iter_swap_if(first + 7u, first + 25u, compare, projection); - iter_swap_if(first + 27u, first + 29u, compare, projection); - iter_swap_if(first + 15u, first + 23u, compare, projection); - iter_swap_if(first + 3u, first + 5u, compare, projection); - iter_swap_if(first + 9u, first + 17u, compare, projection); - iter_swap_if(first + 3u, first + 9u, compare, projection); - iter_swap_if(first + 15u, first + 27u, compare, projection); - iter_swap_if(first + 5u, first + 17u, compare, projection); - iter_swap_if(first + 23u, first + 29u, compare, projection); - iter_swap_if(first + 5u, first + 9u, compare, projection); - iter_swap_if(first + 11u, first + 13u, compare, projection); - iter_swap_if(first + 19u, first + 21u, compare, projection); - iter_swap_if(first + 23u, first + 27u, compare, projection); - iter_swap_if(first + 7u, first + 17u, compare, projection); - iter_swap_if(first + 15u, first + 25u, compare, projection); - iter_swap_if(first + 13u, first + 17u, compare, projection); - iter_swap_if(first + 21u, first + 25u, compare, projection); - iter_swap_if(first + 7u, first + 11u, compare, projection); - iter_swap_if(first + 15u, first + 19u, compare, projection); - iter_swap_if(first + 7u, first + 9u, compare, projection); - iter_swap_if(first + 11u, first + 13u, compare, projection); - iter_swap_if(first + 15u, first + 17u, compare, projection); - iter_swap_if(first + 19u, first + 21u, compare, projection); - iter_swap_if(first + 23u, first + 25u, compare, projection); - iter_swap_if(first + 13u, first + 15u, compare, projection); - iter_swap_if(first + 17u, first + 19u, compare, projection); - iter_swap_if(first, first + 1u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 8u, first + 9u, compare, projection); - iter_swap_if(first + 10u, first + 11u, compare, projection); - iter_swap_if(first + 12u, first + 13u, compare, projection); - iter_swap_if(first + 14u, first + 15u, compare, projection); - iter_swap_if(first + 16u, first + 17u, compare, projection); - iter_swap_if(first + 18u, first + 19u, compare, projection); - iter_swap_if(first + 20u, first + 21u, compare, projection); - iter_swap_if(first + 22u, first + 23u, compare, projection); - iter_swap_if(first + 24u, first + 25u, compare, projection); - iter_swap_if(first + 26u, first + 27u, compare, projection); - iter_swap_if(first + 28u, first + 29u, compare, projection); - iter_swap_if(first + 1u, first + 16u, compare, projection); - iter_swap_if(first + 3u, first + 18u, compare, projection); - iter_swap_if(first + 5u, first + 20u, compare, projection); - iter_swap_if(first + 7u, first + 22u, compare, projection); - iter_swap_if(first + 9u, first + 24u, compare, projection); - iter_swap_if(first + 11u, first + 26u, compare, projection); - iter_swap_if(first + 13u, first + 28u, compare, projection); - iter_swap_if(first + 1u, first + 8u, compare, projection); - iter_swap_if(first + 3u, first + 10u, compare, projection); - iter_swap_if(first + 5u, first + 12u, compare, projection); - iter_swap_if(first + 7u, first + 14u, compare, projection); - iter_swap_if(first + 9u, first + 16u, compare, projection); - iter_swap_if(first + 11u, first + 18u, compare, projection); - iter_swap_if(first + 13u, first + 20u, compare, projection); - iter_swap_if(first + 15u, first + 22u, compare, projection); - iter_swap_if(first + 17u, first + 24u, compare, projection); - iter_swap_if(first + 19u, first + 26u, compare, projection); - iter_swap_if(first + 21u, first + 28u, compare, projection); - iter_swap_if(first + 1u, first + 4u, compare, projection); - iter_swap_if(first + 3u, first + 6u, compare, projection); - iter_swap_if(first + 5u, first + 8u, compare, projection); - iter_swap_if(first + 7u, first + 10u, compare, projection); - iter_swap_if(first + 9u, first + 12u, compare, projection); - iter_swap_if(first + 11u, first + 14u, compare, projection); - iter_swap_if(first + 13u, first + 16u, compare, projection); - iter_swap_if(first + 15u, first + 18u, compare, projection); - iter_swap_if(first + 17u, first + 20u, compare, projection); - iter_swap_if(first + 19u, first + 22u, compare, projection); - iter_swap_if(first + 21u, first + 24u, compare, projection); - iter_swap_if(first + 23u, first + 26u, compare, projection); - iter_swap_if(first + 25u, first + 28u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); - iter_swap_if(first + 9u, first + 10u, compare, projection); - iter_swap_if(first + 11u, first + 12u, compare, projection); - iter_swap_if(first + 13u, first + 14u, compare, projection); - iter_swap_if(first + 15u, first + 16u, compare, projection); - iter_swap_if(first + 17u, first + 18u, compare, projection); - iter_swap_if(first + 19u, first + 20u, compare, projection); - iter_swap_if(first + 21u, first + 22u, compare, projection); - iter_swap_if(first + 23u, first + 24u, compare, projection); - iter_swap_if(first + 25u, first + 26u, compare, projection); - iter_swap_if(first + 27u, first + 28u, compare, projection); + sorting_network_sorter<15>{}(first, first + 15, compare, projection); + sorting_network_sorter<15>{}(first + 15, last, compare, projection); + + iter_swap_if(first + 14, first + 29, compare, projection); + iter_swap_if(first, first + 15, compare, projection); + iter_swap_if(first + 13, first + 28, compare, projection); + iter_swap_if(first + 1, first + 16, compare, projection); + iter_swap_if(first + 12, first + 27, compare, projection); + iter_swap_if(first + 2, first + 17, compare, projection); + iter_swap_if(first + 3, first + 18, compare, projection); + iter_swap_if(first + 4, first + 19, compare, projection); + iter_swap_if(first + 9, first + 24, compare, projection); + iter_swap_if(first + 10, first + 25, compare, projection); + iter_swap_if(first + 11, first + 26, compare, projection); + iter_swap_if(first + 5, first + 20, compare, projection); + iter_swap_if(first + 6, first + 21, compare, projection); + iter_swap_if(first + 7, first + 22, compare, projection); + iter_swap_if(first + 8, first + 23, compare, projection); + iter_swap_if(first + 9, first + 16, compare, projection); + iter_swap_if(first + 10, first + 17, compare, projection); + iter_swap_if(first + 11, first + 18, compare, projection); + iter_swap_if(first + 12, first + 19, compare, projection); + iter_swap_if(first + 5, first + 9, compare, projection); + iter_swap_if(first + 6, first + 10, compare, projection); + iter_swap_if(first + 7, first + 11, compare, projection); + iter_swap_if(first + 8, first + 15, compare, projection); + iter_swap_if(first + 13, first + 20, compare, projection); + iter_swap_if(first + 14, first + 21, compare, projection); + iter_swap_if(first + 18, first + 22, compare, projection); + iter_swap_if(first + 19, first + 23, compare, projection); + iter_swap_if(first + 3, first + 5, compare, projection); + iter_swap_if(first + 4, first + 8, compare, projection); + iter_swap_if(first + 7, first + 9, compare, projection); + iter_swap_if(first + 12, first + 15, compare, projection); + iter_swap_if(first + 13, first + 16, compare, projection); + iter_swap_if(first + 14, first + 17, compare, projection); + iter_swap_if(first + 20, first + 24, compare, projection); + iter_swap_if(first + 21, first + 25, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 6, first + 8, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 11, first + 13, compare, projection); + iter_swap_if(first + 14, first + 15, compare, projection); + iter_swap_if(first + 16, first + 18, compare, projection); + iter_swap_if(first + 17, first + 19, compare, projection); + iter_swap_if(first + 20, first + 22, compare, projection); + iter_swap_if(first + 21, first + 23, compare, projection); + iter_swap_if(first + 24, first + 26, compare, projection); + iter_swap_if(first + 25, first + 27, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 9, first + 10, compare, projection); + iter_swap_if(first + 11, first + 12, compare, projection); + iter_swap_if(first + 13, first + 14, compare, projection); + iter_swap_if(first + 15, first + 16, compare, projection); + iter_swap_if(first + 17, first + 18, compare, projection); + iter_swap_if(first + 19, first + 20, compare, projection); + iter_swap_if(first + 21, first + 22, compare, projection); + iter_swap_if(first + 23, first + 24, compare, projection); + iter_swap_if(first + 25, first + 26, compare, projection); + iter_swap_if(first + 27, first + 28, compare, projection); } template diff --git a/include/cpp-sort/detail/sorting_network/sort31.h b/include/cpp-sort/detail/sorting_network/sort31.h index 6d089737..ae0abae7 100644 --- a/include/cpp-sort/detail/sorting_network/sort31.h +++ b/include/cpp-sort/detail/sorting_network/sort31.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SORTING_NETWORK_SORT31_H_ @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<31u> + struct sorting_network_sorter_impl<31> { template< typename RandomAccessIterator, @@ -24,73 +24,186 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - sorting_network_sorter<16u>{}(first, first+16u, compare, projection); - sorting_network_sorter<15u>{}(first+16u, first+31u, compare, projection); - - iter_swap_if(first, first + 16u, compare, projection); - iter_swap_if(first + 8u, first + 24u, compare, projection); - iter_swap_if(first + 8u, first + 16u, compare, projection); - iter_swap_if(first + 4u, first + 20u, compare, projection); - iter_swap_if(first + 12u, first + 28u, compare, projection); - iter_swap_if(first + 12u, first + 20u, compare, projection); - iter_swap_if(first + 4u, first + 8u, compare, projection); - iter_swap_if(first + 12u, first + 16u, compare, projection); - iter_swap_if(first + 20u, first + 24u, compare, projection); - iter_swap_if(first + 2u, first + 18u, compare, projection); - iter_swap_if(first + 10u, first + 26u, compare, projection); - iter_swap_if(first + 10u, first + 18u, compare, projection); - iter_swap_if(first + 6u, first + 22u, compare, projection); - iter_swap_if(first + 14u, first + 30u, compare, projection); - iter_swap_if(first + 14u, first + 22u, compare, projection); - iter_swap_if(first + 6u, first + 10u, compare, projection); - iter_swap_if(first + 14u, first + 18u, compare, projection); - iter_swap_if(first + 22u, first + 26u, compare, projection); - iter_swap_if(first + 2u, first + 4u, compare, projection); - iter_swap_if(first + 6u, first + 8u, compare, projection); - iter_swap_if(first + 10u, first + 12u, compare, projection); - iter_swap_if(first + 14u, first + 16u, compare, projection); - iter_swap_if(first + 18u, first + 20u, compare, projection); - iter_swap_if(first + 22u, first + 24u, compare, projection); - iter_swap_if(first + 26u, first + 28u, compare, projection); - iter_swap_if(first + 1u, first + 17u, compare, projection); - iter_swap_if(first + 9u, first + 25u, compare, projection); - iter_swap_if(first + 9u, first + 17u, compare, projection); - iter_swap_if(first + 5u, first + 21u, compare, projection); - iter_swap_if(first + 13u, first + 29u, compare, projection); - iter_swap_if(first + 13u, first + 21u, compare, projection); - iter_swap_if(first + 5u, first + 9u, compare, projection); - iter_swap_if(first + 13u, first + 17u, compare, projection); - iter_swap_if(first + 21u, first + 25u, compare, projection); - iter_swap_if(first + 3u, first + 19u, compare, projection); - iter_swap_if(first + 11u, first + 27u, compare, projection); - iter_swap_if(first + 11u, first + 19u, compare, projection); - iter_swap_if(first + 7u, first + 23u, compare, projection); - iter_swap_if(first + 15u, first + 23u, compare, projection); - iter_swap_if(first + 7u, first + 11u, compare, projection); - iter_swap_if(first + 15u, first + 19u, compare, projection); - iter_swap_if(first + 23u, first + 27u, compare, projection); - iter_swap_if(first + 3u, first + 5u, compare, projection); - iter_swap_if(first + 7u, first + 9u, compare, projection); - iter_swap_if(first + 11u, first + 13u, compare, projection); - iter_swap_if(first + 15u, first + 17u, compare, projection); - iter_swap_if(first + 19u, first + 21u, compare, projection); - iter_swap_if(first + 23u, first + 25u, compare, projection); - iter_swap_if(first + 27u, first + 29u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); - iter_swap_if(first + 9u, first + 10u, compare, projection); - iter_swap_if(first + 11u, first + 12u, compare, projection); - iter_swap_if(first + 13u, first + 14u, compare, projection); - iter_swap_if(first + 15u, first + 16u, compare, projection); - iter_swap_if(first + 17u, first + 18u, compare, projection); - iter_swap_if(first + 19u, first + 20u, compare, projection); - iter_swap_if(first + 21u, first + 22u, compare, projection); - iter_swap_if(first + 23u, first + 24u, compare, projection); - iter_swap_if(first + 25u, first + 26u, compare, projection); - iter_swap_if(first + 27u, first + 28u, compare, projection); - iter_swap_if(first + 29u, first + 30u, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 12, first + 13, compare, projection); + iter_swap_if(first + 14, first + 15, compare, projection); + iter_swap_if(first + 16, first + 17, compare, projection); + iter_swap_if(first + 18, first + 19, compare, projection); + iter_swap_if(first + 20, first + 21, compare, projection); + iter_swap_if(first + 22, first + 23, compare, projection); + iter_swap_if(first + 24, first + 25, compare, projection); + iter_swap_if(first + 26, first + 27, compare, projection); + iter_swap_if(first + 28, first + 29, compare, projection); + iter_swap_if(first, first + 2, compare, projection); + iter_swap_if(first + 1, first + 3, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first + 5, first + 7, compare, projection); + iter_swap_if(first + 8, first + 10, compare, projection); + iter_swap_if(first + 9, first + 11, compare, projection); + iter_swap_if(first + 12, first + 14, compare, projection); + iter_swap_if(first + 13, first + 15, compare, projection); + iter_swap_if(first + 16, first + 18, compare, projection); + iter_swap_if(first + 17, first + 19, compare, projection); + iter_swap_if(first + 20, first + 22, compare, projection); + iter_swap_if(first + 21, first + 23, compare, projection); + iter_swap_if(first + 24, first + 26, compare, projection); + iter_swap_if(first + 25, first + 27, compare, projection); + iter_swap_if(first + 28, first + 30, compare, projection); + iter_swap_if(first, first + 4, compare, projection); + iter_swap_if(first + 1, first + 5, compare, projection); + iter_swap_if(first + 2, first + 6, compare, projection); + iter_swap_if(first + 3, first + 7, compare, projection); + iter_swap_if(first + 8, first + 12, compare, projection); + iter_swap_if(first + 9, first + 13, compare, projection); + iter_swap_if(first + 10, first + 14, compare, projection); + iter_swap_if(first + 11, first + 15, compare, projection); + iter_swap_if(first + 16, first + 20, compare, projection); + iter_swap_if(first + 17, first + 21, compare, projection); + iter_swap_if(first + 18, first + 22, compare, projection); + iter_swap_if(first + 19, first + 23, compare, projection); + iter_swap_if(first + 24, first + 28, compare, projection); + iter_swap_if(first + 25, first + 29, compare, projection); + iter_swap_if(first + 26, first + 30, compare, projection); + iter_swap_if(first, first + 8, compare, projection); + iter_swap_if(first + 1, first + 9, compare, projection); + iter_swap_if(first + 2, first + 10, compare, projection); + iter_swap_if(first + 3, first + 11, compare, projection); + iter_swap_if(first + 4, first + 12, compare, projection); + iter_swap_if(first + 5, first + 13, compare, projection); + iter_swap_if(first + 6, first + 14, compare, projection); + iter_swap_if(first + 7, first + 15, compare, projection); + iter_swap_if(first + 16, first + 24, compare, projection); + iter_swap_if(first + 17, first + 25, compare, projection); + iter_swap_if(first + 18, first + 26, compare, projection); + iter_swap_if(first + 19, first + 27, compare, projection); + iter_swap_if(first + 20, first + 28, compare, projection); + iter_swap_if(first + 21, first + 29, compare, projection); + iter_swap_if(first + 22, first + 30, compare, projection); + iter_swap_if(first, first + 16, compare, projection); + iter_swap_if(first + 1, first + 8, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 3, first + 12, compare, projection); + iter_swap_if(first + 5, first + 10, compare, projection); + iter_swap_if(first + 6, first + 9, compare, projection); + iter_swap_if(first + 7, first + 14, compare, projection); + iter_swap_if(first + 11, first + 13, compare, projection); + iter_swap_if(first + 17, first + 24, compare, projection); + iter_swap_if(first + 18, first + 20, compare, projection); + iter_swap_if(first + 19, first + 28, compare, projection); + iter_swap_if(first + 21, first + 26, compare, projection); + iter_swap_if(first + 22, first + 25, compare, projection); + iter_swap_if(first + 23, first + 30, compare, projection); + iter_swap_if(first + 27, first + 29, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 3, first + 5, compare, projection); + iter_swap_if(first + 4, first + 8, compare, projection); + iter_swap_if(first + 6, first + 22, compare, projection); + iter_swap_if(first + 7, first + 11, compare, projection); + iter_swap_if(first + 9, first + 25, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 13, first + 14, compare, projection); + iter_swap_if(first + 17, first + 18, compare, projection); + iter_swap_if(first + 19, first + 21, compare, projection); + iter_swap_if(first + 20, first + 24, compare, projection); + iter_swap_if(first + 23, first + 27, compare, projection); + iter_swap_if(first + 26, first + 28, compare, projection); + iter_swap_if(first + 29, first + 30, compare, projection); + iter_swap_if(first + 1, first + 17, compare, projection); + iter_swap_if(first + 2, first + 18, compare, projection); + iter_swap_if(first + 3, first + 19, compare, projection); + iter_swap_if(first + 4, first + 20, compare, projection); + iter_swap_if(first + 5, first + 10, compare, projection); + iter_swap_if(first + 7, first + 23, compare, projection); + iter_swap_if(first + 8, first + 24, compare, projection); + iter_swap_if(first + 11, first + 27, compare, projection); + iter_swap_if(first + 12, first + 28, compare, projection); + iter_swap_if(first + 13, first + 29, compare, projection); + iter_swap_if(first + 14, first + 30, compare, projection); + iter_swap_if(first + 21, first + 26, compare, projection); + iter_swap_if(first + 3, first + 17, compare, projection); + iter_swap_if(first + 4, first + 16, compare, projection); + iter_swap_if(first + 5, first + 21, compare, projection); + iter_swap_if(first + 6, first + 18, compare, projection); + iter_swap_if(first + 7, first + 9, compare, projection); + iter_swap_if(first + 8, first + 20, compare, projection); + iter_swap_if(first + 10, first + 26, compare, projection); + iter_swap_if(first + 11, first + 23, compare, projection); + iter_swap_if(first + 13, first + 25, compare, projection); + iter_swap_if(first + 14, first + 28, compare, projection); + iter_swap_if(first + 15, first + 27, compare, projection); + iter_swap_if(first + 22, first + 24, compare, projection); + iter_swap_if(first + 1, first + 4, compare, projection); + iter_swap_if(first + 3, first + 8, compare, projection); + iter_swap_if(first + 5, first + 16, compare, projection); + iter_swap_if(first + 7, first + 17, compare, projection); + iter_swap_if(first + 9, first + 21, compare, projection); + iter_swap_if(first + 10, first + 22, compare, projection); + iter_swap_if(first + 11, first + 19, compare, projection); + iter_swap_if(first + 12, first + 20, compare, projection); + iter_swap_if(first + 14, first + 24, compare, projection); + iter_swap_if(first + 15, first + 26, compare, projection); + iter_swap_if(first + 23, first + 28, compare, projection); + iter_swap_if(first + 27, first + 30, compare, projection); + iter_swap_if(first + 2, first + 5, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 9, first + 18, compare, projection); + iter_swap_if(first + 11, first + 17, compare, projection); + iter_swap_if(first + 12, first + 16, compare, projection); + iter_swap_if(first + 13, first + 22, compare, projection); + iter_swap_if(first + 14, first + 20, compare, projection); + iter_swap_if(first + 15, first + 19, compare, projection); + iter_swap_if(first + 23, first + 24, compare, projection); + iter_swap_if(first + 26, first + 29, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 6, first + 12, compare, projection); + iter_swap_if(first + 9, first + 16, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 13, first + 17, compare, projection); + iter_swap_if(first + 14, first + 18, compare, projection); + iter_swap_if(first + 15, first + 22, compare, projection); + iter_swap_if(first + 19, first + 25, compare, projection); + iter_swap_if(first + 20, first + 21, compare, projection); + iter_swap_if(first + 27, first + 29, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 8, first + 12, compare, projection); + iter_swap_if(first + 9, first + 10, compare, projection); + iter_swap_if(first + 11, first + 13, compare, projection); + iter_swap_if(first + 14, first + 16, compare, projection); + iter_swap_if(first + 15, first + 17, compare, projection); + iter_swap_if(first + 18, first + 20, compare, projection); + iter_swap_if(first + 19, first + 23, compare, projection); + iter_swap_if(first + 21, first + 22, compare, projection); + iter_swap_if(first + 25, first + 26, compare, projection); + iter_swap_if(first + 3, first + 5, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 11, first + 14, compare, projection); + iter_swap_if(first + 13, first + 16, compare, projection); + iter_swap_if(first + 15, first + 18, compare, projection); + iter_swap_if(first + 17, first + 20, compare, projection); + iter_swap_if(first + 19, first + 21, compare, projection); + iter_swap_if(first + 22, first + 23, compare, projection); + iter_swap_if(first + 24, first + 25, compare, projection); + iter_swap_if(first + 26, first + 28, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 9, first + 10, compare, projection); + iter_swap_if(first + 11, first + 12, compare, projection); + iter_swap_if(first + 13, first + 14, compare, projection); + iter_swap_if(first + 15, first + 16, compare, projection); + iter_swap_if(first + 17, first + 18, compare, projection); + iter_swap_if(first + 19, first + 20, compare, projection); + iter_swap_if(first + 21, first + 22, compare, projection); + iter_swap_if(first + 23, first + 24, compare, projection); + iter_swap_if(first + 25, first + 26, compare, projection); + iter_swap_if(first + 27, first + 28, compare, projection); } template diff --git a/include/cpp-sort/detail/sorting_network/sort32.h b/include/cpp-sort/detail/sorting_network/sort32.h index 4bb59619..165fd731 100644 --- a/include/cpp-sort/detail/sorting_network/sort32.h +++ b/include/cpp-sort/detail/sorting_network/sort32.h @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<32u> + struct sorting_network_sorter_impl<32> { template< typename RandomAccessIterator, @@ -24,74 +24,191 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - sorting_network_sorter<16u>{}(first, first+16u, compare, projection); - sorting_network_sorter<16u>{}(first+16u, first+32u, compare, projection); - - iter_swap_if(first, first + 16u, compare, projection); - iter_swap_if(first + 8u, first + 24u, compare, projection); - iter_swap_if(first + 8u, first + 16u, compare, projection); - iter_swap_if(first + 4u, first + 20u, compare, projection); - iter_swap_if(first + 12u, first + 28u, compare, projection); - iter_swap_if(first + 12u, first + 20u, compare, projection); - iter_swap_if(first + 4u, first + 8u, compare, projection); - iter_swap_if(first + 12u, first + 16u, compare, projection); - iter_swap_if(first + 20u, first + 24u, compare, projection); - iter_swap_if(first + 2u, first + 18u, compare, projection); - iter_swap_if(first + 10u, first + 26u, compare, projection); - iter_swap_if(first + 10u, first + 18u, compare, projection); - iter_swap_if(first + 6u, first + 22u, compare, projection); - iter_swap_if(first + 14u, first + 30u, compare, projection); - iter_swap_if(first + 14u, first + 22u, compare, projection); - iter_swap_if(first + 6u, first + 10u, compare, projection); - iter_swap_if(first + 14u, first + 18u, compare, projection); - iter_swap_if(first + 22u, first + 26u, compare, projection); - iter_swap_if(first + 2u, first + 4u, compare, projection); - iter_swap_if(first + 6u, first + 8u, compare, projection); - iter_swap_if(first + 10u, first + 12u, compare, projection); - iter_swap_if(first + 14u, first + 16u, compare, projection); - iter_swap_if(first + 18u, first + 20u, compare, projection); - iter_swap_if(first + 22u, first + 24u, compare, projection); - iter_swap_if(first + 26u, first + 28u, compare, projection); - iter_swap_if(first + 1u, first + 17u, compare, projection); - iter_swap_if(first + 9u, first + 25u, compare, projection); - iter_swap_if(first + 9u, first + 17u, compare, projection); - iter_swap_if(first + 5u, first + 21u, compare, projection); - iter_swap_if(first + 13u, first + 29u, compare, projection); - iter_swap_if(first + 13u, first + 21u, compare, projection); - iter_swap_if(first + 5u, first + 9u, compare, projection); - iter_swap_if(first + 13u, first + 17u, compare, projection); - iter_swap_if(first + 21u, first + 25u, compare, projection); - iter_swap_if(first + 3u, first + 19u, compare, projection); - iter_swap_if(first + 11u, first + 27u, compare, projection); - iter_swap_if(first + 11u, first + 19u, compare, projection); - iter_swap_if(first + 7u, first + 23u, compare, projection); - iter_swap_if(first + 15u, first + 31u, compare, projection); - iter_swap_if(first + 15u, first + 23u, compare, projection); - iter_swap_if(first + 7u, first + 11u, compare, projection); - iter_swap_if(first + 15u, first + 19u, compare, projection); - iter_swap_if(first + 23u, first + 27u, compare, projection); - iter_swap_if(first + 3u, first + 5u, compare, projection); - iter_swap_if(first + 7u, first + 9u, compare, projection); - iter_swap_if(first + 11u, first + 13u, compare, projection); - iter_swap_if(first + 15u, first + 17u, compare, projection); - iter_swap_if(first + 19u, first + 21u, compare, projection); - iter_swap_if(first + 23u, first + 25u, compare, projection); - iter_swap_if(first + 27u, first + 29u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); - iter_swap_if(first + 9u, first + 10u, compare, projection); - iter_swap_if(first + 11u, first + 12u, compare, projection); - iter_swap_if(first + 13u, first + 14u, compare, projection); - iter_swap_if(first + 15u, first + 16u, compare, projection); - iter_swap_if(first + 17u, first + 18u, compare, projection); - iter_swap_if(first + 19u, first + 20u, compare, projection); - iter_swap_if(first + 21u, first + 22u, compare, projection); - iter_swap_if(first + 23u, first + 24u, compare, projection); - iter_swap_if(first + 25u, first + 26u, compare, projection); - iter_swap_if(first + 27u, first + 28u, compare, projection); - iter_swap_if(first + 29u, first + 30u, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 12, first + 13, compare, projection); + iter_swap_if(first + 14, first + 15, compare, projection); + iter_swap_if(first + 16, first + 17, compare, projection); + iter_swap_if(first + 18, first + 19, compare, projection); + iter_swap_if(first + 20, first + 21, compare, projection); + iter_swap_if(first + 22, first + 23, compare, projection); + iter_swap_if(first + 24, first + 25, compare, projection); + iter_swap_if(first + 26, first + 27, compare, projection); + iter_swap_if(first + 28, first + 29, compare, projection); + iter_swap_if(first + 30, first + 31, compare, projection); + iter_swap_if(first, first + 2, compare, projection); + iter_swap_if(first + 1, first + 3, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first + 5, first + 7, compare, projection); + iter_swap_if(first + 8, first + 10, compare, projection); + iter_swap_if(first + 9, first + 11, compare, projection); + iter_swap_if(first + 12, first + 14, compare, projection); + iter_swap_if(first + 13, first + 15, compare, projection); + iter_swap_if(first + 16, first + 18, compare, projection); + iter_swap_if(first + 17, first + 19, compare, projection); + iter_swap_if(first + 20, first + 22, compare, projection); + iter_swap_if(first + 21, first + 23, compare, projection); + iter_swap_if(first + 24, first + 26, compare, projection); + iter_swap_if(first + 25, first + 27, compare, projection); + iter_swap_if(first + 28, first + 30, compare, projection); + iter_swap_if(first + 29, first + 31, compare, projection); + iter_swap_if(first, first + 4, compare, projection); + iter_swap_if(first + 1, first + 5, compare, projection); + iter_swap_if(first + 2, first + 6, compare, projection); + iter_swap_if(first + 3, first + 7, compare, projection); + iter_swap_if(first + 8, first + 12, compare, projection); + iter_swap_if(first + 9, first + 13, compare, projection); + iter_swap_if(first + 10, first + 14, compare, projection); + iter_swap_if(first + 11, first + 15, compare, projection); + iter_swap_if(first + 16, first + 20, compare, projection); + iter_swap_if(first + 17, first + 21, compare, projection); + iter_swap_if(first + 18, first + 22, compare, projection); + iter_swap_if(first + 19, first + 23, compare, projection); + iter_swap_if(first + 24, first + 28, compare, projection); + iter_swap_if(first + 25, first + 29, compare, projection); + iter_swap_if(first + 26, first + 30, compare, projection); + iter_swap_if(first + 27, first + 31, compare, projection); + iter_swap_if(first, first + 8, compare, projection); + iter_swap_if(first + 1, first + 9, compare, projection); + iter_swap_if(first + 2, first + 10, compare, projection); + iter_swap_if(first + 3, first + 11, compare, projection); + iter_swap_if(first + 4, first + 12, compare, projection); + iter_swap_if(first + 5, first + 13, compare, projection); + iter_swap_if(first + 6, first + 14, compare, projection); + iter_swap_if(first + 7, first + 15, compare, projection); + iter_swap_if(first + 16, first + 24, compare, projection); + iter_swap_if(first + 17, first + 25, compare, projection); + iter_swap_if(first + 18, first + 26, compare, projection); + iter_swap_if(first + 19, first + 27, compare, projection); + iter_swap_if(first + 20, first + 28, compare, projection); + iter_swap_if(first + 21, first + 29, compare, projection); + iter_swap_if(first + 22, first + 30, compare, projection); + iter_swap_if(first + 23, first + 31, compare, projection); + iter_swap_if(first, first + 16, compare, projection); + iter_swap_if(first + 1, first + 8, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 3, first + 12, compare, projection); + iter_swap_if(first + 5, first + 10, compare, projection); + iter_swap_if(first + 6, first + 9, compare, projection); + iter_swap_if(first + 7, first + 14, compare, projection); + iter_swap_if(first + 11, first + 13, compare, projection); + iter_swap_if(first + 15, first + 31, compare, projection); + iter_swap_if(first + 17, first + 24, compare, projection); + iter_swap_if(first + 18, first + 20, compare, projection); + iter_swap_if(first + 19, first + 28, compare, projection); + iter_swap_if(first + 21, first + 26, compare, projection); + iter_swap_if(first + 22, first + 25, compare, projection); + iter_swap_if(first + 23, first + 30, compare, projection); + iter_swap_if(first + 27, first + 29, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 3, first + 5, compare, projection); + iter_swap_if(first + 4, first + 8, compare, projection); + iter_swap_if(first + 6, first + 22, compare, projection); + iter_swap_if(first + 7, first + 11, compare, projection); + iter_swap_if(first + 9, first + 25, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 13, first + 14, compare, projection); + iter_swap_if(first + 17, first + 18, compare, projection); + iter_swap_if(first + 19, first + 21, compare, projection); + iter_swap_if(first + 20, first + 24, compare, projection); + iter_swap_if(first + 23, first + 27, compare, projection); + iter_swap_if(first + 26, first + 28, compare, projection); + iter_swap_if(first + 29, first + 30, compare, projection); + iter_swap_if(first + 1, first + 17, compare, projection); + iter_swap_if(first + 2, first + 18, compare, projection); + iter_swap_if(first + 3, first + 19, compare, projection); + iter_swap_if(first + 4, first + 20, compare, projection); + iter_swap_if(first + 5, first + 10, compare, projection); + iter_swap_if(first + 7, first + 23, compare, projection); + iter_swap_if(first + 8, first + 24, compare, projection); + iter_swap_if(first + 11, first + 27, compare, projection); + iter_swap_if(first + 12, first + 28, compare, projection); + iter_swap_if(first + 13, first + 29, compare, projection); + iter_swap_if(first + 14, first + 30, compare, projection); + iter_swap_if(first + 21, first + 26, compare, projection); + iter_swap_if(first + 3, first + 17, compare, projection); + iter_swap_if(first + 4, first + 16, compare, projection); + iter_swap_if(first + 5, first + 21, compare, projection); + iter_swap_if(first + 6, first + 18, compare, projection); + iter_swap_if(first + 7, first + 9, compare, projection); + iter_swap_if(first + 8, first + 20, compare, projection); + iter_swap_if(first + 10, first + 26, compare, projection); + iter_swap_if(first + 11, first + 23, compare, projection); + iter_swap_if(first + 13, first + 25, compare, projection); + iter_swap_if(first + 14, first + 28, compare, projection); + iter_swap_if(first + 15, first + 27, compare, projection); + iter_swap_if(first + 22, first + 24, compare, projection); + iter_swap_if(first + 1, first + 4, compare, projection); + iter_swap_if(first + 3, first + 8, compare, projection); + iter_swap_if(first + 5, first + 16, compare, projection); + iter_swap_if(first + 7, first + 17, compare, projection); + iter_swap_if(first + 9, first + 21, compare, projection); + iter_swap_if(first + 10, first + 22, compare, projection); + iter_swap_if(first + 11, first + 19, compare, projection); + iter_swap_if(first + 12, first + 20, compare, projection); + iter_swap_if(first + 14, first + 24, compare, projection); + iter_swap_if(first + 15, first + 26, compare, projection); + iter_swap_if(first + 23, first + 28, compare, projection); + iter_swap_if(first + 27, first + 30, compare, projection); + iter_swap_if(first + 2, first + 5, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 9, first + 18, compare, projection); + iter_swap_if(first + 11, first + 17, compare, projection); + iter_swap_if(first + 12, first + 16, compare, projection); + iter_swap_if(first + 13, first + 22, compare, projection); + iter_swap_if(first + 14, first + 20, compare, projection); + iter_swap_if(first + 15, first + 19, compare, projection); + iter_swap_if(first + 23, first + 24, compare, projection); + iter_swap_if(first + 26, first + 29, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 6, first + 12, compare, projection); + iter_swap_if(first + 9, first + 16, compare, projection); + iter_swap_if(first + 10, first + 11, compare, projection); + iter_swap_if(first + 13, first + 17, compare, projection); + iter_swap_if(first + 14, first + 18, compare, projection); + iter_swap_if(first + 15, first + 22, compare, projection); + iter_swap_if(first + 19, first + 25, compare, projection); + iter_swap_if(first + 20, first + 21, compare, projection); + iter_swap_if(first + 27, first + 29, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 8, first + 12, compare, projection); + iter_swap_if(first + 9, first + 10, compare, projection); + iter_swap_if(first + 11, first + 13, compare, projection); + iter_swap_if(first + 14, first + 16, compare, projection); + iter_swap_if(first + 15, first + 17, compare, projection); + iter_swap_if(first + 18, first + 20, compare, projection); + iter_swap_if(first + 19, first + 23, compare, projection); + iter_swap_if(first + 21, first + 22, compare, projection); + iter_swap_if(first + 25, first + 26, compare, projection); + iter_swap_if(first + 3, first + 5, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 8, first + 9, compare, projection); + iter_swap_if(first + 10, first + 12, compare, projection); + iter_swap_if(first + 11, first + 14, compare, projection); + iter_swap_if(first + 13, first + 16, compare, projection); + iter_swap_if(first + 15, first + 18, compare, projection); + iter_swap_if(first + 17, first + 20, compare, projection); + iter_swap_if(first + 19, first + 21, compare, projection); + iter_swap_if(first + 22, first + 23, compare, projection); + iter_swap_if(first + 24, first + 25, compare, projection); + iter_swap_if(first + 26, first + 28, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 9, first + 10, compare, projection); + iter_swap_if(first + 11, first + 12, compare, projection); + iter_swap_if(first + 13, first + 14, compare, projection); + iter_swap_if(first + 15, first + 16, compare, projection); + iter_swap_if(first + 17, first + 18, compare, projection); + iter_swap_if(first + 19, first + 20, compare, projection); + iter_swap_if(first + 21, first + 22, compare, projection); + iter_swap_if(first + 23, first + 24, compare, projection); + iter_swap_if(first + 25, first + 26, compare, projection); + iter_swap_if(first + 27, first + 28, compare, projection); } template diff --git a/include/cpp-sort/detail/sorting_network/sort4.h b/include/cpp-sort/detail/sorting_network/sort4.h index b91bc162..1d446589 100644 --- a/include/cpp-sort/detail/sorting_network/sort4.h +++ b/include/cpp-sort/detail/sorting_network/sort4.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SORTING_NETWORK_SORT4_H_ @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<4u> + struct sorting_network_sorter_impl<4> { template< typename RandomAccessIterator, @@ -24,11 +24,11 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - iter_swap_if(first, first + 1u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first, first + 2u, compare, projection); - iter_swap_if(first + 1u, first + 3u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); + iter_swap_if(first, first + 2, compare, projection); + iter_swap_if(first + 1, first + 3, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); } template diff --git a/include/cpp-sort/detail/sorting_network/sort5.h b/include/cpp-sort/detail/sorting_network/sort5.h index 10084520..268395d7 100644 --- a/include/cpp-sort/detail/sorting_network/sort5.h +++ b/include/cpp-sort/detail/sorting_network/sort5.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SORTING_NETWORK_SORT5_H_ @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<5u> + struct sorting_network_sorter_impl<5> { template< typename RandomAccessIterator, @@ -24,15 +24,15 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - iter_swap_if(first, first + 1u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 2u, first + 4u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first, first + 3u, compare, projection); - iter_swap_if(first, first + 2u, compare, projection); - iter_swap_if(first + 1u, first + 4u, compare, projection); - iter_swap_if(first + 1u, first + 3u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); + iter_swap_if(first, first + 3, compare, projection); + iter_swap_if(first + 1, first + 4, compare, projection); + iter_swap_if(first, first + 2, compare, projection); + iter_swap_if(first + 1, first + 3, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); } template @@ -40,10 +40,10 @@ namespace detail -> std::array, 9> { return {{ - {0, 3}, {1,4}, - {0, 2}, {1,3}, - {0, 1}, {2,4}, - {1, 2}, {3,4}, + {0, 3}, {1, 4}, + {0, 2}, {1, 3}, + {0, 1}, {2, 4}, + {1, 2}, {3, 4}, {2, 3}, }}; } diff --git a/include/cpp-sort/detail/sorting_network/sort6.h b/include/cpp-sort/detail/sorting_network/sort6.h index 03787f02..ffba4cda 100644 --- a/include/cpp-sort/detail/sorting_network/sort6.h +++ b/include/cpp-sort/detail/sorting_network/sort6.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SORTING_NETWORK_SORT6_H_ @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<6u> + struct sorting_network_sorter_impl<6> { template< typename RandomAccessIterator, @@ -24,18 +24,18 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first, first + 2u, compare, projection); - iter_swap_if(first, first + 1u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 3u, first + 5u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first, first + 3u, compare, projection); - iter_swap_if(first + 1u, first + 4u, compare, projection); - iter_swap_if(first + 2u, first + 5u, compare, projection); - iter_swap_if(first + 2u, first + 4u, compare, projection); - iter_swap_if(first + 1u, first + 3u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); + iter_swap_if(first, first + 5, compare, projection); + iter_swap_if(first + 1, first + 3, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first, first + 3, compare, projection); + iter_swap_if(first + 2, first + 5, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); } template diff --git a/include/cpp-sort/detail/sorting_network/sort7.h b/include/cpp-sort/detail/sorting_network/sort7.h index 8fbdbbb2..6e16ad32 100644 --- a/include/cpp-sort/detail/sorting_network/sort7.h +++ b/include/cpp-sort/detail/sorting_network/sort7.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SORTING_NETWORK_SORT7_H_ @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<7u> + struct sorting_network_sorter_impl<7> { template< typename RandomAccessIterator, @@ -24,22 +24,22 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first, first + 2u, compare, projection); - iter_swap_if(first, first + 1u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first + 3u, first + 5u, compare, projection); - iter_swap_if(first + 4u, first + 6u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first, first + 4u, compare, projection); - iter_swap_if(first, first + 3u, compare, projection); - iter_swap_if(first + 1u, first + 5u, compare, projection); - iter_swap_if(first + 2u, first + 6u, compare, projection); - iter_swap_if(first + 2u, first + 5u, compare, projection); - iter_swap_if(first + 1u, first + 3u, compare, projection); - iter_swap_if(first + 2u, first + 4u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); + iter_swap_if(first, first + 6, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first, first + 2, compare, projection); + iter_swap_if(first + 1, first + 4, compare, projection); + iter_swap_if(first + 3, first + 6, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 2, first + 5, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); } template diff --git a/include/cpp-sort/detail/sorting_network/sort8.h b/include/cpp-sort/detail/sorting_network/sort8.h index f6c87924..ed862c51 100644 --- a/include/cpp-sort/detail/sorting_network/sort8.h +++ b/include/cpp-sort/detail/sorting_network/sort8.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SORTING_NETWORK_SORT8_H_ @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<8u> + struct sorting_network_sorter_impl<8> { template< typename RandomAccessIterator, @@ -24,25 +24,25 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - iter_swap_if(first, first + 1u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first, first + 2u, compare, projection); - iter_swap_if(first + 1u, first + 3u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 4u, first + 6u, compare, projection); - iter_swap_if(first + 5u, first + 7u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); - iter_swap_if(first, first + 4u, compare, projection); - iter_swap_if(first + 1u, first + 5u, compare, projection); - iter_swap_if(first + 1u, first + 4u, compare, projection); - iter_swap_if(first + 2u, first + 6u, compare, projection); - iter_swap_if(first + 3u, first + 7u, compare, projection); - iter_swap_if(first + 3u, first + 6u, compare, projection); - iter_swap_if(first + 2u, first + 4u, compare, projection); - iter_swap_if(first + 3u, first + 5u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); + iter_swap_if(first, first + 2, compare, projection); + iter_swap_if(first + 1, first + 3, compare, projection); + iter_swap_if(first + 4, first + 6, compare, projection); + iter_swap_if(first + 5, first + 7, compare, projection); + iter_swap_if(first, first + 4, compare, projection); + iter_swap_if(first + 1, first + 5, compare, projection); + iter_swap_if(first + 2, first + 6, compare, projection); + iter_swap_if(first + 3, first + 7, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 3, first + 5, compare, projection); + iter_swap_if(first + 1, first + 4, compare, projection); + iter_swap_if(first + 3, first + 6, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); } template diff --git a/include/cpp-sort/detail/sorting_network/sort9.h b/include/cpp-sort/detail/sorting_network/sort9.h index cb9440d5..e5195134 100644 --- a/include/cpp-sort/detail/sorting_network/sort9.h +++ b/include/cpp-sort/detail/sorting_network/sort9.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SORTING_NETWORK_SORT9_H_ @@ -10,7 +10,7 @@ namespace cppsort namespace detail { template<> - struct sorting_network_sorter_impl<9u> + struct sorting_network_sorter_impl<9> { template< typename RandomAccessIterator, @@ -24,31 +24,31 @@ namespace detail Compare compare={}, Projection projection={}) const -> void { - iter_swap_if(first, first + 1u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first + 1u, first + 2u, compare, projection); - iter_swap_if(first + 4u, first + 5u, compare, projection); - iter_swap_if(first + 7u, first + 8u, compare, projection); - iter_swap_if(first, first + 1u, compare, projection); - iter_swap_if(first + 3u, first + 4u, compare, projection); - iter_swap_if(first + 6u, first + 7u, compare, projection); - iter_swap_if(first, first + 3u, compare, projection); - iter_swap_if(first + 3u, first + 6u, compare, projection); - iter_swap_if(first, first + 3u, compare, projection); - iter_swap_if(first + 1u, first + 4u, compare, projection); - iter_swap_if(first + 4u, first + 7u, compare, projection); - iter_swap_if(first + 1u, first + 4u, compare, projection); - iter_swap_if(first + 2u, first + 5u, compare, projection); - iter_swap_if(first + 5u, first + 8u, compare, projection); - iter_swap_if(first + 2u, first + 5u, compare, projection); - iter_swap_if(first + 1u, first + 3u, compare, projection); - iter_swap_if(first + 5u, first + 7u, compare, projection); - iter_swap_if(first + 2u, first + 6u, compare, projection); - iter_swap_if(first + 4u, first + 6u, compare, projection); - iter_swap_if(first + 2u, first + 4u, compare, projection); - iter_swap_if(first + 2u, first + 3u, compare, projection); - iter_swap_if(first + 5u, first + 6u, compare, projection); + iter_swap_if(first, first + 3, compare, projection); + iter_swap_if(first + 1, first + 7, compare, projection); + iter_swap_if(first + 2, first + 5, compare, projection); + iter_swap_if(first + 4, first + 8, compare, projection); + iter_swap_if(first, first + 7, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 3, first + 8, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); + iter_swap_if(first, first + 2, compare, projection); + iter_swap_if(first + 1, first + 3, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 7, first + 8, compare, projection); + iter_swap_if(first + 1, first + 4, compare, projection); + iter_swap_if(first + 3, first + 6, compare, projection); + iter_swap_if(first + 5, first + 7, compare, projection); + iter_swap_if(first, first + 1, compare, projection); + iter_swap_if(first + 2, first + 4, compare, projection); + iter_swap_if(first + 3, first + 5, compare, projection); + iter_swap_if(first + 6, first + 8, compare, projection); + iter_swap_if(first + 2, first + 3, compare, projection); + iter_swap_if(first + 4, first + 5, compare, projection); + iter_swap_if(first + 6, first + 7, compare, projection); + iter_swap_if(first + 1, first + 2, compare, projection); + iter_swap_if(first + 3, first + 4, compare, projection); + iter_swap_if(first + 5, first + 6, compare, projection); } template From 0e9720b0d2ddb5175b1dc3a143c2b7bbaeaa69b2 Mon Sep 17 00:00:00 2001 From: Morwenn Date: Sun, 11 Sep 2022 15:03:02 +0200 Subject: [PATCH 37/51] Mark sorting_network_sorter::index_pairs() as [[nodiscard]] --- docs/Fixed-size-sorters.md | 4 +++- include/cpp-sort/detail/sorting_network/sort10.h | 1 + include/cpp-sort/detail/sorting_network/sort11.h | 1 + include/cpp-sort/detail/sorting_network/sort12.h | 1 + include/cpp-sort/detail/sorting_network/sort13.h | 1 + include/cpp-sort/detail/sorting_network/sort14.h | 1 + include/cpp-sort/detail/sorting_network/sort15.h | 1 + include/cpp-sort/detail/sorting_network/sort16.h | 1 + include/cpp-sort/detail/sorting_network/sort17.h | 1 + include/cpp-sort/detail/sorting_network/sort18.h | 1 + include/cpp-sort/detail/sorting_network/sort19.h | 1 + include/cpp-sort/detail/sorting_network/sort2.h | 1 + include/cpp-sort/detail/sorting_network/sort20.h | 1 + include/cpp-sort/detail/sorting_network/sort21.h | 1 + include/cpp-sort/detail/sorting_network/sort22.h | 1 + include/cpp-sort/detail/sorting_network/sort23.h | 1 + include/cpp-sort/detail/sorting_network/sort24.h | 1 + include/cpp-sort/detail/sorting_network/sort25.h | 1 + include/cpp-sort/detail/sorting_network/sort26.h | 1 + include/cpp-sort/detail/sorting_network/sort27.h | 1 + include/cpp-sort/detail/sorting_network/sort28.h | 1 + include/cpp-sort/detail/sorting_network/sort29.h | 1 + include/cpp-sort/detail/sorting_network/sort3.h | 1 + include/cpp-sort/detail/sorting_network/sort30.h | 1 + include/cpp-sort/detail/sorting_network/sort31.h | 1 + include/cpp-sort/detail/sorting_network/sort32.h | 3 ++- include/cpp-sort/detail/sorting_network/sort4.h | 1 + include/cpp-sort/detail/sorting_network/sort5.h | 1 + include/cpp-sort/detail/sorting_network/sort6.h | 1 + include/cpp-sort/detail/sorting_network/sort7.h | 1 + include/cpp-sort/detail/sorting_network/sort8.h | 1 + include/cpp-sort/detail/sorting_network/sort9.h | 1 + include/cpp-sort/fixed/sorting_network_sorter.h | 3 ++- tools/generate_sorting_network.py | 1 + 34 files changed, 38 insertions(+), 3 deletions(-) diff --git a/docs/Fixed-size-sorters.md b/docs/Fixed-size-sorters.md index 5a327513..ce2dfbd6 100644 --- a/docs/Fixed-size-sorters.md +++ b/docs/Fixed-size-sorters.md @@ -157,7 +157,7 @@ All specializations of `sorting_network_sorter` provide a `index_pairs() static` ```cpp template -static constexpr auto index_pairs() +[[nodiscard]] static constexpr auto index_pairs() -> std::array, /* Number of CEs in the network */>; ``` @@ -173,6 +173,8 @@ static constexpr auto index_pairs() *Changed in version 1.13.1:* sorting 25 inputs requires 130 CEs instead of 131. +*Changed in version 1.13.1:* `index_pair()` is now `[[nodiscard]]` when possible for all `sorting_network_sorter` specializations. + [double-insertion-sort]: Original-research.md#double-insertion-sort [fixed-sorter-traits]: Sorter-traits.md#fixed_sorter_traits diff --git a/include/cpp-sort/detail/sorting_network/sort10.h b/include/cpp-sort/detail/sorting_network/sort10.h index 0985d02d..374801fd 100644 --- a/include/cpp-sort/detail/sorting_network/sort10.h +++ b/include/cpp-sort/detail/sorting_network/sort10.h @@ -56,6 +56,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 29> { diff --git a/include/cpp-sort/detail/sorting_network/sort11.h b/include/cpp-sort/detail/sorting_network/sort11.h index 743c3e0f..202e2989 100644 --- a/include/cpp-sort/detail/sorting_network/sort11.h +++ b/include/cpp-sort/detail/sorting_network/sort11.h @@ -62,6 +62,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 35> { diff --git a/include/cpp-sort/detail/sorting_network/sort12.h b/include/cpp-sort/detail/sorting_network/sort12.h index c3325545..6bda26cd 100644 --- a/include/cpp-sort/detail/sorting_network/sort12.h +++ b/include/cpp-sort/detail/sorting_network/sort12.h @@ -66,6 +66,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 39> { diff --git a/include/cpp-sort/detail/sorting_network/sort13.h b/include/cpp-sort/detail/sorting_network/sort13.h index dd7a7cb9..c012ae0d 100644 --- a/include/cpp-sort/detail/sorting_network/sort13.h +++ b/include/cpp-sort/detail/sorting_network/sort13.h @@ -72,6 +72,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 45> { diff --git a/include/cpp-sort/detail/sorting_network/sort14.h b/include/cpp-sort/detail/sorting_network/sort14.h index 2f1a0a03..aef91aee 100644 --- a/include/cpp-sort/detail/sorting_network/sort14.h +++ b/include/cpp-sort/detail/sorting_network/sort14.h @@ -78,6 +78,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 51> { diff --git a/include/cpp-sort/detail/sorting_network/sort15.h b/include/cpp-sort/detail/sorting_network/sort15.h index 8feb1941..aa79732f 100644 --- a/include/cpp-sort/detail/sorting_network/sort15.h +++ b/include/cpp-sort/detail/sorting_network/sort15.h @@ -83,6 +83,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 56> { diff --git a/include/cpp-sort/detail/sorting_network/sort16.h b/include/cpp-sort/detail/sorting_network/sort16.h index dd613673..b6ab2933 100644 --- a/include/cpp-sort/detail/sorting_network/sort16.h +++ b/include/cpp-sort/detail/sorting_network/sort16.h @@ -87,6 +87,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 60> { diff --git a/include/cpp-sort/detail/sorting_network/sort17.h b/include/cpp-sort/detail/sorting_network/sort17.h index fd81ceb0..d1d1765b 100644 --- a/include/cpp-sort/detail/sorting_network/sort17.h +++ b/include/cpp-sort/detail/sorting_network/sort17.h @@ -98,6 +98,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 71> { diff --git a/include/cpp-sort/detail/sorting_network/sort18.h b/include/cpp-sort/detail/sorting_network/sort18.h index bc942526..134cb6eb 100644 --- a/include/cpp-sort/detail/sorting_network/sort18.h +++ b/include/cpp-sort/detail/sorting_network/sort18.h @@ -104,6 +104,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 77> { diff --git a/include/cpp-sort/detail/sorting_network/sort19.h b/include/cpp-sort/detail/sorting_network/sort19.h index 03744aa4..f54e9d85 100644 --- a/include/cpp-sort/detail/sorting_network/sort19.h +++ b/include/cpp-sort/detail/sorting_network/sort19.h @@ -112,6 +112,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 85> { diff --git a/include/cpp-sort/detail/sorting_network/sort2.h b/include/cpp-sort/detail/sorting_network/sort2.h index 3f3f0ccb..3c868ba0 100644 --- a/include/cpp-sort/detail/sorting_network/sort2.h +++ b/include/cpp-sort/detail/sorting_network/sort2.h @@ -28,6 +28,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 1> { diff --git a/include/cpp-sort/detail/sorting_network/sort20.h b/include/cpp-sort/detail/sorting_network/sort20.h index f0f8319b..751dbfda 100644 --- a/include/cpp-sort/detail/sorting_network/sort20.h +++ b/include/cpp-sort/detail/sorting_network/sort20.h @@ -118,6 +118,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 91> { diff --git a/include/cpp-sort/detail/sorting_network/sort21.h b/include/cpp-sort/detail/sorting_network/sort21.h index ef2acdf8..e0feac1c 100644 --- a/include/cpp-sort/detail/sorting_network/sort21.h +++ b/include/cpp-sort/detail/sorting_network/sort21.h @@ -126,6 +126,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 99> { diff --git a/include/cpp-sort/detail/sorting_network/sort22.h b/include/cpp-sort/detail/sorting_network/sort22.h index adbad987..0bf071db 100644 --- a/include/cpp-sort/detail/sorting_network/sort22.h +++ b/include/cpp-sort/detail/sorting_network/sort22.h @@ -133,6 +133,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 106> { diff --git a/include/cpp-sort/detail/sorting_network/sort23.h b/include/cpp-sort/detail/sorting_network/sort23.h index f0f546d0..1b5bdcc7 100644 --- a/include/cpp-sort/detail/sorting_network/sort23.h +++ b/include/cpp-sort/detail/sorting_network/sort23.h @@ -141,6 +141,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 114> { diff --git a/include/cpp-sort/detail/sorting_network/sort24.h b/include/cpp-sort/detail/sorting_network/sort24.h index b59e1450..95d96179 100644 --- a/include/cpp-sort/detail/sorting_network/sort24.h +++ b/include/cpp-sort/detail/sorting_network/sort24.h @@ -147,6 +147,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 120> { diff --git a/include/cpp-sort/detail/sorting_network/sort25.h b/include/cpp-sort/detail/sorting_network/sort25.h index 5442f5e0..612f2515 100644 --- a/include/cpp-sort/detail/sorting_network/sort25.h +++ b/include/cpp-sort/detail/sorting_network/sort25.h @@ -157,6 +157,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 130> { diff --git a/include/cpp-sort/detail/sorting_network/sort26.h b/include/cpp-sort/detail/sorting_network/sort26.h index 3e0734a0..cef80e94 100644 --- a/include/cpp-sort/detail/sorting_network/sort26.h +++ b/include/cpp-sort/detail/sorting_network/sort26.h @@ -166,6 +166,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 139> { diff --git a/include/cpp-sort/detail/sorting_network/sort27.h b/include/cpp-sort/detail/sorting_network/sort27.h index e09e7b4c..cbf9ec30 100644 --- a/include/cpp-sort/detail/sorting_network/sort27.h +++ b/include/cpp-sort/detail/sorting_network/sort27.h @@ -175,6 +175,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 148> { diff --git a/include/cpp-sort/detail/sorting_network/sort28.h b/include/cpp-sort/detail/sorting_network/sort28.h index 0ad9c84f..af801916 100644 --- a/include/cpp-sort/detail/sorting_network/sort28.h +++ b/include/cpp-sort/detail/sorting_network/sort28.h @@ -182,6 +182,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 155> { diff --git a/include/cpp-sort/detail/sorting_network/sort29.h b/include/cpp-sort/detail/sorting_network/sort29.h index ec877aac..d9ef117e 100644 --- a/include/cpp-sort/detail/sorting_network/sort29.h +++ b/include/cpp-sort/detail/sorting_network/sort29.h @@ -191,6 +191,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 164> { diff --git a/include/cpp-sort/detail/sorting_network/sort3.h b/include/cpp-sort/detail/sorting_network/sort3.h index 193025e5..7e0d6609 100644 --- a/include/cpp-sort/detail/sorting_network/sort3.h +++ b/include/cpp-sort/detail/sorting_network/sort3.h @@ -30,6 +30,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 3> { diff --git a/include/cpp-sort/detail/sorting_network/sort30.h b/include/cpp-sort/detail/sorting_network/sort30.h index 06568ef0..ee6e31e8 100644 --- a/include/cpp-sort/detail/sorting_network/sort30.h +++ b/include/cpp-sort/detail/sorting_network/sort30.h @@ -90,6 +90,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 172> { diff --git a/include/cpp-sort/detail/sorting_network/sort31.h b/include/cpp-sort/detail/sorting_network/sort31.h index ae0abae7..a91f2a2c 100644 --- a/include/cpp-sort/detail/sorting_network/sort31.h +++ b/include/cpp-sort/detail/sorting_network/sort31.h @@ -207,6 +207,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 180> { diff --git a/include/cpp-sort/detail/sorting_network/sort32.h b/include/cpp-sort/detail/sorting_network/sort32.h index 165fd731..7ffcf6db 100644 --- a/include/cpp-sort/detail/sorting_network/sort32.h +++ b/include/cpp-sort/detail/sorting_network/sort32.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SORTING_NETWORK_SORT32_H_ @@ -212,6 +212,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 185> { diff --git a/include/cpp-sort/detail/sorting_network/sort4.h b/include/cpp-sort/detail/sorting_network/sort4.h index 1d446589..74a7ff77 100644 --- a/include/cpp-sort/detail/sorting_network/sort4.h +++ b/include/cpp-sort/detail/sorting_network/sort4.h @@ -32,6 +32,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 5> { diff --git a/include/cpp-sort/detail/sorting_network/sort5.h b/include/cpp-sort/detail/sorting_network/sort5.h index 268395d7..ca7ac7f2 100644 --- a/include/cpp-sort/detail/sorting_network/sort5.h +++ b/include/cpp-sort/detail/sorting_network/sort5.h @@ -36,6 +36,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 9> { diff --git a/include/cpp-sort/detail/sorting_network/sort6.h b/include/cpp-sort/detail/sorting_network/sort6.h index ffba4cda..78de3fe5 100644 --- a/include/cpp-sort/detail/sorting_network/sort6.h +++ b/include/cpp-sort/detail/sorting_network/sort6.h @@ -39,6 +39,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 12> { diff --git a/include/cpp-sort/detail/sorting_network/sort7.h b/include/cpp-sort/detail/sorting_network/sort7.h index 6e16ad32..139127c3 100644 --- a/include/cpp-sort/detail/sorting_network/sort7.h +++ b/include/cpp-sort/detail/sorting_network/sort7.h @@ -43,6 +43,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 16> { diff --git a/include/cpp-sort/detail/sorting_network/sort8.h b/include/cpp-sort/detail/sorting_network/sort8.h index ed862c51..492a8b28 100644 --- a/include/cpp-sort/detail/sorting_network/sort8.h +++ b/include/cpp-sort/detail/sorting_network/sort8.h @@ -46,6 +46,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 19> { diff --git a/include/cpp-sort/detail/sorting_network/sort9.h b/include/cpp-sort/detail/sorting_network/sort9.h index e5195134..eb03cc4f 100644 --- a/include/cpp-sort/detail/sorting_network/sort9.h +++ b/include/cpp-sort/detail/sorting_network/sort9.h @@ -52,6 +52,7 @@ namespace detail } template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, 25> { diff --git a/include/cpp-sort/fixed/sorting_network_sorter.h b/include/cpp-sort/fixed/sorting_network_sorter.h index 73de1c7b..8a9054bf 100644 --- a/include/cpp-sort/fixed/sorting_network_sorter.h +++ b/include/cpp-sort/fixed/sorting_network_sorter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_FIXED_SORTING_NETWORK_SORTER_H_ @@ -77,6 +77,7 @@ namespace cppsort #include #include #include +#include "../detail/attributes.h" #include "../detail/swap_if.h" #include "../detail/type_traits.h" diff --git a/tools/generate_sorting_network.py b/tools/generate_sorting_network.py index 81ac116f..d6254967 100644 --- a/tools/generate_sorting_network.py +++ b/tools/generate_sorting_network.py @@ -71,6 +71,7 @@ def generate_cxx(network: list[list[tuple]]): }} template + CPPSORT_ATTRIBUTE_NODISCARD static constexpr auto index_pairs() -> std::array, {nb_indices}> {{ From aa2318ea590453b88bc18ab4b6f504e25102483d Mon Sep 17 00:00:00 2001 From: Morwenn Date: Fri, 23 Sep 2022 16:48:44 +0200 Subject: [PATCH 38/51] Assortment of documentation fixes --- docs/Chainable-projections.md | 2 +- docs/Changelog.md | 2 +- docs/Fixed-size-sorters.md | 6 +++++- docs/Miscellaneous-utilities.md | 2 +- docs/Sorter-facade.md | 2 +- docs/Tooling.md | 2 +- docs/Writing-a-bubble_sorter.md | 2 +- 7 files changed, 11 insertions(+), 7 deletions(-) diff --git a/docs/Chainable-projections.md b/docs/Chainable-projections.md index 2e8061fc..2b2be55e 100644 --- a/docs/Chainable-projections.md +++ b/docs/Chainable-projections.md @@ -1,6 +1,6 @@ *New in version 1.7.0* -Sometimes one might need to apply several transformations to the elements of a collection before comparing them. To support this use case, some projection functions in **cpp-sort** can be composed with `operator|` +Sometimes one needs to apply several transformations to the elements of a collection before comparing them. To support this use case, some projection functions in **cpp-sort** can be composed with `operator|` ```cpp struct my_negate: diff --git a/docs/Changelog.md b/docs/Changelog.md index 5179686f..8619db38 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -73,7 +73,7 @@ When compiled with C++20, **cpp-sort** might gain a few additional features depe * When available, [`std::ranges::less`][std-ranges-less] and [`std::ranges::greater`][std-ranges-greater] benefit from dedicated support wherever [`std::less<>`][std-less-void] and [`std::greater<>`][std-greater-void] are supported, with equivalent semantics. -* [`utility::iter_swap`][utility-iter-move] can now be used in more `constexpr` functions thanks to [`std::swap`][std-swap] begin `constexpr`. +* [`utility::iter_swap`][utility-iter-move] can now be used in more `constexpr` functions thanks to [`std::swap`][std-swap] being `constexpr`. The feature-test macro `__cpp_lib_constexpr_algorithms` can be used to check whether `std::swap` is `constexpr`. diff --git a/docs/Fixed-size-sorters.md b/docs/Fixed-size-sorters.md index ce2dfbd6..f14f7d05 100644 --- a/docs/Fixed-size-sorters.md +++ b/docs/Fixed-size-sorters.md @@ -105,7 +105,9 @@ template -> std::array, /* Number of CEs in the network */>; ``` -### `merge_exchange_network_sorter` +*New in version 1.11.0* + +### `odd_even_merge_network_sorter` ```cpp #include @@ -128,6 +130,8 @@ template -> std::array, /* Number of CEs in the network */>; ``` +*New in version 1.11.0* + ### `sorting_network_sorter` ```cpp diff --git a/docs/Miscellaneous-utilities.md b/docs/Miscellaneous-utilities.md index d687b89c..57b166cf 100644 --- a/docs/Miscellaneous-utilities.md +++ b/docs/Miscellaneous-utilities.md @@ -180,7 +180,7 @@ struct function_constant }; ``` -This utility is modeled after [`std::integral_constant`][std-integral-constant], but is different in that it takes its parameter as `template`, and `operator()` calls the wrapped value instead of returning it. The goal is to store function pointers and pointer to members "for free": they are only "stored" as a template parameter, which allows `function_constant` to be an empty class. This has two main advantages: `function_constant` can benefit from [*Empty Base Optimization*][ebo] since it weights virtually nothing, and it won't need to be pushed on the stack when passed to a function, while the wrapped pointer would have been if passed unwrapped. Unless you are micro-optimizing some specific piece of code, you shouldn't need this class. +This utility is modeled after [`std::integral_constant`][std-integral-constant], but is different in that it takes its parameter as `template`, and `operator()` calls the wrapped value instead of returning it. The goal is to store function pointers and pointer to members "for free": they are only "stored" as a template parameter, which allows `function_constant` to be an empty class. This has two main advantages: `function_constant` can benefit from [*Empty Base Optimization*][ebo] since it weighs virtually nothing, and it won't need to be pushed on the stack when passed to a function, while the wrapped pointer would have been if passed unwrapped. Unless you are micro-optimizing some specific piece of code, you shouldn't need this class. `is_probably_branchless_comparison` and `is_probably_branchless_projection` will correspond to `std::true_type` if the wrapped `Function` also gives `std::true_type`. Moreover, you can even specialize these traits for specific `function_constant` instanciations if you need even more performance. diff --git a/docs/Sorter-facade.md b/docs/Sorter-facade.md index 2b871b05..afa27911 100644 --- a/docs/Sorter-facade.md +++ b/docs/Sorter-facade.md @@ -49,7 +49,7 @@ Note that the function pointer conversion syntax above is made up, but it allows ***WARNING:** conversion to function pointers does not work with MSVC ([issue #185][issue-185]).* -*Changed in version 1.5.0:* these conversion operators exists if and only if the wrapped *sorter implementation* is empty and default-constructible. +*Changed in version 1.5.0:* these conversion operators exist if and only if the wrapped *sorter implementation* is empty and default-constructible. *Changed in version 1.10.0:* the conversion operators are always `constexpr` (it used to be a C++17 feature). diff --git a/docs/Tooling.md b/docs/Tooling.md index 88e435bd..a84267bd 100644 --- a/docs/Tooling.md +++ b/docs/Tooling.md @@ -29,7 +29,7 @@ The project's CMake files offers some options, though they are mainly used to co * `CPPSORT_BUILD_EXAMPLES`: whether to build the examples, defaults to `OFF`. * `CPPSORT_ENABLE_COVERAGE`: whether to produce code coverage information when building the test suite, defaults to `OFF`. * `CPPSORT_USE_VALGRIND`: whether to run the test suite through Valgrind, defaults to `OFF`. -* `CPPSORT_SANITIZE`: values to pass to the `-fsanitize` flags of compilers that supports them, default to empty. +* `CPPSORT_SANITIZE`: comma-separated list of values to pass to the `-fsanitize` flag of compilers that support it, defaults to an empty string. * `CPPSORT_STATIC_TESTS`: when `ON`, some tests are executed at compile time instead of runtime, defaults to `OFF`. Some of those options also exist without the `CPPSORT_` prefix, but they are deprecated. For compatibility reasons, the options with the `CPPSORT_` prefix default to the values of the equivalent unprefixed options. diff --git a/docs/Writing-a-bubble_sorter.md b/docs/Writing-a-bubble_sorter.md index 790d74fe..bc9691d5 100644 --- a/docs/Writing-a-bubble_sorter.md +++ b/docs/Writing-a-bubble_sorter.md @@ -401,7 +401,7 @@ namespace } // C++17 -inline constexpr auto&& bubble_sort = bubble_sorter{}; +inline constexpr bubble_sorter bubble_sort{}; ``` The combination of [`utility::static_const`][utility-static-const] with an anonymous namespace is a trick used to avoid ODR problems; you can read more about how and why it works in [Eric Niebler's original article](https://ericniebler.com/2014/10/21/customization-point-design-in-c11-and-beyond/). It is basically a poor man's substitute to compensate the lack of `inline` variables pre-C++17. From 229aa20637343e1d3cd6950bbd158d9b9c96352e Mon Sep 17 00:00:00 2001 From: Morwenn Date: Fri, 23 Sep 2022 23:09:24 +0200 Subject: [PATCH 39/51] Add/remove includes as needed --- include/cpp-sort/detail/grail_sort.h | 3 ++- include/cpp-sort/detail/memory.h | 3 ++- include/cpp-sort/detail/slabsort.h | 3 ++- include/cpp-sort/sorters/ska_sorter.h | 3 +-- tests/testing-tools/test_vector.h | 4 ++++ 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/include/cpp-sort/detail/grail_sort.h b/include/cpp-sort/detail/grail_sort.h index 3c00a30d..834d4184 100644 --- a/include/cpp-sort/detail/grail_sort.h +++ b/include/cpp-sort/detail/grail_sort.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/include/cpp-sort/detail/memory.h b/include/cpp-sort/detail/memory.h index 08ad8b32..baee5955 100644 --- a/include/cpp-sort/detail/memory.h +++ b/include/cpp-sort/detail/memory.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 Morwenn + * Copyright (c) 2016-2022 Morwenn * SPDX-License-Identifier: MIT */ @@ -22,6 +22,7 @@ #include #include #include +#include #include "type_traits.h" namespace cppsort diff --git a/include/cpp-sort/detail/slabsort.h b/include/cpp-sort/detail/slabsort.h index ac0bb690..0216be6c 100644 --- a/include/cpp-sort/detail/slabsort.h +++ b/include/cpp-sort/detail/slabsort.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Morwenn + * Copyright (c) 2021-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SLABSORT_H_ @@ -21,6 +21,7 @@ #include "iterator_traits.h" #include "lower_bound.h" #include "melsort.h" +#include "memory.h" #include "stable_partition.h" #include "nth_element.h" diff --git a/include/cpp-sort/sorters/ska_sorter.h b/include/cpp-sort/sorters/ska_sorter.h index 48b6f953..bbafcfab 100644 --- a/include/cpp-sort/sorters/ska_sorter.h +++ b/include/cpp-sort/sorters/ska_sorter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2021 Morwenn + * Copyright (c) 2017-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_SORTERS_SKA_SORTER_H_ @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include "../detail/iterator_traits.h" diff --git a/tests/testing-tools/test_vector.h b/tests/testing-tools/test_vector.h index 036f0288..39065656 100644 --- a/tests/testing-tools/test_vector.h +++ b/tests/testing-tools/test_vector.h @@ -8,7 +8,11 @@ //////////////////////////////////////////////////////////// // Headers //////////////////////////////////////////////////////////// +#include #include +#include +#include +#include #include //////////////////////////////////////////////////////////// From 1d378437a29603884bcee8e6819aa8417cd3741b Mon Sep 17 00:00:00 2001 From: Morwenn Date: Fri, 23 Sep 2022 23:33:32 +0200 Subject: [PATCH 40/51] More include fixes --- include/cpp-sort/detail/boost_common/range.h | 3 +-- include/cpp-sort/detail/container_aware/mel_sort.h | 3 ++- include/cpp-sort/detail/indiesort.h | 1 - include/cpp-sort/detail/slabsort.h | 1 + include/cpp-sort/detail/split_sort.h | 3 ++- include/cpp-sort/detail/spreadsort/detail/string_sort.h | 1 + include/cpp-sort/probes/dis.h | 3 ++- 7 files changed, 9 insertions(+), 6 deletions(-) diff --git a/include/cpp-sort/detail/boost_common/range.h b/include/cpp-sort/detail/boost_common/range.h index 7db63d6f..2877a755 100644 --- a/include/cpp-sort/detail/boost_common/range.h +++ b/include/cpp-sort/detail/boost_common/range.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2021 Morwenn + * Copyright (c) 2019-2022 Morwenn * SPDX-License-Identifier: MIT */ @@ -23,7 +23,6 @@ #include #include #include -#include #include "util/merge.h" #include "../config.h" #include "../iterator_traits.h" diff --git a/include/cpp-sort/detail/container_aware/mel_sort.h b/include/cpp-sort/detail/container_aware/mel_sort.h index 2b0b35c3..06c1be9f 100644 --- a/include/cpp-sort/detail/container_aware/mel_sort.h +++ b/include/cpp-sort/detail/container_aware/mel_sort.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Morwenn + * Copyright (c) 2021-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_CONTAINER_AWARE_MEL_SORT_H_ @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include "../lower_bound.h" diff --git a/include/cpp-sort/detail/indiesort.h b/include/cpp-sort/detail/indiesort.h index 2192b284..2bc98dde 100644 --- a/include/cpp-sort/detail/indiesort.h +++ b/include/cpp-sort/detail/indiesort.h @@ -30,7 +30,6 @@ //////////////////////////////////////////////////////////// #include #include -#include #include #include "../detail/immovable_vector.h" #include "iterator_traits.h" diff --git a/include/cpp-sort/detail/slabsort.h b/include/cpp-sort/detail/slabsort.h index 0216be6c..618eb3c0 100644 --- a/include/cpp-sort/detail/slabsort.h +++ b/include/cpp-sort/detail/slabsort.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "bitops.h" #include "fixed_size_list.h" diff --git a/include/cpp-sort/detail/split_sort.h b/include/cpp-sort/detail/split_sort.h index 7ace9c14..f571bc23 100644 --- a/include/cpp-sort/detail/split_sort.h +++ b/include/cpp-sort/detail/split_sort.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020 Morwenn + * Copyright (c) 2019-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SPLIT_SORT_H_ @@ -10,6 +10,7 @@ //////////////////////////////////////////////////////////// #include #include +#include #include #include "inplace_merge.h" #include "iterator_traits.h" diff --git a/include/cpp-sort/detail/spreadsort/detail/string_sort.h b/include/cpp-sort/detail/spreadsort/detail/string_sort.h index d9852edb..cb3ecda9 100644 --- a/include/cpp-sort/detail/spreadsort/detail/string_sort.h +++ b/include/cpp-sort/detail/spreadsort/detail/string_sort.h @@ -30,6 +30,7 @@ Phil Endecott and Frank Gennari #include #include #include +#include #include #include "common.h" #include "constants.h" diff --git a/include/cpp-sort/probes/dis.h b/include/cpp-sort/probes/dis.h index 952fde70..738b6aad 100644 --- a/include/cpp-sort/probes/dis.h +++ b/include/cpp-sort/probes/dis.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 Morwenn + * Copyright (c) 2016-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_PROBES_DIS_H_ @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include From 3c62ea75e5feb40f45f917a6a803559afeb75360 Mon Sep 17 00:00:00 2001 From: Morwenn Date: Sat, 24 Sep 2022 21:53:09 +0200 Subject: [PATCH 41/51] class -> typename --- include/cpp-sort/adapters/hybrid_adapter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/cpp-sort/adapters/hybrid_adapter.h b/include/cpp-sort/adapters/hybrid_adapter.h index a20b60ff..b5d76b78 100644 --- a/include/cpp-sort/adapters/hybrid_adapter.h +++ b/include/cpp-sort/adapters/hybrid_adapter.h @@ -308,7 +308,7 @@ namespace cppsort //////////////////////////////////////////////////////////// // Mechanism used to unwrap nested hybrid_adapter - template class Flattenable, class TypeList, class Accumulator> + template class Flattenable, typename TypeList, typename Accumulator> struct flatten_fold; template< From ce9a53ef5f08436072ac5ddf66ef7e956178a548 Mon Sep 17 00:00:00 2001 From: Morwenn Date: Sat, 24 Sep 2022 22:27:29 +0200 Subject: [PATCH 42/51] Use is_projection_v instead of is_projection where possible --- include/cpp-sort/adapters/container_aware_adapter.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/cpp-sort/adapters/container_aware_adapter.h b/include/cpp-sort/adapters/container_aware_adapter.h index 51a26116..d53b5a42 100644 --- a/include/cpp-sort/adapters/container_aware_adapter.h +++ b/include/cpp-sort/adapters/container_aware_adapter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2021 Morwenn + * Copyright (c) 2016-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_ADAPTERS_CONTAINER_AWARE_ADAPTER_H_ @@ -157,7 +157,7 @@ namespace cppsort > auto operator()(Iterable& iterable, Compare compare) const -> detail::enable_if_t< - not is_projection::value && + not is_projection_v && not detail::can_comparison_sort::value, conditional_t< Stability, @@ -242,7 +242,7 @@ namespace cppsort > auto operator()(Iterable& iterable, Projection projection) const -> detail::enable_if_t< - is_projection::value && + is_projection_v && not detail::can_projection_sort::value && not detail::can_comparison_projection_sort, Projection>::value && not detail::can_comparison_sort< From 5bf2a164853b2af3b36cbe738040369bd19d7e7e Mon Sep 17 00:00:00 2001 From: Morwenn Date: Sat, 24 Sep 2022 23:03:29 +0200 Subject: [PATCH 43/51] More constexpr sized_iterator --- include/cpp-sort/detail/sized_iterator.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/cpp-sort/detail/sized_iterator.h b/include/cpp-sort/detail/sized_iterator.h index 900a21af..03fba901 100644 --- a/include/cpp-sort/detail/sized_iterator.h +++ b/include/cpp-sort/detail/sized_iterator.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Morwenn + * Copyright (c) 2020-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_SIZED_ITERATOR_H_ @@ -56,14 +56,14 @@ namespace detail // Members access CPPSORT_ATTRIBUTE_NODISCARD - auto base() const + constexpr auto base() const -> iterator_type { return _it; } CPPSORT_ATTRIBUTE_NODISCARD - auto size() const + constexpr auto size() const -> difference_type { return _size; @@ -73,14 +73,14 @@ namespace detail // Element access CPPSORT_ATTRIBUTE_NODISCARD - auto operator*() const + constexpr auto operator*() const -> reference { return *_it; } CPPSORT_ATTRIBUTE_NODISCARD - auto operator->() const + constexpr auto operator->() const -> pointer { return &(operator*()); @@ -104,7 +104,7 @@ namespace detail template CPPSORT_ATTRIBUTE_NODISCARD - auto make_sized_iterator(Iterator it, difference_type_t size) + constexpr auto make_sized_iterator(Iterator it, difference_type_t size) -> sized_iterator { return { it, size }; From 6ef712e6b62b4d6b340e07135297c10b6bdac394 Mon Sep 17 00:00:00 2001 From: Morwenn Date: Sun, 25 Sep 2022 00:08:16 +0200 Subject: [PATCH 44/51] Simplify to_unsigned_or_bool --- include/cpp-sort/detail/ska_sort.h | 46 +++++------------------------- 1 file changed, 7 insertions(+), 39 deletions(-) diff --git a/include/cpp-sort/detail/ska_sort.h b/include/cpp-sort/detail/ska_sort.h index d96b710e..a39bdc75 100644 --- a/include/cpp-sort/detail/ska_sort.h +++ b/include/cpp-sort/detail/ska_sort.h @@ -37,16 +37,14 @@ namespace detail //////////////////////////////////////////////////////////// // ska_sort algorithm - inline auto to_unsigned_or_bool(bool b) - -> bool - { - return b; - } - - inline auto to_unsigned_or_bool(unsigned char c) - -> unsigned char + template + auto to_unsigned_or_bool(Unsigned value) + -> detail::enable_if_t< + detail::is_unsigned::value, // also covers bool + Unsigned + > { - return c; + return value; } inline auto to_unsigned_or_bool(signed char c) @@ -86,12 +84,6 @@ namespace detail + static_cast(1 << std::numeric_limits::digits); } - inline auto to_unsigned_or_bool(unsigned short i) - -> unsigned short - { - return i; - } - inline auto to_unsigned_or_bool(int i) -> unsigned int { @@ -99,12 +91,6 @@ namespace detail + static_cast(1 << std::numeric_limits::digits); } - inline auto to_unsigned_or_bool(unsigned int i) - -> unsigned int - { - return i; - } - inline auto to_unsigned_or_bool(long l) -> unsigned long { @@ -112,12 +98,6 @@ namespace detail + static_cast(1l << std::numeric_limits::digits); } - inline auto to_unsigned_or_bool(unsigned long l) - -> unsigned long - { - return l; - } - inline auto to_unsigned_or_bool(long long l) -> unsigned long long { @@ -125,12 +105,6 @@ namespace detail + static_cast(1ll << std::numeric_limits::digits); } - inline auto to_unsigned_or_bool(unsigned long long l) - -> unsigned long long - { - return l; - } - #ifdef __SIZEOF_INT128__ inline auto to_unsigned_or_bool(__int128_t l) -> __uint128_t @@ -138,12 +112,6 @@ namespace detail return static_cast<__uint128_t>(l) + static_cast<__uint128_t>(__int128_t(1) << (CHAR_BIT * sizeof(__int128_t) - 1)); } - - inline auto to_unsigned_or_bool(__uint128_t l) - -> __uint128_t - { - return l; - } #endif inline auto to_unsigned_or_bool(float f) From 1f2178045167747969363c9291e50829e95d9d62 Mon Sep 17 00:00:00 2001 From: Morwenn Date: Sun, 25 Sep 2022 20:52:42 +0200 Subject: [PATCH 45/51] Simplify is_integral and friends --- include/cpp-sort/detail/type_traits.h | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/include/cpp-sort/detail/type_traits.h b/include/cpp-sort/detail/type_traits.h index 97642869..82cb1d5f 100644 --- a/include/cpp-sort/detail/type_traits.h +++ b/include/cpp-sort/detail/type_traits.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #ifndef CPPSORT_DETAIL_TYPE_TRAITS_H_ @@ -260,12 +260,14 @@ namespace detail //////////////////////////////////////////////////////////// // Type traits to take __int128 into account even when the // standard library isn't instrumented but the type is still - // available (e.g. -std=c++17) + // available: + // * libstdc++ is instrumented in gnu++ mode only + // * libc++ is always instrumented -#ifdef __SIZEOF_INT128__ +#if defined(__SIZEOF_INT128__) && defined(__GLIBCXX__) template struct is_integral: - std::is_integral + std::is_integral::type {}; template<> @@ -280,7 +282,7 @@ namespace detail template struct is_signed: - std::is_signed + std::is_signed::type {}; template<> @@ -290,7 +292,7 @@ namespace detail template struct is_unsigned: - std::is_unsigned + std::is_unsigned::type {}; template<> @@ -298,14 +300,9 @@ namespace detail std::true_type {}; #else - template - using is_integral = std::is_integral; - - template - using is_signed = std::is_signed; - - template - using is_unsigned = std::is_unsigned; + using std::is_integral; + using std::is_signed; + using std::is_unsigned; #endif //////////////////////////////////////////////////////////// From 3aee03d1ced0738b5cee875a8c88f092c1f97120 Mon Sep 17 00:00:00 2001 From: Morwenn Date: Wed, 28 Sep 2022 23:35:03 +0200 Subject: [PATCH 46/51] Benchmarks: make dist::as_long_string more useful - const-qualify its operator() - make it inherit from projection_base --- benchmarks/benchmarking-tools/distributions.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/benchmarks/benchmarking-tools/distributions.h b/benchmarks/benchmarking-tools/distributions.h index b35e8f2e..ff282e93 100644 --- a/benchmarks/benchmarking-tools/distributions.h +++ b/benchmarks/benchmarking-tools/distributions.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021 Morwenn + * Copyright (c) 2015-2022 Morwenn * SPDX-License-Identifier: MIT */ #include @@ -13,6 +13,7 @@ #include #include #include +#include // Pseudo-random number generator, used by some distributions thread_local std::mt19937_64 distributions_prng(std::time(nullptr)); @@ -400,9 +401,10 @@ namespace dist static constexpr const char* output = "vergesort_killer.txt"; }; - struct as_long_string + struct as_long_string: + cppsort::utility::projection_base { - auto operator()(long long int value) + auto operator()(long long int value) const -> std::string { auto str = std::to_string(value); From 45fceb1edd59d6b458b5cf0b6138307a4d268f57 Mon Sep 17 00:00:00 2001 From: Morwenn Date: Thu, 29 Sep 2022 00:14:11 +0200 Subject: [PATCH 47/51] Document granular spread_sorter includes --- docs/Sorters.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/Sorters.md b/docs/Sorters.md index 3b80f8dc..1241e9e6 100644 --- a/docs/Sorters.md +++ b/docs/Sorters.md @@ -536,6 +536,9 @@ This sorter accepts projections, as long as `ska_sorter` can handle the return t ```cpp #include +#include +#include +#include ``` `spread_sorter` implements a [spreadsort][spreadsort]. From 56e40d635c0bcefe9b54e0c0338aa93019958873 Mon Sep 17 00:00:00 2001 From: Morwenn Date: Fri, 30 Sep 2022 00:57:21 +0200 Subject: [PATCH 48/51] Add a bullet point for Gollum in the release checklist --- tools/release-checklist.md | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/release-checklist.md b/tools/release-checklist.md index 64808bb2..eb845996 100644 --- a/tools/release-checklist.md +++ b/tools/release-checklist.md @@ -22,6 +22,7 @@ List of actions to perform when releasing a new cpp-sort version. - [ ] Home.md in the documentation (1) - [ ] Tooling.md/Conan in the documentation (2) - [ ] Verify that the Conan recipe works. +- [ ] Try to open `docs` with the latest version of Gollum. - [ ] Find a name for the new version. - [ ] Open a merge request, let the CI do its job. - [ ] Merge `develop` into `master`. From 4ca1e0eab1769eb76aec382550c105618b2fe8a3 Mon Sep 17 00:00:00 2001 From: Morwenn Date: Fri, 30 Sep 2022 12:37:56 +0200 Subject: [PATCH 49/51] .gitignore: ignore all folders starting with 'build' --- .gitignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 73337f00..250fcc44 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,8 @@ -# Copyright (c) 2015-2021 Morwenn +# Copyright (c) 2015-2022 Morwenn # SPDX-License-Identifier: MIT # Usual build directory -build +build* # Benchmark results directories results From 3d86572e9f9aba995082a469270681fb485ca0f1 Mon Sep 17 00:00:00 2001 From: Morwenn Date: Fri, 30 Sep 2022 19:40:37 +0200 Subject: [PATCH 50/51] Update benchmarks page in the documentation --- docs/Benchmarks.md | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/docs/Benchmarks.md b/docs/Benchmarks.md index a45f733c..685c79e9 100644 --- a/docs/Benchmarks.md +++ b/docs/Benchmarks.md @@ -1,6 +1,9 @@ -*Note: this page only benchmarls sorting algorithms under specific conditions. It can be used as a quick guide but if you really need a fast algorithm for a specific use case, you better run your own benchmarks.* +*Note: this page only benchmarks sorting algorithms under specific conditions. It can be used as a quick guide but if you really need a fast algorithm for a specific use case, you better run your own benchmarks.* -*Last meaningful update: 1.9.0 release, 1.12.0 for measures of presortedness.* +*Last meaningful updates:* +* *1.13.1 for unstable random-access sorts, slow O(n log n) sorts, forward sorts, and the expensive move/cheap comparison benchmark* +* *1.12.0 for measures of presortedness* +* *1.9.0 otherwise* Benchmarking is hard and I might not be doing it right. Moreover, benchmarking sorting algorithms highlights that the time needed to sort a collection of elements depends on several things: the type to sort, the size of the collection, the cost of comparing two values, the cost of moving an element, the patterns formed by the distribution of the values in the collection to sort, the type of the collection itself, etc. The aim of this page is to help you choose a sorting algorithm depending on your needs. You can find two main kinds of benchmarks: the ones that compare algorithms against shuffled collections of different sizes, and the ones that compare algorithms against different data patterns for a given collection size. @@ -8,7 +11,7 @@ It is worth noting that most benchmarks on this page use collections of `double` All of the graphs on this page have been generated with slightly modified versions of the scripts found in the project's benchmarks folder. There are just too many things to check; if you ever want a specific benchmark, don't hesitate to ask for it. -*The benchmarks were run on Windows 10 with 64-bit MinGW-w64 g++10.1, with the flags -O3 -march=native -std=c++2a.* +*The latest benchmarks were run on Windows 10 with 64-bit MinGW-w64 g++12.0, with the flags -O3 -march=native -std=c++20.* # Random-access iterables @@ -19,7 +22,7 @@ Most sorting algorithms are designed to work with random-access iterators, so th Sorting a random-access collection with an unstable sort is probably one of the most common things to want, and not only are those sorts among the fastest comparison sorts, but type-specific sorters can also be used to sort a variety of types. If you don't know what algorithm you want and don't have specific needs, then you probably want one of these. ![Benchmark speed of unstable sorts with increasing size for std::vector](https://i.imgur.com/Q3IEeci.png) -![Benchmark speed of unstable sorts with increasing size for std::deque](https://i.imgur.com/XjRGUmc.png) +![Benchmark speed of unstable sorts with increasing size for std::deque](https://i.imgur.com/oRW5kFr.png) The plots above show a few general tendencies: * `selection_sort` is O(n²) and doesn't scale. @@ -28,8 +31,8 @@ The plots above show a few general tendencies: The quicksort derivatives and the hybrid radix sorts are generally the fastest of the lot, yet `drop_merge_sort` seems to offer interesting speedups for `std::deque` despite not being designed to be the fastest on truly shuffled data. Part of the explanation is that it uses `pdq_sort` in a contiguous memory buffer underneath, which might be faster for `std::deque` than sorting completely in-place. -![Benchmark unstable sorts over different patterns for std::vector](https://i.imgur.com/MlEcGuL.png) -![Benchmark unstable sorts over different patterns for std::deque](https://i.imgur.com/o7sOfMB.png) +![Benchmark unstable sorts over different patterns for std::vector](https://i.imgur.com/WZ4s6Xt.png) +![Benchmark unstable sorts over different patterns for std::deque](https://i.imgur.com/UAaObUW.png) A few random takeways: * All the algorithms are more or less adaptive, not always for the same patterns. @@ -61,15 +64,15 @@ These plots highlight a few important things: I decided to include a dedicated category for slow O(n log n) sorts, because I find this class of algorithms interesting. This category contains experimental algorithms, often taken from rather old research papers. `heap_sort` is used as the "fast" algorithm in this category, despite it being consistently the slowest in the previous category. -![Benchmark speed of slow O(n log n) sorts with increasing size for std::vector](https://i.imgur.com/nSX9n1q.png) -![Benchmark slow O(n log n) sorts over different patterns for std::vector](https://i.imgur.com/z9dR16G.png) -![Benchmark slow O(n log n) sorts over different patterns for std::deque](https://i.imgur.com/Viu13nj.png) +![Benchmark speed of slow O(n log n) sorts with increasing size for std::vector](https://i.imgur.com/2sx8Hk7.png) +![Benchmark slow O(n log n) sorts over different patterns for std::vector](https://i.imgur.com/RkiYdy8.png) +![Benchmark slow O(n log n) sorts over different patterns for std::deque](https://i.imgur.com/Z9O4I6p.png) The analysis is pretty simple here: * Most of the algorithms in this category are slow, but exhibit a good adaptiveness with most kinds of patterns. It isn't all that surprising since I specifically found them in literature about adaptive sorting. -* `poplar_sort` is slower for `std::vector` than for `std::deque`, which makes me suspect a codegen issue somewhere. +* `poplar_sort` is a bit slower for `std::vector` than for `std::deque`, which makes me suspect a weird issue somewhere. * As a result `smooth_sort` and `poplar_sort` beat each other depending on the type of the collection to sort. -* Slabsort has an unusual graph: it seems that even for shuffled data it might end up beating `heap_sort` when the collection grows big enough. +* Slabsort has an unusual graph: even for shuffled data it might end up beating `heap_sort` when the collection becomes big enough. # Bidirectional iterables @@ -91,14 +94,14 @@ For elements as small as `double`, there are two clear winners here: `drop_merge Even fewer sorters can handle forward iterators. `out_of_place_adapter(pdq_sort)` was not included in the patterns benchmark, because it adapts to patterns the same way `pdq_sort` does. -![Benchmark speed of sorts with increasing size for std::forward_list](https://i.imgur.com/SMTKhqG.png) -![Benchmark sorts over different patterns for std::forward_list](https://i.imgur.com/XLndRbU.png) +![Benchmark speed of sorts with increasing size for std::forward_list](https://i.imgur.com/if15kX1.png) +![Benchmark sorts over different patterns for std::forward_list](https://i.imgur.com/uF0UzLm.png) The results are roughly the same than with bidirectional iterables: * Sorting out-of-place is faster than anything else. -* [`std::forward_list::sort`][std-forward-list-sort] doesn't scale well unless moves are expensive. +* [`std::forward_list::sort`][std-forward-list-sort] doesn't scale well when moves are inexpensive. * `quick_sort` and `quick_merge_sort` are good enough contenders when trying to avoid heap memory allocations. -* `mel_sort` is still bad, but becomes a dcent alternative when the input exhibits recognizable patterns. +* `mel_sort` is still bad, but becomes a decent alternative when the input exhibits recognizable patterns. # Sorting under specific constraints @@ -129,11 +132,11 @@ Both algorithms can be interesting depending on the sorting scenario. ## Expensive moves, cheap comparisons -Sometimes we have to sort a collection whose elements are expensive to move around but cheap to compare. In such a situation we can use `indirect_adapter` which sorts iterators to the elements and moves the elements into their direct place once the sorting order is known. +Sometimes one has to sort a collection whose elements are expensive to move around but cheap to compare. In such a situation `indirect_adapter` can be used: it sorts a collection of iterators to the elements, and moves the elements into their direct place once the sorting order is known. The following example uses a collection of `std::array` whose first element is the only one compared during the sort. Albeit a bit artificial, it illustrates the point well enough. -![Benchmark heap_sort vs. indirect_adapter(heap_sort) for a collection of std::array](https://i.imgur.com/mYUaxRT.png) +![Benchmark heap_sort vs. indirect_adapter(heap_sort) for a collection of std::array](https://i.imgur.com/Okkahwf.png) The improvements are not always as clear as in this benchmark, but it shows that `indirect_adapter` might be an interesting tool to have in your sorting toolbox in such a scenario. From b0de0fac64e09469bd2d7018f33de334344cc36c Mon Sep 17 00:00:00 2001 From: Morwenn Date: Fri, 30 Sep 2022 19:49:56 +0200 Subject: [PATCH 51/51] Preparing release 1.13.1 --- CMakeLists.txt | 4 ++-- README.md | 4 ++-- conanfile.py | 4 ++-- docs/Home.md | 2 +- docs/Tooling.md | 4 ++-- include/cpp-sort/version.h | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ac1c68ff..5b257c18 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,11 +1,11 @@ -# Copyright (c) 2015-2021 Morwenn +# Copyright (c) 2015-2022 Morwenn # SPDX-License-Identifier: MIT cmake_minimum_required(VERSION 3.8.0) list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) -project(cpp-sort VERSION 1.13.0 LANGUAGES CXX) +project(cpp-sort VERSION 1.13.1 LANGUAGES CXX) include(CMakePackageConfigHelpers) include(GNUInstallDirs) diff --git a/README.md b/README.md index e47ff8b5..9194a663 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ![cpp-sort logo](docs/images/cpp-sort-logo.svg) -[![Latest Release](https://img.shields.io/badge/release-1.13.0-blue.svg)](https://github.com/Morwenn/cpp-sort/releases/tag/1.13.0) -[![Conan Package](https://img.shields.io/badge/conan-cpp--sort%2F1.13.0-blue.svg)](https://conan.io/center/cpp-sort?version=1.13.0) +[![Latest Release](https://img.shields.io/badge/release-1.13.1-blue.svg)](https://github.com/Morwenn/cpp-sort/releases/tag/1.13.1) +[![Conan Package](https://img.shields.io/badge/conan-cpp--sort%2F1.13.1-blue.svg)](https://conan.io/center/cpp-sort?version=1.13.1) [![Code Coverage](https://codecov.io/gh/Morwenn/cpp-sort/branch/develop/graph/badge.svg)](https://codecov.io/gh/Morwenn/cpp-sort) [![Pitchfork Layout](https://img.shields.io/badge/standard-PFL-orange.svg)](https://github.com/vector-of-bool/pitchfork) diff --git a/conanfile.py b/conanfile.py index 544b6007..0f6b6af2 100644 --- a/conanfile.py +++ b/conanfile.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2018-2021 Morwenn +# Copyright (c) 2018-2022 Morwenn # SPDX-License-Identifier: MIT from conans import CMake, ConanFile @@ -10,7 +10,7 @@ class CppSortConan(ConanFile): name = "cpp-sort" - version = "1.13.0" + version = "1.13.1" description = "Additional sorting algorithms & related tools" topics = "conan", "cpp-sort", "sorting", "algorithms" url = "https://github.com/Morwenn/cpp-sort" diff --git a/docs/Home.md b/docs/Home.md index 58d1ec40..6718c570 100644 --- a/docs/Home.md +++ b/docs/Home.md @@ -1,6 +1,6 @@ ![cpp-sort logo](images/cpp-sort-logo.svg) -Welcome to the **cpp-sort 1.13.0** documentation! +Welcome to the **cpp-sort 1.13.1** documentation! You probably read the introduction in the README, so I won't repeat it here. This wiki contains documentation about the library: basic documentation about the many sorting tools and how to use them, documentation about the additional utilities provided by the library and even some detailed tutorials if you ever want to write your own sorters or sorter adapters. This main page explains a few general things that didn't quite fit in other parts of the documentation. diff --git a/docs/Tooling.md b/docs/Tooling.md index a84267bd..20d61eb4 100644 --- a/docs/Tooling.md +++ b/docs/Tooling.md @@ -56,10 +56,10 @@ Some of those options also exist without the `CPPSORT_` prefix, but they are dep conan search cpp-sort --remote=conan-center ``` -And then install any version to your local cache as follows (here with version 1.13.0): +And then install any version to your local cache as follows (here with version 1.13.1): ```sh -conan install cpp-sort/1.13.0 +conan install cpp-sort/1.13.1 ``` The packages downloaded from conan-center are minimal and only contain the files required to use **cpp-sort** as a library: the headers, CMake files and licensing information. If you need anything else you have to build your own package with the `conanfile.py` available in this repository. diff --git a/include/cpp-sort/version.h b/include/cpp-sort/version.h index ee66059c..0c348e35 100644 --- a/include/cpp-sort/version.h +++ b/include/cpp-sort/version.h @@ -9,6 +9,6 @@ #define CPPSORT_VERSION_MAJOR 1 #define CPPSORT_VERSION_MINOR 13 -#define CPPSORT_VERSION_PATCH 0 +#define CPPSORT_VERSION_PATCH 1 #endif // CPPSORT_VERSION_H_