swap_noexcept.pass.cpp revision c6c26a44def0e7811ffcd928b8eeafa1a6edd626
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_map> 13 14// void swap(unordered_map& 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_map> 29#include <cassert> 30 31#include "test_macros.h" 32#include "MoveOnly.h" 33#include "test_allocator.h" 34 35template <class T> 36struct some_comp 37{ 38 typedef T value_type; 39 40 some_comp() {} 41 some_comp(const some_comp&) {} 42}; 43 44template <class T> 45struct some_comp2 46{ 47 typedef T value_type; 48 49 some_comp2() {} 50 some_comp2(const some_comp2&) {} 51 void deallocate(void*, unsigned) {} 52 typedef std::true_type propagate_on_container_swap; 53}; 54 55#if TEST_STD_VER >= 14 56template <typename T> 57void swap(some_comp2<T>&, some_comp2<T>&) noexcept {} 58#endif 59 60template <class T> 61struct some_hash 62{ 63 typedef T value_type; 64 some_hash() {} 65 some_hash(const some_hash&); 66}; 67 68template <class T> 69struct some_hash2 70{ 71 typedef T value_type; 72 some_hash2() {} 73 some_hash2(const some_hash2&); 74}; 75 76#if TEST_STD_VER >= 14 77template <typename T> 78void swap(some_hash2<T>&, some_hash2<T>&) noexcept {} 79#endif 80 81template <class T> 82struct some_alloc 83{ 84 typedef T value_type; 85 86 some_alloc() {} 87 some_alloc(const some_alloc&); 88 void deallocate(void*, unsigned) {} 89 90 typedef std::true_type propagate_on_container_swap; 91}; 92 93template <class T> 94struct some_alloc2 95{ 96 typedef T value_type; 97 98 some_alloc2() {} 99 some_alloc2(const some_alloc2&); 100 void deallocate(void*, unsigned) {} 101 102 typedef std::false_type propagate_on_container_swap; 103 typedef std::true_type is_always_equal; 104}; 105 106template <class T> 107struct some_alloc3 108{ 109 typedef T value_type; 110 111 some_alloc3() {} 112 some_alloc3(const some_alloc3&); 113 void deallocate(void*, unsigned) {} 114 115 typedef std::false_type propagate_on_container_swap; 116 typedef std::false_type is_always_equal; 117}; 118 119 120int main() 121{ 122 typedef std::pair<const MoveOnly, MoveOnly> MapType; 123 { 124 typedef std::unordered_map<MoveOnly, MoveOnly> C; 125 C c1, c2; 126 static_assert(noexcept(swap(c1, c2)), ""); 127 } 128 { 129 typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>, 130 std::equal_to<MoveOnly>, test_allocator<MapType>> C; 131 C c1, c2; 132 static_assert(noexcept(swap(c1, c2)), ""); 133 } 134 { 135 typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>, 136 std::equal_to<MoveOnly>, other_allocator<MapType>> C; 137 C c1, c2; 138 static_assert(noexcept(swap(c1, c2)), ""); 139 } 140 { 141 typedef std::unordered_map<MoveOnly, MoveOnly, some_hash<MoveOnly>> C; 142 C c1, c2; 143 static_assert(!noexcept(swap(c1, c2)), ""); 144 } 145 { 146 typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>, 147 some_comp<MoveOnly>> C; 148 C c1, c2; 149 static_assert(!noexcept(swap(c1, c2)), ""); 150 } 151 152#if TEST_STD_VER >= 14 153 { // POCS allocator, throwable swap for hash, throwable swap for comp 154 typedef std::unordered_map<MoveOnly, MoveOnly, some_hash<MoveOnly>, some_comp <MoveOnly>, some_alloc <MapType>> C; 155 C c1, c2; 156 static_assert(!noexcept(swap(c1, c2)), ""); 157 } 158 { // always equal allocator, throwable swap for hash, throwable swap for comp 159 typedef std::unordered_map<MoveOnly, MoveOnly, some_hash<MoveOnly>, some_comp <MoveOnly>, some_alloc2<MapType>> C; 160 C c1, c2; 161 static_assert(!noexcept(swap(c1, c2)), ""); 162 } 163 { // POCS allocator, throwable swap for hash, nothrow swap for comp 164 typedef std::unordered_map<MoveOnly, MoveOnly, some_hash<MoveOnly>, some_comp2<MoveOnly>, some_alloc <MapType>> C; 165 C c1, c2; 166 static_assert(!noexcept(swap(c1, c2)), ""); 167 } 168 { // always equal allocator, throwable swap for hash, nothrow swap for comp 169 typedef std::unordered_map<MoveOnly, MoveOnly, some_hash<MoveOnly>, some_comp2<MoveOnly>, some_alloc2<MapType>> C; 170 C c1, c2; 171 static_assert(!noexcept(swap(c1, c2)), ""); 172 } 173 { // POCS allocator, nothrow swap for hash, throwable swap for comp 174 typedef std::unordered_map<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp <MoveOnly>, some_alloc <MapType>> C; 175 C c1, c2; 176 static_assert(!noexcept(swap(c1, c2)), ""); 177 } 178 { // always equal allocator, nothrow swap for hash, throwable swap for comp 179 typedef std::unordered_map<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp <MoveOnly>, some_alloc2<MapType>> C; 180 C c1, c2; 181 static_assert(!noexcept(swap(c1, c2)), ""); 182 } 183 { // POCS allocator, nothrow swap for hash, nothrow swap for comp 184 typedef std::unordered_map<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc <MapType>> C; 185 C c1, c2; 186 static_assert( noexcept(swap(c1, c2)), ""); 187 } 188 { // always equal allocator, nothrow swap for hash, nothrow swap for comp 189 typedef std::unordered_map<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc2<MapType>> C; 190 C c1, c2; 191 static_assert( noexcept(swap(c1, c2)), ""); 192 } 193 194 { // NOT always equal allocator, nothrow swap for hash, nothrow swap for comp 195 typedef std::unordered_map<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc3<MapType>> C; 196 C c1, c2; 197 static_assert( noexcept(swap(c1, c2)), ""); 198 } 199#endif 200} 201