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