155 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// <utility>10 11// template<ValueType T, size_t N>12// requires Swappable<T>13// void swap(T (&a)[N], T (&b)[N]); // constexpr since C++2014 15#include <algorithm>16#include <cassert>17#include <memory>18#include <type_traits>19#include <utility>20 21#include "test_macros.h"22 23#if TEST_STD_VER >= 1124struct CopyOnly {25 TEST_CONSTEXPR_CXX20 CopyOnly() {}26 TEST_CONSTEXPR_CXX20 CopyOnly(CopyOnly const&) noexcept {}27 TEST_CONSTEXPR_CXX20 CopyOnly& operator=(CopyOnly const&) { return *this; }28};29 30struct NoexceptMoveOnly {31 TEST_CONSTEXPR_CXX20 NoexceptMoveOnly() {}32 TEST_CONSTEXPR_CXX20 NoexceptMoveOnly(NoexceptMoveOnly&&) noexcept {}33 TEST_CONSTEXPR_CXX20 NoexceptMoveOnly& operator=(NoexceptMoveOnly&&) noexcept { return *this; }34};35 36struct NotMoveConstructible {37 TEST_CONSTEXPR_CXX20 NotMoveConstructible() {}38 TEST_CONSTEXPR_CXX20 NotMoveConstructible& operator=(NotMoveConstructible&&) { return *this; }39 NotMoveConstructible(NotMoveConstructible&&) = delete;40};41 42template <class Tp>43auto can_swap_test(int) -> decltype(std::swap(std::declval<Tp>(), std::declval<Tp>()));44 45template <class Tp>46auto can_swap_test(...) -> std::false_type;47 48template <class Tp>49constexpr bool can_swap() {50 return std::is_same<decltype(can_swap_test<Tp>(0)), void>::value;51}52 53TEST_CONSTEXPR_CXX23 void test_unique_ptr() {54 std::unique_ptr<int> i[3];55 for (int k = 0; k < 3; ++k)56 i[k].reset(new int(k + 1));57 std::unique_ptr<int> j[3];58 for (int k = 0; k < 3; ++k)59 j[k].reset(new int(k + 4));60 std::swap(i, j);61 assert(*i[0] == 4);62 assert(*i[1] == 5);63 assert(*i[2] == 6);64 assert(*j[0] == 1);65 assert(*j[1] == 2);66 assert(*j[2] == 3);67}68#endif69 70TEST_CONSTEXPR_CXX20 bool test() {71 {72 int i[3] = {1, 2, 3};73 int j[3] = {4, 5, 6};74 std::swap(i, j);75 assert(i[0] == 4);76 assert(i[1] == 5);77 assert(i[2] == 6);78 assert(j[0] == 1);79 assert(j[1] == 2);80 assert(j[2] == 3);81 }82 {83 int a[2][2] = {{0, 1}, {2, 3}};84 decltype(a) b = {{9, 8}, {7, 6}};85 86 std::swap(a, b);87 88 assert(a[0][0] == 9);89 assert(a[0][1] == 8);90 assert(a[1][0] == 7);91 assert(a[1][1] == 6);92 93 assert(b[0][0] == 0);94 assert(b[0][1] == 1);95 assert(b[1][0] == 2);96 assert(b[1][1] == 3);97 }98 99 {100 int a[3][3] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}};101 decltype(a) b = {{9, 8, 7}, {6, 5, 4}, {3, 2, 1}};102 103 std::swap(a, b);104 105 assert(a[0][0] == 9);106 assert(a[0][1] == 8);107 assert(a[0][2] == 7);108 assert(a[1][0] == 6);109 assert(a[1][1] == 5);110 assert(a[1][2] == 4);111 assert(a[2][0] == 3);112 assert(a[2][1] == 2);113 assert(a[2][2] == 1);114 115 assert(b[0][0] == 0);116 assert(b[0][1] == 1);117 assert(b[0][2] == 2);118 assert(b[1][0] == 3);119 assert(b[1][1] == 4);120 assert(b[1][2] == 5);121 assert(b[2][0] == 6);122 assert(b[2][1] == 7);123 assert(b[2][2] == 8);124 }125#if TEST_STD_VER >= 11126 {127 using CA = CopyOnly[42];128 using MA = NoexceptMoveOnly[42];129 using NA = NotMoveConstructible[42];130 static_assert(can_swap<CA&>(), "");131 static_assert(can_swap<MA&>(), "");132 static_assert(!can_swap<NA&>(), "");133 134 CA ca;135 MA ma;136 static_assert(!noexcept(std::swap(ca, ca)), "");137 static_assert(noexcept(std::swap(ma, ma)), "");138 }139 140 if (TEST_STD_AT_LEAST_23_OR_RUNTIME_EVALUATED)141 test_unique_ptr();142#endif143 144 return true;145}146 147int main(int, char**) {148 test();149#if TEST_STD_VER >= 20150 static_assert(test());151#endif152 153 return 0;154}155