1 module it.c.compile.enum_;
2 
3 import it;
4 
5 @("Named enum with non-assigned members foo and bar")
6 @safe unittest {
7     shouldCompile(
8         C(
9             q{
10                 enum Foo {
11                     foo,
12                     bar
13                 };
14             }
15         ),
16 
17         D(
18             q{
19                 static assert(is(typeof(foo) == Foo));
20                 static assert(is(typeof(bar) == Foo));
21                 static assert(foo == 0);
22                 static assert(bar == 1);
23                 static assert(Foo.foo == 0);
24                 static assert(Foo.bar == 1);
25             }
26         ),
27 
28     );}
29 
30 @("Named enum with non-assigned members quux and toto")
31 @safe unittest {
32     shouldCompile(
33         C(
34             q{
35                 enum Enum {
36                     quux,
37                     toto
38                 };
39             }
40         ),
41 
42         D(
43             q{
44                 static assert(is(typeof(quux) == Enum));
45                 static assert(is(typeof(toto) == Enum));
46                 static assert(quux == 0);
47                 static assert(toto == 1);
48                 static assert(Enum.quux == 0);
49                 static assert(Enum.toto == 1);
50             }
51         ),
52 
53     );}
54 
55 @("Named enum with assigned members foo, bar, baz")
56 @safe unittest {
57     shouldCompile(
58         C(
59             q{
60                 enum FooBarBaz {
61                     foo = 2,
62                     bar = 5,
63                     baz = 7
64                 };
65             }
66         ),
67 
68         D(
69             q{
70                 static assert(is(typeof(foo) == FooBarBaz));
71                 static assert(is(typeof(bar) == FooBarBaz));
72                 static assert(is(typeof(baz) == FooBarBaz));
73                 static assert(foo == 2);
74                 static assert(bar == 5);
75                 static assert(baz == 7);
76                 static assert(FooBarBaz.foo == 2);
77                 static assert(FooBarBaz.bar == 5);
78                 static assert(FooBarBaz.baz == 7);
79             }
80         ),
81 
82     );
83 }
84 
85 // TODO: convert to unit test
86 @("typedef nameless enum")
87 @safe unittest {
88     shouldCompile(
89         C(
90             q{
91                 typedef enum {
92                     foo = 2,
93                     bar = 5,
94                     baz = 7
95                 } FooBarBaz;
96             }
97         ),
98 
99         D(
100             q{
101                 static assert(is(typeof(bar) == FooBarBaz));
102                 static assert(bar == 5);
103                 static assert(FooBarBaz.baz == 7);
104             }
105         ),
106 
107     );}
108 
109 // TODO: convert to unit test
110 @("typedef named enum")
111 @safe unittest {
112     shouldCompile(
113         C(
114             q{
115                 typedef enum FooBarBaz_ {
116                     foo = 2,
117                     bar = 5,
118                     baz = 7
119                 } FooBarBaz;
120             }
121         ),
122 
123         D(
124             q{
125 
126                 static assert(is(typeof(bar) == FooBarBaz_));
127                 static assert(FooBarBaz_.foo == 2);
128                 static assert(bar == 5);
129                 static assert(FooBarBaz.baz == 7);
130             }
131        ),
132 
133     );
134 }
135 
136 @("named enum with immediate variable declaration")
137 @safe unittest {
138     shouldCompile(
139         C(
140             q{
141                 enum Numbers {
142                     one = 1,
143                     two = 2,
144                 } numbers;
145             }
146         ),
147 
148         D(
149             q{
150 
151                 static assert(is(typeof(one) == Numbers));
152                 static assert(is(typeof(two) == Numbers));
153                 numbers = one;
154                 numbers = two;
155                 numbers = Numbers.one;
156             }
157         ),
158 
159     );
160 }
161 
162 @("nameless enum with immediate variable declaration")
163 @safe unittest {
164     shouldCompile(
165         C(
166             q{
167                 enum {
168                     one = 1,
169                     two = 2,
170                 } numbers;
171             }
172         ),
173 
174         D(
175             q{
176                 static assert(is(typeof(one) == typeof(numbers)));
177                 static assert(is(typeof(two) == typeof(numbers)));
178                 numbers = one;
179                 numbers = two;
180             }
181         ),
182 
183     );
184 }
185 
186 // TODO: convert to unit test
187 @("nameless enum inside a struct")
188 @safe unittest {
189     shouldCompile(
190         C(
191             q{
192                 struct Struct {
193                     enum {
194                         one = 1,
195                         two = 2,
196                     };
197                 };
198             }
199         ),
200 
201         D(
202             q{
203 
204                 static assert(is(typeof(Struct.one) == enum));
205                 static assert(Struct.two == 2);
206             }
207         ),
208 
209     );
210 }
211 
212 @("nameless enum with variable inside a struct")
213 @safe unittest {
214     shouldCompile(
215         C(
216             q{
217                 struct Struct {
218                     enum {
219                         one = 1,
220                         two = 2,
221                     } numbers;
222                 };
223             }
224         ),
225 
226         D(
227             q{
228                 auto s = Struct();
229                 static assert(is(typeof(s.one) == typeof(s.numbers)));
230                 s.numbers = Struct.one;
231             }
232         ),
233 
234     );
235 }
236 
237 
238 // TODO: convert to unit test
239 @("named enum inside a struct")
240 @safe unittest {
241     shouldCompile(
242         C(
243             q{
244                 struct Struct {
245                     enum Numbers {
246                         one = 1,
247                         two = 2,
248                     };
249                 };
250             }
251         ),
252 
253         D(
254             q{
255                 static assert(is(typeof(Struct.one) == Struct.Numbers));
256                 static assert(Struct.Numbers.two == 2);
257             }
258         ),
259 
260     );
261 }
262 
263 // TODO: convert to unit test
264 @("named enum with variable inside a struct")
265 @safe unittest {
266     shouldCompile(
267         C(
268             q{
269                 struct Struct {
270                     enum Numbers {
271                         one = 1,
272                         two = 2,
273                     } numbers;
274                 };
275             }
276         ),
277 
278         D(
279             q{
280                 static assert(is(typeof(Struct.one) == Struct.Numbers));
281                 static assert(is(typeof(Struct.numbers) == Struct.Numbers));
282                 auto s = Struct();
283                 s.numbers = Struct.Numbers.one;
284             }
285         ),
286     );
287 }
288 
289 @("call and return enums")
290 @safe unittest {
291     shouldCompile(
292         C(
293             q{
294                 enum Enum { one, two, three };
295                 enum Enum fun(int, int);
296                 void gun(enum Enum);
297             }
298          ),
299 
300         D(
301             q{
302                 Enum e = fun(42, 33);
303                 gun(two);
304             }
305          ),
306     );
307 }
308 
309 
310 @("rename")
311 @safe unittest {
312     shouldCompile(
313         C(
314             q{
315                 enum FancyWidget { Widget_foo,  Widget_bar };
316             }
317          ),
318 
319         D(
320             q{
321                 mixin dpp.EnumD!("Widget", FancyWidget, "Widget_");
322                 static assert(cast(FancyWidget) Widget.foo == Widget_foo);
323                 static assert(cast(FancyWidget) Widget.foo == FancyWidget.Widget_foo);
324                 static assert(cast(FancyWidget) Widget.bar == Widget_bar);
325                 static assert(cast(FancyWidget) Widget.bar == FancyWidget.Widget_bar);
326             }
327          ),
328     );
329 }
330 
331 
332 @("keyword")
333 @safe unittest {
334     shouldCompile(
335         C(
336             q{
337                 enum Enum { debug, other };
338             }
339          ),
340 
341         D(
342             q{
343                 auto d = Enum.debug_;
344                 auto o = Enum.other;
345             }
346          ),
347     );
348 }
349 
350 @("enumBaseType changed to long")
351 @safe unittest {
352     shouldCompile(
353         C(
354             `
355                 #include <limits.h>
356                 enum Promoted { A = 1, B = LONG_MAX };
357                 enum NotPromoted { C = 1, D = 3 };
358             `
359          ),
360 
361         D(
362             q{
363                 import core.stdc.config : c_long;
364                 auto a = Promoted.A;
365                 auto b = Promoted.B;
366                 static assert(c_long.max == Promoted.B);
367                 static assert(Promoted.sizeof == c_long.sizeof);
368                 static assert(NotPromoted.sizeof == int.sizeof);
369             }
370          ),
371     );
372 }