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 <vector>
     18 #include "test_macros.h"
     19 
     20 namespace MyNS {
     21 
     22 // Make the test types non-copyable so that generic std::swap is not valid.
     23 struct A {
     24   A(A const&) = delete;
     25   A& operator=(A const&) = delete;
     26 };
     27 
     28 struct B {
     29   B(B const&) = delete;
     30   B& operator=(B const&) = delete;
     31 };
     32 
     33 void swap(A&, A&) noexcept {}
     34 void swap(B&, B&) {}
     35 
     36 struct M {
     37   M(M const&) = delete;
     38   M& operator=(M const&) = delete;
     39 };
     40 
     41 void swap(M&&, M&&) noexcept {}
     42 
     43 struct ThrowingMove {
     44     ThrowingMove(ThrowingMove&&) {}
     45     ThrowingMove& operator=(ThrowingMove&&) { return *this; }
     46 };
     47 
     48 } // namespace MyNS
     49 
     50 int main()
     51 {
     52     using namespace MyNS;
     53     {
     54         // Test that is_swappable applies an lvalue reference to the type.
     55         static_assert(std::is_nothrow_swappable<int>::value, "");
     56         static_assert(std::is_nothrow_swappable<int&>::value, "");
     57         static_assert(!std::is_nothrow_swappable<M>::value, "");
     58         static_assert(!std::is_nothrow_swappable<M&&>::value, "");
     59     }
     60     {
     61         // Test that it correctly deduces the noexcept of swap.
     62         static_assert(std::is_nothrow_swappable<A>::value, "");
     63         static_assert(!std::is_nothrow_swappable<B>::value
     64                       && std::is_swappable<B>::value, "");
     65         static_assert(!std::is_nothrow_swappable<ThrowingMove>::value
     66                       && std::is_swappable<ThrowingMove>::value, "");
     67     }
     68     {
     69         // Test that it doesn't drop the qualifiers
     70         static_assert(!std::is_nothrow_swappable<const A>::value, "");
     71     }
     72     {
     73         // test non-referenceable types
     74         static_assert(!std::is_nothrow_swappable<void>::value, "");
     75         static_assert(!std::is_nothrow_swappable<int() const>::value, "");
     76         static_assert(!std::is_nothrow_swappable<int(int, ...) const &>::value, "");
     77     }
     78     {
     79         // test for presence of is_nothrow_swappable_v
     80         static_assert(std::is_nothrow_swappable_v<int>, "");
     81         static_assert(!std::is_nothrow_swappable_v<void>, "");
     82     }
     83 }
     84