Home | History | Annotate | Download | only in meta.unary.prop
      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, c++11, c++14
     11 
     12 // type_traits
     13 
     14 // is_swappable
     15 
     16 #include <type_traits>
     17 #include <utility>
     18 #include <vector>
     19 #include "test_macros.h"
     20 
     21 namespace MyNS {
     22 
     23 // Make the test types non-copyable so that generic std::swap is not valid.
     24 struct A {
     25   A(A const&) = delete;
     26   A& operator=(A const&) = delete;
     27 };
     28 
     29 struct B {
     30   B(B const&) = delete;
     31   B& operator=(B const&) = delete;
     32 };
     33 
     34 struct C {};
     35 struct D {};
     36 
     37 void swap(A&, A&) {}
     38 
     39 void swap(A&, B&) {}
     40 void swap(B&, A&) {}
     41 
     42 void swap(A&, C&) {} // missing swap(C, A)
     43 void swap(D&, C&) {}
     44 
     45 struct M {
     46   M(M const&) = delete;
     47   M& operator=(M const&) = delete;
     48 };
     49 
     50 void swap(M&&, M&&) {}
     51 
     52 struct DeletedSwap {
     53   friend void swap(DeletedSwap&, DeletedSwap&) = delete;
     54 };
     55 
     56 } // namespace MyNS
     57 
     58 namespace MyNS2 {
     59 
     60 struct AmbiguousSwap {};
     61 
     62 template <class T>
     63 void swap(T&, T&) {}
     64 
     65 } // end namespace MyNS2
     66 
     67 int main()
     68 {
     69     using namespace MyNS;
     70     {
     71         // Test that is_swappable applies an lvalue reference to the type.
     72         static_assert(std::is_swappable<A>::value, "");
     73         static_assert(std::is_swappable<A&>::value, "");
     74         static_assert(!std::is_swappable<M>::value, "");
     75         static_assert(!std::is_swappable<M&&>::value, "");
     76     }
     77     static_assert(!std::is_swappable<B>::value, "");
     78     static_assert(std::is_swappable<C>::value, "");
     79     {
     80         // test non-referencable types
     81         static_assert(!std::is_swappable<void>::value, "");
     82         static_assert(!std::is_swappable<int() const>::value, "");
     83         static_assert(!std::is_swappable<int() &>::value, "");
     84     }
     85     {
     86         // test that a deleted swap is correctly handled.
     87         static_assert(!std::is_swappable<DeletedSwap>::value, "");
     88     }
     89     {
     90         // test that a swap with ambiguous overloads is handled correctly.
     91         static_assert(!std::is_swappable<MyNS2::AmbiguousSwap>::value, "");
     92     }
     93     {
     94         // test for presence of is_swappable_v
     95         static_assert(std::is_swappable_v<int>, "");
     96         static_assert(!std::is_swappable_v<M>, "");
     97     }
     98 }
     99