swap_noexcept.pass.cpp (6510B)
1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // UNSUPPORTED: c++98, c++03 11 12 // <unordered_set> 13 14 // void swap(unordered_set& c) 15 // noexcept( 16 // (!allocator_type::propagate_on_container_swap::value || 17 // __is_nothrow_swappable<allocator_type>::value) && 18 // __is_nothrow_swappable<hasher>::value && 19 // __is_nothrow_swappable<key_equal>::value); 20 // 21 // In C++17, the standard says that swap shall have: 22 // noexcept(allocator_traits<Allocator>::is_always_equal::value && 23 // noexcept(swap(declval<Hash&>(), declval<Hash&>())) && 24 // noexcept(swap(declval<Pred&>(), declval<Pred&>()))); 25 26 // This tests a conforming extension 27 28 #include <unordered_set> 29 #include <utility> 30 #include <cassert> 31 32 #include "test_macros.h" 33 #include "MoveOnly.h" 34 #include "test_allocator.h" 35 36 template <class T> 37 struct some_comp 38 { 39 typedef T value_type; 40 41 some_comp() {} 42 some_comp(const some_comp&) {} 43 bool operator()(const T&, const T&) const { return false; } 44 }; 45 46 template <class T> 47 struct some_comp2 48 { 49 typedef T value_type; 50 51 some_comp2() {} 52 some_comp2(const some_comp2&) {} 53 bool operator()(const T&, const T&) const { return false; } 54 }; 55 56 #if TEST_STD_VER >= 14 57 template <typename T> 58 void swap(some_comp2<T>&, some_comp2<T>&) noexcept {} 59 #endif 60 61 template <class T> 62 struct some_hash 63 { 64 typedef T value_type; 65 some_hash() {} 66 some_hash(const some_hash&); 67 std::size_t operator()(const T&) const { return 0; } 68 }; 69 70 template <class T> 71 struct some_hash2 72 { 73 typedef T value_type; 74 some_hash2() {} 75 some_hash2(const some_hash2&); 76 std::size_t operator()(const T&) const { return 0; } 77 }; 78 79 #if TEST_STD_VER >= 14 80 template <typename T> 81 void swap(some_hash2<T>&, some_hash2<T>&) noexcept {} 82 #endif 83 84 template <class T> 85 struct some_alloc 86 { 87 typedef T value_type; 88 89 some_alloc() {} 90 some_alloc(const some_alloc&); 91 void deallocate(void*, unsigned) {} 92 93 typedef std::true_type propagate_on_container_swap; 94 }; 95 96 template <class T> 97 struct some_alloc2 98 { 99 typedef T value_type; 100 101 some_alloc2() {} 102 some_alloc2(const some_alloc2&); 103 void deallocate(void*, unsigned) {} 104 105 typedef std::false_type propagate_on_container_swap; 106 typedef std::true_type is_always_equal; 107 }; 108 109 template <class T> 110 struct some_alloc3 111 { 112 typedef T value_type; 113 114 some_alloc3() {} 115 some_alloc3(const some_alloc3&); 116 void deallocate(void*, unsigned) {} 117 118 typedef std::false_type propagate_on_container_swap; 119 typedef std::false_type is_always_equal; 120 }; 121 122 int main() 123 { 124 { 125 typedef std::unordered_set<MoveOnly> C; 126 static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), ""); 127 } 128 #if defined(_LIBCPP_VERSION) 129 { 130 typedef std::unordered_set<MoveOnly, std::hash<MoveOnly>, 131 std::equal_to<MoveOnly>, test_allocator<MoveOnly>> C; 132 static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), ""); 133 } 134 { 135 typedef std::unordered_set<MoveOnly, std::hash<MoveOnly>, 136 std::equal_to<MoveOnly>, other_allocator<MoveOnly>> C; 137 static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), ""); 138 } 139 #endif // _LIBCPP_VERSION 140 { 141 typedef std::unordered_set<MoveOnly, some_hash<MoveOnly>> C; 142 static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), ""); 143 } 144 { 145 typedef std::unordered_set<MoveOnly, std::hash<MoveOnly>, 146 some_comp<MoveOnly>> C; 147 static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), ""); 148 } 149 150 #if TEST_STD_VER >= 14 151 { // POCS allocator, throwable swap for hash, throwable swap for comp 152 typedef std::unordered_set<MoveOnly, some_hash<MoveOnly>, some_comp <MoveOnly>, some_alloc <MoveOnly>> C; 153 static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), ""); 154 } 155 { // always equal allocator, throwable swap for hash, throwable swap for comp 156 typedef std::unordered_set<MoveOnly, some_hash<MoveOnly>, some_comp <MoveOnly>, some_alloc2<MoveOnly>> C; 157 static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), ""); 158 } 159 { // POCS allocator, throwable swap for hash, nothrow swap for comp 160 typedef std::unordered_set<MoveOnly, some_hash<MoveOnly>, some_comp2<MoveOnly>, some_alloc <MoveOnly>> C; 161 static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), ""); 162 } 163 { // always equal allocator, throwable swap for hash, nothrow swap for comp 164 typedef std::unordered_set<MoveOnly, some_hash<MoveOnly>, some_comp2<MoveOnly>, some_alloc2<MoveOnly>> C; 165 static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), ""); 166 } 167 { // POCS allocator, nothrow swap for hash, throwable swap for comp 168 typedef std::unordered_set<MoveOnly, some_hash2<MoveOnly>, some_comp <MoveOnly>, some_alloc <MoveOnly>> C; 169 static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), ""); 170 } 171 { // always equal allocator, nothrow swap for hash, throwable swap for comp 172 typedef std::unordered_set<MoveOnly, some_hash2<MoveOnly>, some_comp <MoveOnly>, some_alloc2<MoveOnly>> C; 173 static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), ""); 174 } 175 { // POCS allocator, nothrow swap for hash, nothrow swap for comp 176 typedef std::unordered_set<MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc <MoveOnly>> C; 177 static_assert( noexcept(swap(std::declval<C&>(), std::declval<C&>())), ""); 178 } 179 { // always equal allocator, nothrow swap for hash, nothrow swap for comp 180 typedef std::unordered_set<MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc2<MoveOnly>> C; 181 static_assert( noexcept(swap(std::declval<C&>(), std::declval<C&>())), ""); 182 } 183 #if defined(_LIBCPP_VERSION) 184 { // NOT always equal allocator, nothrow swap for hash, nothrow swap for comp 185 typedef std::unordered_set<MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc3<MoveOnly>> C; 186 static_assert( noexcept(swap(std::declval<C&>(), std::declval<C&>())), ""); 187 } 188 #endif // _LIBCPP_VERSION 189 #endif 190 }