Home | History | Annotate | Download | only in utility.swap
      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 // <utility>
     11 
     12 // template<class T>
     13 //   requires MoveAssignable<T> && MoveConstructible<T>
     14 //   void
     15 //   swap(T& a, T& b);
     16 
     17 #include <utility>
     18 #include <cassert>
     19 #include <memory>
     20 
     21 #include "test_macros.h"
     22 
     23 #if TEST_STD_VER >= 11
     24 struct CopyOnly {
     25     CopyOnly() {}
     26     CopyOnly(CopyOnly const&) noexcept {}
     27     CopyOnly& operator=(CopyOnly const&) { return *this; }
     28 };
     29 
     30 struct MoveOnly {
     31     MoveOnly() {}
     32     MoveOnly(MoveOnly&&) {}
     33     MoveOnly& operator=(MoveOnly&&) noexcept { return *this; }
     34 };
     35 
     36 struct NoexceptMoveOnly {
     37     NoexceptMoveOnly() {}
     38     NoexceptMoveOnly(NoexceptMoveOnly&&) noexcept {}
     39     NoexceptMoveOnly& operator=(NoexceptMoveOnly&&) noexcept { return *this; }
     40 };
     41 
     42 struct NotMoveConstructible {
     43     NotMoveConstructible& operator=(NotMoveConstructible&&) { return *this; }
     44 private:
     45     NotMoveConstructible(NotMoveConstructible&&);
     46 };
     47 
     48 struct NotMoveAssignable {
     49     NotMoveAssignable(NotMoveAssignable&&);
     50 private:
     51     NotMoveAssignable& operator=(NotMoveAssignable&&);
     52 };
     53 
     54 template <class Tp>
     55 auto can_swap_test(int) -> decltype(std::swap(std::declval<Tp>(), std::declval<Tp>()));
     56 
     57 template <class Tp>
     58 auto can_swap_test(...) -> std::false_type;
     59 
     60 template <class Tp>
     61 constexpr bool can_swap() {
     62     return std::is_same<decltype(can_swap_test<Tp>(0)), void>::value;
     63 }
     64 #endif
     65 
     66 int main()
     67 {
     68 
     69     {
     70         int i = 1;
     71         int j = 2;
     72         std::swap(i, j);
     73         assert(i == 2);
     74         assert(j == 1);
     75     }
     76 #if TEST_STD_VER >= 11
     77     {
     78 
     79         std::unique_ptr<int> i(new int(1));
     80         std::unique_ptr<int> j(new int(2));
     81         std::swap(i, j);
     82         assert(*i == 2);
     83         assert(*j == 1);
     84 
     85     }
     86     {
     87         // test that the swap
     88         static_assert(can_swap<CopyOnly&>(), "");
     89         static_assert(can_swap<MoveOnly&>(), "");
     90         static_assert(can_swap<NoexceptMoveOnly&>(), "");
     91 
     92         static_assert(!can_swap<NotMoveConstructible&>(), "");
     93         static_assert(!can_swap<NotMoveAssignable&>(), "");
     94 
     95         CopyOnly c;
     96         MoveOnly m;
     97         NoexceptMoveOnly nm;
     98         static_assert(!noexcept(std::swap(c, c)), "");
     99         static_assert(!noexcept(std::swap(m, m)), "");
    100         static_assert(noexcept(std::swap(nm, nm)), "");
    101     }
    102 #endif
    103 }
    104