]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | |
2 | // Copyright 2006-2009 Daniel James. | |
3 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
4 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
5 | ||
6 | #include "./containers.hpp" | |
b32b8144 | 7 | |
7c673cae | 8 | #include "../helpers/invariants.hpp" |
b32b8144 FG |
9 | #include "../helpers/random_values.hpp" |
10 | #include "../helpers/tracker.hpp" | |
7c673cae FG |
11 | |
12 | #if defined(BOOST_MSVC) | |
b32b8144 | 13 | #pragma warning(disable : 4512) // assignment operator could not be generated |
7c673cae FG |
14 | #endif |
15 | ||
16 | test::seed_t initialize_seed(9387); | |
17 | ||
b32b8144 | 18 | template <class T> struct self_swap_base : public test::exception_base |
7c673cae | 19 | { |
b32b8144 FG |
20 | test::random_values<T> values; |
21 | self_swap_base(std::size_t count = 0) : values(count, test::limited_range) {} | |
22 | ||
23 | typedef T data_type; | |
24 | T init() const { return T(values.begin(), values.end()); } | |
25 | ||
26 | void run(T& x) const | |
27 | { | |
28 | x.swap(x); | |
29 | ||
30 | DISABLE_EXCEPTIONS; | |
31 | test::check_container(x, this->values); | |
32 | test::check_equivalent_keys(x); | |
33 | } | |
34 | ||
35 | void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x) const | |
36 | { | |
37 | std::string scope(test::scope); | |
38 | ||
39 | // TODO: In C++11 exceptions are only allowed in the swap function. | |
40 | BOOST_TEST(scope == "hash::hash(hash)" || | |
41 | scope == "hash::operator=(hash)" || | |
42 | scope == "equal_to::equal_to(equal_to)" || | |
43 | scope == "equal_to::operator=(equal_to)"); | |
44 | ||
45 | test::check_equivalent_keys(x); | |
46 | } | |
7c673cae FG |
47 | }; |
48 | ||
b32b8144 FG |
49 | template <class T> struct self_swap_test1 : self_swap_base<T> |
50 | { | |
51 | }; | |
7c673cae | 52 | |
b32b8144 | 53 | template <class T> struct self_swap_test2 : self_swap_base<T> |
7c673cae | 54 | { |
b32b8144 | 55 | self_swap_test2() : self_swap_base<T>(100) {} |
7c673cae FG |
56 | }; |
57 | ||
b32b8144 | 58 | template <class T> struct swap_base : public test::exception_base |
7c673cae | 59 | { |
b32b8144 FG |
60 | const test::random_values<T> x_values, y_values; |
61 | const T initial_x, initial_y; | |
7c673cae | 62 | |
b32b8144 FG |
63 | typedef BOOST_DEDUCED_TYPENAME T::hasher hasher; |
64 | typedef BOOST_DEDUCED_TYPENAME T::key_equal key_equal; | |
65 | typedef BOOST_DEDUCED_TYPENAME T::allocator_type allocator_type; | |
7c673cae | 66 | |
b32b8144 FG |
67 | swap_base(unsigned int count1, unsigned int count2, int tag1, int tag2) |
68 | : x_values(count1, test::limited_range), | |
69 | y_values(count2, test::limited_range), | |
7c673cae | 70 | initial_x(x_values.begin(), x_values.end(), 0, hasher(tag1), |
b32b8144 | 71 | key_equal(tag1), allocator_type(tag1)), |
7c673cae | 72 | initial_y(y_values.begin(), y_values.end(), 0, hasher(tag2), |
b32b8144 FG |
73 | key_equal(tag2), |
74 | allocator_type(T::allocator_type::propagate_on_container_swap::value | |
75 | ? tag2 | |
76 | : tag1)) | |
77 | { | |
78 | } | |
79 | ||
80 | struct data_type | |
81 | { | |
82 | data_type(T const& x_, T const& y_) : x(x_), y(y_) {} | |
83 | ||
84 | T x, y; | |
85 | }; | |
86 | ||
87 | data_type init() const { return data_type(initial_x, initial_y); } | |
88 | ||
89 | void run(data_type& d) const | |
90 | { | |
91 | try { | |
92 | d.x.swap(d.y); | |
93 | } catch (std::runtime_error) { | |
7c673cae | 94 | } |
b32b8144 FG |
95 | |
96 | DISABLE_EXCEPTIONS; | |
97 | test::check_container(d.x, this->y_values); | |
98 | test::check_equivalent_keys(d.x); | |
99 | test::check_container(d.y, this->x_values); | |
100 | test::check_equivalent_keys(d.y); | |
101 | } | |
102 | ||
103 | void check BOOST_PREVENT_MACRO_SUBSTITUTION(data_type const& d) const | |
104 | { | |
105 | std::string scope(test::scope); | |
106 | ||
107 | // TODO: In C++11 exceptions are only allowed in the swap function. | |
108 | BOOST_TEST(scope == "hash::hash(hash)" || | |
109 | scope == "hash::operator=(hash)" || | |
110 | scope == "equal_to::equal_to(equal_to)" || | |
111 | scope == "equal_to::operator=(equal_to)"); | |
112 | ||
113 | test::check_equivalent_keys(d.x); | |
114 | test::check_equivalent_keys(d.y); | |
115 | } | |
7c673cae FG |
116 | }; |
117 | ||
b32b8144 | 118 | template <class T> struct swap_test1 : swap_base<T> |
7c673cae | 119 | { |
b32b8144 | 120 | swap_test1() : swap_base<T>(0, 0, 0, 0) {} |
7c673cae FG |
121 | }; |
122 | ||
b32b8144 | 123 | template <class T> struct swap_test2 : swap_base<T> |
7c673cae | 124 | { |
b32b8144 | 125 | swap_test2() : swap_base<T>(60, 0, 0, 0) {} |
7c673cae FG |
126 | }; |
127 | ||
b32b8144 | 128 | template <class T> struct swap_test3 : swap_base<T> |
7c673cae | 129 | { |
b32b8144 | 130 | swap_test3() : swap_base<T>(0, 60, 0, 0) {} |
7c673cae FG |
131 | }; |
132 | ||
b32b8144 | 133 | template <class T> struct swap_test4 : swap_base<T> |
7c673cae | 134 | { |
b32b8144 | 135 | swap_test4() : swap_base<T>(10, 10, 1, 2) {} |
7c673cae FG |
136 | }; |
137 | ||
b32b8144 | 138 | // clang-format off |
7c673cae | 139 | EXCEPTION_TESTS( |
b32b8144 FG |
140 | (self_swap_test1)(self_swap_test2) |
141 | (swap_test1)(swap_test2)(swap_test3)(swap_test4), | |
142 | CONTAINER_SEQ) | |
143 | // clang-format on | |
144 | ||
7c673cae | 145 | RUN_TESTS() |