xref: /llvm-project/libcxx/test/std/utilities/utility/utility.swap/swap_array.pass.cpp (revision 6adbc83ee9e46b476e0f75d5671c3a21f675a936)
15a83710eSEric Fiselier //===----------------------------------------------------------------------===//
25a83710eSEric Fiselier //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65a83710eSEric Fiselier //
75a83710eSEric Fiselier //===----------------------------------------------------------------------===//
85a83710eSEric Fiselier 
95a83710eSEric Fiselier // <utility>
105a83710eSEric Fiselier 
115a83710eSEric Fiselier // template<ValueType T, size_t N>
125a83710eSEric Fiselier //   requires Swappable<T>
135a83710eSEric Fiselier //   void
145a83710eSEric Fiselier //   swap(T (&a)[N], T (&b)[N]);
155a83710eSEric Fiselier 
16*6adbc83eSChristopher Di Bella #include <algorithm>
175a83710eSEric Fiselier #include <cassert>
185a83710eSEric Fiselier #include <memory>
19*6adbc83eSChristopher Di Bella #include <type_traits>
20*6adbc83eSChristopher Di Bella #include <utility>
21f07dd8d0SEric Fiselier 
22f07dd8d0SEric Fiselier #include "test_macros.h"
23f07dd8d0SEric Fiselier 
24f07dd8d0SEric Fiselier 
25f07dd8d0SEric Fiselier #if TEST_STD_VER >= 11
26f07dd8d0SEric Fiselier struct CopyOnly {
CopyOnlyCopyOnly27f07dd8d0SEric Fiselier     CopyOnly() {}
CopyOnlyCopyOnly28f07dd8d0SEric Fiselier     CopyOnly(CopyOnly const&) noexcept {}
operator =CopyOnly29f07dd8d0SEric Fiselier     CopyOnly& operator=(CopyOnly const&) { return *this; }
30f07dd8d0SEric Fiselier };
31f07dd8d0SEric Fiselier 
32f07dd8d0SEric Fiselier 
33f07dd8d0SEric Fiselier struct NoexceptMoveOnly {
NoexceptMoveOnlyNoexceptMoveOnly34f07dd8d0SEric Fiselier     NoexceptMoveOnly() {}
NoexceptMoveOnlyNoexceptMoveOnly35f07dd8d0SEric Fiselier     NoexceptMoveOnly(NoexceptMoveOnly&&) noexcept {}
operator =NoexceptMoveOnly36f07dd8d0SEric Fiselier     NoexceptMoveOnly& operator=(NoexceptMoveOnly&&) noexcept { return *this; }
37f07dd8d0SEric Fiselier };
38f07dd8d0SEric Fiselier 
39f07dd8d0SEric Fiselier struct NotMoveConstructible {
NotMoveConstructibleNotMoveConstructible40f07dd8d0SEric Fiselier     NotMoveConstructible() {}
operator =NotMoveConstructible41f07dd8d0SEric Fiselier     NotMoveConstructible& operator=(NotMoveConstructible&&) { return *this; }
42f07dd8d0SEric Fiselier private:
43f07dd8d0SEric Fiselier     NotMoveConstructible(NotMoveConstructible&&);
44f07dd8d0SEric Fiselier };
45f07dd8d0SEric Fiselier 
46f07dd8d0SEric Fiselier template <class Tp>
47f07dd8d0SEric Fiselier auto can_swap_test(int) -> decltype(std::swap(std::declval<Tp>(), std::declval<Tp>()));
48f07dd8d0SEric Fiselier 
49f07dd8d0SEric Fiselier template <class Tp>
50f07dd8d0SEric Fiselier auto can_swap_test(...) -> std::false_type;
51f07dd8d0SEric Fiselier 
52f07dd8d0SEric Fiselier template <class Tp>
can_swap()53f07dd8d0SEric Fiselier constexpr bool can_swap() {
54f07dd8d0SEric Fiselier     return std::is_same<decltype(can_swap_test<Tp>(0)), void>::value;
55f07dd8d0SEric Fiselier }
565a83710eSEric Fiselier #endif
575a83710eSEric Fiselier 
5828e01871SZoe Carver #if TEST_STD_VER > 17
test_swap_constexpr()5928e01871SZoe Carver constexpr bool test_swap_constexpr()
6028e01871SZoe Carver {
6128e01871SZoe Carver     int i[3] = {1, 2, 3};
6228e01871SZoe Carver     int j[3] = {4, 5, 6};
6328e01871SZoe Carver     std::swap(i, j);
6428e01871SZoe Carver     return i[0] == 4 &&
6528e01871SZoe Carver            i[1] == 5 &&
6628e01871SZoe Carver            i[2] == 6 &&
6728e01871SZoe Carver            j[0] == 1 &&
6828e01871SZoe Carver            j[1] == 2 &&
6928e01871SZoe Carver            j[2] == 3;
7028e01871SZoe Carver }
7128e01871SZoe Carver #endif // TEST_STD_VER > 17
72f07dd8d0SEric Fiselier 
main(int,char **)732df59c50SJF Bastien int main(int, char**)
74f07dd8d0SEric Fiselier {
755a83710eSEric Fiselier     {
765a83710eSEric Fiselier         int i[3] = {1, 2, 3};
775a83710eSEric Fiselier         int j[3] = {4, 5, 6};
785a83710eSEric Fiselier         std::swap(i, j);
795a83710eSEric Fiselier         assert(i[0] == 4);
805a83710eSEric Fiselier         assert(i[1] == 5);
815a83710eSEric Fiselier         assert(i[2] == 6);
825a83710eSEric Fiselier         assert(j[0] == 1);
835a83710eSEric Fiselier         assert(j[1] == 2);
845a83710eSEric Fiselier         assert(j[2] == 3);
855a83710eSEric Fiselier     }
86f07dd8d0SEric Fiselier #if TEST_STD_VER >= 11
875a83710eSEric Fiselier     {
885a83710eSEric Fiselier         std::unique_ptr<int> i[3];
895a83710eSEric Fiselier         for (int k = 0; k < 3; ++k)
905a83710eSEric Fiselier             i[k].reset(new int(k+1));
915a83710eSEric Fiselier         std::unique_ptr<int> j[3];
925a83710eSEric Fiselier         for (int k = 0; k < 3; ++k)
935a83710eSEric Fiselier             j[k].reset(new int(k+4));
945a83710eSEric Fiselier         std::swap(i, j);
955a83710eSEric Fiselier         assert(*i[0] == 4);
965a83710eSEric Fiselier         assert(*i[1] == 5);
975a83710eSEric Fiselier         assert(*i[2] == 6);
985a83710eSEric Fiselier         assert(*j[0] == 1);
995a83710eSEric Fiselier         assert(*j[1] == 2);
1005a83710eSEric Fiselier         assert(*j[2] == 3);
1015a83710eSEric Fiselier     }
1025a83710eSEric Fiselier     {
103f07dd8d0SEric Fiselier         using CA = CopyOnly[42];
104f07dd8d0SEric Fiselier         using MA = NoexceptMoveOnly[42];
105f07dd8d0SEric Fiselier         using NA = NotMoveConstructible[42];
106f07dd8d0SEric Fiselier         static_assert(can_swap<CA&>(), "");
107f07dd8d0SEric Fiselier         static_assert(can_swap<MA&>(), "");
108f07dd8d0SEric Fiselier         static_assert(!can_swap<NA&>(), "");
109f07dd8d0SEric Fiselier 
110f07dd8d0SEric Fiselier         CA ca;
111f07dd8d0SEric Fiselier         MA ma;
112f07dd8d0SEric Fiselier         static_assert(!noexcept(std::swap(ca, ca)), "");
113f07dd8d0SEric Fiselier         static_assert(noexcept(std::swap(ma, ma)), "");
114f07dd8d0SEric Fiselier     }
1155a83710eSEric Fiselier #endif
1162df59c50SJF Bastien 
11728e01871SZoe Carver #if TEST_STD_VER > 17
11828e01871SZoe Carver     static_assert(test_swap_constexpr());
11928e01871SZoe Carver #endif // TEST_STD_VER > 17
12028e01871SZoe Carver 
1212df59c50SJF Bastien   return 0;
1225a83710eSEric Fiselier }
123