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)
6 #include "./containers.hpp"
8 #include "../helpers/random_values.hpp"
9 #include "../helpers/invariants.hpp"
10 #include "../helpers/strong.hpp"
11 #include "../helpers/helpers.hpp"
14 test::seed_t
initialize_seed(747373);
17 struct insert_test_base
: public test::exception_base
19 test::random_values
<T
> values
;
20 insert_test_base(unsigned int count
= 5) : values(count
, test::limited_range
) {}
23 typedef test::strong
<T
> strong_type
;
25 data_type
init() const {
29 void check
BOOST_PREVENT_MACRO_SUBSTITUTION(
30 T
const& x
, strong_type
const& strong
) const
32 std::string
scope(test::scope
);
34 if(scope
.find("hash::operator()") == std::string::npos
)
35 strong
.test(x
, test::detail::tracker
.count_allocations
);
36 test::check_equivalent_keys(x
);
40 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
43 struct emplace_test1
: public insert_test_base
<T
>
45 typedef BOOST_DEDUCED_TYPENAME insert_test_base
<T
>::strong_type strong_type
;
47 void run(T
& x
, strong_type
& strong
) const {
48 for(BOOST_DEDUCED_TYPENAME
test::random_values
<T
>::const_iterator
49 it
= this->values
.begin(), end
= this->values
.end();
52 strong
.store(x
, test::detail::tracker
.count_allocations
);
61 struct insert_test1
: public insert_test_base
<T
>
63 typedef BOOST_DEDUCED_TYPENAME insert_test_base
<T
>::strong_type strong_type
;
65 void run(T
& x
, strong_type
& strong
) const {
66 for(BOOST_DEDUCED_TYPENAME
test::random_values
<T
>::const_iterator
67 it
= this->values
.begin(), end
= this->values
.end();
70 strong
.store(x
, test::detail::tracker
.count_allocations
);
77 struct insert_test2
: public insert_test_base
<T
>
79 typedef BOOST_DEDUCED_TYPENAME insert_test_base
<T
>::strong_type strong_type
;
81 void run(T
& x
, strong_type
& strong
) const {
82 for(BOOST_DEDUCED_TYPENAME
test::random_values
<T
>::const_iterator
83 it
= this->values
.begin(), end
= this->values
.end();
86 strong
.store(x
, test::detail::tracker
.count_allocations
);
87 x
.insert(x
.begin(), *it
);
93 struct insert_test3
: public insert_test_base
<T
>
95 void run(T
& x
) const {
96 x
.insert(this->values
.begin(), this->values
.end());
99 void check
BOOST_PREVENT_MACRO_SUBSTITUTION(T
const& x
) const {
100 test::check_equivalent_keys(x
);
105 struct insert_test4
: public insert_test_base
<T
>
107 typedef BOOST_DEDUCED_TYPENAME insert_test_base
<T
>::strong_type strong_type
;
109 void run(T
& x
, strong_type
& strong
) const {
110 for(BOOST_DEDUCED_TYPENAME
test::random_values
<T
>::const_iterator
111 it
= this->values
.begin(), end
= this->values
.end();
114 strong
.store(x
, test::detail::tracker
.count_allocations
);
115 x
.insert(it
, test::next(it
));
121 struct insert_test_rehash1
: public insert_test_base
<T
>
123 typedef BOOST_DEDUCED_TYPENAME insert_test_base
<T
>::strong_type strong_type
;
125 insert_test_rehash1() : insert_test_base
<T
>(1000) {}
129 typedef BOOST_DEDUCED_TYPENAME
T::size_type size_type
;
132 x
.max_load_factor(0.25);
133 // TODO: This doesn't really work is bucket_count is 0
134 size_type bucket_count
= x
.bucket_count();
135 size_type initial_elements
= static_cast<size_type
>(
136 ceil((double) bucket_count
* (double) x
.max_load_factor()) - 1);
137 BOOST_TEST(initial_elements
< this->values
.size());
138 x
.insert(this->values
.begin(),
139 test::next(this->values
.begin(), initial_elements
));
140 BOOST_TEST(bucket_count
== x
.bucket_count());
144 void run(T
& x
, strong_type
& strong
) const {
145 BOOST_DEDUCED_TYPENAME
T::size_type bucket_count
= x
.bucket_count();
147 BOOST_DEDUCED_TYPENAME
T::const_iterator pos
= x
.cbegin();
149 for(BOOST_DEDUCED_TYPENAME
test::random_values
<T
>::const_iterator
150 it
= test::next(this->values
.begin(), x
.size()),
151 end
= this->values
.end();
152 it
!= end
&& count
< 10; ++it
, ++count
)
154 strong
.store(x
, test::detail::tracker
.count_allocations
);
155 pos
= x
.insert(pos
, *it
);
158 // This isn't actually a failure, but it means the test isn't doing its
160 BOOST_TEST(x
.bucket_count() != bucket_count
);
165 struct insert_test_rehash2
: public insert_test_rehash1
<T
>
167 typedef BOOST_DEDUCED_TYPENAME insert_test_base
<T
>::strong_type strong_type
;
169 void run(T
& x
, strong_type
& strong
) const {
170 BOOST_DEDUCED_TYPENAME
T::size_type bucket_count
= x
.bucket_count();
173 for(BOOST_DEDUCED_TYPENAME
test::random_values
<T
>::const_iterator
174 it
= test::next(this->values
.begin(), x
.size()),
175 end
= this->values
.end();
176 it
!= end
&& count
< 10; ++it
, ++count
)
178 strong
.store(x
, test::detail::tracker
.count_allocations
);
182 // This isn't actually a failure, but it means the test isn't doing its
184 BOOST_TEST(x
.bucket_count() != bucket_count
);
189 struct insert_test_rehash3
: public insert_test_base
<T
>
191 BOOST_DEDUCED_TYPENAME
T::size_type
mutable
192 rehash_bucket_count
, original_bucket_count
;
194 insert_test_rehash3() : insert_test_base
<T
>(1000) {}
198 typedef BOOST_DEDUCED_TYPENAME
T::size_type size_type
;
201 x
.max_load_factor(0.25);
203 original_bucket_count
= x
.bucket_count();
204 rehash_bucket_count
= static_cast<size_type
>(
205 ceil((double) original_bucket_count
* (double) x
.max_load_factor())) - 1;
207 size_type initial_elements
=
208 rehash_bucket_count
> 5 ? rehash_bucket_count
- 5 : 1;
210 BOOST_TEST(initial_elements
< this->values
.size());
211 x
.insert(this->values
.begin(),
212 test::next(this->values
.begin(), initial_elements
));
213 BOOST_TEST(original_bucket_count
== x
.bucket_count());
217 void run(T
& x
) const {
218 BOOST_DEDUCED_TYPENAME
T::size_type bucket_count
= x
.bucket_count();
220 x
.insert(test::next(this->values
.begin(), x
.size()),
221 test::next(this->values
.begin(), x
.size() + 20));
223 // This isn't actually a failure, but it means the test isn't doing its
225 BOOST_TEST(x
.bucket_count() != bucket_count
);
228 void check
BOOST_PREVENT_MACRO_SUBSTITUTION(T
const& x
) const {
229 if(x
.size() < rehash_bucket_count
) {
230 //BOOST_TEST(x.bucket_count() == original_bucket_count);
232 test::check_equivalent_keys(x
);
236 #define BASIC_TESTS \
237 (insert_test1)(insert_test2)(insert_test3)(insert_test4) \
238 (insert_test_rehash1)(insert_test_rehash2)(insert_test_rehash3)
240 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
241 #define ALL_TESTS (emplace_test1)BASIC_TESTS
243 #define ALL_TESTS BASIC_TESTS
247 EXCEPTION_TESTS(ALL_TESTS
, CONTAINER_SEQ
)