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