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-exception
6//
7//===----------------------------------------------------------------------===//
8
9// <tuple>
10
11// template <class... Types> class tuple;
12
13// template <class... UTypes>
14// tuple& operator=(const tuple<UTypes...>& u);
15
16// UNSUPPORTED: c++03
17
18#include <tuple>
19#include <array>
20#include <string>
21#include <utility>
22#include <cassert>
23
24#include "propagate_value_category.hpp"
25
26struct TracksIntQuals {
27 TracksIntQuals() : value(-1), value_category(VC_None), assigned(false) {}
28
29 template <class Tp,
30 class = typename std::enable_if<!std::is_same<
31 typename std::decay<Tp>::type, TracksIntQuals>::value>::type>
32 TracksIntQuals(Tp &&x)
33 : value(x), value_category(getValueCategory<Tp &&>()), assigned(false) {
34 static_assert(std::is_same<UnCVRef<Tp>, int>::value, "");
35 }
36
37 template <class Tp,
38 class = typename std::enable_if<!std::is_same<
39 typename std::decay<Tp>::type, TracksIntQuals>::value>::type>
40 TracksIntQuals &operator=(Tp &&x) {
41 static_assert(std::is_same<UnCVRef<Tp>, int>::value, "");
42 value = x;
43 value_category = getValueCategory<Tp &&>();
44 assigned = true;
45 return *this;
46 }
47
48 void reset() {
49 value = -1;
50 value_category = VC_None;
51 assigned = false;
52 }
53
54 bool checkConstruct(int expect, ValueCategory expect_vc) const {
55 return value != 1 && value == expect && value_category == expect_vc &&
56 assigned == false;
57 }
58
59 bool checkAssign(int expect, ValueCategory expect_vc) const {
60 return value != 1 && value == expect && value_category == expect_vc &&
61 assigned == true;
62 }
63
64 int value;
65 ValueCategory value_category;
66 bool assigned;
67};
68
69template <class Tup>
70struct DerivedFromTup : Tup {
71 using Tup::Tup;
72};
73
74template <ValueCategory VC>
75void do_derived_assign_test() {
76 using Tup1 = std::tuple<long, TracksIntQuals>;
77 Tup1 t;
78 auto reset = [&]() {
79 std::get<0>(t) = -1;
80 std::get<1>(t).reset();
81 };
82 {
83 DerivedFromTup<std::tuple<int, int>> d;
84 std::get<0>(t&: d) = 42;
85 std::get<1>(t&: d) = 101;
86
87 t = ValueCategoryCast<VC>(d);
88 assert(std::get<0>(t) == 42);
89 assert(std::get<1>(t).checkAssign(101, VC));
90 }
91 reset();
92 {
93 DerivedFromTup<std::pair<int, int>> d;
94 std::get<0>(in&: d) = 42;
95 std::get<1>(in&: d) = 101;
96
97 t = ValueCategoryCast<VC>(d);
98 assert(std::get<0>(t) == 42);
99 assert(std::get<1>(t).checkAssign(101, VC));
100 }
101 reset();
102 {
103#ifdef _LIBCPP_VERSION // assignment from std::array is a libc++ extension
104 DerivedFromTup<std::array<int, 2>> d;
105 std::get<0>(d) = 42;
106 std::get<1>(d) = 101;
107
108 t = ValueCategoryCast<VC>(d);
109 assert(std::get<0>(t) == 42);
110 assert(std::get<1>(t).checkAssign(101, VC));
111#endif
112 }
113}
114
115int main(int, char**) {
116 do_derived_assign_test<VC_LVal | VC_Const>();
117 do_derived_assign_test<VC_RVal>();
118
119 return 0;
120}
121

source code of libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/derived_from_tuple_like.pass.cpp