libcxx

libcxx mirror with random patches
git clone https://git.neptards.moe/neptards/libcxx.git
Log | Files | Refs

swap_noexcept.pass.cpp (6585B)


      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_multiset& 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_multiset<MoveOnly> C;
    126         static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
    127     }
    128 #if defined(_LIBCPP_VERSION)
    129     {
    130         typedef std::unordered_multiset<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_multiset<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_multiset<MoveOnly, some_hash<MoveOnly>> C;
    142         static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
    143     }
    144     {
    145         typedef std::unordered_multiset<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_multiset<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_multiset<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_multiset<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_multiset<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_multiset<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_multiset<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_multiset<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_multiset<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_multiset<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 }