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_nothrow_swappable_with
     15 
     16 #include <type_traits>
     17 #include <vector>
     18 #include "test_macros.h"
     19 
     20 namespace MyNS {
     21 
     22 struct A {
     23   A(A const&) = delete;
     24   A& operator=(A const&) = delete;
     25 };
     26 
     27 struct B {
     28   B(B const&) = delete;
     29   B& operator=(B const&) = delete;
     30 };
     31 
     32 struct C {};
     33 struct D {};
     34 
     35 void swap(A&, A&) {}
     36 
     37 void swap(A&, B&) noexcept {}
     38 void swap(B&, A&) noexcept {}
     39 
     40 void swap(A&, C&) noexcept {}
     41 void swap(C&, A&) {}
     42 
     43 struct M {};
     44 
     45 void swap(M&&, M&&) noexcept {}
     46 
     47 } // namespace MyNS
     48 
     49 int main()
     50 {
     51     using namespace MyNS;
     52     {
     53         // Test that is_swappable_with doesn't apply an lvalue reference
     54         // to the type. Instead it is up to the user.
     55         static_assert(!std::is_nothrow_swappable_with<int, int>::value, "");
     56         static_assert(std::is_nothrow_swappable_with<int&, int&>::value, "");
     57         static_assert(std::is_nothrow_swappable_with<M, M>::value, "");
     58         static_assert(std::is_swappable_with<A&, A&>::value &&
     59                       !std::is_nothrow_swappable_with<A&, A&>::value, "");
     60     }
     61     {
     62         // test that hetrogenius swap is allowed only if both 'swap(A, B)' and
     63         // 'swap(B, A)' are valid.
     64         static_assert(std::is_nothrow_swappable_with<A&, B&>::value, "");
     65         static_assert(!std::is_nothrow_swappable_with<A&, C&>::value &&
     66                       std::is_swappable_with<A&, C&>::value, "");
     67         static_assert(!std::is_nothrow_swappable_with<D&, C&>::value, "");
     68     }
     69     {
     70         // test we guard against cv void inputs as required.
     71         static_assert(!std::is_nothrow_swappable_with_v<void, int>);
     72         static_assert(!std::is_nothrow_swappable_with_v<int, void>);
     73         static_assert(!std::is_nothrow_swappable_with_v<const void, const volatile void>);
     74 
     75     }
     76     {
     77         // test for presense of is_nothrow_swappable_with_v
     78         static_assert(std::is_nothrow_swappable_with_v<int&, int&>);
     79         static_assert(!std::is_nothrow_swappable_with_v<int&&, int&&>);
     80     }
     81 }
     82