Skip to content

Commit e16bb2e

Browse files
committed
is(): Add tests for variant
1 parent 53b158d commit e16bb2e

File tree

5 files changed

+363
-0
lines changed

5 files changed

+363
-0
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
test: (forward v) = {
2+
std::cout << "v is empty = (v is void)$" << std::endl;
3+
std::cout << "v is std::monostate = (v is std::monostate)$" << std::endl;
4+
std::cout << "v is X< 0> = (v is X< 0>)$,\t(v as X< 1>) = " << expect_no_throw(forward v, :(forward v) v as X<0>) << std::endl;
5+
std::cout << "v is X< 1> = (v is X< 1>)$,\t(v as X< 1>).to_string() = (expect_no_throw(forward v, :(forward v) -> std::string = { return (v as X< 1>).to_string();}))$" << std::endl;
6+
std::cout << "v is X<19> = (v is X<19>)$,\t(v as X<19>).to_string() = (expect_no_throw(forward v, :(forward v) -> std::string = { return (v as X<19>).to_string();}))$" << std::endl;
7+
std::cout << "v is X<20> = (v is X<20>)$,\t(v as X<20>) = " << expect_no_throw(forward v, :(forward v) v as X<20>) << std::endl;
8+
std::cout << std::endl;
9+
}
10+
11+
main: () -> int = {
12+
13+
v: std::variant<std::monostate,
14+
X< 1>, X< 2>, X< 3>, X< 4>, X< 5>, X< 6>, X< 7>, X< 8>, X< 9>, X<10>,
15+
X<11>, X<12>, X<13>, X<14>, X<15>, X<16>, X<17>, X<18>, X<19>, X<20> > = ();
16+
17+
header(1, "std::monostate");
18+
v..emplace<0>();
19+
run_tests(v);
20+
21+
header(1, "X<1>");
22+
v..emplace<1>();
23+
run_tests(v);
24+
25+
header(1, "X<19>");
26+
v..emplace<19>();
27+
run_tests(v);
28+
29+
header(1, "X<20>");
30+
v..emplace<20>();
31+
run_tests(v);
32+
33+
header(1, "X<10>(std::exception)");
34+
set_to_valueless_by_exception<10>(v);
35+
run_tests(v);
36+
37+
}
38+
39+
run_tests: (forward v) = {
40+
header(2, "v as lvalue reference");
41+
test(v);
42+
43+
header(2, "v as const lvalue reference");
44+
test(std::as_const(v));
45+
46+
header(2, "v as rvalue reference");
47+
test(move v);
48+
}
49+
50+
header: (lvl : int, msg: std::string) = {
51+
std::cout << std::string(lvl, '#') << " " << msg << "\n" << std::endl;
52+
}
53+
54+
template<int I>
55+
struct X {
56+
operator int() const { return I; }
57+
X() = default;
58+
X(std::exception const& e) { throw e; }
59+
auto to_string() const { return "X<" + std::to_string(I) + ">"; }
60+
};
61+
62+
template <std::size_t I>
63+
void set_to_valueless_by_exception(auto& v) try {
64+
v.template emplace<I>(std::runtime_error("make valueless"));
65+
} catch (...) {}
66+
67+
auto expect_no_throw(auto&& l) -> std::string try {
68+
if constexpr ( requires { { l() } -> std::convertible_to<std::string>; }) {
69+
return l();
70+
} else {
71+
l();
72+
return "works!";
73+
}
74+
} catch (std::exception const& e) {
75+
return e.what();
76+
} catch (...) {
77+
return "unknow exception!";
78+
}
79+
80+
auto expect_no_throw(auto&& v, auto&& l) -> std::string try {
81+
if constexpr ( requires { { l(v) } -> std::convertible_to<std::string>; }) {
82+
return l(v);
83+
} else {
84+
l(v);
85+
return "works!";
86+
}
87+
} catch (std::exception const& e) {
88+
return e.what();
89+
} catch (...) {
90+
return "unknow exception!";
91+
}
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
# std::monostate
2+
3+
## v as lvalue reference
4+
5+
v is empty = true
6+
v is std::monostate = true
7+
v is X< 0> = false, (v as X< 1>) = bad_variant_access
8+
v is X< 1> = false, (v as X< 1>).to_string() = bad_variant_access
9+
v is X<19> = false, (v as X<19>).to_string() = bad_variant_access
10+
v is X<20> = false, (v as X<20>) = bad_variant_access
11+
12+
## v as const lvalue reference
13+
14+
v is empty = true
15+
v is std::monostate = true
16+
v is X< 0> = false, (v as X< 1>) = bad_variant_access
17+
v is X< 1> = false, (v as X< 1>).to_string() = bad_variant_access
18+
v is X<19> = false, (v as X<19>).to_string() = bad_variant_access
19+
v is X<20> = false, (v as X<20>) = bad_variant_access
20+
21+
## v as rvalue reference
22+
23+
v is empty = true
24+
v is std::monostate = true
25+
v is X< 0> = false, (v as X< 1>) = bad_variant_access
26+
v is X< 1> = false, (v as X< 1>).to_string() = bad_variant_access
27+
v is X<19> = false, (v as X<19>).to_string() = bad_variant_access
28+
v is X<20> = false, (v as X<20>) = bad_variant_access
29+
30+
# X<1>
31+
32+
## v as lvalue reference
33+
34+
v is empty = false
35+
v is std::monostate = false
36+
v is X< 0> = false, (v as X< 1>) = bad_variant_access
37+
v is X< 1> = true, (v as X< 1>).to_string() = X<1>
38+
v is X<19> = false, (v as X<19>).to_string() = bad_variant_access
39+
v is X<20> = false, (v as X<20>) = bad_variant_access
40+
41+
## v as const lvalue reference
42+
43+
v is empty = false
44+
v is std::monostate = false
45+
v is X< 0> = false, (v as X< 1>) = bad_variant_access
46+
v is X< 1> = true, (v as X< 1>).to_string() = X<1>
47+
v is X<19> = false, (v as X<19>).to_string() = bad_variant_access
48+
v is X<20> = false, (v as X<20>) = bad_variant_access
49+
50+
## v as rvalue reference
51+
52+
v is empty = false
53+
v is std::monostate = false
54+
v is X< 0> = false, (v as X< 1>) = bad_variant_access
55+
v is X< 1> = true, (v as X< 1>).to_string() = X<1>
56+
v is X<19> = false, (v as X<19>).to_string() = bad_variant_access
57+
v is X<20> = false, (v as X<20>) = bad_variant_access
58+
59+
# X<19>
60+
61+
## v as lvalue reference
62+
63+
v is empty = false
64+
v is std::monostate = false
65+
v is X< 0> = false, (v as X< 1>) = bad_variant_access
66+
v is X< 1> = false, (v as X< 1>).to_string() = bad_variant_access
67+
v is X<19> = true, (v as X<19>).to_string() = X<19>
68+
v is X<20> = false, (v as X<20>) = bad_variant_access
69+
70+
## v as const lvalue reference
71+
72+
v is empty = false
73+
v is std::monostate = false
74+
v is X< 0> = false, (v as X< 1>) = bad_variant_access
75+
v is X< 1> = false, (v as X< 1>).to_string() = bad_variant_access
76+
v is X<19> = true, (v as X<19>).to_string() = X<19>
77+
v is X<20> = false, (v as X<20>) = bad_variant_access
78+
79+
## v as rvalue reference
80+
81+
v is empty = false
82+
v is std::monostate = false
83+
v is X< 0> = false, (v as X< 1>) = bad_variant_access
84+
v is X< 1> = false, (v as X< 1>).to_string() = bad_variant_access
85+
v is X<19> = true, (v as X<19>).to_string() = X<19>
86+
v is X<20> = false, (v as X<20>) = bad_variant_access
87+
88+
# X<20>
89+
90+
## v as lvalue reference
91+
92+
v is empty = false
93+
v is std::monostate = false
94+
v is X< 0> = false, (v as X< 1>) = bad_variant_access
95+
v is X< 1> = false, (v as X< 1>).to_string() = bad_variant_access
96+
v is X<19> = false, (v as X<19>).to_string() = bad_variant_access
97+
v is X<20> = false, (v as X<20>) = bad_variant_access
98+
99+
## v as const lvalue reference
100+
101+
v is empty = false
102+
v is std::monostate = false
103+
v is X< 0> = false, (v as X< 1>) = bad_variant_access
104+
v is X< 1> = false, (v as X< 1>).to_string() = bad_variant_access
105+
v is X<19> = false, (v as X<19>).to_string() = bad_variant_access
106+
v is X<20> = false, (v as X<20>) = bad_variant_access
107+
108+
## v as rvalue reference
109+
110+
v is empty = false
111+
v is std::monostate = false
112+
v is X< 0> = false, (v as X< 1>) = bad_variant_access
113+
v is X< 1> = false, (v as X< 1>).to_string() = bad_variant_access
114+
v is X<19> = false, (v as X<19>).to_string() = bad_variant_access
115+
v is X<20> = false, (v as X<20>) = bad_variant_access
116+
117+
# X<10>(std::exception)
118+
119+
## v as lvalue reference
120+
121+
v is empty = true
122+
v is std::monostate = false
123+
v is X< 0> = false, (v as X< 1>) = bad_variant_access
124+
v is X< 1> = false, (v as X< 1>).to_string() = bad_variant_access
125+
v is X<19> = false, (v as X<19>).to_string() = bad_variant_access
126+
v is X<20> = false, (v as X<20>) = bad_variant_access
127+
128+
## v as const lvalue reference
129+
130+
v is empty = true
131+
v is std::monostate = false
132+
v is X< 0> = false, (v as X< 1>) = bad_variant_access
133+
v is X< 1> = false, (v as X< 1>).to_string() = bad_variant_access
134+
v is X<19> = false, (v as X<19>).to_string() = bad_variant_access
135+
v is X<20> = false, (v as X<20>) = bad_variant_access
136+
137+
## v as rvalue reference
138+
139+
v is empty = true
140+
v is std::monostate = false
141+
v is X< 0> = false, (v as X< 1>) = bad_variant_access
142+
v is X< 1> = false, (v as X< 1>).to_string() = bad_variant_access
143+
v is X<19> = false, (v as X<19>).to_string() = bad_variant_access
144+
v is X<20> = false, (v as X<20>) = bad_variant_access
145+

