1 // RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify -Wunused-variable %s
3 template <typename
, typename
>
4 constexpr bool is_same
= false;
6 constexpr bool is_same
<T
, T
> = true;
13 void check_category() {
16 auto [v
, r
] = S
{1, a
};
18 static_assert(is_same
<decltype(v
), int>);
19 static_assert(is_same
<decltype(r
), int &>);
23 auto [v
, r
] = S
{1, a
};
25 static_assert(is_same
<decltype(v
), int>);
26 static_assert(is_same
<decltype(r
), int &>);
31 const auto &[v
, r
] = s
;
33 static_assert(is_same
<decltype(v
), const int>);
34 static_assert(is_same
<decltype(r
), int &>);
39 const auto &[v
, r
] = s
;
41 static_assert(is_same
<decltype(v
), const int>);
42 static_assert(is_same
<decltype(r
), int &>);
48 int arr
[2] = {42, 42};
51 static_assert(is_same
<decltype(a
), int>);
52 static_assert(is_same
<decltype(b
), int>);
57 template <unsigned long I
>
58 decltype(auto) get() {
59 if constexpr (I
== 0) {
66 template <unsigned long I
>
67 decltype(auto) get() const {
68 if constexpr (I
== 0) {
85 struct tuple_size
<T
&> : tuple_size
<T
>{};
88 requires requires
{ tuple_size
<T
>::value
; }
89 struct tuple_size
<const T
> : tuple_size
<T
>{};
92 struct tuple_size
<tuple
> {
93 static constexpr unsigned long value
= 2;
96 template <unsigned long, typename T
>
100 struct tuple_element
<0, tuple
> {
105 struct tuple_element
<1, tuple
> {
110 struct tuple_element
<0, const tuple
> {
115 struct tuple_element
<1, const tuple
> {
116 using type
= const int &;
120 void check_tuple_like() {
125 static_assert(is_same
<decltype(v
), int>);
126 static_assert(is_same
<decltype(r
), int &>);
132 static_assert(is_same
<decltype(v
), int>);
133 static_assert(is_same
<decltype(r
), int &>);
137 const auto &[v
, r
] = t
;
139 static_assert(is_same
<decltype(v
), int>);
140 static_assert(is_same
<decltype(r
), const int &>);
144 const auto &[v
, r
] = t
;
146 static_assert(is_same
<decltype(v
), int>);
147 static_assert(is_same
<decltype(r
), const int &>);
152 namespace ODRUseTests
{
153 struct P
{ int a
; int b
; };
155 const auto [a
, b
] = P
{1, 2}; //expected-note 2{{'b' declared here}} \
156 //expected-note 3{{'a' declared here}}
157 (void)[&](auto c
) { return b
+ [&a
] {
160 (void)[&](auto c
) { return b
+ [&a
](auto) {
163 (void)[=](auto c
) { return b
+ [&a
](auto) {
166 (void)[&a
,&b
](auto c
) { return b
+ [&a
](auto) {
169 (void)[&a
,&b
](auto c
) { return b
+ [a
](auto) {
172 (void)[&a
](auto c
) { return b
+ [&a
](auto) { // expected-error 2{{variable 'b' cannot be implicitly captured}} \
173 // expected-note 2{{lambda expression begins here}} \
174 // expected-note 4{{capture 'b'}}
176 }(0); }(0); // expected-note {{in instantiation}}
177 (void)[&b
](auto c
) { return b
+ [](auto) { // expected-note 3{{lambda expression begins here}} \
178 // expected-note 6{{capture 'a'}} \
179 // expected-note 6{{default capture}} \
180 // expected-note {{in instantiation}} \
181 // expected-note {{while substituting into a lambda}}
182 return a
; // expected-error 3{{variable 'a' cannot be implicitly captured}}
183 }(0); }(0); // expected-note 2{{in instantiation}}