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// <map> 13 14// void swap(map& c) 15// noexcept(!allocator_type::propagate_on_container_swap::value || 16// __is_nothrow_swappable<allocator_type>::value); 17// 18// In C++17, the standard says that swap shall have: 19// noexcept(allocator_traits<Allocator>::is_always_equal::value && 20// noexcept(swap(declval<Compare&>(), declval<Compare&>()))); 21 22// This tests a conforming extension 23 24#include <map> 25#include <utility> 26#include <cassert> 27 28#include "test_macros.h" 29#include "MoveOnly.h" 30#include "test_allocator.h" 31 32template <class T> 33struct some_comp 34{ 35 typedef T value_type; 36 37 some_comp() {} 38 some_comp(const some_comp&) {} 39 bool operator()(const T&, const T&) const { return false; } 40}; 41 42template <class T> 43struct some_comp2 44{ 45 typedef T value_type; 46 47 some_comp2() {} 48 some_comp2(const some_comp2&) {} 49 bool operator()(const T&, const T&) const { return false; } 50}; 51 52#if TEST_STD_VER >= 14 53template <typename T> 54void swap(some_comp2<T>&, some_comp2<T>&) noexcept {} 55#endif 56 57template <class T> 58struct some_alloc 59{ 60 typedef T value_type; 61 62 some_alloc() {} 63 some_alloc(const some_alloc&); 64 void deallocate(void*, unsigned) {} 65 66 typedef std::true_type propagate_on_container_swap; 67}; 68 69template <class T> 70struct some_alloc2 71{ 72 typedef T value_type; 73 74 some_alloc2() {} 75 some_alloc2(const some_alloc2&); 76 void deallocate(void*, unsigned) {} 77 78 typedef std::false_type propagate_on_container_swap; 79 typedef std::true_type is_always_equal; 80}; 81 82template <class T> 83struct some_alloc3 84{ 85 typedef T value_type; 86 87 some_alloc3() {} 88 some_alloc3(const some_alloc3&); 89 void deallocate(void*, unsigned) {} 90 91 typedef std::false_type propagate_on_container_swap; 92 typedef std::false_type is_always_equal; 93}; 94 95int main() 96{ 97 typedef std::pair<const MoveOnly, MoveOnly> V; 98 { 99 typedef std::map<MoveOnly, MoveOnly> C; 100 static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), ""); 101 } 102#if defined(_LIBCPP_VERSION) 103 { 104 typedef std::map<MoveOnly, MoveOnly, std::less<MoveOnly>, test_allocator<V>> C; 105 static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), ""); 106 } 107 { 108 typedef std::map<MoveOnly, MoveOnly, std::less<MoveOnly>, other_allocator<V>> C; 109 static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), ""); 110 } 111#endif // _LIBCPP_VERSION 112 { 113 typedef std::map<MoveOnly, MoveOnly, some_comp<MoveOnly>> C; 114 static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), ""); 115 } 116 117#if TEST_STD_VER >= 14 118 { // POCS allocator, throwable swap for comp 119 typedef std::map<MoveOnly, MoveOnly, some_comp <MoveOnly>, some_alloc <V>> C; 120 static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), ""); 121 } 122 { // always equal allocator, throwable swap for comp 123 typedef std::map<MoveOnly, MoveOnly, some_comp <MoveOnly>, some_alloc2<V>> C; 124 static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), ""); 125 } 126 { // POCS allocator, nothrow swap for comp 127 typedef std::map<MoveOnly, MoveOnly, some_comp2<MoveOnly>, some_alloc <V>> C; 128 static_assert( noexcept(swap(std::declval<C&>(), std::declval<C&>())), ""); 129 } 130 { // always equal allocator, nothrow swap for comp 131 typedef std::map<MoveOnly, MoveOnly, some_comp2<MoveOnly>, some_alloc2<V>> C; 132 static_assert( noexcept(swap(std::declval<C&>(), std::declval<C&>())), ""); 133 } 134#if defined(_LIBCPP_VERSION) 135 { // NOT always equal allocator, nothrow swap for comp 136 typedef std::map<MoveOnly, MoveOnly, some_comp2<MoveOnly>, some_alloc3<V>> C; 137 static_assert( noexcept(swap(std::declval<C&>(), std::declval<C&>())), ""); 138 } 139#endif // _LIBCPP_VERSION 140#endif 141 142} 143