1 /**
2    Tests "inspired" by the ones in dstep's functional directory
3  */
4 module it.c.dstep.functional;
5 
6 import it;
7 
8 @("const int")
9 @safe unittest {
10     shouldCompile(
11         C(
12             q{
13                 const int a; // const int
14                 const int* b; // mutable pointer to const int
15                 int* const c; // const pointer to mutable int
16                 const int* const d; // const pointer to const int
17                 const int* const * e; // mutable pointer to const pointer to const int
18                 const int* const * const f; // const pointer to const pointer to const int
19                 int* const * const g; // const pointer to const pointer to mutable int
20             }
21         ),
22         D(
23             q{
24                 void assertType(E, A, string file = __FILE__, size_t line = __LINE__)
25                     (auto ref A t)
26                 {
27                     import std.conv: text;
28                     static assert(is(A == E),
29                                   text(file, ":", line, " Expected: ", E.stringof,
30                                        "  Got: ", A.stringof));
31                 }
32 
33                 assertType!(const int)(a);
34                 assertType!(const(int)*)(b);
35                 assertType!(int*)(c);
36                 assertType!(const int*)(d);
37                 assertType!(const(int*)*)(e);
38                 assertType!(const int**)(f);
39                 assertType!(int**)(g);
40             }
41         ),
42     );
43 }
44 
45 @("const struct")
46 @safe unittest {
47 
48     shouldCompile(
49         C(
50             q{
51                 typedef struct { int i; } Struct;
52                 const Struct a; // const Struct
53                 const Struct* b; // mutable pointer to const Struct
54                 Struct* const c; // const pointer to mutable Struct
55                 const Struct* const d; // const pointer to const Struct
56                 const Struct* const * e; // mutable pointer to const pointer to const Struct
57                 const Struct* const * const f; // const pointer to const pointer to const Struct
58                 Struct* const * const g; // const pointer to const pointer to mutable Struct
59             }
60         ),
61         D(
62             q{
63                 void assertType(E, A, string file = __FILE__, size_t line = __LINE__)
64                     (auto ref A t)
65                 {
66                     import std.conv: text;
67                     static assert(is(A == E),
68                                   text(file, ":", line, " Expected: ", E.stringof,
69                                        "  Got: ", A.stringof));
70                 }
71 
72                 assertType!(const Struct)(a);
73                 assertType!(const(Struct)*)(b);
74                 assertType!(Struct*)(c);
75                 assertType!(const Struct*)(d);
76                 assertType!(const(Struct*)*)(e);
77                 assertType!(const Struct**)(f);
78                 assertType!(Struct**)(g);
79             }
80         ),
81     );
82 }
83 
84 @("dynamic")
85 @safe unittest {
86     shouldCompile(
87         C(
88             q{
89                 typedef struct
90                 {
91                     int x;
92                     int data[0];
93                 } Dynamic;
94             }
95         ),
96         D(
97             q{
98                 import core.stdc.stdlib: malloc;
99                 auto d = cast(Dynamic*)malloc(Dynamic.sizeof + 5 * int.sizeof);
100                 d.x = 42;
101                 // out of bounds
102                 static assert(!__traits(compiles, d.data[3]));
103                 auto ptr = d.data.ptr;
104                 ptr[3] = 77;
105             }
106         ),
107     );
108 }
109 
110 @("function_pointers")
111 @safe unittest {
112     shouldCompile(
113         C(
114             q{
115                 void (*a) (void);
116                 int (*b) (void);
117                 void (*c) (int);
118                 int (*d) (int, int);
119                 int (*e) (int a, int b);
120                 int (*f) (int a, int b, ...);
121             }
122         ),
123         D(
124             q{
125                 static assert(is(typeof(a()) == void));
126                 static assert(is(typeof(b()) == int));
127                 c(42);
128                 int dres = d(2, 3);
129                 int eres = e(4, 5);
130                 int fres = f(6, 7, 9.0, null);
131                 static assert(!__traits(compiles, f.init(6)));
132                 static assert(!__traits(compiles, f.init(6, 9.0)));
133             }
134         ),
135     );
136 }