]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/sort/test/float_sort_test.cpp
update sources to v12.2.4
[ceph.git] / ceph / src / boost / libs / sort / test / float_sort_test.cpp
CommitLineData
3a9019d9
FG
1// Boost Sort library float_sort_test.cpp file -----------------------------//\r
2\r
3// Copyright Steven Ross 2014. Use, modification and\r
4// distribution is subject to the Boost Software License, Version\r
5// 1.0. (See accompanying file LICENSE_1_0.txt or copy at\r
6// http://www.boost.org/LICENSE_1_0.txt)\r
7\r
8// See http://www.boost.org/libs/sort for library home page.\r
9\r
10#include <boost/sort/spreadsort/spreadsort.hpp>\r
11// Include unit test framework\r
12#include <boost/test/included/test_exec_monitor.hpp>\r
13#include <boost/test/test_tools.hpp>\r
14#include <vector>\r
15\r
16\r
17using namespace std;\r
18using namespace boost::sort::spreadsort;\r
19\r
20//Casting to an integer before bitshifting\r
21struct rightshift {\r
22 int operator()(const float &x, const unsigned offset) const { \r
23 return float_mem_cast<float, int>(x) >> offset; \r
24 }\r
25};\r
26\r
27struct rightshift_64 {\r
28 boost::int64_t operator()(const double &x, const boost::uint64_t offset) const\r
29 { \r
30 return float_mem_cast<double, boost::int64_t>(x) >> offset; \r
31 }\r
32};\r
33\r
34boost::int32_t \r
35rand_32(bool sign = true) {\r
36 boost::int32_t result = rand() | (rand()<< 16);\r
37 if (rand() % 2)\r
38 result |= 1 << 15;\r
39 //Adding the sign bit\r
40 if (sign && (rand() % 2))\r
41 result *= -1;\r
42 return result;\r
43}\r
44\r
45static const unsigned input_count = 1000000;\r
46\r
47// Helper class to run tests across all float_sort interface variants.\r
48template<class FloatType, class RightShift>\r
49void test_vector(vector<FloatType> base_vec, RightShift shifter) {\r
50 vector<FloatType> sorted_vec = base_vec;\r
51 vector<FloatType> test_vec = base_vec;\r
52 std::sort(sorted_vec.begin(), sorted_vec.end());\r
53 //Testing boost::sort::spreadsort version\r
54 test_vec = base_vec;\r
55 boost::sort::spreadsort::spreadsort(test_vec.begin(), test_vec.end());\r
56 BOOST_CHECK(test_vec == sorted_vec);\r
57 //One functor\r
58 test_vec = base_vec;\r
59 float_sort(test_vec.begin(), test_vec.end(), shifter);\r
60 BOOST_CHECK(test_vec == sorted_vec);\r
61 //Both functors\r
62 test_vec = base_vec;\r
63 float_sort(test_vec.begin(), test_vec.end(), shifter, less<FloatType>());\r
64 BOOST_CHECK(test_vec == sorted_vec);\r
65}\r
66\r
67void float_test()\r
68{\r
69 // Prepare inputs\r
70 vector<float> base_vec;\r
71\r
72 //Generating semirandom numbers that will work for basic testing\r
73 for (unsigned u = 0; u < input_count; ++u) {\r
74 float val = float(rand_32());\r
75 //As std::sort gives arbitrary results for NaNs and 0.0 vs. -0.0, treat all\r
76 //those as just 0.0 for testing\r
77 if (!(val < 0.0) && !(0.0 < val))\r
78 base_vec.push_back(0.0);\r
79 else\r
80 base_vec.push_back(val);\r
81 }\r
82 test_vector(base_vec, rightshift());\r
83\r
84 // Trying both positive and negative sorted and reverse sorted data.\r
85 base_vec.clear();\r
86 for (size_t i = 0; i < input_count; ++i) base_vec.push_back(-i);\r
87 test_vector(base_vec, rightshift());\r
88 base_vec.clear();\r
89 for (size_t i = 0; i < input_count; ++i) base_vec.push_back(i - input_count);\r
90 test_vector(base_vec, rightshift());\r
91 base_vec.clear();\r
92 for (size_t i = 0; i < input_count; ++i) base_vec.push_back(input_count - i);\r
93 test_vector(base_vec, rightshift());\r
94 base_vec.clear();\r
95 for (size_t i = 0; i < input_count; ++i) base_vec.push_back(i);\r
96 test_vector(base_vec, rightshift());\r
97 base_vec.clear();\r
98 for (size_t i = 0; i < input_count; ++i) base_vec.push_back(i);\r
99 for (size_t i = 0; i < input_count; i += 2) base_vec[i] *= -1;\r
100 test_vector(base_vec, rightshift());\r
101}\r
102\r
103void double_test() {\r
104 vector<double> base_vec;\r
105 for (unsigned u = 0; u < input_count; ++u) {\r
106 double val = double\r
107 ((((boost::int64_t)rand_32()) << ((8 * sizeof(int)) -1)) + rand_32(false));\r
108 //As std::sort gives arbitrary results for NaNs and 0.0 vs. -0.0, \r
109 //treat all those as just 0.0 for testing\r
110 if (!(val < 0.0) && !(0.0 < val))\r
111 base_vec.push_back(0.0);\r
112 else\r
113 base_vec.push_back(val);\r
114 }\r
115 test_vector(base_vec, rightshift_64());\r
116\r
117 // Trying both positive and negative sorted and reverse sorted data.\r
118 base_vec.clear();\r
119 for (size_t i = 0; i < input_count; ++i) base_vec.push_back(-i);\r
120 test_vector(base_vec, rightshift_64());\r
121 base_vec.clear();\r
122 for (size_t i = 0; i < input_count; ++i) base_vec.push_back(i - input_count);\r
123 test_vector(base_vec, rightshift_64());\r
124 base_vec.clear();\r
125 for (size_t i = 0; i < input_count; ++i) base_vec.push_back(input_count - i);\r
126 test_vector(base_vec, rightshift_64());\r
127 base_vec.clear();\r
128 for (size_t i = 0; i < input_count; ++i) base_vec.push_back(i);\r
129 test_vector(base_vec, rightshift_64());\r
130 base_vec.clear();\r
131 for (size_t i = 0; i < input_count; ++i) base_vec.push_back(i);\r
132 for (size_t i = 0; i < input_count; i += 2) base_vec[i] *= -1;\r
133 test_vector(base_vec, rightshift_64());\r
134}\r
135\r
136// Verify that 0 and 1 elements work correctly.\r
137void corner_test() {\r
138 vector<float> test_vec;\r
139 boost::sort::spreadsort::spreadsort(test_vec.begin(), test_vec.end());\r
140 const float test_value = -0.0;\r
141 test_vec.push_back(test_value);\r
142 boost::sort::spreadsort::spreadsort(test_vec.begin(), test_vec.end());\r
143 BOOST_CHECK(test_vec.size() == 1);\r
144 BOOST_CHECK(test_vec[0] == test_value);\r
145}\r
146\r
147// test main \r
148int test_main( int, char*[] )\r
149{\r
150 srand(1);\r
151 float_test();\r
152 double_test();\r
153 corner_test();\r
154 return 0;\r
155}\r