Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
variant_tests.cpp
Go to the documentation of this file.
1#include <sysio/vm/variant.hpp>
2
3#include <catch2/catch.hpp>
4
5using namespace sysio;
6using namespace sysio::vm;
7
8TEST_CASE("Testing variant with stateless class", "[variant_stateless_tests]") {
9 struct vis {
10 int operator()(signed char v) { return v + 1; }
11 int operator()(short v) { return v + 2; }
12 int operator()(int v) { return v + 3; }
13 int operator()(long v) { return v + 4; }
14 int operator()(float v) { return v + 5.0f; }
15 int operator()(double v) { return v + 6.0; }
16 };
17
19
20 {
21 variant_type v((signed char)42);
22 CHECK(visit(vis{}, v) == 43);
23 }
24 {
25 variant_type v((short)142);
26 CHECK(visit(vis{}, v) == 144);
27 }
28 {
29 variant_type v((int)242);
30 CHECK(visit(vis{}, v) == 245);
31 }
32 {
33 variant_type v((long)342);
34 CHECK(visit(vis{}, v) == 346);
35 }
36 {
37 variant_type v((float)442);
38 CHECK(visit(vis{}, v) == 447);
39 }
40 {
41 variant_type v((double)542);
42 CHECK(visit(vis{}, v) == 548);
43 }
44}
45
46
47TEST_CASE("Testing argument forwarding for visit", "[variant_forward_tests]") {
48
50
51 // visitor forwarding
52
53 // lvalue
54 {
55 struct vis {
56 int r = -1;
57 void operator()(double v) & { r = v + 1; }
58 void operator()(...) {}
59 };
60 variant_type v((double)42);
61 vis f;
62 visit(f, v);
63 CHECK(f.r == 43);
64 }
65 // rvalue
66 {
67 struct vis {
68 int r = -1;
69 void operator()(double v) && { r = v + 1; }
70 void operator()(...) {}
71 };
72 variant_type v((double)42);
73 vis f;
74 visit(std::move(f), v);
75 CHECK(f.r == 43);
76 }
77 // const lvalue
78 {
79 struct vis {
80 mutable int r = -1;
81 void operator()(double v) const & { r = v + 1; }
82 void operator()(...) {}
83 };
84 variant_type v((double)42);
85 const vis f;
86 visit(f, v);
87 CHECK(f.r == 43);
88 }
89
90 // variant forwarding
91
92 // lvalue
93 {
94 struct vis {
95 void operator()(double& v) { v = v + 1; }
96 void operator()(...) {}
97 };
98 variant_type v((double)42);
99 visit(vis{}, v);
100 CHECK(v.get<double>() == 43);
101 }
102
103 // rvalue
104 {
105 struct vis {
106 void operator()(double&& v) {
107 v = v + 1;
108 }
109 void operator()(...) {}
110 };
111 variant_type v((double)42);
112 visit(vis{}, std::move(v));
113 CHECK(v.get<double>() == 43);
114 }
115
116 // const lvalue
117 {
118 struct vis {
119 void operator()(const double& v) {
120 const_cast<double&>(v) = v + 1;
121 }
122 void operator()(...) {}
123 };
124 // Don't declare this const, because that would make casting away const illegal.
125 variant_type v((double)42);
126 visit(vis{}, static_cast<const variant_type&>(v));
127 CHECK(v.get<double>() == 43);
128 }
129}
130
131template<typename V, typename T>
132constexpr bool variant_constexpr_assign(T&& t) {
133 V v{t};
134 T expected{t};
135 bool result = true;
136 v = static_cast<T&&>(t);
137 result = result && (v.template get<T>() == expected);
138 v = t;
139 result = result && (v.template get<T>() == expected);
140 v = static_cast<const T&>(t);
141 result = result && (v.template get<T>() == expected);
142
143 // copy and move assignment
144 v = static_cast<V&>(v);
145 result = result && (v.template get<T>() == expected);
146 v = static_cast<V&&>(v);
147 result = result && (v.template get<T>() == expected);
148 v = static_cast<const V&>(v);
149 result = result && (v.template get<T>() == expected);
150 return result;
151}
152
153template<typename V, typename T>
154constexpr bool variant_constexpr_get(T&& t) {
155 V v{t};
156 T expected{t};
157 bool result = true;
158 static_assert(std::is_same_v<decltype(v.template get<T>()), T&>, "check get result type");
159 static_assert(std::is_same_v<decltype(static_cast<V&&>(v).template get<T>()), T&&>, "check get result type");
160 static_assert(std::is_same_v<decltype(static_cast<const V&>(v).template get<T>()), const T&>, "check get result type");
161 static_assert(std::is_same_v<decltype(static_cast<const V&&>(v).template get<T>()), const T&&>, "check get result type");
162
163 result = result && (v.template get<T>() == expected);
164 result = result && (static_cast<V&&>(v).template get<T>() == expected);
165 result = result && (static_cast<const V&>(v).template get<T>() == expected);
166 result = result && (static_cast<const V&&>(v).template get<T>() == expected);
167 return result;
168}
169
170TEST_CASE("Testing constexpr variant", "[variant_constexpr_tests]") {
172
173 {
174 constexpr variant_type v{(signed char)2};
175 constexpr signed char result_lv{v.get<signed char>()};
176 CHECK(result_lv == 2);
177 constexpr signed char result_rv{variant_type{(signed char)4}.get<signed char>()};
178 CHECK(result_rv == 4);
179 }
180 {
181 constexpr variant_type v{(double)2};
182 constexpr double result_lv{v.get<double>()};
183 CHECK(result_lv == 2);
184 constexpr double result_rv{variant_type{(double)4}.get<double>()};
185 CHECK(result_rv == 4);
186 }
187 constexpr bool assign0 = variant_constexpr_assign<variant_type>((signed char)2);
188 CHECK(assign0);
189 constexpr bool assign1 = variant_constexpr_assign<variant_type>((double)4);
190 CHECK(assign1);
191
192 constexpr bool get0 = variant_constexpr_get<variant_type>((signed char)2);
193 CHECK(get0);
194 constexpr bool get1 = variant_constexpr_get<variant_type>((double)4);
195 CHECK(get1);
196
197#ifdef CONSTEXPR_STD_INVOKE
198 {
199 struct vis {
200 constexpr int operator()(signed char v) { return v + 1; }
201 constexpr int operator()(short v) { return v + 2; }
202 constexpr int operator()(int v) { return v + 3; }
203 constexpr int operator()(long v) { return v + 4; }
204 constexpr int operator()(float v) { return v + 5.0f; }
205 constexpr int operator()(double v) { return v + 6.0; }
206 };
207
209
210 {
211 constexpr int test = visit(vis{}, variant_type{(signed char)2});
212 CHECK(test == 3);
213 }
214 }
215#endif
216}
217
218// Minimal requirements. Delete everything that shouldn't be needed by visit
220 minimal_vis(const minimal_vis&) = delete;
222 template<typename T>
223 int operator()(T v) const {
224 return v + 1;
225 }
226 static minimal_vis& make() { static minimal_vis singleton; return singleton; }
227 private:
228 minimal_vis() = default;
229 ~minimal_vis() = default;
230};
233 variant_type v((double)42);
235 visit(std::move(minimal_vis::make()), v);
236 visit(const_cast<const minimal_vis&>(minimal_vis::make()), v);
237}
const mie::Vuint & r
Definition bn.cpp:28
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object's.
Definition variant.hpp:191
#define CHECK(cond)
Definition util.h:80
#define TEST_CASE(...)
Definition catch.hpp:222
constexpr auto visit(Visitor &&vis, Variant &&var)
Definition variant.hpp:156
#define T(meth, val, expected)
Definition test_zm.cpp:19
minimal_vis(const minimal_vis &)=delete
int operator()(T v) const
static minimal_vis & make()
minimal_vis & operator=(const minimal_vis &)=delete
void check_requirements()
constexpr bool variant_constexpr_assign(T &&t)
constexpr bool variant_constexpr_get(T &&t)