libcxx

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

swap_noexcept.pass.cpp (6671B)


      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 <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()(T const&) const;
     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()(T const&) const;
     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 
    123 int main()
    124 {
    125     typedef std::pair<const MoveOnly, MoveOnly> MapType;
    126     {
    127         typedef std::unordered_map<MoveOnly, MoveOnly> C;
    128         static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
    129     }
    130 #if defined(_LIBCPP_VERSION)
    131     {
    132         typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>,
    133                            std::equal_to<MoveOnly>, test_allocator<MapType>> C;
    134         static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
    135     }
    136     {
    137         typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>,
    138                           std::equal_to<MoveOnly>, other_allocator<MapType>> C;
    139         static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
    140     }
    141 #endif // _LIBCPP_VERSION
    142     {
    143         typedef std::unordered_map<MoveOnly, MoveOnly, some_hash<MoveOnly>> C;
    144         static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
    145     }
    146     {
    147         typedef std::unordered_map<MoveOnly, MoveOnly, std::hash<MoveOnly>,
    148                                                          some_comp<MoveOnly>> C;
    149         static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
    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     static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
    156     }
    157     { // always equal allocator, throwable swap for hash, throwable swap for comp
    158     typedef std::unordered_map<MoveOnly, MoveOnly, some_hash<MoveOnly>, some_comp <MoveOnly>, some_alloc2<MapType>> C;
    159     static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
    160     }
    161     { // POCS allocator, throwable swap for hash, nothrow swap for comp
    162     typedef std::unordered_map<MoveOnly, MoveOnly, some_hash<MoveOnly>, some_comp2<MoveOnly>, some_alloc <MapType>> C;
    163     static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
    164     }
    165     { // always equal allocator, throwable swap for hash, nothrow swap for comp
    166     typedef std::unordered_map<MoveOnly, MoveOnly, some_hash<MoveOnly>, some_comp2<MoveOnly>, some_alloc2<MapType>> C;
    167     static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
    168     }
    169     { // POCS allocator, nothrow swap for hash, throwable swap for comp
    170     typedef std::unordered_map<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp <MoveOnly>, some_alloc <MapType>> C;
    171     static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
    172     }
    173     { // always equal allocator, nothrow swap for hash, throwable swap for comp
    174     typedef std::unordered_map<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp <MoveOnly>, some_alloc2<MapType>> C;
    175     static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
    176     }
    177     { // POCS allocator, nothrow swap for hash, nothrow swap for comp
    178     typedef std::unordered_map<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc <MapType>> C;
    179     static_assert( noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
    180     }
    181     { // always equal allocator, nothrow swap for hash, nothrow swap for comp
    182     typedef std::unordered_map<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc2<MapType>> C;
    183     static_assert( noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
    184     }
    185 #if defined(_LIBCPP_VERSION)
    186     { // NOT always equal allocator, nothrow swap for hash, nothrow swap for comp
    187     typedef std::unordered_map<MoveOnly, MoveOnly, some_hash2<MoveOnly>, some_comp2<MoveOnly>, some_alloc3<MapType>> C;
    188     static_assert( noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
    189     }
    190 #endif // _LIBCPP_VERSION
    191 #endif
    192 }