Skip to content

Commit b88b154

Browse files
committed
Add tests for is() inspections
1 parent 30be721 commit b88b154

5 files changed

+951
-0
lines changed
Lines changed: 327 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,327 @@
1+
int* raw_null = nullptr;
2+
3+
auto expect_throws(auto l) -> bool {
4+
try {
5+
l();
6+
} catch (...) {
7+
return true;
8+
}
9+
return false;
10+
}
11+
12+
struct ThrowingConstruction {
13+
constexpr ThrowingConstruction() = default;
14+
ThrowingConstruction(int) { throw 1; }
15+
};
16+
17+
18+
main: () = {
19+
20+
print_header("type is type");
21+
{
22+
print("<A> is A", cpp2::is<A,A>(), true);
23+
print("<A> is B", cpp2::is<A,B>(), false);
24+
print("<A> is C", cpp2::is<A,C>(), false);
25+
print("<B> is A", cpp2::is<B,A>(), false);
26+
print("<B> is B", cpp2::is<B,B>(), true);
27+
print("<B> is C", cpp2::is<B,C>(), false);
28+
print("<C> is A", cpp2::is<C,A>(), true);
29+
print("<C> is B", cpp2::is<C,B>(), false);
30+
print("<C> is C", cpp2::is<C,C>(), true);
31+
}
32+
33+
print_header("type is template");
34+
{
35+
print("<std::vector<int>> is std::vector", cpp2::is<std::vector<int>,std::vector>(), true);
36+
print("<std::vector<int>> is std::array", cpp2::is<std::vector<int>,std::array>(), false);
37+
print("<std::vector<int>> is std::optional", cpp2::is<std::vector<int>,std::optional>(), false);
38+
print("<std::array<int, 3>> is ", cpp2::is<std::array<int, 3>,std::vector>(), false);
39+
print("<std::array<int, 3>> is ", cpp2::is<std::array<int, 3>,std::array>(), true);
40+
print("<std::array<int, 3>> is ", cpp2::is<std::array<int, 3>,std::optional>(), false);
41+
print("<std::optional<int>> is ", cpp2::is<std::optional<int>,std::vector>(), false);
42+
print("<std::optional<int>> is ", cpp2::is<std::optional<int>,std::array>(), false);
43+
print("<std::optional<int>> is ", cpp2::is<std::optional<int>,std::optional>(), true);
44+
}
45+
46+
print_header("type is type_trait");
47+
{
48+
v : std::vector<int> = ();
49+
print("<const std::vector<int>> is std::is_const", cpp2::is<const std::vector<int>,std::is_const>(), true);
50+
print("<std::vector<int>> is std::is_const", cpp2::is<std::vector<int>,std::is_const>(), false);
51+
print("<std::vector<int>&> is std::is_reference", cpp2::is<decltype(v),std::is_reference>(), true);
52+
}
53+
54+
print_header("type is concept");
55+
{
56+
// requires: clang-13+, gcc-12.1+, msvc-v19.34+
57+
print("<int> is std::integral", cpp2::is<int,:<T:std::integral>()={}>(), true);
58+
print("<double> is std::integral", cpp2::is<double,:<T:std::integral>()={}>(), false);
59+
}
60+
61+
print_header("variable is template");
62+
{
63+
v : std::vector = (1, 2, 3);
64+
print("v is vector", v is std::vector, true);
65+
print("v is array", v is std::array, false);
66+
print("v is optional", v is std::optional, false);
67+
a : std::array<int,4> = (4,3,2,1);
68+
print("a is array", a is std::array, true);
69+
print("a is vector", a is std::vector, false);
70+
print("a is optional", a is std::optional, false);
71+
o : std::optional = 42;
72+
print("o is array", o is std::array, false);
73+
print("o is vector", o is std::vector, false);
74+
print("o is optional", o is std::optional, true);
75+
76+
}
77+
78+
print_header("variable is type");
79+
{
80+
a: A = ();
81+
b: B = ();
82+
c: C = ();
83+
print("a is A", a is A, true);
84+
print("b is A", b is A, false);
85+
print("c is A", c is A, true);
86+
}
87+
{
88+
vc: VC = ();
89+
ptr_va0: *VA<0> = vc&;
90+
ptr_va1: *VA<1> = vc&;
91+
cptr_va0: * const VA<0> = vc&;
92+
93+
print("vc is VA<0>", vc is VA<0>, true);
94+
print("vc is VA<1>", vc is VA<1>, true);
95+
print("vc& is *VA<0>", vc& is *VA<0>, true);
96+
print("vc& is *VA<1>", vc& is *VA<1>, true);
97+
98+
print("ptr_va0 is *VC", ptr_va0 is *VC, true);
99+
print("ptr_va1 is *VC", ptr_va1 is *VC, true);
100+
print("ptr_va0 is *VA<1>", ptr_va0 is *VA<1>, true);
101+
print("ptr_va1 is *VA<0>", ptr_va1 is *VA<0>, true);
102+
print("cptr_va0 is *VC", cptr_va0 is *VC, false);
103+
print("cptr_va0 is * const VC", cptr_va0 is * const VC, true);
104+
105+
print("ptr_va0* is VC", ptr_va0* is VC, true);
106+
print("ptr_va1* is VC", ptr_va1* is VC, true);
107+
print("ptr_va0* is VA<1>", ptr_va0* is VA<1>, true);
108+
print("ptr_va1* is VA<0>", ptr_va1* is VA<0>, true);
109+
print("cptr_va0* is VC", cptr_va0* is VC, false);
110+
print("cptr_va0* is const VC", cptr_va0* is const VC, true);
111+
}
112+
113+
print_header("pointer-like variable is empty");
114+
{
115+
print("raw_null is empty", raw_null is cpp2::empty, true);
116+
print("nullptr is empty", nullptr is cpp2::empty, true);
117+
print("shared_ptr() is empty", std::shared_ptr<int>() is cpp2::empty, true);
118+
print("unique_ptr() is empty", std::unique_ptr<int>() is cpp2::empty, true);
119+
120+
i := 42;
121+
print("i& is empty", i& is cpp2::empty, false);
122+
print("std::make_shared<int>(42) is empty", std::make_shared<int>(42) is cpp2::empty, false);
123+
print("std::make_unique<int>(44) is empty", std::make_unique<int>(44) is cpp2::empty, false);
124+
}
125+
126+
print_header("variable is value");
127+
{
128+
i := 42;
129+
print("i{42} is empty", i is cpp2::empty, false);
130+
print("i{42} is 24", i is 24, false);
131+
print("i{42} is 42", i is 42, true);
132+
print("i{42} is 42u", i is 42u, true);
133+
print("i{42} is 42L", i is 42L, true);
134+
print("i{42} is 42.0", i is 42.0, true);
135+
print("i{42} is 42.0f", i is 42.0f, true);
136+
print("3.14f is 3.14", 3.14f is 3.14, false);
137+
close_to := :(v) -> _ = :(x) -> bool = {
138+
return std::abs(v$ - x) < std::max<std::common_type_t<std::decay_t<decltype(x)>,std::decay_t<decltype(v$)>>>(std::numeric_limits<std::decay_t<decltype(x)>>::epsilon(), std::numeric_limits<std::decay_t<decltype(v$)>>::epsilon());
139+
};
140+
print("3.14f is (close_to(3.14 ))", 3.14f is (close_to(3.14 )), true);
141+
print("3.14 is (close_to(3.14f))", 3.14 is (close_to(3.14f)), true);
142+
}
143+
144+
print_header("variable is type_trait");
145+
{
146+
i : int = 42;
147+
ci : const int = 24;
148+
149+
print("i{int} is std::is_const", i is std::is_const, false);
150+
print("ci{const int} is std::is_const", ci is std::is_const, true);
151+
print("ci{const int} is std::is_integral", ci is std::is_integral, true);
152+
print("ci{const int} is std::is_floating_point", ci is std::is_floating_point, false);
153+
}
154+
155+
print_header("variable is predicate");
156+
{
157+
d := 3.14;
158+
159+
print("d{3.14} is (:(x) -> bool = x>0;)", d is (:(x) -> bool = x>0;), true);
160+
print("d{3.14} is (:(x:int) -> bool = x>0;)", d is (:(x:int) -> bool = x>0;), false);
161+
print("d{3.14} is (:(x:std::string) -> bool = x.ssize()>5;)", d is (:(x:std::string) -> bool = x.ssize()>5;), false);
162+
print("std::string(\"abcdefg\") is (:(x:std::string) -> bool = x.ssize()>5;)", std::string("abcdefg") is (:(x:std::string) -> bool = x.ssize()>5;), true);
163+
164+
print("d{3.14} is (pred_i)", d is (pred_i), false);
165+
print("d{3.14} is (pred_d)", d is (pred_d), true);
166+
print("d{3.14} is (pred_)", true, true);
167+
168+
print("d{3.14} is (:<T:std::floating_point> () -> _ = true;)", d is (:<T:std::floating_point> () -> _ = true;), true);
169+
print("d{3.14} is (:<T:std::floating_point> () = {})", d is (:<T:std::floating_point> () = {}), true);
170+
print("d{3.14} is (:<T:std::integral> () = {})", d is (:<T:std::integral> () = {}), false);
171+
}
172+
173+
print_header("variant variable is value");
174+
{
175+
v : std::variant<int, long, float, double, std::string, std::vector<int>> = (42);
176+
177+
print("v{42} is 42", v is 42, true);
178+
print("v{42} is int", v is int, true);
179+
print("v{42} is int", v is double, false);
180+
print("v{42} is 42.0", v is 42.0, true);
181+
print("v{42} is 24", v is 24, false);
182+
print("v{42} is (std::string(\"hello\"))", v is (std::string("hello")), false);
183+
print("v{42} is std::integral", v is (:<T:std::integral> () = {}), true);
184+
print("v{42} is std::floating_point", v is (:<T:std::floating_point> () = {}), false);
185+
186+
v = std::string("hello");
187+
print("v{hello} is (std::string(\"hello\"))", v is (std::string("hello")), true);
188+
print("v{hello} is 42", v is 42, false);
189+
print("v{hello} is empty", v is cpp2::empty, false);
190+
print("v{hello} is int", v is int, false);
191+
print("v{hello} is std::string", v is std::string, true);
192+
193+
v = :std::vector = (1,2,3,4);
194+
print("v{std::vector{1,2,3,4}} is std::vector<int>", v is std::vector<int>, true );
195+
print("v{std::vector{1,2,3,4}} is std::vector", v is std::vector, true );
196+
print("v{std::vector{1,2,3,4}} is std::map", v is std::map, false);
197+
print("v{std::vector{1,2,3,4}} is std::variant", v is std::variant, true );
198+
}
199+
200+
print_header("variant variable is empty");
201+
{
202+
v : std::variant<int, ThrowingConstruction, std::monostate> = ();
203+
print("v{int} is empty", v is cpp2::empty, false, "v contains default value of first type");
204+
205+
v = std::monostate();
206+
print("v{monostate} is empty", v is cpp2::empty, true);
207+
208+
expect_throws(:() = v&$*.emplace<1>(42););
209+
print("v{valueless_by_exception} is empty", v is cpp2::empty, true, "is valueless: " + cpp2::to_string(v.valueless_by_exception()));
210+
211+
}
212+
213+
print_header("any variable is type");
214+
{
215+
a : std::any = 42;
216+
217+
print("a{42} is int", a is int, true);
218+
print("a{42} is double", a is double, false);
219+
print("a{42} is empty", a is cpp2::empty, false);
220+
221+
print("std::any() is empty", std::any() is cpp2::empty, true);
222+
}
223+
224+
print_header("any variable is value");
225+
{
226+
a : std::any = 42;
227+
228+
print("a{42} is 42", a is 42, true);
229+
print("a{42} is 24", a is 24, false);
230+
print("a{42} is 42L", a is 42L, false);
231+
print("std::any(3.14) is 3", std::any(3.14) is 3, false);
232+
233+
print("a{42} is :(v)->bool = v.has_value();", a is :(v)->bool = v.has_value();, true);
234+
print("a{42} is :(v:std::any)->bool = v.has_value();", a is :(v:std::any)->bool = v.has_value();, true);
235+
print("a{42} is :(v:int)->bool = v>0;", a is :(v:int)->bool = v>0;, true);
236+
}
237+
238+
print_header("optional variable is type");
239+
{
240+
o : std::optional = 42;
241+
242+
print("o{42} is int", o is int, true);
243+
print("o{42} is empty", o is cpp2::empty, false);
244+
print("std::optional<int>() is empty", std::optional<int>() is cpp2::empty, true);
245+
}
246+
247+
print_header("optional variable is value");
248+
{
249+
o : std::optional = 42;
250+
251+
print("o{42} is 42", o is 42, true);
252+
print("o{42} is 24", o is 24, false);
253+
print("o{42} is 42.0", o is 42.0, true);
254+
255+
print("o{42} is :(v) -> bool = v > 0;", o is :(v) -> bool = v > 0;, true);
256+
print("o{42} is :(v:std::optional<int>) -> bool = v > 0;", o is :(v:std::optional<int>) -> bool = v > 0;, true);
257+
print("o{42} is :(v:std::optional<long>) -> bool = v > 0;", o is :(v:std::optional<long>) -> bool = v > 0;, true);
258+
print("std::optional(3.14) is :(v:std::optional<int>) -> bool = v == 3;", std::optional(3.14) is :(v:std::optional<int>) -> bool = v* == 3;, false);
259+
}
260+
261+
}
262+
263+
A: type = {}
264+
B: type = {}
265+
C: type = {
266+
this: A = ();
267+
}
268+
269+
VA: @polymorphic_base <I:int> type = {}
270+
271+
VC: type = {
272+
this: VA<0>;
273+
this: VA<1>;
274+
}
275+
276+
277+
pred_i: (x : int ) -> bool = {
278+
return x > 0;
279+
}
280+
281+
pred_d: (x : double ) -> bool = {
282+
return x > 0;
283+
}
284+
285+
pred_: (x) -> bool = {
286+
return x > 0;
287+
}
288+
289+
col : std::array<int, 5> = (70, 8, 8, 8, 40);
290+
291+
print: (what, value, expected, comment) = {
292+
l := :(value) -> std::string = {
293+
if value {
294+
return "true";
295+
} else {
296+
return "false";
297+
}
298+
};
299+
print(what, l(value), l(expected), inspect (value == expected) -> std::string { is (true) = "OK"; is _ = "FAILED!";}, comment );
300+
}
301+
302+
print: (what, value, expected) = {
303+
print(what, value, expected, std::string());
304+
}
305+
306+
print: (what, value, expected, result, comment) = {
307+
std::cout << "|" << std::setw(col[0]) << std::right << what;
308+
std::cout << "|" << std::setw(col[1]) << std::internal << value;
309+
std::cout << "|" << std::setw(col[2]) << std::internal << expected;
310+
std::cout << "|" << std::setw(col[3]) << std::internal << result;
311+
std::cout << "|" << std::setw(col[4]) << std::left << std::setprecision(20) << comment;
312+
std::cout << "|" << std::endl;
313+
}
314+
315+
print_header: (title) = {
316+
std::cout << "\n# (title)$\n\n";
317+
print("Test", "Actual", "Expected", "Result", "Comment");
318+
print( std::string(col[0]-1,'-')+":"
319+
, ":"+std::string(col[1]-2,'-')+":"
320+
, ":"+std::string(col[2]-2,'-')+":"
321+
, ":"+std::string(col[3]-2,'-')+":"
322+
, ":"+std::string(col[4]-1,'-')
323+
);
324+
}
325+
326+
#include <iomanip>
327+
#include <map>

0 commit comments

Comments
 (0)