diff --git a/BaseLib/quicksort.h b/BaseLib/quicksort.h index 53b96553593561f2f37f8c3c20fcfd22c230656c..2be3ebbd91fd1c29c86207686af5b881123265fe 100644 --- a/BaseLib/quicksort.h +++ b/BaseLib/quicksort.h @@ -30,7 +30,7 @@ void quicksort(T1* array, std::size_t beg, std::size_t end, T2* perm) // Zip input arrays. std::vector<std::pair<T1, T2>> data; data.reserve(end-beg); - std::transform(array+beg, array+(end-beg), perm+beg, + std::transform(array+beg, array+end, perm+beg, std::back_inserter(data), [](T1 const& t1, T2 const& t2) { @@ -72,7 +72,7 @@ void quicksort(std::vector<T1*>& array, std::size_t beg, std::size_t end, std::v // Zip input arrays. std::vector<std::pair<T1*, T2>> data; data.reserve(end-beg); - std::transform(array.begin()+beg, array.begin()+(end-beg), perm.begin()+beg, + std::transform(array.begin()+beg, array.begin()+end, perm.begin()+beg, std::back_inserter(data), [](T1* const& t1, T2 const& t2) { diff --git a/Tests/BaseLib/TestQuicksort.cpp b/Tests/BaseLib/TestQuicksort.cpp index 183cc2a9c261bb11188135545caa61e33db31385..b6996dc39e27a678e49f4820ad2997e4c70a4f47 100644 --- a/Tests/BaseLib/TestQuicksort.cpp +++ b/Tests/BaseLib/TestQuicksort.cpp @@ -14,8 +14,10 @@ #include <algorithm> #include <numeric> +#include <random> #include <sstream> #include <string> +#include <tuple> #include <vector> #include <gtest/gtest.h> @@ -214,3 +216,50 @@ TEST_F(BaseLibQuicksort, ReportCorrectPermutationsReverseWithPointer) }), gtest_reporter, cls); } + +template <typename T, typename Gen = ac::generator<T>> +struct randomSortedPairGenerator +{ + Gen source; + using result_type = std::tuple<T, T>; + + result_type operator()(std::size_t) + { + auto p = std::make_tuple(source(), source()); + if (std::get<0>(p) > std::get<1>(p)) + std::swap(std::get<0>(p), std::get<1>(p)); + + return p; + } +}; + +TEST_F(BaseLibQuicksort, SortsRangeAsSTLSort) +{ + auto quicksortSortsRangeAsSTLSort = [](std::vector<int>& xs, + std::tuple<std::size_t, std::size_t> const& range) -> bool + { + if (xs.empty()) + return true; + + std::vector<std::size_t> perm(xs.size()); + std::iota(perm.begin(), perm.end(), 0); + BaseLib::quicksort(xs, std::get<0>(range), std::get<1>(range), perm); + return + std::is_sorted( + xs.begin() + std::get<0>(range), xs.begin() + std::get<1>(range)) + && std::is_sorted(perm.begin(), perm.begin() + std::get<0>(range)) + && std::is_sorted(perm.begin() + std::get<1>(range), perm.end()); + }; + + ac::check<std::vector<int>, std::tuple<std::size_t, std::size_t>>( + quicksortSortsRangeAsSTLSort, + 100, + ac::make_arbitrary(ac::generator<std::vector<int>>(), + randomSortedPairGenerator<std::size_t>()) + .discard_if([](std::vector<int> const& xs, + std::tuple<std::size_t, std::size_t> const& range) + { + return std::get<1>(range) >= xs.size(); + }), + gtest_reporter); +} diff --git a/Tests/MathLib/AutoCheckTools.h b/Tests/MathLib/AutoCheckTools.h index 8824feea5b5050a5b777158b6007abe122cb2211..ddef5115977bcc3b3e49bad937bfdf5d74602e71 100644 --- a/Tests/MathLib/AutoCheckTools.h +++ b/Tests/MathLib/AutoCheckTools.h @@ -30,8 +30,8 @@ struct randomTupleGenerator } }; -// Generates non-negative integers from 0 to given maximum dimension DIM -// independent of size. +/// Generates non-negative integers from 0 to given maximum dimension DIM +/// independent of size. template <typename T, T DIM, typename Gen = generator<T>> struct randomCoordinateIndexGenerator {