xref: /llvm-project/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/copy.pass.cpp (revision 06e2b737aa0347b42e8bf37cb00a053eab0a9393)
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 // <tuple>
105a83710eSEric Fiselier 
115a83710eSEric Fiselier // template <class... Types> class tuple;
125a83710eSEric Fiselier 
135a83710eSEric Fiselier // tuple& operator=(const tuple& u);
145a83710eSEric Fiselier 
1531cbe0f2SLouis Dionne // UNSUPPORTED: c++03
160a52cd79SEric Fiselier 
175a83710eSEric Fiselier #include <tuple>
18b10fc370SEric Fiselier #include <memory>
195a83710eSEric Fiselier #include <string>
205a83710eSEric Fiselier #include <cassert>
215a83710eSEric Fiselier 
22aedcbf89SEric Fiselier #include "test_macros.h"
23aedcbf89SEric Fiselier 
24aedcbf89SEric Fiselier struct NonAssignable {
25aedcbf89SEric Fiselier   NonAssignable& operator=(NonAssignable const&) = delete;
26aedcbf89SEric Fiselier   NonAssignable& operator=(NonAssignable&&) = delete;
27aedcbf89SEric Fiselier };
28aedcbf89SEric Fiselier struct CopyAssignable {
29aedcbf89SEric Fiselier   CopyAssignable& operator=(CopyAssignable const&) = default;
30aedcbf89SEric Fiselier   CopyAssignable& operator=(CopyAssignable &&) = delete;
31aedcbf89SEric Fiselier };
32aedcbf89SEric Fiselier static_assert(std::is_copy_assignable<CopyAssignable>::value, "");
33aedcbf89SEric Fiselier struct MoveAssignable {
34aedcbf89SEric Fiselier   MoveAssignable& operator=(MoveAssignable const&) = delete;
35aedcbf89SEric Fiselier   MoveAssignable& operator=(MoveAssignable&&) = default;
36aedcbf89SEric Fiselier };
37a0839b14SLouis Dionne struct NothrowCopyAssignable {
operator =NothrowCopyAssignable38a0839b14SLouis Dionne   NothrowCopyAssignable& operator=(NothrowCopyAssignable const&) noexcept { return *this; }
39a0839b14SLouis Dionne };
40a0839b14SLouis Dionne struct PotentiallyThrowingCopyAssignable {
operator =PotentiallyThrowingCopyAssignable41a0839b14SLouis Dionne   PotentiallyThrowingCopyAssignable& operator=(PotentiallyThrowingCopyAssignable const&) { return *this; }
42a0839b14SLouis Dionne };
43aedcbf89SEric Fiselier 
4482c4701dSzoecarver struct CopyAssignableInt {
operator =CopyAssignableInt4582c4701dSzoecarver   CopyAssignableInt& operator=(int&) { return *this; }
4682c4701dSzoecarver };
4782c4701dSzoecarver 
48*06e2b737SArthur O'Dwyer TEST_CONSTEXPR_CXX20
test()49*06e2b737SArthur O'Dwyer bool test()
505a83710eSEric Fiselier {
515a83710eSEric Fiselier     {
525a83710eSEric Fiselier         typedef std::tuple<> T;
535a83710eSEric Fiselier         T t0;
545a83710eSEric Fiselier         T t;
555a83710eSEric Fiselier         t = t0;
565a83710eSEric Fiselier     }
575a83710eSEric Fiselier     {
585a83710eSEric Fiselier         typedef std::tuple<int> T;
595a83710eSEric Fiselier         T t0(2);
605a83710eSEric Fiselier         T t;
615a83710eSEric Fiselier         t = t0;
625a83710eSEric Fiselier         assert(std::get<0>(t) == 2);
635a83710eSEric Fiselier     }
645a83710eSEric Fiselier     {
655a83710eSEric Fiselier         typedef std::tuple<int, char> T;
665a83710eSEric Fiselier         T t0(2, 'a');
675a83710eSEric Fiselier         T t;
685a83710eSEric Fiselier         t = t0;
695a83710eSEric Fiselier         assert(std::get<0>(t) == 2);
705a83710eSEric Fiselier         assert(std::get<1>(t) == 'a');
715a83710eSEric Fiselier     }
725a83710eSEric Fiselier     {
73aedcbf89SEric Fiselier         // test reference assignment.
74aedcbf89SEric Fiselier         using T = std::tuple<int&, int&&>;
75aedcbf89SEric Fiselier         int x = 42;
76aedcbf89SEric Fiselier         int y = 100;
77aedcbf89SEric Fiselier         int x2 = -1;
78aedcbf89SEric Fiselier         int y2 = 500;
79aedcbf89SEric Fiselier         T t(x, std::move(y));
80aedcbf89SEric Fiselier         T t2(x2, std::move(y2));
81aedcbf89SEric Fiselier         t = t2;
82aedcbf89SEric Fiselier         assert(std::get<0>(t) == x2);
83aedcbf89SEric Fiselier         assert(&std::get<0>(t) == &x);
84aedcbf89SEric Fiselier         assert(std::get<1>(t) == y2);
85aedcbf89SEric Fiselier         assert(&std::get<1>(t) == &y);
86aedcbf89SEric Fiselier     }
87*06e2b737SArthur O'Dwyer 
88*06e2b737SArthur O'Dwyer     return true;
89*06e2b737SArthur O'Dwyer }
90*06e2b737SArthur O'Dwyer 
main(int,char **)91*06e2b737SArthur O'Dwyer int main(int, char**)
92*06e2b737SArthur O'Dwyer {
93*06e2b737SArthur O'Dwyer     test();
94*06e2b737SArthur O'Dwyer #if TEST_STD_VER >= 20
95*06e2b737SArthur O'Dwyer     static_assert(test());
96*06e2b737SArthur O'Dwyer #endif
97*06e2b737SArthur O'Dwyer 
98*06e2b737SArthur O'Dwyer     {
99*06e2b737SArthur O'Dwyer         // cannot be constexpr because of std::string
100*06e2b737SArthur O'Dwyer         typedef std::tuple<int, char, std::string> T;
101*06e2b737SArthur O'Dwyer         const T t0(2, 'a', "some text");
102*06e2b737SArthur O'Dwyer         T t;
103*06e2b737SArthur O'Dwyer         t = t0;
104*06e2b737SArthur O'Dwyer         assert(std::get<0>(t) == 2);
105*06e2b737SArthur O'Dwyer         assert(std::get<1>(t) == 'a');
106*06e2b737SArthur O'Dwyer         assert(std::get<2>(t) == "some text");
107*06e2b737SArthur O'Dwyer     }
108aedcbf89SEric Fiselier     {
109aedcbf89SEric Fiselier         // test that the implicitly generated copy assignment operator
110aedcbf89SEric Fiselier         // is properly deleted
111aedcbf89SEric Fiselier         using T = std::tuple<std::unique_ptr<int>>;
112aedcbf89SEric Fiselier         static_assert(!std::is_copy_assignable<T>::value, "");
113aedcbf89SEric Fiselier     }
114aedcbf89SEric Fiselier     {
115aedcbf89SEric Fiselier         using T = std::tuple<int, NonAssignable>;
116aedcbf89SEric Fiselier         static_assert(!std::is_copy_assignable<T>::value, "");
117aedcbf89SEric Fiselier     }
118aedcbf89SEric Fiselier     {
119aedcbf89SEric Fiselier         using T = std::tuple<int, CopyAssignable>;
120aedcbf89SEric Fiselier         static_assert(std::is_copy_assignable<T>::value, "");
121aedcbf89SEric Fiselier     }
122aedcbf89SEric Fiselier     {
123aedcbf89SEric Fiselier         using T = std::tuple<int, MoveAssignable>;
124aedcbf89SEric Fiselier         static_assert(!std::is_copy_assignable<T>::value, "");
125aedcbf89SEric Fiselier     }
12682c4701dSzoecarver     {
12782c4701dSzoecarver         using T = std::tuple<int, int, int>;
12882c4701dSzoecarver         using P = std::pair<int, int>;
1295f5416e1SLouis Dionne         static_assert(!std::is_assignable<T&, P>::value, "");
13082c4701dSzoecarver     }
1315f5416e1SLouis Dionne     {
1325f5416e1SLouis Dionne         // test const requirement
13382c4701dSzoecarver         using T = std::tuple<CopyAssignableInt, CopyAssignableInt>;
13482c4701dSzoecarver         using P = std::pair<int, int>;
13582c4701dSzoecarver         static_assert(!std::is_assignable<T&, P const>::value, "");
13682c4701dSzoecarver     }
13782c4701dSzoecarver     {
13882c4701dSzoecarver         using T = std::tuple<int, MoveAssignable>;
13982c4701dSzoecarver         using P = std::pair<int, MoveAssignable>;
14082c4701dSzoecarver         static_assert(!std::is_assignable<T&, P&>::value, "");
14182c4701dSzoecarver     }
142a0839b14SLouis Dionne     {
143a0839b14SLouis Dionne         using T = std::tuple<NothrowCopyAssignable, int>;
144a0839b14SLouis Dionne         static_assert(std::is_nothrow_copy_assignable<T>::value, "");
145a0839b14SLouis Dionne     }
146a0839b14SLouis Dionne     {
147a0839b14SLouis Dionne         using T = std::tuple<PotentiallyThrowingCopyAssignable, int>;
148*06e2b737SArthur O'Dwyer         static_assert(std::is_copy_assignable<T>::value, "");
149a0839b14SLouis Dionne         static_assert(!std::is_nothrow_copy_assignable<T>::value, "");
150a0839b14SLouis Dionne     }
1512df59c50SJF Bastien 
1522df59c50SJF Bastien     return 0;
1535a83710eSEric Fiselier }
154