xref: /llvm-project/clang/test/SemaCXX/overload-ary-bind.cpp (revision bb3f5f5d788dd9375ab260f77612fab4a707a1ac)
1 // RUN: %clang_cc1 -std=c++20 -verify %s
2 // RUN: %clang_cc1 -std=c++17 -verify %s
3 
4 namespace One {
5 char (&b(int(&&)[1]))[1]; // #1 expected-note{{too many initializers}}
6 char (&b(int(&&)[2]))[2]; // #2 expected-note{{too many initializers}}
7 
f()8 void f() {
9   static_assert(sizeof(b({1})) == 1);    // #1
10   static_assert(sizeof(b({1, 2})) == 2); // #2
11 
12   b({1, 2, 3}); // expected-error{{no matching function}}
13 }
14 } // namespace One
15 
16 namespace Two {
17 struct Bob {
18   Bob(int = 1);
19 };
20 
21 char (&b(Bob(&&)[1]))[1]; // #1
22 char (&b(Bob(&&)[2]))[2]; // #2
23 
f()24 void f() {
25   static_assert(sizeof(b({})) == 1);         // #1
26   static_assert(sizeof(b({Bob()})) == 1);    // #1
27   static_assert(sizeof(b({2, Bob()})) == 2); // #2
28 }
29 } // namespace Two
30 
31 namespace Three {
32 struct Kevin {
33   Kevin(int);
34 };
35 
36 char (&b(Kevin(&&)[2]))[2]; // #2 expected-note{{too few initializers}}
37 
f()38 void f() {
39   b({2}); // #1 expected-error{{no matching function}}
40 }
41 } // namespace Three
42 
43 namespace Four {
44 char (&b(int(&&)[1], float))[1];  // #1 expected-note{{candidate}}
45 char (&b(int(&&)[1], double))[2]; // #2 expected-note{{candidate}}
46 
47 char (&c(float, int(&&)[1]))[1];  // #1 expected-note{{candidate}}
48 char (&c(double, int(&&)[1]))[2]; // #2 expected-note{{candidate}}
49 
f()50 void f() {
51   b({1}, 0); // expected-error{{is ambiguous}}
52   c(0, {1}); // expected-error{{is ambiguous}}
53 }
54 } // namespace Four
55 
56 typedef decltype(sizeof(char)) size_t;
57 namespace std {
58 // sufficient initializer list
59 template <class _E>
60 class initializer_list {
61   const _E *__begin_;
62   size_t __size_;
63 
initializer_list(const _E * __b,size_t __s)64   constexpr initializer_list(const _E *__b, size_t __s)
65       : __begin_(__b),
66         __size_(__s) {}
67 
68 public:
69   typedef _E value_type;
70   typedef const _E &reference;
71   typedef const _E &const_reference;
72   typedef size_t size_type;
73 
74   typedef const _E *iterator;
75   typedef const _E *const_iterator;
76 
initializer_list()77   constexpr initializer_list() : __begin_(nullptr), __size_(0) {}
78 
size() const79   constexpr size_t size() const { return __size_; }
begin() const80   constexpr const _E *begin() const { return __begin_; }
end() const81   constexpr const _E *end() const { return __begin_ + __size_; }
82 };
83 } // namespace std
84 
85 namespace Five {
86 struct ugly {
87   ugly(char *);
88   ugly(int);
89 };
90 char (&f(std::initializer_list<char *>))[1]; // #1
91 char (&f(std::initializer_list<ugly>))[2];   // #2
g()92 void g() {
93   // Pick #2 as #1 not viable (3->char * fails).
94   static_assert(sizeof(f({"hello", 3})) == 2); // expected-warning{{not allow}}
95 }
96 
97 } // namespace Five
98