xref: /llvm-project/libcxx/test/std/utilities/utility/utility.swap/swap.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<class T>
125a83710eSEric Fiselier //   requires MoveAssignable<T> && MoveConstructible<T>
135a83710eSEric Fiselier //   void
145a83710eSEric Fiselier //   swap(T& a, T& b);
155a83710eSEric Fiselier 
165a83710eSEric Fiselier #include <cassert>
175a83710eSEric Fiselier #include <memory>
18*6adbc83eSChristopher Di Bella #include <type_traits>
19*6adbc83eSChristopher Di Bella #include <utility>
20f07dd8d0SEric Fiselier 
21f07dd8d0SEric Fiselier #include "test_macros.h"
22f07dd8d0SEric Fiselier 
23f07dd8d0SEric Fiselier #if TEST_STD_VER >= 11
24f07dd8d0SEric Fiselier struct CopyOnly {
CopyOnlyCopyOnly25f07dd8d0SEric Fiselier     CopyOnly() {}
CopyOnlyCopyOnly26f07dd8d0SEric Fiselier     CopyOnly(CopyOnly const&) noexcept {}
operator =CopyOnly27f07dd8d0SEric Fiselier     CopyOnly& operator=(CopyOnly const&) { return *this; }
28f07dd8d0SEric Fiselier };
29f07dd8d0SEric Fiselier 
30f07dd8d0SEric Fiselier struct MoveOnly {
MoveOnlyMoveOnly31f07dd8d0SEric Fiselier     MoveOnly() {}
MoveOnlyMoveOnly32f07dd8d0SEric Fiselier     MoveOnly(MoveOnly&&) {}
operator =MoveOnly33f07dd8d0SEric Fiselier     MoveOnly& operator=(MoveOnly&&) noexcept { return *this; }
34f07dd8d0SEric Fiselier };
35f07dd8d0SEric Fiselier 
36f07dd8d0SEric Fiselier struct NoexceptMoveOnly {
NoexceptMoveOnlyNoexceptMoveOnly37f07dd8d0SEric Fiselier     NoexceptMoveOnly() {}
NoexceptMoveOnlyNoexceptMoveOnly38f07dd8d0SEric Fiselier     NoexceptMoveOnly(NoexceptMoveOnly&&) noexcept {}
operator =NoexceptMoveOnly39f07dd8d0SEric Fiselier     NoexceptMoveOnly& operator=(NoexceptMoveOnly&&) noexcept { return *this; }
40f07dd8d0SEric Fiselier };
41f07dd8d0SEric Fiselier 
42f07dd8d0SEric Fiselier struct NotMoveConstructible {
operator =NotMoveConstructible43f07dd8d0SEric Fiselier     NotMoveConstructible& operator=(NotMoveConstructible&&) { return *this; }
44f07dd8d0SEric Fiselier private:
45f07dd8d0SEric Fiselier     NotMoveConstructible(NotMoveConstructible&&);
46f07dd8d0SEric Fiselier };
47f07dd8d0SEric Fiselier 
48f07dd8d0SEric Fiselier struct NotMoveAssignable {
49f07dd8d0SEric Fiselier     NotMoveAssignable(NotMoveAssignable&&);
50f07dd8d0SEric Fiselier private:
51f07dd8d0SEric Fiselier     NotMoveAssignable& operator=(NotMoveAssignable&&);
52f07dd8d0SEric Fiselier };
53f07dd8d0SEric Fiselier 
54f07dd8d0SEric Fiselier template <class Tp>
55f07dd8d0SEric Fiselier auto can_swap_test(int) -> decltype(std::swap(std::declval<Tp>(), std::declval<Tp>()));
56f07dd8d0SEric Fiselier 
57f07dd8d0SEric Fiselier template <class Tp>
58f07dd8d0SEric Fiselier auto can_swap_test(...) -> std::false_type;
59f07dd8d0SEric Fiselier 
60f07dd8d0SEric Fiselier template <class Tp>
can_swap()61f07dd8d0SEric Fiselier constexpr bool can_swap() {
62f07dd8d0SEric Fiselier     return std::is_same<decltype(can_swap_test<Tp>(0)), void>::value;
63f07dd8d0SEric Fiselier }
645a83710eSEric Fiselier #endif
655a83710eSEric Fiselier 
6628e01871SZoe Carver #if TEST_STD_VER > 17
test_swap_constexpr()6728e01871SZoe Carver constexpr bool test_swap_constexpr()
6828e01871SZoe Carver {
6928e01871SZoe Carver     int i = 1;
7028e01871SZoe Carver     int j = 2;
7128e01871SZoe Carver     std::swap(i, j);
7228e01871SZoe Carver     return i == 2 && j == 1;
7328e01871SZoe Carver }
7428e01871SZoe Carver #endif // TEST_STD_VER > 17
7528e01871SZoe Carver 
main(int,char **)762df59c50SJF Bastien int main(int, char**)
77f07dd8d0SEric Fiselier {
78f07dd8d0SEric Fiselier 
795a83710eSEric Fiselier     {
805a83710eSEric Fiselier         int i = 1;
815a83710eSEric Fiselier         int j = 2;
825a83710eSEric Fiselier         std::swap(i, j);
835a83710eSEric Fiselier         assert(i == 2);
845a83710eSEric Fiselier         assert(j == 1);
855a83710eSEric Fiselier     }
86f07dd8d0SEric Fiselier #if TEST_STD_VER >= 11
875a83710eSEric Fiselier     {
88f07dd8d0SEric Fiselier 
895a83710eSEric Fiselier         std::unique_ptr<int> i(new int(1));
905a83710eSEric Fiselier         std::unique_ptr<int> j(new int(2));
915a83710eSEric Fiselier         std::swap(i, j);
925a83710eSEric Fiselier         assert(*i == 2);
935a83710eSEric Fiselier         assert(*j == 1);
94f07dd8d0SEric Fiselier 
955a83710eSEric Fiselier     }
965a83710eSEric Fiselier     {
97f07dd8d0SEric Fiselier         // test that the swap
98f07dd8d0SEric Fiselier         static_assert(can_swap<CopyOnly&>(), "");
99f07dd8d0SEric Fiselier         static_assert(can_swap<MoveOnly&>(), "");
100f07dd8d0SEric Fiselier         static_assert(can_swap<NoexceptMoveOnly&>(), "");
101f07dd8d0SEric Fiselier 
102f07dd8d0SEric Fiselier         static_assert(!can_swap<NotMoveConstructible&>(), "");
103f07dd8d0SEric Fiselier         static_assert(!can_swap<NotMoveAssignable&>(), "");
104f07dd8d0SEric Fiselier 
105f07dd8d0SEric Fiselier         CopyOnly c;
106f07dd8d0SEric Fiselier         MoveOnly m;
107f07dd8d0SEric Fiselier         NoexceptMoveOnly nm;
108f07dd8d0SEric Fiselier         static_assert(!noexcept(std::swap(c, c)), "");
109f07dd8d0SEric Fiselier         static_assert(!noexcept(std::swap(m, m)), "");
110f07dd8d0SEric Fiselier         static_assert(noexcept(std::swap(nm, nm)), "");
111f07dd8d0SEric Fiselier     }
1125a83710eSEric Fiselier #endif
1132df59c50SJF Bastien 
11428e01871SZoe Carver #if TEST_STD_VER > 17
11528e01871SZoe Carver     static_assert(test_swap_constexpr());
11628e01871SZoe Carver #endif // TEST_STD_VER > 17
11728e01871SZoe Carver 
1182df59c50SJF Bastien   return 0;
1195a83710eSEric Fiselier }
120