regression-tests/test-results/apple-clang-14-c++2b/mixed-is-as-variant.cpp.output

Whitespace-only changes.
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
2+
3+
//=== Cpp2 type declarations ====================================================
4+
5+
6+
#include "cpp2util.h"
7+
8+
#line 1 "mixed-is-as-variant.cpp2"
9+
10+
11+
//=== Cpp2 type definitions and function declarations ===========================
12+
13+
#line 1 "mixed-is-as-variant.cpp2"
14+
auto test(auto&& v) -> void;
15+
16+
#line 11 "mixed-is-as-variant.cpp2"
17+
[[nodiscard]] auto main() -> int;
18+
19+
#line 39 "mixed-is-as-variant.cpp2"
20+
auto run_tests(auto&& v) -> void;
21+
22+
#line 50 "mixed-is-as-variant.cpp2"
23+
auto header(cpp2::impl::in<int> lvl, cpp2::impl::in<std::string> msg) -> void;
24+
#line 53 "mixed-is-as-variant.cpp2"
25+
26+
template<int I>
27+
struct X {
28+
operator int() const { return I; }
29+
X() = default;
30+
X(std::exception const& e) { throw e; }
31+
auto to_string() const { return "X<" + std::to_string(I) + ">"; }
32+
};
33+
34+
template <std::size_t I>
35+
void set_to_valueless_by_exception(auto& v) try {
36+
v.template emplace<I>(std::runtime_error("make valueless"));
37+
} catch (...) {}
38+
39+
auto expect_no_throw(auto&& l) -> std::string try {
40+
if constexpr ( requires { { l() } -> std::convertible_to<std::string>; }) {
41+
return l();
42+
} else {
43+
l();
44+
return "works!";
45+
}
46+
} catch (std::exception const& e) {
47+
return e.what();
48+
} catch (...) {
49+
return "unknow exception!";
50+
}
51+
52+
auto expect_no_throw(auto&& v, auto&& l) -> std::string try {
53+
if constexpr ( requires { { l(v) } -> std::convertible_to<std::string>; }) {
54+
return l(v);
55+
} else {
56+
l(v);
57+
return "works!";
58+
}
59+
} catch (std::exception const& e) {
60+
return e.what();
61+
} catch (...) {
62+
return "unknow exception!";
63+
}
64+
65+
66+
//=== Cpp2 function definitions =================================================
67+
68+
#line 1 "mixed-is-as-variant.cpp2"
69+
auto test(auto&& v) -> void{
70+
#line 2 "mixed-is-as-variant.cpp2"
71+
std::cout << "v is empty = " + cpp2::to_string(cpp2::impl::is<void>(v)) + "" << std::endl;
72+
std::cout << "v is std::monostate = " + cpp2::to_string(cpp2::impl::is<std::monostate>(v)) + "" << std::endl;
73+
std::cout << "v is X< 0> = " + cpp2::to_string(cpp2::impl::is<X<0>>(v)) + ",\t(v as X< 1>) = " << expect_no_throw(CPP2_FORWARD(v), [](auto&& v) mutable -> auto { return cpp2::impl::as_<X<0>>(CPP2_FORWARD(v)); }) << std::endl;
74+
std::cout << "v is X< 1> = " + cpp2::to_string(cpp2::impl::is<X<1>>(v)) + ",\t(v as X< 1>).to_string() = " + cpp2::to_string(expect_no_throw(CPP2_FORWARD(v), [](auto&& v) mutable -> std::string{return CPP2_UFCS(to_string)((cpp2::impl::as_<X<1>>(CPP2_FORWARD(v)))); })) + "" << std::endl;
75+
std::cout << "v is X<19> = " + cpp2::to_string(cpp2::impl::is<X<19>>(v)) + ",\t(v as X<19>).to_string() = " + cpp2::to_string(expect_no_throw(CPP2_FORWARD(v), [](auto&& v) mutable -> std::string{return CPP2_UFCS(to_string)((cpp2::impl::as_<X<19>>(CPP2_FORWARD(v)))); })) + "" << std::endl;
76+
std::cout << "v is X<20> = " + cpp2::to_string(cpp2::impl::is<X<20>>(v)) + ",\t(v as X<20>) = " << expect_no_throw(CPP2_FORWARD(v), [](auto&& v) mutable -> auto { return cpp2::impl::as_<X<20>>(CPP2_FORWARD(v)); }) << std::endl;
77+
std::cout << std::endl;
78+
}
79+
80+
#line 11 "mixed-is-as-variant.cpp2"
81+
[[nodiscard]] auto main() -> int{
82+
83+
std::variant<std::monostate,X<1>,X<2>,X<3>,X<4>,X<5>,X<6>,X<7>,X<8>,X<9>,X<10>,X<11>,X<12>,X<13>,X<14>,X<15>,X<16>,X<17>,X<18>,X<19>,X<20>> v {
84+
85+
};
86+
87+
header(1, "std::monostate");
88+
CPP2_UFCS_TEMPLATE(emplace<0>)(v);
89+
run_tests(v);
90+
91+
header(1, "X<1>");
92+
CPP2_UFCS_TEMPLATE(emplace<1>)(v);
93+
run_tests(v);
94+
95+
header(1, "X<19>");
96+
CPP2_UFCS_TEMPLATE(emplace<19>)(v);
97+
run_tests(v);
98+
99+
header(1, "X<20>");
100+
CPP2_UFCS_TEMPLATE(emplace<20>)(v);
101+
run_tests(v);
102+
103+
header(1, "X<10>(std::exception)");
104+
set_to_valueless_by_exception<10>(v);
105+
run_tests(cpp2::move(v));
106+
107+
}
108+
109+
#line 39 "mixed-is-as-variant.cpp2"
110+
auto run_tests(auto&& v) -> void{
111+
header(2, "v as lvalue reference");
112+
test(v);
113+
114+
header(2, "v as const lvalue reference");
115+
test(std::as_const(v));
116+
117+
header(2, "v as rvalue reference");
118+
test(std::move(CPP2_FORWARD(v)));
119+
}
120+
121+
#line 50 "mixed-is-as-variant.cpp2"
122+
auto header(cpp2::impl::in<int> lvl, cpp2::impl::in<std::string> msg) -> void{
123+
std::cout << std::string(lvl, '#') << " " << msg << "\n" << std::endl;
124+
}
125+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
mixed-is-as-variant.cpp2... ok (mixed Cpp1/Cpp2, Cpp2 code passes safety checks)
2+

0 commit comments

Comments
 (0)