xref: /llvm-project/clang/test/AST/ByteCode/initializer_list.cpp (revision 35f7cfb22420a7c94b48e54fa28195ada9863d1a)
1d6d60707STimm Baeder // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -fms-extensions -std=c++20 -verify=expected,both %s
2d6d60707STimm Baeder // RUN: %clang_cc1 -std=c++20 -fms-extensions -verify=ref,both %s
3d6d60707STimm Baeder 
4d6d60707STimm Baeder namespace std {
5d6d60707STimm Baeder   typedef decltype(sizeof(int)) size_t;
6d6d60707STimm Baeder   template <class _E>
7d6d60707STimm Baeder   class initializer_list
8d6d60707STimm Baeder   {
9d6d60707STimm Baeder     const _E* __begin_;
10d6d60707STimm Baeder     size_t    __size_;
11d6d60707STimm Baeder 
12d6d60707STimm Baeder     initializer_list(const _E* __b, size_t __s)
13d6d60707STimm Baeder       : __begin_(__b),
14d6d60707STimm Baeder         __size_(__s)
15d6d60707STimm Baeder     {}
16d6d60707STimm Baeder 
17d6d60707STimm Baeder   public:
18d6d60707STimm Baeder     typedef _E        value_type;
19d6d60707STimm Baeder     typedef const _E& reference;
20d6d60707STimm Baeder     typedef const _E& const_reference;
21d6d60707STimm Baeder     typedef size_t    size_type;
22d6d60707STimm Baeder 
23d6d60707STimm Baeder     typedef const _E* iterator;
24d6d60707STimm Baeder     typedef const _E* const_iterator;
25d6d60707STimm Baeder 
26d6d60707STimm Baeder     constexpr initializer_list() : __begin_(nullptr), __size_(0) {}
27d6d60707STimm Baeder 
28d6d60707STimm Baeder     constexpr size_t    size()  const {return __size_;}
29d6d60707STimm Baeder     constexpr const _E* begin() const {return __begin_;}
30d6d60707STimm Baeder     constexpr const _E* end()   const {return __begin_ + __size_;}
31d6d60707STimm Baeder   };
32d6d60707STimm Baeder }
33d6d60707STimm Baeder 
34d6d60707STimm Baeder class Thing {
35d6d60707STimm Baeder public:
36d6d60707STimm Baeder   int m = 12;
37d6d60707STimm Baeder   constexpr Thing(int m) : m(m) {}
38d6d60707STimm Baeder   constexpr bool operator==(const Thing& that) const {
39d6d60707STimm Baeder     return this->m == that.m;
40d6d60707STimm Baeder   }
41d6d60707STimm Baeder };
42d6d60707STimm Baeder 
43d6d60707STimm Baeder constexpr bool is_contained(std::initializer_list<Thing> Set, const Thing &Element) {
44d6d60707STimm Baeder    return (*Set.begin() == Element);
45d6d60707STimm Baeder }
46d6d60707STimm Baeder 
47d6d60707STimm Baeder constexpr int foo() {
48d6d60707STimm Baeder   const Thing a{12};
49d6d60707STimm Baeder   const Thing b{14};
50d6d60707STimm Baeder   return is_contained({a}, b);
51d6d60707STimm Baeder }
52d6d60707STimm Baeder 
53d6d60707STimm Baeder static_assert(foo() == 0);
54*35f7cfb2STimm Baeder 
55*35f7cfb2STimm Baeder 
56*35f7cfb2STimm Baeder namespace rdar13395022 {
57*35f7cfb2STimm Baeder   struct MoveOnly { // both-note {{candidate}}
58*35f7cfb2STimm Baeder     MoveOnly(MoveOnly&&); // both-note 2{{copy constructor is implicitly deleted because}} both-note {{candidate}}
59*35f7cfb2STimm Baeder   };
60*35f7cfb2STimm Baeder 
61*35f7cfb2STimm Baeder   void test(MoveOnly mo) {
62*35f7cfb2STimm Baeder     auto &&list1 = {mo}; // both-error {{call to implicitly-deleted copy constructor}} both-note {{in initialization of temporary of type 'std::initializer_list}}
63*35f7cfb2STimm Baeder     MoveOnly (&&list2)[1] = {mo}; // both-error {{call to implicitly-deleted copy constructor}} both-note {{in initialization of temporary of type 'MoveOnly[1]'}}
64*35f7cfb2STimm Baeder     std::initializer_list<MoveOnly> &&list3 = {};
65*35f7cfb2STimm Baeder     MoveOnly (&&list4)[1] = {}; // both-error {{no matching constructor}}
66*35f7cfb2STimm Baeder     // both-note@-1 {{in implicit initialization of array element 0 with omitted initializer}}
67*35f7cfb2STimm Baeder     // both-note@-2 {{in initialization of temporary of type 'MoveOnly[1]' created to list-initialize this reference}}
68*35f7cfb2STimm Baeder   }
69*35f7cfb2STimm Baeder }
70*35f7cfb2STimm Baeder 
71*35f7cfb2STimm Baeder 
72