• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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"
7 
8 #include "../helpers/invariants.hpp"
9 #include "../helpers/random_values.hpp"
10 #include "../helpers/tracker.hpp"
11 
12 #if defined(BOOST_MSVC)
13 #pragma warning(                                                               \
14   disable : 4512) // move_assignment operator could not be generated
15 #endif
16 
17 test::seed_t initialize_seed(12847);
18 
19 template <class T> struct move_assign_base : public test::exception_base
20 {
21   test::random_values<T> x_values, y_values;
22   T x, y;
23 
24   typedef typename T::hasher hasher;
25   typedef typename T::key_equal key_equal;
26   typedef typename T::allocator_type allocator_type;
27 
move_assign_basemove_assign_base28   move_assign_base(int tag1, int tag2, float mlf1 = 1.0, float mlf2 = 1.0)
29       : x_values(), y_values(),
30         x(0, hasher(tag1), key_equal(tag1), allocator_type(tag1)),
31         y(0, hasher(tag2), key_equal(tag2), allocator_type(tag2))
32   {
33     x.max_load_factor(mlf1);
34     y.max_load_factor(mlf2);
35   }
36 
37   typedef T data_type;
initmove_assign_base38   T init() const { return T(x); }
runmove_assign_base39   void run(T& x1) const
40   {
41     test::exceptions_enable disable_exceptions(false);
42     T y1 = y;
43     disable_exceptions.release();
44     x1 = boost::move(y1);
45 
46     DISABLE_EXCEPTIONS;
47     test::check_container(x1, y_values);
48     test::check_equivalent_keys(x1);
49   }
50 
BOOST_PREVENT_MACRO_SUBSTITUTIONmove_assign_base51   void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x1) const
52   {
53     test::check_equivalent_keys(x1);
54 
55     // If the container is empty at the point of the exception, the
56     // internal structure is hidden, this exposes it, at the cost of
57     // messing up the data.
58     if (x_values.size()) {
59       T& x2 = const_cast<T&>(x1);
60       x2.emplace(*x_values.begin());
61       test::check_equivalent_keys(x2);
62     }
63   }
64 };
65 
66 template <class T> struct move_assign_values : move_assign_base<T>
67 {
move_assign_valuesmove_assign_values68   move_assign_values(unsigned int count1, unsigned int count2, int tag1,
69     int tag2, float mlf1 = 1.0, float mlf2 = 1.0)
70       : move_assign_base<T>(tag1, tag2, mlf1, mlf2)
71   {
72     this->x_values.fill(count1, test::limited_range);
73     this->y_values.fill(count2, test::limited_range);
74     this->x.insert(this->x_values.begin(), this->x_values.end());
75     this->y.insert(this->y_values.begin(), this->y_values.end());
76   }
77 };
78 
79 template <class T> struct move_assign_test1 : move_assign_values<T>
80 {
move_assign_test1move_assign_test181   move_assign_test1() : move_assign_values<T>(0, 0, 0, 0) {}
82 };
83 
84 template <class T> struct move_assign_test2 : move_assign_values<T>
85 {
move_assign_test2move_assign_test286   move_assign_test2() : move_assign_values<T>(60, 0, 0, 0) {}
87 };
88 
89 template <class T> struct move_assign_test3 : move_assign_values<T>
90 {
move_assign_test3move_assign_test391   move_assign_test3() : move_assign_values<T>(0, 60, 0, 0) {}
92 };
93 
94 template <class T> struct move_assign_test4 : move_assign_values<T>
95 {
move_assign_test4move_assign_test496   move_assign_test4() : move_assign_values<T>(10, 10, 1, 2) {}
97 };
98 
99 template <class T> struct move_assign_test4a : move_assign_values<T>
100 {
move_assign_test4amove_assign_test4a101   move_assign_test4a() : move_assign_values<T>(10, 100, 1, 2) {}
102 };
103 
104 template <class T> struct move_assign_test5 : move_assign_values<T>
105 {
move_assign_test5move_assign_test5106   move_assign_test5() : move_assign_values<T>(5, 60, 0, 0, 1.0f, 0.1f) {}
107 };
108 
109 template <class T> struct equivalent_test1 : move_assign_base<T>
110 {
equivalent_test1equivalent_test1111   equivalent_test1() : move_assign_base<T>(0, 0)
112   {
113     test::random_values<T> x_values2(10, test::limited_range);
114     this->x_values.insert(x_values2.begin(), x_values2.end());
115     this->x_values.insert(x_values2.begin(), x_values2.end());
116     test::random_values<T> y_values2(10, test::limited_range);
117     this->y_values.insert(y_values2.begin(), y_values2.end());
118     this->y_values.insert(y_values2.begin(), y_values2.end());
119     this->x.insert(this->x_values.begin(), this->x_values.end());
120     this->y.insert(this->y_values.begin(), this->y_values.end());
121   }
122 };
123 
124 // clang-format off
125 EXCEPTION_TESTS(
126   (move_assign_test1)(move_assign_test2)(move_assign_test3)
127   (move_assign_test4)(move_assign_test4a)(move_assign_test5)
128   (equivalent_test1),
129   CONTAINER_SEQ)
130 // clang-format on
131 
132 RUN_TESTS()
133