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