1 2 // Copyright 2008-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 // clang-format off 7 #include "../helpers/prefix.hpp" 8 #include <boost/unordered_set.hpp> 9 #include <boost/unordered_map.hpp> 10 #include "../helpers/postfix.hpp" 11 // clang-format on 12 13 #include <boost/preprocessor/seq.hpp> 14 #include <list> 15 #include "../helpers/test.hpp" 16 17 namespace equality_tests { 18 struct mod_compare 19 { 20 bool alt_hash_; 21 mod_compareequality_tests::mod_compare22 explicit mod_compare(bool alt_hash = false) : alt_hash_(alt_hash) {} 23 operator ()equality_tests::mod_compare24 bool operator()(int x, int y) const { return x % 1000 == y % 1000; } 25 operator ()equality_tests::mod_compare26 std::size_t operator()(int x) const 27 { 28 return alt_hash_ ? static_cast<std::size_t>(x % 250) 29 : static_cast<std::size_t>((x + 5) % 250); 30 } 31 }; 32 33 #define UNORDERED_EQUALITY_SET_TEST(seq1, op, seq2) \ 34 { \ 35 boost::unordered_set<int, mod_compare, mod_compare> set1, set2; \ 36 BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set1, seq1) \ 37 BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set2, seq2) \ 38 BOOST_TEST(set1 op set2); \ 39 } 40 41 #define UNORDERED_EQUALITY_MULTISET_TEST(seq1, op, seq2) \ 42 { \ 43 boost::unordered_multiset<int, mod_compare, mod_compare> set1, set2; \ 44 BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set1, seq1) \ 45 BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set2, seq2) \ 46 BOOST_TEST(set1 op set2); \ 47 } 48 49 #define UNORDERED_EQUALITY_MAP_TEST(seq1, op, seq2) \ 50 { \ 51 boost::unordered_map<int, int, mod_compare, mod_compare> map1, map2; \ 52 BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \ 53 BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \ 54 BOOST_TEST(map1 op map2); \ 55 } 56 57 #define UNORDERED_EQUALITY_MULTIMAP_TEST(seq1, op, seq2) \ 58 { \ 59 boost::unordered_multimap<int, int, mod_compare, mod_compare> map1, map2; \ 60 BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \ 61 BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \ 62 BOOST_TEST(map1 op map2); \ 63 } 64 65 #define UNORDERED_SET_INSERT(r, set, item) set.insert(item); 66 #define UNORDERED_MAP_INSERT(r, map, item) \ 67 map.insert(std::pair<int const, int> BOOST_PP_SEQ_TO_TUPLE(item)); 68 UNORDERED_AUTO_TEST(equality_size_tests)69 UNORDERED_AUTO_TEST (equality_size_tests) { 70 boost::unordered_set<int> x1, x2; 71 BOOST_TEST(x1 == x2); 72 BOOST_TEST(!(x1 != x2)); 73 74 x1.insert(1); 75 BOOST_TEST(x1 != x2); 76 BOOST_TEST(!(x1 == x2)); 77 BOOST_TEST(x2 != x1); 78 BOOST_TEST(!(x2 == x1)); 79 80 x2.insert(1); 81 BOOST_TEST(x1 == x2); 82 BOOST_TEST(!(x1 != x2)); 83 84 x2.insert(2); 85 BOOST_TEST(x1 != x2); 86 BOOST_TEST(!(x1 == x2)); 87 BOOST_TEST(x2 != x1); 88 BOOST_TEST(!(x2 == x1)); 89 } 90 UNORDERED_AUTO_TEST(equality_key_value_tests)91 UNORDERED_AUTO_TEST (equality_key_value_tests) { 92 UNORDERED_EQUALITY_MULTISET_TEST((1), !=, (2)) 93 UNORDERED_EQUALITY_SET_TEST((2), ==, (2)) 94 UNORDERED_EQUALITY_MAP_TEST(((1)(1))((2)(1)), !=, ((1)(1))((3)(1))) 95 } 96 UNORDERED_AUTO_TEST(equality_collision_test)97 UNORDERED_AUTO_TEST (equality_collision_test) { 98 UNORDERED_EQUALITY_MULTISET_TEST((1), !=, (501)) 99 UNORDERED_EQUALITY_MULTISET_TEST((1)(251), !=, (1)(501)) 100 UNORDERED_EQUALITY_MULTIMAP_TEST(((251)(1))((1)(1)), !=, ((501)(1))((1)(1))) 101 UNORDERED_EQUALITY_MULTISET_TEST((1)(501), ==, (1)(501)) 102 UNORDERED_EQUALITY_SET_TEST((1)(501), ==, (501)(1)) 103 } 104 UNORDERED_AUTO_TEST(equality_group_size_test)105 UNORDERED_AUTO_TEST (equality_group_size_test) { 106 UNORDERED_EQUALITY_MULTISET_TEST((10)(20)(20), !=, (10)(10)(20)) 107 UNORDERED_EQUALITY_MULTIMAP_TEST( 108 ((10)(1))((20)(1))((20)(1)), !=, ((10)(1))((20)(1))((10)(1))) 109 UNORDERED_EQUALITY_MULTIMAP_TEST( 110 ((20)(1))((10)(1))((10)(1)), ==, ((10)(1))((20)(1))((10)(1))) 111 } 112 UNORDERED_AUTO_TEST(equality_map_value_test)113 UNORDERED_AUTO_TEST (equality_map_value_test) { 114 UNORDERED_EQUALITY_MAP_TEST(((1)(1)), !=, ((1)(2))) 115 UNORDERED_EQUALITY_MAP_TEST(((1)(1)), ==, ((1)(1))) 116 UNORDERED_EQUALITY_MULTIMAP_TEST(((1)(1)), !=, ((1)(2))) 117 UNORDERED_EQUALITY_MULTIMAP_TEST(((1)(1))((1)(1)), !=, ((1)(1))((1)(2))) 118 UNORDERED_EQUALITY_MULTIMAP_TEST(((1)(2))((1)(1)), ==, ((1)(1))((1)(2))) 119 UNORDERED_EQUALITY_MULTIMAP_TEST(((1)(2))((1)(1)), !=, ((1)(1))((1)(3))) 120 } 121 UNORDERED_AUTO_TEST(equality_predicate_test)122 UNORDERED_AUTO_TEST (equality_predicate_test) { 123 UNORDERED_EQUALITY_SET_TEST((1), !=, (1001)) 124 UNORDERED_EQUALITY_MAP_TEST(((1)(2))((1001)(1)), !=, ((1001)(2))((1)(1))) 125 } 126 UNORDERED_AUTO_TEST(equality_multiple_group_test)127 UNORDERED_AUTO_TEST (equality_multiple_group_test) { 128 UNORDERED_EQUALITY_MULTISET_TEST( 129 (1)(1)(1)(1001)(2001)(2001)(2)(1002)(3)(1003)(2003), ==, 130 (3)(1003)(2003)(1002)(2)(2001)(2001)(1)(1001)(1)(1)) 131 } 132 133 // Test that equality still works when the two containers have 134 // different hash functions but the same equality predicate. 135 UNORDERED_AUTO_TEST(equality_different_hash_test)136 UNORDERED_AUTO_TEST (equality_different_hash_test) { 137 typedef boost::unordered_set<int, mod_compare, mod_compare> set; 138 set set1(0, mod_compare(false), mod_compare(false)); 139 set set2(0, mod_compare(true), mod_compare(true)); 140 BOOST_TEST(set1 == set2); 141 set1.insert(1); 142 set2.insert(2); 143 BOOST_TEST(set1 != set2); 144 set1.insert(2); 145 set2.insert(1); 146 BOOST_TEST(set1 == set2); 147 set1.insert(10); 148 set2.insert(20); 149 BOOST_TEST(set1 != set2); 150 set1.insert(20); 151 set2.insert(10); 152 BOOST_TEST(set1 == set2); 153 } 154 } 155 156 RUN_TESTS() 157