summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/sort/test
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
commit483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch)
treee5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/boost/libs/sort/test
parentInitial commit. (diff)
downloadceph-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.v265
-rw-r--r--src/boost/libs/sort/test/float_sort_test.cpp155
-rw-r--r--src/boost/libs/sort/test/integer_sort_test.cpp131
-rw-r--r--src/boost/libs/sort/test/list.txt15
-rw-r--r--src/boost/libs/sort/test/sort_detail_test.cpp294
-rw-r--r--src/boost/libs/sort/test/string_sort_test.cpp162
-rw-r--r--src/boost/libs/sort/test/test.log37
-rw-r--r--src/boost/libs/sort/test/test_block_indirect_sort.cpp186
-rw-r--r--src/boost/libs/sort/test/test_flat_stable_sort.cpp140
-rw-r--r--src/boost/libs/sort/test/test_insert_sort.cpp163
-rw-r--r--src/boost/libs/sort/test/test_parallel_stable_sort.cpp183
-rw-r--r--src/boost/libs/sort/test/test_pdqsort.cpp163
-rw-r--r--src/boost/libs/sort/test/test_sample_sort.cpp181
-rw-r--r--src/boost/libs/sort/test/test_spinsort.cpp180
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;
+};