1 /*=============================================================================
2 Copyright (c) 2010 Tim Blechmann
4 Use, modification and distribution is subject to the Boost Software
5 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 http://www.boost.org/LICENSE_1_0.txt)
7 =============================================================================*/
9 #ifndef COMMON_HEAP_TESTS_HPP_INCLUDED
10 #define COMMON_HEAP_TESTS_HPP_INCLUDED
15 #include <boost/concept/assert.hpp>
16 #include <boost/concept_archetype.hpp>
17 #include <boost/shared_ptr.hpp>
19 #include <boost/heap/heap_concepts.hpp>
22 typedef boost::default_constructible_archetype<
23 boost::less_than_comparable_archetype<
24 boost::copy_constructible_archetype<
25 boost::assignable_archetype<
26 > > > > test_value_type;
29 typedef std::vector<int> test_data;
30 const int test_size = 32;
39 test_data make_test_data(int size, int offset = 0, int strive = 1)
43 for (int i = 0; i != size; ++i)
44 ret.push_back(i * strive + offset);
49 template <typename pri_queue, typename data_container>
50 void check_q(pri_queue & q, data_container const & expected)
52 BOOST_REQUIRE_EQUAL(q.size(), expected.size());
54 for (unsigned int i = 0; i != expected.size(); ++i)
56 BOOST_REQUIRE_EQUAL(q.size(), expected.size() - i);
57 BOOST_REQUIRE_EQUAL(q.top(), expected[expected.size()-1-i]);
61 BOOST_REQUIRE(q.empty());
65 template <typename pri_queue, typename data_container>
66 void fill_q(pri_queue & q, data_container const & data)
68 for (unsigned int i = 0; i != data.size(); ++i)
72 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
73 template <typename pri_queue, typename data_container>
74 void fill_emplace_q(pri_queue & q, data_container const & data)
76 for (unsigned int i = 0; i != data.size(); ++i) {
77 typename pri_queue::value_type value = data[i];
78 q.emplace(std::move(value));
83 template <typename pri_queue>
84 void pri_queue_test_sequential_push(void)
86 for (int i = 0; i != test_size; ++i)
89 test_data data = make_test_data(i);
95 template <typename pri_queue>
96 void pri_queue_test_sequential_reverse_push(void)
98 for (int i = 0; i != test_size; ++i)
101 test_data data = make_test_data(i);
102 std::reverse(data.begin(), data.end());
104 std::reverse(data.begin(), data.end());
109 template <typename pri_queue>
110 void pri_queue_test_emplace(void)
112 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
113 for (int i = 0; i != test_size; ++i)
116 test_data data = make_test_data(i);
117 std::reverse(data.begin(), data.end());
118 fill_emplace_q(q, data);
119 std::reverse(data.begin(), data.end());
126 template <typename pri_queue>
127 void pri_queue_test_random_push(void)
129 for (int i = 0; i != test_size; ++i)
132 test_data data = make_test_data(i);
134 test_data shuffled (data);
135 std::random_shuffle(shuffled.begin(), shuffled.end());
143 template <typename pri_queue>
144 void pri_queue_test_copyconstructor(void)
146 for (int i = 0; i != test_size; ++i)
149 test_data data = make_test_data(i);
158 template <typename pri_queue>
159 void pri_queue_test_assignment(void)
161 for (int i = 0; i != test_size; ++i)
164 test_data data = make_test_data(i);
174 template <typename pri_queue>
175 void pri_queue_test_moveconstructor(void)
177 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
179 test_data data = make_test_data(test_size);
182 pri_queue r(std::move(q));
185 BOOST_REQUIRE(q.empty());
189 template <typename pri_queue>
190 void pri_queue_test_move_assignment(void)
192 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
194 test_data data = make_test_data(test_size);
201 BOOST_REQUIRE(q.empty());
206 template <typename pri_queue>
207 void pri_queue_test_swap(void)
209 for (int i = 0; i != test_size; ++i)
212 test_data data = make_test_data(i);
213 test_data shuffled (data);
214 std::random_shuffle(shuffled.begin(), shuffled.end());
221 BOOST_REQUIRE(q.empty());
226 template <typename pri_queue>
227 void pri_queue_test_iterators(void)
229 for (int i = 0; i != test_size; ++i) {
230 test_data data = make_test_data(test_size);
231 test_data shuffled (data);
232 std::random_shuffle(shuffled.begin(), shuffled.end());
234 BOOST_REQUIRE(q.begin() == q.end());
237 for (unsigned long j = 0; j != data.size(); ++j)
238 BOOST_REQUIRE(std::find(q.begin(), q.end(), data[j]) != q.end());
240 for (unsigned long j = 0; j != data.size(); ++j)
241 BOOST_REQUIRE(std::find(q.begin(), q.end(), data[j] + data.size()) == q.end());
243 test_data data_from_queue(q.begin(), q.end());
244 std::sort(data_from_queue.begin(), data_from_queue.end());
246 BOOST_REQUIRE(data == data_from_queue);
248 for (unsigned long j = 0; j != data.size(); ++j) {
249 BOOST_REQUIRE_EQUAL((long)std::distance(q.begin(), q.end()), (long)(data.size() - j));
255 template <typename pri_queue>
256 void pri_queue_test_ordered_iterators(void)
258 for (int i = 0; i != test_size; ++i) {
259 test_data data = make_test_data(i);
260 test_data shuffled (data);
261 std::random_shuffle(shuffled.begin(), shuffled.end());
263 BOOST_REQUIRE(q.ordered_begin() == q.ordered_end());
266 test_data data_from_queue(q.ordered_begin(), q.ordered_end());
267 std::reverse(data_from_queue.begin(), data_from_queue.end());
268 BOOST_REQUIRE(data == data_from_queue);
270 for (unsigned long j = 0; j != data.size(); ++j)
271 BOOST_REQUIRE(std::find(q.ordered_begin(), q.ordered_end(), data[j]) != q.ordered_end());
273 for (unsigned long j = 0; j != data.size(); ++j)
274 BOOST_REQUIRE(std::find(q.ordered_begin(), q.ordered_end(), data[j] + data.size()) == q.ordered_end());
276 for (unsigned long j = 0; j != data.size(); ++j) {
277 BOOST_REQUIRE_EQUAL((long)std::distance(q.begin(), q.end()), (long)(data.size() - j));
284 template <typename pri_queue>
285 void pri_queue_test_equality(void)
287 for (int i = 0; i != test_size; ++i)
290 test_data data = make_test_data(i);
292 std::reverse(data.begin(), data.end());
295 BOOST_REQUIRE(r == q);
299 template <typename pri_queue>
300 void pri_queue_test_inequality(void)
302 for (int i = 1; i != test_size; ++i)
305 test_data data = make_test_data(i);
307 data[0] = data.back() + 1;
310 BOOST_REQUIRE(r != q);
314 template <typename pri_queue>
315 void pri_queue_test_less(void)
317 for (int i = 1; i != test_size; ++i)
320 test_data data = make_test_data(i);
321 test_data r_data(data);
327 BOOST_REQUIRE(r < q);
330 for (int i = 1; i != test_size; ++i)
333 test_data data = make_test_data(i);
334 test_data r_data(data);
335 data.push_back(data.back() + 1);
340 BOOST_REQUIRE(r < q);
343 for (int i = 1; i != test_size; ++i)
346 test_data data = make_test_data(i);
347 test_data r_data(data);
354 BOOST_REQUIRE(r < q);
357 for (int i = 1; i != test_size; ++i)
360 test_data data = make_test_data(i);
361 test_data r_data(data);
368 BOOST_REQUIRE(r < q);
373 template <typename pri_queue>
374 void pri_queue_test_clear(void)
376 for (int i = 0; i != test_size; ++i)
379 test_data data = make_test_data(i);
383 BOOST_REQUIRE(q.size() == 0);
384 BOOST_REQUIRE(q.empty());
389 template <typename pri_queue>
390 void run_concept_check(void)
392 BOOST_CONCEPT_ASSERT((boost::heap::PriorityQueue<pri_queue>));
395 template <typename pri_queue>
396 void run_common_heap_tests(void)
398 pri_queue_test_sequential_push<pri_queue>();
399 pri_queue_test_sequential_reverse_push<pri_queue>();
400 pri_queue_test_random_push<pri_queue>();
401 pri_queue_test_equality<pri_queue>();
402 pri_queue_test_inequality<pri_queue>();
403 pri_queue_test_less<pri_queue>();
404 pri_queue_test_clear<pri_queue>();
406 pri_queue_test_emplace<pri_queue>();
409 template <typename pri_queue>
410 void run_iterator_heap_tests(void)
412 pri_queue_test_iterators<pri_queue>();
416 template <typename pri_queue>
417 void run_copyable_heap_tests(void)
419 pri_queue_test_copyconstructor <pri_queue>();
420 pri_queue_test_assignment<pri_queue>();
421 pri_queue_test_swap<pri_queue>();
425 template <typename pri_queue>
426 void run_moveable_heap_tests(void)
428 pri_queue_test_moveconstructor <pri_queue>();
429 pri_queue_test_move_assignment <pri_queue>();
433 template <typename pri_queue>
434 void run_reserve_heap_tests(void)
436 test_data data = make_test_data(test_size);
444 template <typename pri_queue>
445 void run_leak_check_test(void)
448 q.push(boost::shared_ptr<int>(new int(0)));
455 bool operator()(const int& a, const int& b) const
462 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
466 thing( int a_, int b_, int c_ ) : a(a_), b(b_), c(c_) {}
475 bool operator() ( const thing& lhs, const thing& rhs ) const {
476 return lhs.a > rhs.a;
478 bool operator() ( const thing& lhs, const thing& rhs ) {
479 return lhs.a > rhs.a;
483 #define RUN_EMPLACE_TEST(HEAP_TYPE) \
486 boost::heap::HEAP_TYPE<thing, boost::heap::compare<cmpthings> > vpq(ord); \
487 vpq.emplace(5, 6, 7); \
488 boost::heap::HEAP_TYPE<thing, boost::heap::compare<cmpthings>, boost::heap::stable<true> > vpq2(ord); \
489 vpq2.emplace(5, 6, 7); \
493 #define RUN_EMPLACE_TEST(HEAP_TYPE)
497 #endif // COMMON_HEAP_TESTS_HPP_INCLUDED