]>
Commit | Line | Data |
---|---|---|
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 | |
17 | using namespace std;\r | |
18 | using namespace boost::sort::spreadsort;\r | |
19 | \r | |
20 | //Casting to an integer before bitshifting\r | |
21 | struct 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 | |
27 | struct 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 | |
34 | boost::int32_t \r | |
35 | rand_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 | |
45 | static const unsigned input_count = 1000000;\r | |
46 | \r | |
47 | // Helper class to run tests across all float_sort interface variants.\r | |
48 | template<class FloatType, class RightShift>\r | |
49 | void 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 | |
67 | void 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 | |
103 | void 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 | |
137 | void 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 | |
148 | int 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 |