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... Types>
14// struct tuple_size<tuple<Types...>>
15// : public integral_constant<size_t, sizeof...(Types)> { };
16
17// UNSUPPORTED: c++03, c++11, c++14
18
19#include <array>
20#include <cassert>
21#include <tuple>
22#include <utility>
23
24#include "test_macros.h"
25
26struct S { int x; };
27
28void test_decomp_user_type() {
29 {
30 S s{.x: 99};
31 auto [m1] = s;
32 auto& [r1] = s;
33 assert(m1 == 99);
34 assert(&r1 == &s.x);
35 }
36 {
37 S const s{.x: 99};
38 auto [m1] = s;
39 auto& [r1] = s;
40 assert(m1 == 99);
41 assert(&r1 == &s.x);
42 }
43}
44
45void test_decomp_tuple() {
46 typedef std::tuple<int> T;
47 {
48 T s{99};
49 auto [m1] = s;
50 auto& [r1] = s;
51 assert(m1 == 99);
52 assert(&r1 == &std::get<0>(s));
53 }
54 {
55 T const s{99};
56 auto [m1] = s;
57 auto& [r1] = s;
58 assert(m1 == 99);
59 assert(&r1 == &std::get<0>(s));
60 }
61}
62
63
64void test_decomp_pair() {
65 typedef std::pair<int, double> T;
66 {
67 T s{99, 42.5};
68 auto [m1, m2] = s;
69 auto& [r1, r2] = s;
70 assert(m1 == 99);
71 assert(m2 == 42.5);
72 assert(&r1 == &std::get<0>(s));
73 assert(&r2 == &std::get<1>(s));
74 }
75 {
76 T const s{99, 42.5};
77 auto [m1, m2] = s;
78 auto& [r1, r2] = s;
79 assert(m1 == 99);
80 assert(m2 == 42.5);
81 assert(&r1 == &std::get<0>(s));
82 assert(&r2 == &std::get<1>(s));
83 }
84}
85
86void test_decomp_array() {
87 typedef std::array<int, 3> T;
88 {
89 T s{._M_elems: {99, 42, -1}};
90 auto [m1, m2, m3] = s;
91 auto& [r1, r2, r3] = s;
92 assert(m1 == 99);
93 assert(m2 == 42);
94 assert(m3 == -1);
95 assert(&r1 == &std::get<0>(s));
96 assert(&r2 == &std::get<1>(s));
97 assert(&r3 == &std::get<2>(s));
98 }
99 {
100 T const s{._M_elems: {99, 42, -1}};
101 auto [m1, m2, m3] = s;
102 auto& [r1, r2, r3] = s;
103 assert(m1 == 99);
104 assert(m2 == 42);
105 assert(m3 == -1);
106 assert(&r1 == &std::get<0>(s));
107 assert(&r2 == &std::get<1>(s));
108 assert(&r3 == &std::get<2>(s));
109 }
110}
111
112struct Test {
113 int x;
114};
115
116template <std::size_t N>
117int get(Test const&) { static_assert(N == 0, ""); return -1; }
118
119template <>
120struct std::tuple_element<0, Test> {
121 typedef int type;
122};
123
124void test_before_tuple_size_specialization() {
125 Test const t{.x: 99};
126 auto& [p] = t;
127 assert(p == 99);
128}
129
130template <>
131struct std::tuple_size<Test> {
132public:
133 static const std::size_t value = 1;
134};
135
136void test_after_tuple_size_specialization() {
137 Test const t{.x: 99};
138 auto& [p] = t;
139 assert(p == -1);
140}
141
142int main(int, char**) {
143 test_decomp_user_type();
144 test_decomp_tuple();
145 test_decomp_pair();
146 test_decomp_array();
147 test_before_tuple_size_specialization();
148 test_after_tuple_size_specialization();
149
150 return 0;
151}
152

source code of libcxx/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple_size_structured_bindings.pass.cpp