Home | History | Annotate | Download | only in multiset.special
      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 // <set>
     13 
     14 // void swap(multiset& 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 <set>
     25 #include <utility>
     26 #include <cassert>
     27 
     28 #include "test_macros.h"
     29 #include "MoveOnly.h"
     30 #include "test_allocator.h"
     31 
     32 template <class T>
     33 struct 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 
     42 template <class T>
     43 struct 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
     53 template <typename T>
     54 void swap(some_comp2<T>&, some_comp2<T>&) noexcept {}
     55 #endif
     56 
     57 template <class T>
     58 struct 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 
     69 template <class T>
     70 struct 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 
     82 template <class T>
     83 struct 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 
     95 int main()
     96 {
     97     {
     98         typedef std::multiset<MoveOnly> C;
     99         static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
    100     }
    101 #if defined(_LIBCPP_VERSION)
    102     {
    103         typedef std::multiset<MoveOnly, std::less<MoveOnly>, test_allocator<MoveOnly>> C;
    104         static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
    105     }
    106     {
    107         typedef std::multiset<MoveOnly, std::less<MoveOnly>, other_allocator<MoveOnly>> C;
    108         static_assert(noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
    109     }
    110 #endif // _LIBCPP_VERSION
    111     {
    112         typedef std::multiset<MoveOnly, some_comp<MoveOnly>> C;
    113         static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
    114     }
    115 
    116 #if TEST_STD_VER >= 14
    117     { // POCS allocator, throwable swap for comp
    118     typedef std::multiset<MoveOnly, some_comp <MoveOnly>, some_alloc <MoveOnly>> C;
    119     static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
    120     }
    121     { // always equal allocator, throwable swap for comp
    122     typedef std::multiset<MoveOnly, some_comp <MoveOnly>, some_alloc2<MoveOnly>> C;
    123     static_assert(!noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
    124     }
    125     { // POCS allocator, nothrow swap for comp
    126     typedef std::multiset<MoveOnly, some_comp2<MoveOnly>, some_alloc <MoveOnly>> C;
    127     static_assert( noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
    128     }
    129     { // always equal allocator, nothrow swap for comp
    130     typedef std::multiset<MoveOnly, some_comp2<MoveOnly>, some_alloc2<MoveOnly>> C;
    131     static_assert( noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
    132     }
    133 #if defined(_LIBCPP_VERSION)
    134     { // NOT always equal allocator, nothrow swap for comp
    135     typedef std::multiset<MoveOnly, some_comp2<MoveOnly>, some_alloc3<MoveOnly>> C;
    136     static_assert( noexcept(swap(std::declval<C&>(), std::declval<C&>())), "");
    137     }
    138 #endif // _LIBCPP_VERSION
    139 #endif
    140 }
    141