diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
commit | 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch) | |
tree | e5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/boost/libs/sort/test | |
parent | Initial commit. (diff) | |
download | ceph-upstream.tar.xz ceph-upstream.zip |
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/sort/test')
-rw-r--r-- | src/boost/libs/sort/test/Jamfile.v2 | 65 | ||||
-rw-r--r-- | src/boost/libs/sort/test/float_sort_test.cpp | 155 | ||||
-rw-r--r-- | src/boost/libs/sort/test/integer_sort_test.cpp | 131 | ||||
-rw-r--r-- | src/boost/libs/sort/test/list.txt | 15 | ||||
-rw-r--r-- | src/boost/libs/sort/test/sort_detail_test.cpp | 294 | ||||
-rw-r--r-- | src/boost/libs/sort/test/string_sort_test.cpp | 162 | ||||
-rw-r--r-- | src/boost/libs/sort/test/test.log | 37 | ||||
-rw-r--r-- | src/boost/libs/sort/test/test_block_indirect_sort.cpp | 186 | ||||
-rw-r--r-- | src/boost/libs/sort/test/test_flat_stable_sort.cpp | 140 | ||||
-rw-r--r-- | src/boost/libs/sort/test/test_insert_sort.cpp | 163 | ||||
-rw-r--r-- | src/boost/libs/sort/test/test_parallel_stable_sort.cpp | 183 | ||||
-rw-r--r-- | src/boost/libs/sort/test/test_pdqsort.cpp | 163 | ||||
-rw-r--r-- | src/boost/libs/sort/test/test_sample_sort.cpp | 181 | ||||
-rw-r--r-- | src/boost/libs/sort/test/test_spinsort.cpp | 180 |
14 files changed, 2055 insertions, 0 deletions
diff --git a/src/boost/libs/sort/test/Jamfile.v2 b/src/boost/libs/sort/test/Jamfile.v2 new file mode 100644 index 00000000..1d581a8d --- /dev/null +++ b/src/boost/libs/sort/test/Jamfile.v2 @@ -0,0 +1,65 @@ +# Boost sorting_algo library test suite Jamfile ---------------------------- +# +# Copyright Steven Ross 2009. Use, modification and +# distribution is subject to the Boost Software License, Version +# 1.0. (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) +# +# See http://www.boost.org/libs/sort for library home page. + +import ../../config/checks/config : requires ; +import testing ; + +{ + test-suite "sort" + : [ run integer_sort_test.cpp + : : : : integer_sort ] + [ run float_sort_test.cpp + : : : : float_sort ] + [ run string_sort_test.cpp + : : : : string_sort ] + [ run sort_detail_test.cpp + : : : : sort_detail ] + + [ run test_pdqsort.cpp + : : : [ requires + cxx11_hdr_random ] <optimization>speed : test_pdqsort ] + + [ run test_flat_stable_sort.cpp + : : : [ requires + cxx11_constexpr + cxx11_noexcept ] <optimization>speed : test_flat_stable_sort ] + + [ run test_spinsort.cpp + : : : [ requires + cxx11_constexpr + cxx11_noexcept ] <optimization>speed : test_spinsort ] + + [ run test_insert_sort.cpp + : : : [ requires + cxx11_constexpr + cxx11_noexcept ] <optimization>speed : test_insert_sort ] + + + [ run test_block_indirect_sort.cpp + : : : [ requires + cxx11_constexpr + cxx11_noexcept + cxx11_thread_local + cxx11_lambdas ] <optimization>speed <threading>multi : test_block_indirect_sort ] + + [ run test_sample_sort.cpp + : : : [ requires + cxx11_constexpr + cxx11_noexcept + cxx11_thread_local + cxx11_lambdas ] <optimization>speed <threading>multi : test_sample_sort ] + + [ run test_parallel_stable_sort.cpp + : : : [ requires + cxx11_constexpr + cxx11_noexcept + cxx11_thread_local + cxx11_lambdas ] <optimization>speed <threading>multi : test_parallel_stable_sort ] + ; +} diff --git a/src/boost/libs/sort/test/float_sort_test.cpp b/src/boost/libs/sort/test/float_sort_test.cpp new file mode 100644 index 00000000..c562e00d --- /dev/null +++ b/src/boost/libs/sort/test/float_sort_test.cpp @@ -0,0 +1,155 @@ +// Boost Sort library float_sort_test.cpp file -----------------------------// + +// Copyright Steven Ross 2014. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/sort for library home page. + +#include <boost/sort/spreadsort/spreadsort.hpp> +// Include unit test framework +#include <boost/test/included/test_exec_monitor.hpp> +#include <boost/test/test_tools.hpp> +#include <vector> + + +using namespace std; +using namespace boost::sort::spreadsort; + +//Casting to an integer before bitshifting +struct rightshift { + int operator()(const float &x, const unsigned offset) const { + return float_mem_cast<float, int>(x) >> offset; + } +}; + +struct rightshift_64 { + boost::int64_t operator()(const double &x, const boost::uint64_t offset) const + { + return float_mem_cast<double, boost::int64_t>(x) >> offset; + } +}; + +boost::int32_t +rand_32(bool sign = true) { + boost::int32_t result = rand() | (rand()<< 16); + if (rand() % 2) + result |= 1 << 15; + //Adding the sign bit + if (sign && (rand() % 2)) + result *= -1; + return result; +} + +static const unsigned input_count = 1000000; + +// Helper class to run tests across all float_sort interface variants. +template<class FloatType, class RightShift> +void test_vector(vector<FloatType> base_vec, RightShift shifter) { + vector<FloatType> sorted_vec = base_vec; + vector<FloatType> test_vec = base_vec; + std::sort(sorted_vec.begin(), sorted_vec.end()); + //Testing boost::sort::spreadsort version + test_vec = base_vec; + boost::sort::spreadsort::spreadsort(test_vec.begin(), test_vec.end()); + BOOST_CHECK(test_vec == sorted_vec); + //One functor + test_vec = base_vec; + float_sort(test_vec.begin(), test_vec.end(), shifter); + BOOST_CHECK(test_vec == sorted_vec); + //Both functors + test_vec = base_vec; + float_sort(test_vec.begin(), test_vec.end(), shifter, less<FloatType>()); + BOOST_CHECK(test_vec == sorted_vec); +} + +void float_test() +{ + // Prepare inputs + vector<float> base_vec; + + //Generating semirandom numbers that will work for basic testing + for (unsigned u = 0; u < input_count; ++u) { + float val = float(rand_32()); + //As std::sort gives arbitrary results for NaNs and 0.0 vs. -0.0, treat all + //those as just 0.0 for testing + if (!(val < 0.0) && !(0.0 < val)) + base_vec.push_back(0.0); + else + base_vec.push_back(val); + } + test_vector(base_vec, rightshift()); + + // Trying both positive and negative sorted and reverse sorted data. + base_vec.clear(); + for (int i = 0; i < (int)input_count; ++i) base_vec.push_back(-i); + test_vector(base_vec, rightshift()); + base_vec.clear(); + for (int i = 0; i < (int)input_count; ++i) base_vec.push_back(i - input_count); + test_vector(base_vec, rightshift()); + base_vec.clear(); + for (int i = 0; i < (int)input_count; ++i) base_vec.push_back(input_count - i); + test_vector(base_vec, rightshift()); + base_vec.clear(); + for (size_t i = 0; i < input_count; ++i) base_vec.push_back(i); + test_vector(base_vec, rightshift()); + base_vec.clear(); + for (size_t i = 0; i < input_count; ++i) base_vec.push_back(i); + for (size_t i = 0; i < input_count; i += 2) base_vec[i] *= -1; + test_vector(base_vec, rightshift()); +} + +void double_test() { + vector<double> base_vec; + for (unsigned u = 0; u < input_count; ++u) { + double val = double + ((((boost::int64_t)rand_32()) << ((8 * sizeof(int)) -1)) + rand_32(false)); + //As std::sort gives arbitrary results for NaNs and 0.0 vs. -0.0, + //treat all those as just 0.0 for testing + if (!(val < 0.0) && !(0.0 < val)) + base_vec.push_back(0.0); + else + base_vec.push_back(val); + } + test_vector(base_vec, rightshift_64()); + + // Trying both positive and negative sorted and reverse sorted data. + base_vec.clear(); + for (int i = 0; i < (int)input_count; ++i) base_vec.push_back(-i); + test_vector(base_vec, rightshift_64()); + base_vec.clear(); + for (int i = 0; i < (int)input_count; ++i) base_vec.push_back(i - input_count); + test_vector(base_vec, rightshift_64()); + base_vec.clear(); + for (int i = 0; i < (int)input_count; ++i) base_vec.push_back(input_count - i); + test_vector(base_vec, rightshift_64()); + base_vec.clear(); + for (size_t i = 0; i < input_count; ++i) base_vec.push_back(i); + test_vector(base_vec, rightshift_64()); + base_vec.clear(); + for (size_t i = 0; i < input_count; ++i) base_vec.push_back(i); + for (size_t i = 0; i < input_count; i += 2) base_vec[i] *= -1; + test_vector(base_vec, rightshift_64()); +} + +// Verify that 0 and 1 elements work correctly. +void corner_test() { + vector<float> test_vec; + boost::sort::spreadsort::spreadsort(test_vec.begin(), test_vec.end()); + const float test_value = -0.0; + test_vec.push_back(test_value); + boost::sort::spreadsort::spreadsort(test_vec.begin(), test_vec.end()); + BOOST_CHECK(test_vec.size() == 1); + BOOST_CHECK(test_vec[0] == test_value); +} + +// test main +int test_main( int, char*[] ) +{ + srand(1); + float_test(); + double_test(); + corner_test(); + return 0; +} diff --git a/src/boost/libs/sort/test/integer_sort_test.cpp b/src/boost/libs/sort/test/integer_sort_test.cpp new file mode 100644 index 00000000..2a97de01 --- /dev/null +++ b/src/boost/libs/sort/test/integer_sort_test.cpp @@ -0,0 +1,131 @@ +// Boost Sort library int_test.cpp file ------------------------------------// + +// Copyright Steven Ross 2009-2014. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/sort for library home page. + +#include <boost/cstdint.hpp> +#include <boost/sort/spreadsort/spreadsort.hpp> +// Include unit test framework +#include <boost/test/included/test_exec_monitor.hpp> +#include <boost/test/test_tools.hpp> +#include <vector> + +#include <iostream> + + +using namespace std; +using namespace boost::sort::spreadsort; + +struct rightshift { + int operator()(int x, unsigned offset) { return x >> offset; } +}; + +struct rightshift_max { + boost::intmax_t operator()(const boost::intmax_t &x, unsigned offset) { + return x >> offset; + } +}; + +struct negrightshift { + int operator()(const int &x, const unsigned offset) { return -(x >> offset); } +}; + +struct negrightshift_max { + boost::intmax_t operator()(const boost::intmax_t &x, const unsigned offset) { + return -(x >> offset); + } +}; + +boost::int32_t +rand_32(bool sign = true) { + boost::int32_t result = rand() | (rand()<< 16); + if (rand() % 2) + result |= 1 << 15; + //Adding the sign bit + if (sign && (rand() % 2)) + result *= -1; + return result; +} + +void int_test() +{ + // Prepare inputs + vector<int> base_vec; + unsigned count = 100000; + srand(1); + //Generating semirandom numbers + for (unsigned u = 0; u < count; ++u) + base_vec.push_back(rand_32()); + vector<int> sorted_vec = base_vec; + vector<int> test_vec = base_vec; + std::sort(sorted_vec.begin(), sorted_vec.end()); + //Testing basic call + integer_sort(test_vec.begin(), test_vec.end()); + BOOST_CHECK(test_vec == sorted_vec); + //boost::sort::spreadsort variant + test_vec = base_vec; + boost::sort::spreadsort::spreadsort(test_vec.begin(), test_vec.end()); + BOOST_CHECK(test_vec == sorted_vec); + //One functor + test_vec = base_vec; + integer_sort(test_vec.begin(), test_vec.end(), rightshift()); + BOOST_CHECK(test_vec == sorted_vec); + //Both functors + test_vec = base_vec; + integer_sort(test_vec.begin(), test_vec.end(), rightshift(), less<int>()); + BOOST_CHECK(test_vec == sorted_vec); + //reverse order + std::sort(sorted_vec.begin(), sorted_vec.end(), greater<int>()); + integer_sort(test_vec.begin(), test_vec.end(), negrightshift(), + greater<int>()); + BOOST_CHECK(test_vec == sorted_vec); + + //Making sure we're correctly sorting boost::intmax_ts; should use std::sort + vector<boost::intmax_t> long_base_vec; + for (unsigned u = 0; u < base_vec.size(); ++u) + long_base_vec.push_back((((boost::intmax_t)rand_32()) << + ((8 * sizeof(int)) -1)) + rand_32(false)); + vector<boost::intmax_t> long_sorted_vec = long_base_vec; + vector<boost::intmax_t> long_test_vec = long_base_vec; + integer_sort(long_test_vec.begin(), long_test_vec.end()); + std::sort(long_sorted_vec.begin(), long_sorted_vec.end()); + BOOST_CHECK(long_test_vec == long_sorted_vec); + //One functor + long_test_vec = long_base_vec; + integer_sort(long_test_vec.begin(), long_test_vec.end(), rightshift_max()); + BOOST_CHECK(long_test_vec == long_sorted_vec); + //Both functors + long_test_vec = long_base_vec; + integer_sort(long_test_vec.begin(), long_test_vec.end(), rightshift_max(), + less<boost::intmax_t>()); + BOOST_CHECK(long_test_vec == long_sorted_vec); + //reverse order + std::sort(long_sorted_vec.begin(), long_sorted_vec.end(), + greater<boost::intmax_t>()); + integer_sort(long_test_vec.begin(), long_test_vec.end(), negrightshift_max(), + greater<boost::intmax_t>()); + BOOST_CHECK(long_test_vec == long_sorted_vec); +} + +// Verify that 0 and 1 elements work correctly. +void corner_test() { + vector<int> test_vec; + boost::sort::spreadsort::spreadsort(test_vec.begin(), test_vec.end()); + const int test_value = 42; + test_vec.push_back(test_value); + boost::sort::spreadsort::spreadsort(test_vec.begin(), test_vec.end()); + BOOST_CHECK(test_vec.size() == 1); + BOOST_CHECK(test_vec[0] == test_value); +} + +// test main +int test_main( int, char*[] ) +{ + int_test(); + corner_test(); + return 0; +} diff --git a/src/boost/libs/sort/test/list.txt b/src/boost/libs/sort/test/list.txt new file mode 100644 index 00000000..0162042f --- /dev/null +++ b/src/boost/libs/sort/test/list.txt @@ -0,0 +1,15 @@ +CMakeLists.txt +float_sort_test.cpp +integer_sort_test.cpp +Jamfile.v2 +list.txt +sort_detail_test.cpp +string_sort_test.cpp +test_block_indirect_sort.cpp +test_flat_stable_sort.cpp +test_insert_sort.cpp +test.log +test_parallel_stable_sort.cpp +test_pdqsort.cpp +test_sample_sort.cpp +test_spinsort.cpp diff --git a/src/boost/libs/sort/test/sort_detail_test.cpp b/src/boost/libs/sort/test/sort_detail_test.cpp new file mode 100644 index 00000000..c7e7c558 --- /dev/null +++ b/src/boost/libs/sort/test/sort_detail_test.cpp @@ -0,0 +1,294 @@ +// Boost Sort library tests for integer_sort and float_sort details. + +// Copyright Steven Ross 2014. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/sort for library home page. + +#include <boost/cstdint.hpp> +#include <boost/sort/spreadsort/detail/spreadsort_common.hpp> +#include <boost/sort/spreadsort/detail/integer_sort.hpp> +#include <boost/sort/spreadsort/detail/float_sort.hpp> +#include <boost/sort/spreadsort/detail/string_sort.hpp> +#include <boost/sort/spreadsort/float_sort.hpp> +// Include unit test framework +#include <boost/test/included/test_exec_monitor.hpp> +#include <boost/test/test_tools.hpp> +#include <vector> + +#include <iostream> + + +using namespace std; +using namespace boost::sort::spreadsort; +using namespace boost::sort::spreadsort::detail; + +namespace { + +struct int_right_shift { + int operator()(const int x, const unsigned offset) const { + return x >> offset; + } +}; + +struct float_right_shift { + int operator()(const float x, const unsigned offset) const { + return float_mem_cast<float, int>(x) >> offset; + } +}; + +const int max_int_bits = sizeof(boost::uintmax_t) * 8; +const int max_size_bits = sizeof(size_t) * 8; +const boost::uintmax_t one = 1; + +// spreadsort won't recurse for inputs smaller than min_count. +const int int_min_log_count = + (std::min)((int)int_log_finishing_count, + (int)int_log_mean_bin_size + int_log_min_split_count); +const int float_min_log_count = + (std::min)((int)float_log_finishing_count, + (int)float_log_mean_bin_size + float_log_min_split_count); +const unsigned absolute_min_count = (std::min)(1 << int_min_log_count, + 1 << float_min_log_count); + +// Verify that roughlog2 is floor(log base 2) + 1. +void roughlog2_test() +{ + for (boost::uintmax_t i = 0; i < max_int_bits; ++i) { + BOOST_CHECK(detail::rough_log_2_size(one << i) == i + 1); + BOOST_CHECK(detail::rough_log_2_size((one << i) - 1) == i); + } +} + +// Test the worst-case performance handling, and assure that is using the +// correct formula for the worst-case number of radix iterations. +template<unsigned log_mean_bin_size, unsigned log_min_split_count, + unsigned log_finishing_count> +void get_min_count_test() +{ + const unsigned min_log_size = log_mean_bin_size + log_min_split_count; + size_t prev_min_count = absolute_min_count; + for (int log_range = 0; log_range <= max_int_bits; ++log_range) { + size_t min_count = get_min_count<log_mean_bin_size, log_min_split_count, + log_finishing_count>(log_range); + BOOST_CHECK(min_count >= prev_min_count); + prev_min_count = min_count; + // When the range is really small, the radix sort will complete in one + // iteration and worst-case handling doesn't apply. The code below + // guarantees the worst-case number of radix sorting iteration. + if (log_range > min_log_size) { + BOOST_CHECK(min_count >= (1 << min_log_size)); + int iterations = rough_log_2_size(min_count) - min_log_size; + BOOST_CHECK(iterations >= 1); + int base_iterations = max_splits - log_min_split_count; + int covered_log_range = 0; + if (iterations > base_iterations) { + covered_log_range += max_splits * (iterations - base_iterations); + } else { + base_iterations = iterations; + } + // sum of n to n + x = ((x + 1) * (n + (n + x)))/2 + log_mean_bin_size + covered_log_range += + (base_iterations * (log_min_split_count * 2 + base_iterations - 1))/2 + + log_mean_bin_size; + BOOST_CHECK(covered_log_range >= log_range); + BOOST_CHECK(covered_log_range - max_splits < log_range); + } + } +} + +// Test the decision of how many pieces to split up the radix sort into +// (roughly 2^(log_range - log_divisor)) to make sure the results are logical. +void get_log_divisor_test() +{ + for (int log_range = 0; log_range <= max_int_bits; ++log_range) { + int prev_log_divisor = max_int_bits + + (std::max)((int)int_log_mean_bin_size, (int)float_log_mean_bin_size); + for (int log_count = 0; log_count < max_size_bits; ++log_count) { + size_t count = (one << log_count) - 1; + BOOST_CHECK(rough_log_2_size(count) == (unsigned)log_count); + int log_divisor = + get_log_divisor<int_log_mean_bin_size>(count, log_range); + // Only process counts >= int_log_finishing_count in this function. + if (count >= absolute_min_count) + BOOST_CHECK(log_divisor <= log_range); + // More pieces should be used the larger count is. + BOOST_CHECK(log_divisor <= prev_log_divisor); + prev_log_divisor = log_divisor; + BOOST_CHECK(log_divisor >= 0); + if (log_range > log_count) { + BOOST_CHECK(log_range - log_divisor <= max_splits); + } else if (log_range <= max_finishing_splits) { + BOOST_CHECK(log_divisor == 0); + } + } + } +} + +// Verify that is_sorted_or_find_extremes returns true if the data is sorted, +// and otherwise returns the actual min and max. +void is_sorted_or_find_extremes_test() +{ + vector<int> input; + input.push_back(3); + input.push_back(5); + input.push_back(1); + // Test a sorted input. + vector<int> sorted_input(input); + std::sort(sorted_input.begin(), sorted_input.end()); + vector<int>::iterator max, min; + BOOST_CHECK(detail::is_sorted_or_find_extremes(sorted_input.begin(), + sorted_input.end(), max, min)); + // Test an unsorted input. + BOOST_CHECK(!detail::is_sorted_or_find_extremes(input.begin(), input.end(), + max, min)); + BOOST_CHECK(*min == 1); + BOOST_CHECK(*max == 5); + // Test the comparison function version. + BOOST_CHECK(detail::is_sorted_or_find_extremes(sorted_input.begin(), + sorted_input.end(), max, min, + std::less<int>())); + BOOST_CHECK(!detail::is_sorted_or_find_extremes(sorted_input.begin(), + sorted_input.end(), + max, min, + std::greater<int>())); + BOOST_CHECK(*min == 5); + BOOST_CHECK(*max == 1); + + // Test with floats + vector<float> float_input; + float_input.push_back(.3f); + float_input.push_back(4.0f); + float_input.push_back(.1f); + vector<float> sorted_float_input(float_input); + std::sort(sorted_float_input.begin(), sorted_float_input.end()); + // Test cast_float_iter + int cast_min = detail::cast_float_iter<int, vector<float>::iterator>( + sorted_float_input.begin()); + int cast_max = detail::cast_float_iter<int, vector<float>::iterator>( + sorted_float_input.end() - 1); + BOOST_CHECK(cast_min == float_right_shift()(.1f, 0)); + BOOST_CHECK(cast_max == float_right_shift()(4.0f, 0)); + // Test a sorted input + int div_max, div_min; + BOOST_CHECK(detail::is_sorted_or_find_extremes(sorted_float_input.begin(), + sorted_float_input.end(), + div_max, div_min)); + // Test an unsorted input. + BOOST_CHECK(!detail::is_sorted_or_find_extremes(float_input.begin(), + float_input.end(), + div_max, div_min)); + BOOST_CHECK(div_min == cast_min); + BOOST_CHECK(div_max == cast_max); + + // Test with a right_shift functor. + BOOST_CHECK(detail::is_sorted_or_find_extremes(sorted_float_input.begin(), + sorted_float_input.end(), + div_max, div_min, + float_right_shift())); + // Test an unsorted input. + BOOST_CHECK(!detail::is_sorted_or_find_extremes(float_input.begin(), + float_input.end(), div_max, + div_min, + float_right_shift())); + BOOST_CHECK(div_min == float_right_shift()(.1f, 0)); + BOOST_CHECK(div_max == float_right_shift()(4.0f, 0)); +} + +// Make sure bins are created correctly. +void size_bins_test() { + size_t bin_sizes[1 << detail::max_finishing_splits]; + bin_sizes[0] = 1; + bin_sizes[2] = 7; + const int old_bin_value = 7; + std::vector<int> old_bins; + old_bins.push_back(old_bin_value); + std::vector<vector<int>::iterator> bin_cache; + bin_cache.push_back(old_bins.begin()); + unsigned cache_offset = 1; + unsigned cache_end; + const unsigned bin_count = 2; + std::vector<int>::iterator *new_cache_start = + size_bins(bin_sizes, bin_cache, cache_offset, cache_end, bin_count); + BOOST_CHECK((new_cache_start - &bin_cache[0]) == cache_offset); + BOOST_CHECK(bin_sizes[0] == 0); + BOOST_CHECK(bin_sizes[1] == 0); + BOOST_CHECK(bin_sizes[2] == 7); // shouldn't modify past bin_count + BOOST_CHECK(cache_end == 3); + BOOST_CHECK(bin_cache.size() == cache_end); + BOOST_CHECK(old_bins[0] == old_bin_value); +} + +// Test the specialized 3-way swap loops. +void swap_loop_test() { + size_t bin_sizes[1 << detail::max_finishing_splits]; + bin_sizes[0] = bin_sizes[1] = 2; + bin_sizes[2] = 1; + + // test integer swap loop + vector<int> ints; + const int int_div_min = 3; + const int int_log_divisor = 1; + const unsigned int_offset = int_div_min << int_log_divisor; + ints.push_back(2 + int_offset); + ints.push_back(1 + int_offset); // stays in place + ints.push_back(4 + int_offset); + ints.push_back(3 + int_offset); + ints.push_back(0 + int_offset); + vector<vector<int>::iterator> int_bin_vector; + int_bin_vector.push_back(ints.begin()); + int_bin_vector.push_back(int_bin_vector[0] + bin_sizes[0]); + int_bin_vector.push_back(int_bin_vector[1] + bin_sizes[1]); + vector<int>::iterator next_int_bin_start = int_bin_vector[0]; + vector<int>::iterator *int_bins = &int_bin_vector[0]; + int_right_shift integer_right_shift; + swap_loop(int_bins, next_int_bin_start, 0, integer_right_shift, bin_sizes, + int_log_divisor, int_div_min); + for (unsigned i = 0; i < ints.size(); ++i) { + BOOST_CHECK(ints[i] == int(int_offset + i)); + } + BOOST_CHECK(next_int_bin_start == ints.begin() + bin_sizes[0]); + + // test float swap loop + vector<float> floats; + const int float_four_as_int = float_mem_cast<float, int>(4.0f); + const int float_log_divisor = + rough_log_2_size(float_mem_cast<float, int>(5.0f) - float_four_as_int); + const int float_div_min = float_four_as_int >> float_log_divisor; + floats.push_back(6.0f); + floats.push_back(5.0f); // stays in place + floats.push_back(8.0f); + floats.push_back(7.0f); + floats.push_back(4.0f); + vector<vector<float>::iterator> float_bin_vector; + float_bin_vector.push_back(floats.begin()); + float_bin_vector.push_back(float_bin_vector[0] + bin_sizes[0]); + float_bin_vector.push_back(float_bin_vector[1] + bin_sizes[1]); + vector<float>::iterator next_float_bin_start = float_bin_vector[0]; + vector<float>::iterator *float_bins = &float_bin_vector[0]; + float_swap_loop(float_bins, next_float_bin_start, 0, bin_sizes, + float_log_divisor, float_div_min); + for (unsigned i = 0; i < floats.size(); ++i) { + BOOST_CHECK(floats[i] == 4.0f + i); + } + BOOST_CHECK(next_float_bin_start == floats.begin() + bin_sizes[0]); +} + +} // end anonymous namespace + +// test main +int test_main( int, char*[] ) +{ + roughlog2_test(); + get_min_count_test<int_log_mean_bin_size, int_log_min_split_count, + int_log_finishing_count>(); + get_min_count_test<float_log_mean_bin_size, float_log_min_split_count, + float_log_finishing_count>(); + get_log_divisor_test(); + is_sorted_or_find_extremes_test(); + size_bins_test(); + swap_loop_test(); + return 0; +} diff --git a/src/boost/libs/sort/test/string_sort_test.cpp b/src/boost/libs/sort/test/string_sort_test.cpp new file mode 100644 index 00000000..5ccb1e64 --- /dev/null +++ b/src/boost/libs/sort/test/string_sort_test.cpp @@ -0,0 +1,162 @@ +// Boost Sort library string_sort_test.cpp file ----------------------------// + +// Copyright Steven Ross 2009. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/sort for library home page. + +#include <boost/sort/spreadsort/detail/string_sort.hpp> +#include <boost/sort/spreadsort/string_sort.hpp> +#include <boost/sort/spreadsort/spreadsort.hpp> +// Include unit test framework +#include <boost/test/included/test_exec_monitor.hpp> +#include <boost/test/test_tools.hpp> +#include <vector> +#include <string> + + +using namespace std; +using namespace boost::sort::spreadsort; +using boost::sort::spreadsort::detail::offset_less_than; +using boost::sort::spreadsort::detail::offset_greater_than; +using boost::sort::spreadsort::detail::update_offset; + +struct bracket { + unsigned char operator()(const string &x, size_t offset) const { + return x[offset]; + } +}; + +struct wbracket { + wchar_t operator()(const wstring &x, size_t offset) const { + return x[offset]; + } +}; + +struct get_size { + size_t operator()(const string &x) const{ return x.size(); } +}; + +struct wget_size { + size_t operator()(const wstring &x) const{ return x.size(); } +}; + +static const unsigned input_count = 100000; + +// Test that update_offset finds the first character with a difference. +void update_offset_test() { + vector<string> input; + input.push_back("test1"); + input.push_back("test2"); + size_t char_offset = 1; + update_offset<vector<string>::iterator, unsigned char>(input.begin(), + input.end(), + char_offset); + BOOST_CHECK(char_offset == 4); + + // Functor version + char_offset = 1; + update_offset(input.begin(), input.end(), char_offset, bracket(), get_size()); + BOOST_CHECK(char_offset == 4); +} + +// Test that offset comparison operators only look after the offset. +void offset_comparison_test() { + string input1 = "ab"; + string input2 = "ba"; + string input3 = "aba"; + offset_less_than<string, unsigned char> less_than(0); + offset_greater_than<string, unsigned char> greater_than(0); + BOOST_CHECK(less_than(input1, input2)); + BOOST_CHECK(less_than(input1, input3)); + BOOST_CHECK(!less_than(input2, input1)); + BOOST_CHECK(!less_than(input1, input1)); + BOOST_CHECK(!greater_than(input1, input2)); + BOOST_CHECK(!greater_than(input1, input3)); + BOOST_CHECK(greater_than(input2, input1)); + BOOST_CHECK(!greater_than(input1, input1)); + + // Offset comparisons only check after the specified offset. + offset_less_than<string, unsigned char> offset_less(1); + offset_greater_than<string, unsigned char> offset_greater(1); + BOOST_CHECK(!offset_less(input1, input2)); + BOOST_CHECK(offset_less(input1, input3)); + BOOST_CHECK(offset_less(input2, input1)); + BOOST_CHECK(!offset_less(input1, input1)); + BOOST_CHECK(offset_greater(input1, input2)); + BOOST_CHECK(!offset_greater(input1, input3)); + BOOST_CHECK(!offset_greater(input2, input1)); + BOOST_CHECK(!offset_greater(input1, input1)); +} + +void string_test() +{ + // Prepare inputs + vector<string> base_vec; + const unsigned max_length = 32; + srand(1); + //Generating semirandom numbers + for (unsigned u = 0; u < input_count; ++u) { + unsigned length = rand() % max_length; + string result; + for (unsigned v = 0; v < length; ++v) { + result.push_back(rand() % 256); + } + base_vec.push_back(result); + } + vector<string> sorted_vec = base_vec; + vector<string> test_vec = base_vec; + std::sort(sorted_vec.begin(), sorted_vec.end()); + //Testing basic call + string_sort(test_vec.begin(), test_vec.end()); + BOOST_CHECK(test_vec == sorted_vec); + //Testing boost::sort::spreadsort wrapper + test_vec = base_vec; + boost::sort::spreadsort::spreadsort(test_vec.begin(), test_vec.end()); + BOOST_CHECK(test_vec == sorted_vec); + //Character functors + test_vec = base_vec; + string_sort(test_vec.begin(), test_vec.end(), bracket(), get_size()); + BOOST_CHECK(test_vec == sorted_vec); + //All functors + test_vec = base_vec; + string_sort(test_vec.begin(), test_vec.end(), bracket(), get_size(), + less<string>()); + BOOST_CHECK(test_vec == sorted_vec); + //reverse order + std::sort(sorted_vec.begin(), sorted_vec.end(), greater<string>()); + reverse_string_sort(test_vec.begin(), test_vec.end(), greater<string>()); + BOOST_CHECK(test_vec == sorted_vec); + //reverse order with functors + test_vec = base_vec; + reverse_string_sort(test_vec.begin(), test_vec.end(), bracket(), get_size(), + greater<string>()); + BOOST_CHECK(test_vec == sorted_vec); +} + +// Verify that 0, 1, and input_count empty strings all sort correctly. +void corner_test() { + vector<string> test_vec; + boost::sort::spreadsort::spreadsort(test_vec.begin(), test_vec.end()); + test_vec.resize(1); + boost::sort::spreadsort::spreadsort(test_vec.begin(), test_vec.end()); + BOOST_CHECK(test_vec[0].empty()); + test_vec.resize(input_count); + boost::sort::spreadsort::spreadsort(test_vec.begin(), test_vec.end()); + BOOST_CHECK(test_vec.size() == input_count); + for (unsigned i = 0; i < test_vec.size(); ++i) { + BOOST_CHECK(test_vec[i].empty()); + } +} + +// test main +int test_main( int, char*[] ) +{ + update_offset_test(); + offset_comparison_test(); + string_test(); + corner_test(); + return 0; +} diff --git a/src/boost/libs/sort/test/test.log b/src/boost/libs/sort/test/test.log new file mode 100644 index 00000000..e529dcee --- /dev/null +++ b/src/boost/libs/sort/test/test.log @@ -0,0 +1,37 @@ + +Performing configuration checks + + - symlinks supported : yes (cached) +...patience... +...patience... +...found 2544 targets... +...updating 20 targets... +compile-c-c++ ..\..\..\bin.v2\libs\sort\test\integer_sort.test\msvc-12.0\debug\threading-multi\integer_sort_test.obj +integer_sort_test.cpp +msvc.link ..\..\..\bin.v2\libs\sort\test\integer_sort.test\msvc-12.0\debug\threading-multi\integer_sort.exe +msvc.manifest ..\..\..\bin.v2\libs\sort\test\integer_sort.test\msvc-12.0\debug\threading-multi\integer_sort.exe +testing.capture-output ..\..\..\bin.v2\libs\sort\test\integer_sort.test\msvc-12.0\debug\threading-multi\integer_sort.run + 1 file(s) copied. +**passed** ..\..\..\bin.v2\libs\sort\test\integer_sort.test\msvc-12.0\debug\threading-multi\integer_sort.test +compile-c-c++ ..\..\..\bin.v2\libs\sort\test\float_sort.test\msvc-12.0\debug\threading-multi\float_sort_test.obj +float_sort_test.cpp +msvc.link ..\..\..\bin.v2\libs\sort\test\float_sort.test\msvc-12.0\debug\threading-multi\float_sort.exe +msvc.manifest ..\..\..\bin.v2\libs\sort\test\float_sort.test\msvc-12.0\debug\threading-multi\float_sort.exe +testing.capture-output ..\..\..\bin.v2\libs\sort\test\float_sort.test\msvc-12.0\debug\threading-multi\float_sort.run + 1 file(s) copied. +**passed** ..\..\..\bin.v2\libs\sort\test\float_sort.test\msvc-12.0\debug\threading-multi\float_sort.test +compile-c-c++ ..\..\..\bin.v2\libs\sort\test\string_sort.test\msvc-12.0\debug\threading-multi\string_sort_test.obj +string_sort_test.cpp +msvc.link ..\..\..\bin.v2\libs\sort\test\string_sort.test\msvc-12.0\debug\threading-multi\string_sort.exe +msvc.manifest ..\..\..\bin.v2\libs\sort\test\string_sort.test\msvc-12.0\debug\threading-multi\string_sort.exe +testing.capture-output ..\..\..\bin.v2\libs\sort\test\string_sort.test\msvc-12.0\debug\threading-multi\string_sort.run + 1 file(s) copied. +**passed** ..\..\..\bin.v2\libs\sort\test\string_sort.test\msvc-12.0\debug\threading-multi\string_sort.test +compile-c-c++ ..\..\..\bin.v2\libs\sort\test\sort_detail.test\msvc-12.0\debug\threading-multi\sort_detail_test.obj +sort_detail_test.cpp +msvc.link ..\..\..\bin.v2\libs\sort\test\sort_detail.test\msvc-12.0\debug\threading-multi\sort_detail.exe +msvc.manifest ..\..\..\bin.v2\libs\sort\test\sort_detail.test\msvc-12.0\debug\threading-multi\sort_detail.exe +testing.capture-output ..\..\..\bin.v2\libs\sort\test\sort_detail.test\msvc-12.0\debug\threading-multi\sort_detail.run + 1 file(s) copied. +**passed** ..\..\..\bin.v2\libs\sort\test\sort_detail.test\msvc-12.0\debug\threading-multi\sort_detail.test +...updated 20 targets... diff --git a/src/boost/libs/sort/test/test_block_indirect_sort.cpp b/src/boost/libs/sort/test/test_block_indirect_sort.cpp new file mode 100644 index 00000000..b03f00fe --- /dev/null +++ b/src/boost/libs/sort/test/test_block_indirect_sort.cpp @@ -0,0 +1,186 @@ +//---------------------------------------------------------------------------- +/// @file test_block_indirect_sort.cpp +/// @brief Test program of the block_indirect_sort algorithm +/// +/// @author Copyright (c) 2016 Francisco Jose Tapia (fjtapia@gmail.com )\n +/// Distributed under the Boost Software License, Version 1.0.\n +/// ( See accompanying file LICENSE_1_0.txt or copy at +/// http://www.boost.org/LICENSE_1_0.txt ) +/// @version 0.1 +/// +/// @remarks +//----------------------------------------------------------------------------- +#include <algorithm> +#include <random> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <vector> +#include <ciso646> +#include <boost/test/included/test_exec_monitor.hpp> +#include <boost/test/test_tools.hpp> +#include <boost/sort/sort.hpp> + + +namespace bsc = boost::sort::common; +namespace bsp = boost::sort; +using boost::sort::block_indirect_sort; +using bsc::range; + +// ------------------- vector with 64 bits random numbers -------------------- +std::vector< uint64_t > Vrandom; +const uint64_t NELEM = 2000000; + +void test1 (void) +{ + const uint32_t NElem = 500000; + std::vector< uint64_t > V1; + V1.reserve (NElem); + + //------------------ sorted elements 4 threads -------------------------- + V1.clear ( ); + for (uint32_t i = 0; i < NElem; ++i) V1.push_back (i); + + block_indirect_sort ( V1.begin ( ), V1.end ( ), 4); + for (unsigned i = 1; i < NElem; i++) + { BOOST_CHECK (V1[ i - 1 ] <= V1[ i ]); + }; + + //-------------------- reverse sorted elements 4 threads ------------------ + V1.clear ( ); + for (uint32_t i = 0; i < NElem; ++i) V1.push_back (NElem - i); + + block_indirect_sort ( V1.begin ( ), V1.end ( ), 4); + for (unsigned i = 1; i < NElem; i++) + { BOOST_CHECK (V1[ i - 1 ] <= V1[ i ]); + }; + + //-------------------- equal elements 4 threads --------------------------- + V1.clear ( ); + for (uint32_t i = 0; i < NElem; ++i) V1.push_back (1000); + + block_indirect_sort (V1.begin ( ), V1.end ( ), 4); + for (unsigned i = 1; i < NElem; i++) + { BOOST_CHECK (V1[ i - 1 ] == V1[ i ]); + }; + + //------------------ sorted elements 8 threads -------------------------- + V1.clear ( ); + for (uint32_t i = 0; i < NElem; ++i) V1.push_back (i); + + block_indirect_sort ( V1.begin ( ), V1.end ( ), 8); + for (unsigned i = 1; i < NElem; i++) + { BOOST_CHECK (V1[ i - 1 ] <= V1[ i ]); + }; + + //-------------------- reverse sorted elements 8 threads ------------------ + V1.clear ( ); + for (uint32_t i = 0; i < NElem; ++i) V1.push_back (NElem - i); + + block_indirect_sort ( V1.begin ( ), V1.end ( ), 8); + for (unsigned i = 1; i < NElem; i++) + { BOOST_CHECK (V1[ i - 1 ] <= V1[ i ]); + }; + + //-------------------- equal elements 8 threads --------------------------- + V1.clear ( ); + for (uint32_t i = 0; i < NElem; ++i) V1.push_back (1000); + + block_indirect_sort (V1.begin ( ), V1.end ( ), 8); + for (unsigned i = 1; i < NElem; i++) + { BOOST_CHECK (V1[ i - 1 ] == V1[ i ]); + }; +}; + +void test2 (void) +{ + typedef std::less<uint64_t> compare; + std::vector< uint64_t > V1, V2; + V1.reserve ( NELEM ) ; + + V2 = Vrandom; + std::sort (V2.begin ( ), V2.end ( )); + + //------------------- random elements 0 threads --------------------------- + V1 = Vrandom; + block_indirect_sort (V1.begin ( ), V1.end ( ), compare(), 0); + for (unsigned i = 0; i < V1.size(); i++) + { BOOST_CHECK (V1[i] == V2[i]); + }; + + //------------------- random elements 4 threads --------------------------- + V1 = Vrandom; + block_indirect_sort (V1.begin ( ), V1.end ( ), compare(), 4); + for (unsigned i = 0; i < V1.size(); i++) + { BOOST_CHECK (V1[i] == V2[i]); + }; + + //------------------- random elements 8 threads --------------------------- + V1 = Vrandom; + block_indirect_sort (V1.begin ( ), V1.end ( ), compare(), 8); + for (unsigned i = 0; i < V1.size(); i++) + { BOOST_CHECK (V1[i] == V2[i]); + }; + + //------------------- random elements 16 threads --------------------------- + V1 = Vrandom; + block_indirect_sort ( V1.begin ( ), V1.end ( ), compare(), 16); + for (unsigned i = 0; i < V1.size(); i++) + { BOOST_CHECK (V1[i] == V2[i]); + }; + + //------------------- random elements 100 threads --------------------------- + V1 = Vrandom; + block_indirect_sort ( V1.begin ( ), V1.end ( ), compare(), 100); + for (unsigned i = 1; i < V1.size(); i++) + { BOOST_CHECK (V1[i] == V2[i]); + }; +}; + +template<uint32_t NN> +struct int_array +{ + uint64_t M[NN]; + + int_array(uint64_t number = 0) + { for (uint32_t i = 0; i < NN; ++i) M[i] = number; + }; + + bool operator<(const int_array<NN> &A) const + { return M[0] < A.M[0]; + }; +}; + +template<class IA> +void test_int_array(uint32_t NELEM) +{ + std::vector<IA> V1; + V1.reserve(NELEM); + + for (uint32_t i = 0; i < NELEM; ++i) + V1.emplace_back(Vrandom[i]); + + bsp::block_indirect_sort(V1.begin(), V1.end()); + for (unsigned i = 1; i < NELEM; i++) + { BOOST_CHECK(not (V1[i] < V1[i-1])); + }; +}; +void test3 (void) +{ + test_int_array<int_array<1> >(1u << 20); + test_int_array<int_array<2> >(1u << 19); + test_int_array<int_array<8> >(1u << 17); +} + +int test_main (int, char *[]) +{ + std::mt19937 my_rand (0); + Vrandom.reserve (NELEM); + for (uint32_t i = 0; i < NELEM; ++i) Vrandom.push_back (my_rand ( )); + + test1 ( ); + test2 ( ); + test3 ( ); + + return 0; +}; diff --git a/src/boost/libs/sort/test/test_flat_stable_sort.cpp b/src/boost/libs/sort/test/test_flat_stable_sort.cpp new file mode 100644 index 00000000..83aaaad5 --- /dev/null +++ b/src/boost/libs/sort/test/test_flat_stable_sort.cpp @@ -0,0 +1,140 @@ +//---------------------------------------------------------------------------- +/// @file test_flat_stable_sort.cpp +/// @brief test program of the flat_stable_sort algorithm +/// +/// @author Copyright (c) 2017 Francisco José Tapia (fjtapia@gmail.com )\n +/// Distributed under the Boost Software License, Version 1.0.\n +/// ( See accompanying file LICENSE_1_0.txt or copy at +/// http://www.boost.org/LICENSE_1_0.txt ) +/// @version 0.1 +/// +/// @remarks +//----------------------------------------------------------------------------- +#include <algorithm> +#include <iostream> +#include <random> +#include <vector> +#include <ciso646> +#include <boost/sort/flat_stable_sort/flat_stable_sort.hpp> +#include <boost/test/included/test_exec_monitor.hpp> +#include <boost/test/test_tools.hpp> + +using namespace boost::sort; + +void test1 ( ); +void test2 ( ); +void test3 ( ); + +//---------------- stability test ----------------------------------- +struct xk +{ + unsigned tail : 4; + unsigned num : 28; + xk ( uint32_t n =0 , uint32_t t =0): tail (t), num(n){}; + bool operator< (xk A) const { return (num < A.num); }; +}; + +void test1 ( ) +{ + typedef typename std::vector< xk >::iterator iter_t; + typedef std::less< xk > compare_t; + std::mt19937_64 my_rand (0); + + const uint32_t NMAX = 100000; + + std::vector< xk > V1, V2; + V1.reserve (NMAX); + for (uint32_t i = 0; i < 8; ++i) { + for (uint32_t k = 0; k < NMAX; ++k) { + uint32_t NM = my_rand ( ); + xk G; + G.num = NM >> 3; + G.tail = i; + V1.push_back (G); + }; + }; + V2 = V1; + flat_stable_sort< iter_t, compare_t > (V1.begin ( ), V1.end ( ), compare_t ( )); + std::stable_sort (V2.begin ( ), V2.end ( )); + + BOOST_CHECK (V1.size ( ) == V2.size ( )); + for (uint32_t i = 0; i < V1.size ( ); ++i) { + BOOST_CHECK (V1[ i ].num == V2[ i ].num and + V1[ i ].tail == V2[ i ].tail); + }; +}; + +void test2 (void) +{ + typedef std::less< uint64_t > compare_t; + + const uint32_t NElem = 100000; + std::vector< uint64_t > V1,V2; + std::mt19937_64 my_rand (0); + compare_t comp; + + // ------------------------ random elements ------------------------------- + for (uint32_t i = 0; i < NElem; ++i) V1.push_back (my_rand ( ) % NElem); + V2 = V1; + flat_stable_sort (V1.begin ( ), V1.end ( ), comp); + std::stable_sort (V2.begin ( ), V2.end ( ), comp); + for (unsigned i = 0; i < NElem; i++) { + BOOST_CHECK (V2[ i ] == V1[ i ]); + }; + + // --------------------------- sorted elements ---------------------------- + V1.clear ( ); + for (uint32_t i = 0; i < NElem; ++i) V1.push_back (i); + flat_stable_sort (V1.begin ( ), V1.end ( ), comp); + for (unsigned i = 1; i < NElem; i++) { + BOOST_CHECK (V1[ i - 1 ] <= V1[ i ]); + }; + + //-------------------------- reverse sorted elements ---------------------- + V1.clear ( ); + for (uint32_t i = 0; i < NElem; ++i) V1.push_back (NElem - i); + flat_stable_sort (V1.begin ( ), V1.end ( ), comp); + for (unsigned i = 1; i < NElem; i++) { + BOOST_CHECK (V1[ i - 1 ] <= V1[ i ]); + }; + + //---------------------------- equal elements ---------------------------- + V1.clear ( ); + for (uint32_t i = 0; i < NElem; ++i) V1.push_back (1000); + flat_stable_sort (V1.begin ( ), V1.end ( ), comp); + for (unsigned i = 1; i < NElem; i++) { + BOOST_CHECK (V1[ i - 1 ] == V1[ i ]); + }; +}; + + +void test3 (void) +{ + typedef typename std::vector<xk>::iterator iter_t; + typedef std::less<xk> compare_t; + std::mt19937 my_rand (0); + std::vector<xk> V ; + const uint32_t NELEM = 100000; + V.reserve(NELEM * 10); + + + for (uint32_t k =0 ; k < 10 ; ++k) + { for ( uint32_t i =0 ; i < NELEM ; ++i) + { V.emplace_back(i , k); + }; + iter_t first = V.begin() + (k * NELEM); + iter_t last = first + NELEM ; + std::shuffle( first, last, my_rand); + }; + flat_stable_sort( V.begin() , V.end(), compare_t()); + for ( uint32_t i =0 ; i < ( NELEM * 10); ++i) + { BOOST_CHECK ( V[i].num == (i / 10) and V[i].tail == (i %10) ); + }; +} +int test_main (int, char *[]) +{ + test1 ( ); + test2 ( ); + test3 ( ); + return 0; +}; diff --git a/src/boost/libs/sort/test/test_insert_sort.cpp b/src/boost/libs/sort/test/test_insert_sort.cpp new file mode 100644 index 00000000..c2b93db8 --- /dev/null +++ b/src/boost/libs/sort/test/test_insert_sort.cpp @@ -0,0 +1,163 @@ +//---------------------------------------------------------------------------- +/// @file test_insert_sort.cpp +/// @brief Test program of the insert_sort algorithm +/// +/// @author Copyright (c) 2016 Francisco Jose Tapia (fjtapia@gmail.com )\n +/// Distributed under the Boost Software License, Version 1.0.\n +/// ( See accompanying file LICENSE_1_0.txt or copy at +/// http://www.boost.org/LICENSE_1_0.txt ) +/// @version 0.1 +/// +/// @remarks +//----------------------------------------------------------------------------- +#include <ciso646> +#include <iostream> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <vector> +#include <boost/sort/insert_sort/insert_sort.hpp> +#include <boost/test/included/test_exec_monitor.hpp> +#include <boost/test/test_tools.hpp> + + +using namespace boost::sort; +using namespace std; +using boost::sort::common::util::insert_sorted; + +void test01 (void) +{ + unsigned A[] = {7, 4, 23, 15, 17, 2, 24, 13, 8, 3, 11, + 16, 6, 14, 21, 5, 1, 12, 19, 22, 25, 8}; + + std::less< unsigned > comp; + // Insertion Sort Unordered, not repeated + insert_sort (&A[ 0 ], &A[ 22 ], comp); + for (unsigned i = 0; i < 21; i++) { + BOOST_CHECK (A[ i ] <= A[ i + 1 ]); + }; + + unsigned B[] = {1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 17, 18, 19, 20, 21, 23, 24, 25}; + // Insertion Sort Ordered, not repeated + insert_sort (&B[ 0 ], &B[ 22 ], comp); + for (unsigned i = 0; i < 21; i++) { + BOOST_CHECK (B[ i ] <= B[ i + 1 ]); + }; + + unsigned C[] = {27, 26, 25, 23, 22, 21, 19, 18, 17, 16, 15, + 14, 13, 11, 10, 9, 8, 7, 6, 5, 3, 2}; + // Insertion Sort reverse sorted, not repeated + insert_sort (&C[ 0 ], &C[ 22 ], comp); + for (unsigned i = 0; i < 21; i++) { + BOOST_CHECK (C[ i ] <= C[ i + 1 ]); + }; + + unsigned D[] = {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}; + // Insertion Sort equal elements + insert_sort (&D[ 0 ], &D[ 22 ], comp); + for (unsigned i = 0; i < 21; i++) { + BOOST_CHECK (D[ i ] <= D[ i + 1 ]); + }; + + // Insertion Sort 100 random elements + unsigned F[ 100 ]; + for (unsigned i = 0; i < 100; i++) F[ i ] = rand ( ) % 1000; + insert_sort (&F[ 0 ], &F[ 100 ], comp); + for (unsigned i = 0; i < 99; i++) { + BOOST_CHECK (F[ i ] <= F[ i + 1 ]); + }; + + const unsigned NG = 10000; + // Insertion Sort "<<NG<<" random elements + unsigned G[ NG ]; + for (unsigned i = 0; i < NG; i++) G[ i ] = rand ( ) % 1000; + insert_sort (&G[ 0 ], &G[ NG ], comp); + for (unsigned i = 0; i < NG - 1; i++) { + BOOST_CHECK (G[ i ] <= G[ i + 1 ]); + }; +}; +void test02 (void) +{ + typedef typename std::vector< uint64_t >::iterator iter_t; + const uint32_t NELEM = 6667; + std::vector< uint64_t > A; + std::less< uint64_t > comp; + + for (uint32_t i = 0; i < 1000; ++i) A.push_back (0); + for (uint32_t i = 0; i < NELEM; ++i) A.push_back (NELEM - i); + for (uint32_t i = 0; i < 1000; ++i) A.push_back (0); + + insert_sort (A.begin ( ) + 1000, A.begin ( ) + (1000 + NELEM), comp); + + for (iter_t it = A.begin ( ) + 1000; it != A.begin ( ) + (1000 + NELEM); + ++it) + { + BOOST_CHECK ((*(it - 1)) <= (*it)); + }; + BOOST_CHECK (A[ 998 ] == 0 and A[ 999 ] == 0 and A[ 1000 + NELEM ] == 0 and + A[ 1001 + NELEM ] == 0); + + + A.clear ( ); + for (uint32_t i = 0; i < 1000; ++i) A.push_back (999999999); + for (uint32_t i = 0; i < NELEM; ++i) A.push_back (NELEM - i); + for (uint32_t i = 0; i < 1000; ++i) A.push_back (999999999); + + insert_sort (A.begin ( ) + 1000, A.begin ( ) + (1000 + NELEM), comp); + + for (iter_t it = A.begin ( ) + 1001; it != A.begin ( ) + (1000 + NELEM); + ++it) + { + BOOST_CHECK ((*(it - 1)) <= (*it)); + }; + BOOST_CHECK (A[ 998 ] == 999999999 and A[ 999 ] == 999999999 and + A[ 1000 + NELEM ] == 999999999 and + A[ 1001 + NELEM ] == 999999999); +}; + + +void test03 ( void) +{ + std::vector<uint32_t> V {1,3,5,2,4}; + std::less<uint32_t> comp ; + uint32_t aux[10] ; + + insert_sorted ( V.begin() , V.begin()+3, V.end(), comp, aux); + //insert_partial_sort ( V.begin() , V.begin()+3, V.end() , comp); + for ( uint32_t i =0 ; i < V.size() ; ++i) + std::cout<<V[i]<<", "; + std::cout<<std::endl; + + V ={3,5,7,9,11,13,15,17,19,8,6,10,4,2}; + insert_sorted ( V.begin() , V.begin()+9, V.end() , comp, aux); + //insert_partial_sort ( V.begin() , V.begin()+9, V.end() , comp); + for ( uint32_t i =0 ; i < V.size() ; ++i) + std::cout<<V[i]<<", "; + std::cout<<std::endl; + + V ={13,15,17,19,21,23,35,27,29,8,6,10,4,2}; + insert_sorted ( V.begin() , V.begin()+9, V.end() , comp, aux); + //insert_partial_sort ( V.begin() , V.begin()+9, V.end() , comp); + for ( uint32_t i =0 ; i < V.size() ; ++i) + std::cout<<V[i]<<", "; + std::cout<<std::endl; + + V ={3,5,7,9,11,13,15,17,19,28,26,30,24,22}; + insert_sorted ( V.begin() , V.begin()+9, V.end() , comp, aux); + //insert_partial_sort ( V.begin() , V.begin()+9, V.end() , comp); + for ( uint32_t i =0 ; i < V.size() ; ++i) + std::cout<<V[i]<<", "; + std::cout<<std::endl; + + + +} +int test_main (int, char *[]) +{ + test01 ( ); + test02 ( ); + test03 ( ); + return 0; +} diff --git a/src/boost/libs/sort/test/test_parallel_stable_sort.cpp b/src/boost/libs/sort/test/test_parallel_stable_sort.cpp new file mode 100644 index 00000000..6c1dace6 --- /dev/null +++ b/src/boost/libs/sort/test/test_parallel_stable_sort.cpp @@ -0,0 +1,183 @@ +//---------------------------------------------------------------------------- +/// @file test_parallel_stable_sort.cpp +/// @brief test program of the parallel_stable_sort algorithm +/// +/// @author Copyright (c) 2016 Francisco Jose Tapia (fjtapia@gmail.com )\n +/// Distributed under the Boost Software License, Version 1.0.\n +/// ( See accompanying file LICENSE_1_0.txt or copy at +/// http://www.boost.org/LICENSE_1_0.txt ) +/// @version 0.1 +/// +/// @remarks +//----------------------------------------------------------------------------- +#include <ciso646> +#include <cstdio> +#include <cstdlib> +#include <ctime> +#include <vector> +#include <random> +#include <algorithm> +#include <boost/sort/parallel_stable_sort/parallel_stable_sort.hpp> +#include <boost/test/included/test_exec_monitor.hpp> +#include <boost/test/test_tools.hpp> + +namespace bss = boost::sort; + + +struct xk +{ + unsigned tail : 4; + unsigned num : 28; + xk ( uint32_t n =0 , uint32_t t =0): tail (t), num(n){}; + bool operator< (xk A) const { return (num < A.num); }; +}; +void test1() +{ + + std::mt19937_64 my_rand(0); + + const uint32_t NMAX = 100000; + + std::vector<xk> V1, V2, V3; + V1.reserve(NMAX); + for (uint32_t i = 0; i < 8; ++i) + { + for (uint32_t k = 0; k < NMAX; ++k) + { uint32_t NM = my_rand(); + xk G; + G.num = NM >> 3; + G.tail = i; + V1.push_back(G); + }; + }; + V3 = V2 = V1; + bss::parallel_stable_sort(V1.begin(), V1.end()); + std::stable_sort(V2.begin(), V2.end()); + bss::parallel_stable_sort(V3.begin(), V3.end(), 0); + + BOOST_CHECK(V1.size() == V2.size()); + for (uint32_t i = 0; i < V1.size(); ++i) + { BOOST_CHECK(V1[i].num == V2[i].num and V1[i].tail == V2[i].tail); + }; + + BOOST_CHECK(V3.size() == V2.size()); + for (uint32_t i = 0; i < V3.size(); ++i) + { BOOST_CHECK(V3[i].num == V2[i].num and V3[i].tail == V2[i].tail); + }; +}; + +void test2(void) +{ + const uint32_t NElem = 2000000; + std::vector<uint64_t> V1; + + // ----------------- sorted elements ------------------------------------ + V1.clear(); + for (uint32_t i = 0; i < NElem; ++i) V1.push_back(i); + bss::parallel_stable_sort(V1.begin(), V1.end()); + for (unsigned i = 1; i < NElem; i++) + { BOOST_CHECK(V1[i - 1] <= V1[i]); + }; + + // ------------- reverse sorted elements -------------------------------- + V1.clear(); + for (uint32_t i = 0; i < NElem; ++i) V1.push_back(NElem - i); + bss::parallel_stable_sort(V1.begin(), V1.end()); + for (unsigned i = 1; i < NElem; i++) + { BOOST_CHECK(V1[i - 1] <= V1[i]); + }; + + // -------------------- equals elements ----------------------------------- + V1.clear(); + for (uint32_t i = 0; i < NElem; ++i) V1.push_back(1000); + bss::parallel_stable_sort(V1.begin(), V1.end()); + for (unsigned i = 1; i < NElem; i++) + { BOOST_CHECK(V1[i - 1] == V1[i]); + }; +}; +void test3(void) +{ + const uint32_t NElem = 2000000; + std::vector<uint64_t> V1,V2,V3; + std::mt19937_64 my_rand(0); + + for (uint32_t i = 0; i < NElem; ++i) V1.push_back(my_rand() % NElem); + V3 = V2 = V1; + std::stable_sort (V2.begin(), V2.end()); + + + // --------------- unsorted elements 0 threads ---------------------------- + V3 = V1; + bss::parallel_stable_sort(V3.begin(), V3.end(), 0); + for (unsigned i = 0; i < NElem; i++) + { BOOST_CHECK(V3[i] == V2[i]); + }; + + // --------------- unsorted elements ------------------------------------- + V3 = V1; + bss::parallel_stable_sort(V3.begin(), V3.end()); + for (unsigned i = 0; i < NElem; i++) + { BOOST_CHECK(V3[i] == V2[i]); + }; + + // --------------- unsorted elements 100 threads ---------------------------- + V3 = V1; + bss::parallel_stable_sort(V3.begin(), V3.end(), 100); + for (unsigned i = 0; i < NElem; i++) + { BOOST_CHECK(V3[i] == V2[i]); + }; +}; + +void test4(void) +{ + typedef std::less<uint64_t> compare; + const uint32_t KMax = 66000; + + std::vector<uint64_t> K, M; + std::mt19937_64 my_rand(0); + + for (uint32_t i = 0; i < KMax; ++i) + K.push_back(my_rand()); + M = K; + + bss::parallel_stable_sort(K.begin(), K.end(), compare(), 300); + + std::stable_sort(M.begin(), M.end(), compare()); + for (unsigned i = 0; i < KMax; i++) + BOOST_CHECK(M[i] == K[i]); +}; + +void test5 (void) +{ + typedef typename std::vector<xk>::iterator iter_t; + std::mt19937 my_rand (0); + std::vector<xk> V ; + const uint32_t NELEM = 100000; + V.reserve(NELEM * 10); + + + for (uint32_t k =0 ; k < 10 ; ++k) + { for ( uint32_t i =0 ; i < NELEM ; ++i) + { V.emplace_back(i , k); + }; + iter_t first = V.begin() + (k * NELEM); + iter_t last = first + NELEM ; + std::shuffle( first, last, my_rand); + }; + bss::parallel_stable_sort( V.begin() , V.end()); + for ( uint32_t i =0 ; i < ( NELEM * 10); ++i) + { BOOST_CHECK ( V[i].num == (i / 10) and V[i].tail == (i %10) ); + }; +} + + +int test_main(int, char *[]) +{ + test1(); + test2(); + test3(); + test4(); + test5(); + return 0; +}; + diff --git a/src/boost/libs/sort/test/test_pdqsort.cpp b/src/boost/libs/sort/test/test_pdqsort.cpp new file mode 100644 index 00000000..d82bf4ea --- /dev/null +++ b/src/boost/libs/sort/test/test_pdqsort.cpp @@ -0,0 +1,163 @@ +// Boost Sort library test_pdqsort.cpp file ----------------------------// + +// Copyright Orson Peters 2017. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/sort for library home page. + + +#include <vector> +#include <string> +#include <random> + +#include <boost/sort/pdqsort/pdqsort.hpp> +// Include unit test framework +#include <boost/test/included/test_exec_monitor.hpp> +#include <boost/test/test_tools.hpp> + + +// Gives a vector containing strings with the same order. +std::string u32_to_str(uint32_t n) { + std::string r; + for (int i = 0; i < 32; ++i) { + r = char('0' + (n & 1)) + r; + n >>= 1; + } + return r; +} + +std::vector<std::string> vec_u32_to_str(const std::vector<uint32_t>& v) { + std::vector<std::string> r; r.reserve(v.size()); + for (size_t i = 0; i < v.size(); ++i) { + r.push_back(u32_to_str(v[i])); + } + return r; +} + + +// Distributions. +std::vector<uint32_t> shuffled(size_t size, std::mt19937_64& rng) { + std::vector<uint32_t> v; v.reserve(size); + for (uint32_t i = 0; i < size; ++i) v.push_back(i); + std::shuffle(v.begin(), v.end(), rng); + return v; +} + +std::vector<uint32_t> shuffled_16_values(size_t size, std::mt19937_64& rng) { + std::vector<uint32_t> v; v.reserve(size); + for (uint32_t i = 0; i < size; ++i) v.push_back(i % 16); + std::shuffle(v.begin(), v.end(), rng); + return v; +} + +std::vector<uint32_t> all_equal(size_t size, std::mt19937_64& rng) { + std::vector<uint32_t> v; v.reserve(size); + for (uint32_t i = 0; i < size; ++i) v.push_back(0); + return v; +} + +std::vector<uint32_t> ascending(size_t size, std::mt19937_64& rng) { + std::vector<uint32_t> v; v.reserve(size); + for (uint32_t i = 0; i < size; ++i) v.push_back(i); + return v; +} + +std::vector<uint32_t> descending(size_t size, std::mt19937_64& rng) { + std::vector<uint32_t> v; v.reserve(size); + for (uint32_t i = size - 1; ; --i) { + v.push_back(i); + if (i == 0) break; + } + return v; +} + +std::vector<uint32_t> pipe_organ(size_t size, std::mt19937_64& rng) { + std::vector<uint32_t> v; v.reserve(size); + for (uint32_t i = 0; i < size/2; ++i) v.push_back(i); + for (uint32_t i = size/2; i < size; ++i) v.push_back(size - i); + return v; +} + +std::vector<uint32_t> push_front(size_t size, std::mt19937_64& rng) { + std::vector<uint32_t> v; v.reserve(size); + for (uint32_t i = 1; i < size; ++i) v.push_back(i); + v.push_back(0); + return v; +} + +std::vector<uint32_t> push_middle(size_t size, std::mt19937_64& rng) { + std::vector<uint32_t> v; v.reserve(size); + for (uint32_t i = 0; i < size; ++i) { + if (i != size/2) v.push_back(i); + } + v.push_back(size/2); + return v; +} + + +// Tests. +typedef std::vector<uint32_t> (*DistrF)(size_t, std::mt19937_64&); +void execute_test(DistrF distr, std::string distr_name, int repeats) { + // In C++14 we'd just use std::less<>(). + std::less<uint32_t> u32less; + std::greater<uint32_t> u32greater; + std::less<std::string> sless; + std::greater<std::string> sgreater; + + for (size_t sz = 1; sz <= 1000; sz *= 10) { + // Consistent but pseudorandom tests. + std::mt19937_64 rng; rng.seed(0); + + for (int i = 0; i < repeats; ++i) { + std::vector<uint32_t> u32l = distr(sz, rng); + std::vector<uint32_t> u32g = u32l; + std::vector<std::string> sl = vec_u32_to_str(u32l); + std::vector<std::string> sg = sl; + + boost::sort::pdqsort(u32l.begin(), u32l.end(), u32less); + boost::sort::pdqsort(u32g.begin(), u32g.end(), u32greater); + boost::sort::pdqsort(sl.begin(), sl.end(), sless); + boost::sort::pdqsort(sg.begin(), sg.end(), sgreater); + + BOOST_CHECK_MESSAGE( + std::is_sorted(u32l.begin(), u32l.end(), u32less), + "pdqsort<uint32_t, std::less> " + distr_name + " failed with size " + std::to_string(sz) + ); + + BOOST_CHECK_MESSAGE( + std::is_sorted(u32g.begin(), u32g.end(), u32greater), + "pdqsort<uint32_t, std::greater> " + distr_name + " failed with size " + std::to_string(sz) + ); + + BOOST_CHECK_MESSAGE( + std::is_sorted(sl.begin(), sl.end(), sless), + "pdqsort<std::string, std::less> " + distr_name + " failed with size " + std::to_string(sz) + ); + + BOOST_CHECK_MESSAGE( + std::is_sorted(sg.begin(), sg.end(), sgreater), + "pdqsort<std::string, std::greater> " + distr_name + " failed with size " + std::to_string(sz) + ); + } + } +} + + +// test main +int test_main(int argc, char** argv) { + // No unused warning. + (void) argc; (void) argv; + + execute_test(shuffled, "shuffled", 100); + execute_test(shuffled_16_values, "shuffled_16_values", 100); + execute_test(all_equal, "all_equal", 1); + execute_test(ascending, "ascending", 1); + execute_test(descending, "descending", 1); + execute_test(pipe_organ, "pipe_organ", 1); + execute_test(push_front, "push_front", 1); + execute_test(push_middle, "push_middle", 1); + + return 0; +} diff --git a/src/boost/libs/sort/test/test_sample_sort.cpp b/src/boost/libs/sort/test/test_sample_sort.cpp new file mode 100644 index 00000000..a83634f2 --- /dev/null +++ b/src/boost/libs/sort/test/test_sample_sort.cpp @@ -0,0 +1,181 @@ +//---------------------------------------------------------------------------- +/// @file test_sample_sort.cpp +/// @brief test sample_sort algorithm +/// +/// @author Copyright (c) 2016 Francisco Jose Tapia (fjtapia@gmail.com )\n +/// Distributed under the Boost Software License, Version 1.0.\n +/// ( See accompanying file LICENSE_1_0.txt or copy at +/// http://www.boost.org/LICENSE_1_0.txt ) +/// @version 0.1 +/// +/// @remarks +//----------------------------------------------------------------------------- +#include <ciso646> +#include <cstdlib> +#include <ctime> +#include <algorithm> +#include <vector> +#include <random> +#include <boost/sort/sample_sort/sample_sort.hpp> +#include <boost/test/included/test_exec_monitor.hpp> +#include <boost/test/test_tools.hpp> + +namespace bss = boost::sort; + + +struct xk +{ + unsigned tail : 4; + unsigned num : 28; + xk ( uint32_t n =0 , uint32_t t =0): tail (t), num(n){}; + bool operator< (xk A) const { return (num < A.num); }; +}; +void test1() +{ + + std::mt19937_64 my_rand(0); + + const uint32_t NMAX = 100000; + + std::vector<xk> V1, V2, V3; + V1.reserve(NMAX); + for (uint32_t i = 0; i < 8; ++i) + { + for (uint32_t k = 0; k < NMAX; ++k) + { uint32_t NM = my_rand(); + xk G; + G.num = NM >> 3; + G.tail = i; + V1.push_back(G); + }; + }; + V3 = V2 = V1; + bss::sample_sort(V1.begin(), V1.end()); + std::stable_sort(V2.begin(), V2.end()); + bss::sample_sort(V3.begin(), V3.end(), 0); + + BOOST_CHECK(V1.size() == V2.size()); + for (uint32_t i = 0; i < V1.size(); ++i) + { BOOST_CHECK(V1[i].num == V2[i].num and V1[i].tail == V2[i].tail); + }; + + BOOST_CHECK(V3.size() == V2.size()); + for (uint32_t i = 0; i < V3.size(); ++i) + { BOOST_CHECK(V3[i].num == V2[i].num and V3[i].tail == V2[i].tail); + }; +}; + +void test2(void) +{ + const uint32_t NElem = 2000000; + std::vector<uint64_t> V1; + + // ----------------- sorted elements ------------------------------------ + V1.clear(); + for (uint32_t i = 0; i < NElem; ++i) V1.push_back(i); + bss::sample_sort(V1.begin(), V1.end()); + for (unsigned i = 1; i < NElem; i++) + { BOOST_CHECK(V1[i - 1] <= V1[i]); + }; + + // ------------- reverse sorted elements -------------------------------- + V1.clear(); + for (uint32_t i = 0; i < NElem; ++i) V1.push_back(NElem - i); + bss::sample_sort(V1.begin(), V1.end()); + for (unsigned i = 1; i < NElem; i++) + { BOOST_CHECK(V1[i - 1] <= V1[i]); + }; + + // -------------------- equals elements ----------------------------------- + V1.clear(); + for (uint32_t i = 0; i < NElem; ++i) V1.push_back(1000); + bss::sample_sort(V1.begin(), V1.end()); + for (unsigned i = 1; i < NElem; i++) + { BOOST_CHECK(V1[i - 1] == V1[i]); + }; +}; +void test3(void) +{ + typedef std::less<uint64_t> compare; + const uint32_t NElem = 2000000; + std::vector<uint64_t> V1,V2,V3; + std::mt19937_64 my_rand(0); + + for (uint32_t i = 0; i < NElem; ++i) V1.push_back(my_rand() % NElem); + V3 = V2 = V1; + std::stable_sort (V2.begin(), V2.end()); + + + // --------------- unsorted elements 0 threads ---------------------------- + V3 = V1; + bss::sample_sort(V3.begin(), V3.end(), compare(), 0); + for (unsigned i = 0; i < NElem; i++) + { BOOST_CHECK(V3[i] == V2[i]); + }; + + // --------------- unsorted elements ------------------------------------- + V3 = V1; + bss::sample_sort(V3.begin(), V3.end(), compare()); + for (unsigned i = 0; i < NElem; i++) + { BOOST_CHECK(V3[i] == V2[i]); + }; + + // --------------- unsorted elements 100 threads ---------------------------- + V3 = V1; + bss::sample_sort(V3.begin(), V3.end(), compare(), 100); + for (unsigned i = 0; i < NElem; i++) + { BOOST_CHECK(V3[i] == V2[i]); + }; +}; + +void test4(void) +{ + const uint32_t KMax = 66000; + + std::vector<uint64_t> K, M; + std::mt19937_64 my_rand(0); + + for (uint32_t i = 0; i < KMax; ++i) + K.push_back(my_rand()); + M = K; + + bss::sample_sort(K.begin(), K.end(), 300); + + std::stable_sort(M.begin(), M.end()); + for (unsigned i = 0; i < KMax; i++) + BOOST_CHECK(M[i] == K[i]); +}; + +void test5 (void) +{ + typedef typename std::vector<xk>::iterator iter_t; + std::mt19937 my_rand (0); + std::vector<xk> V ; + const uint32_t NELEM = 100000; + V.reserve(NELEM * 10); + + + for (uint32_t k =0 ; k < 10 ; ++k) + { for ( uint32_t i =0 ; i < NELEM ; ++i) + { V.emplace_back(i , k); + }; + iter_t first = V.begin() + (k * NELEM); + iter_t last = first + NELEM ; + std::shuffle( first, last, my_rand); + }; + bss::sample_sort( V.begin() , V.end()); + for ( uint32_t i =0 ; i < ( NELEM * 10); ++i) + { BOOST_CHECK ( V[i].num == (i / 10) and V[i].tail == (i %10) ); + }; +} + + +int test_main(int, char *[]) +{ + test1(); + test2(); + test3(); + test4(); + test5(); + return 0; +}; diff --git a/src/boost/libs/sort/test/test_spinsort.cpp b/src/boost/libs/sort/test/test_spinsort.cpp new file mode 100644 index 00000000..b8e2f268 --- /dev/null +++ b/src/boost/libs/sort/test/test_spinsort.cpp @@ -0,0 +1,180 @@ +//---------------------------------------------------------------------------- +/// @file test_spinsort.cpp +/// @brief test program of the spinsort algorithm +/// +/// @author Copyright (c) 2016 Francisco José Tapia (fjtapia@gmail.com )\n +/// Distributed under the Boost Software License, Version 1.0.\n +/// ( See accompanying file LICENSE_1_0.txt or copy at +/// http://www.boost.org/LICENSE_1_0.txt ) +/// @version 0.1 +/// +/// @remarks +//----------------------------------------------------------------------------- +#include <ciso646> +#include <algorithm> +#include <iostream> +#include <cstdio> +#include <cstdlib> +#include <ctime> +#include <vector> +#include <random> +#include <boost/sort/spinsort/spinsort.hpp> +#include <boost/test/included/test_exec_monitor.hpp> +#include <boost/test/test_tools.hpp> + + +using namespace boost::sort; +using spin_detail::check_stable_sort; +using spin_detail::range_sort; +using common::range; + +void test1 ( ); +void test2 ( ); +void test3 ( ); +void test4 ( ); + +//---------------- stability test ----------------------------------- +struct xk +{ + unsigned tail : 4; + unsigned num : 28; + xk ( uint32_t n =0 , uint32_t t =0): tail (t), num(n){}; + bool operator< (xk A) const { return (num < A.num); }; +}; + +void test1 ( ) +{ + typedef std::less< xk > compare_t; + std::mt19937_64 my_rand (0); + + const uint32_t NMAX = 100000; + + std::vector< xk > V1, V2; + V1.reserve (NMAX); + for (uint32_t i = 0; i < 8; ++i) { + for (uint32_t k = 0; k < NMAX; ++k) { + uint32_t NM = my_rand ( ); + xk G; + G.num = NM >> 3; + G.tail = i; + V1.push_back (G); + }; + }; + V2 = V1; + spinsort (V1.begin ( ), V1.end ( ), compare_t ( )); + std::stable_sort (V2.begin ( ), V2.end ( )); + + BOOST_CHECK (V1.size ( ) == V2.size ( )); + for (uint32_t i = 0; i < V1.size ( ); ++i) { + BOOST_CHECK (V1[ i ].num == V2[ i ].num and + V1[ i ].tail == V2[ i ].tail); + }; +}; + +void test2 (void) +{ + typedef std::less< uint64_t > compare_t; + + const uint32_t NElem = 100000; + std::vector< uint64_t > V1,V2; + std::mt19937_64 my_rand (0); + compare_t comp; + + // ------------------------ random elements ------------------------------- + for (uint32_t i = 0; i < NElem; ++i) V1.push_back (my_rand ( ) % NElem); + V2 = V1; + spinsort (V1.begin ( ), V1.end ( ), comp); + std::stable_sort (V2.begin ( ), V2.end ( ), comp); + for (unsigned i = 0; i < NElem; i++) { + BOOST_CHECK (V2[ i ] == V1[ i ]); + }; + + // --------------------------- sorted elements ---------------------------- + V1.clear ( ); + for (uint32_t i = 0; i < NElem; ++i) V1.push_back (i); + spinsort (V1.begin ( ), V1.end ( ), comp); + for (unsigned i = 1; i < NElem; i++) { + BOOST_CHECK (V1[ i - 1 ] <= V1[ i ]); + }; + + //-------------------------- reverse sorted elements ---------------------- + V1.clear ( ); + for (uint32_t i = 0; i < NElem; ++i) V1.push_back (NElem - i); + spinsort (V1.begin ( ), V1.end ( ), comp); + for (unsigned i = 1; i < NElem; i++) { + BOOST_CHECK (V1[ i - 1 ] <= V1[ i ]); + }; + + //---------------------------- equal elements ---------------------------- + V1.clear ( ); + for (uint32_t i = 0; i < NElem; ++i) V1.push_back (1000); + spinsort (V1.begin ( ), V1.end ( ), comp); + for (unsigned i = 1; i < NElem; i++) { + BOOST_CHECK (V1[ i - 1 ] == V1[ i ]); + }; +}; + + +void test3 (void) +{ + typedef typename std::vector<uint64_t>::iterator iter_t ; + typedef range<iter_t> range_it ; + std::less<uint64_t> comp ; + + std::vector<uint64_t> V = { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, + 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, + 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, + 14, 2, 4, 6, 8, 10, 12, 16, 18, 20}; + range_it rdata (V.begin() , V.end()); + std::vector<uint64_t> aux (40,0 ); + range_it raux ( aux.begin() , aux.end()); + + check_stable_sort ( rdata, raux, comp ); + for ( uint32_t i =0 ; i < V.size() ; ++i) + std::cout<<V[i]<<", "; + std::cout<<std::endl; + + V = {59, 57, 55, 53, 51, 49, 47, 45, 43, 41, + 39, 37, 35, 33, 31, 29, 27, 25, 23, 21, + 19, 17, 15, 13, 11, 9, 7, 5, 3, 1, + 14, 2, 6, 16, 18, 20, 12, 4, 8, 10}; + rdata = range_it (V.begin() , V.end()); + aux.assign (40,0); + raux = range_it ( aux.begin() , aux.end()); + check_stable_sort ( rdata, raux, comp ); + for ( uint32_t i =0 ; i < V.size() ; ++i) + std::cout<<V[i]<<", "; + std::cout<<std::endl; + +} +void test4 (void) +{ + typedef typename std::vector<xk>::iterator iter_t; + typedef std::less<xk> compare_t; + std::mt19937 my_rand (0); + std::vector<xk> V ; + const uint32_t NELEM = 100000; + V.reserve(NELEM * 10); + + + for (uint32_t k =0 ; k < 10 ; ++k) + { for ( uint32_t i =0 ; i < NELEM ; ++i) + { V.emplace_back(i , k); + }; + iter_t first = V.begin() + (k * NELEM); + iter_t last = first + NELEM ; + std::shuffle( first, last, my_rand); + }; + spinsort( V.begin() , V.end(), compare_t()); + for ( uint32_t i =0 ; i < ( NELEM * 10); ++i) + { BOOST_CHECK ( V[i].num == (i / 10) and V[i].tail == (i %10) ); + }; +} +int test_main (int, char *[]) +{ + test1 ( ); + test2 ( ); + test3 ( ); + test4 ( ); + return 0; +}; |