Line data Source code
1 : /**
2 : * @file test_elsaDefines.cpp
3 : *
4 : * @brief Tests for common elsa defines
5 : *
6 : * @author David Frank - initial version
7 : */
8 :
9 : #include "doctest/doctest.h"
10 : #include <iostream>
11 : #include "elsaDefines.h"
12 : #include "TypeCasts.hpp"
13 :
14 : #include <type_traits>
15 :
16 : using namespace elsa;
17 : using namespace doctest;
18 :
19 : TEST_SUITE_BEGIN("core");
20 :
21 : TEST_CASE("elsaDefines: Testing PI")
22 3 : {
23 :
24 3 : THEN("Pi for real_t and pi_t are equal")
25 3 : {
26 1 : REQUIRE_EQ(pi<real_t>, pi_t);
27 1 : }
28 :
29 3 : THEN("pi_t is somewhat close to a representation for pi")
30 3 : {
31 1 : REQUIRE_EQ(pi_t, Approx(3.14159265358979323846).epsilon(1e-5));
32 1 : }
33 :
34 3 : THEN("Pi for double is close to given value for pi")
35 3 : {
36 1 : REQUIRE_EQ(pi<double>, 3.14159265358979323846);
37 1 : }
38 3 : }
39 :
40 : TEST_CASE("elsaDefines: Testing compile-time predicates")
41 1 : {
42 1 : static_assert(std::is_same_v<float, GetFloatingPointType_t<complex<float>>>);
43 1 : static_assert(std::is_same_v<double, GetFloatingPointType_t<complex<double>>>);
44 1 : static_assert(std::is_same_v<double, GetFloatingPointType_t<double>>);
45 1 : static_assert(std::is_same_v<float, GetFloatingPointType_t<float>>);
46 1 : static_assert(!std::is_same_v<float, GetFloatingPointType_t<double>>);
47 :
48 1 : REQUIRE_UNARY(true);
49 1 : }
50 :
51 : TEST_CASE("TypeCasts: Casting to unsigned")
52 2 : {
53 2 : WHEN("Value is in range of the destination type")
54 2 : {
55 1 : std::int8_t signed1{100};
56 1 : std::int16_t signed2{100};
57 1 : std::int32_t signed3{100};
58 1 : std::int64_t signed4{100};
59 :
60 1 : auto unsigned1 = asUnsigned(signed1);
61 1 : auto unsigned2 = asUnsigned(signed2);
62 1 : auto unsigned3 = asUnsigned(signed3);
63 1 : auto unsigned4 = asUnsigned(signed4);
64 :
65 1 : static_assert(std::is_same_v<decltype(unsigned1), std::make_unsigned_t<decltype(signed1)>>);
66 1 : static_assert(std::is_same_v<decltype(unsigned2), std::make_unsigned_t<decltype(signed2)>>);
67 1 : static_assert(std::is_same_v<decltype(unsigned3), std::make_unsigned_t<decltype(signed3)>>);
68 1 : static_assert(std::is_same_v<decltype(unsigned4), std::make_unsigned_t<decltype(signed4)>>);
69 :
70 1 : REQUIRE_EQ(signed1, unsigned1);
71 1 : REQUIRE_EQ(signed2, unsigned2);
72 1 : REQUIRE_EQ(signed3, unsigned3);
73 1 : REQUIRE_EQ(signed4, unsigned4);
74 1 : }
75 :
76 2 : WHEN("Value is already unsigned")
77 2 : {
78 1 : std::uint8_t val1{100};
79 1 : std::uint16_t val2{100};
80 1 : std::uint32_t val3{100};
81 1 : std::uint64_t val4{100};
82 :
83 1 : auto unsigned1 = asUnsigned(val1);
84 1 : auto unsigned2 = asUnsigned(val2);
85 1 : auto unsigned3 = asUnsigned(val3);
86 1 : auto unsigned4 = asUnsigned(val4);
87 :
88 1 : static_assert(std::is_same_v<decltype(unsigned1), decltype(val1)>);
89 1 : static_assert(std::is_same_v<decltype(unsigned2), decltype(val2)>);
90 1 : static_assert(std::is_same_v<decltype(unsigned3), decltype(val3)>);
91 1 : static_assert(std::is_same_v<decltype(unsigned4), decltype(val4)>);
92 :
93 1 : REQUIRE_EQ(val1, unsigned1);
94 1 : REQUIRE_EQ(val2, unsigned2);
95 1 : REQUIRE_EQ(val3, unsigned3);
96 1 : REQUIRE_EQ(val4, unsigned4);
97 1 : }
98 2 : }
99 :
100 : TEST_CASE("TypeCasts: Casting to signed")
101 2 : {
102 2 : WHEN("Value is in range of the destination type")
103 2 : {
104 1 : std::uint8_t unsigned1{100};
105 1 : std::uint16_t unsigned2{100};
106 1 : std::uint32_t unsigned3{100};
107 1 : std::uint64_t unsigned4{100};
108 :
109 1 : auto signed1 = asSigned(unsigned1);
110 1 : auto signed2 = asSigned(unsigned2);
111 1 : auto signed3 = asSigned(unsigned3);
112 1 : auto signed4 = asSigned(unsigned4);
113 :
114 1 : static_assert(std::is_same_v<decltype(signed1), std::make_signed_t<decltype(unsigned1)>>);
115 1 : static_assert(std::is_same_v<decltype(signed2), std::make_signed_t<decltype(unsigned2)>>);
116 1 : static_assert(std::is_same_v<decltype(signed3), std::make_signed_t<decltype(unsigned3)>>);
117 1 : static_assert(std::is_same_v<decltype(signed4), std::make_signed_t<decltype(unsigned4)>>);
118 :
119 1 : REQUIRE_EQ(signed1, unsigned1);
120 1 : REQUIRE_EQ(signed2, unsigned2);
121 1 : REQUIRE_EQ(signed3, unsigned3);
122 1 : REQUIRE_EQ(signed4, unsigned4);
123 1 : }
124 :
125 2 : WHEN("Value is already signed")
126 2 : {
127 1 : std::int8_t val1{100};
128 1 : std::int16_t val2{100};
129 1 : std::int32_t val3{100};
130 1 : std::int64_t val4{100};
131 :
132 1 : auto signed1 = asSigned(val1);
133 1 : auto signed2 = asSigned(val2);
134 1 : auto signed3 = asSigned(val3);
135 1 : auto signed4 = asSigned(val4);
136 :
137 1 : static_assert(std::is_same_v<decltype(signed1), decltype(val1)>);
138 1 : static_assert(std::is_same_v<decltype(signed2), decltype(val2)>);
139 1 : static_assert(std::is_same_v<decltype(signed3), decltype(val3)>);
140 1 : static_assert(std::is_same_v<decltype(signed4), decltype(val4)>);
141 :
142 1 : REQUIRE_EQ(val1, signed1);
143 1 : REQUIRE_EQ(val2, signed2);
144 1 : REQUIRE_EQ(val3, signed3);
145 1 : REQUIRE_EQ(val4, signed4);
146 1 : }
147 2 : }
148 :
149 : TEST_CASE("TypeCasts: Testing is()")
150 9 : {
151 9 : struct Base {
152 9 : virtual ~Base() = default;
153 9 : };
154 9 : struct Derived1 final : Base {
155 9 : ~Derived1() override = default;
156 9 : };
157 9 : struct Derived2 final : public Base {
158 9 : ~Derived2() override = default;
159 9 : };
160 :
161 9 : WHEN("Base pointer points to Derived1")
162 9 : {
163 3 : std::unique_ptr<Base> ptr = std::make_unique<Derived1>();
164 :
165 3 : THEN("Casting to base is also fine")
166 3 : {
167 1 : REQUIRE_UNARY(is<Base>(ptr.get()));
168 1 : REQUIRE_UNARY(ptr);
169 1 : }
170 3 : THEN("Casting to Derived1 is fine")
171 3 : {
172 1 : REQUIRE_UNARY(is<Derived1>(ptr.get()));
173 1 : REQUIRE_UNARY(ptr);
174 1 : }
175 3 : THEN("Casting to Derived2 doesn't work")
176 3 : {
177 1 : REQUIRE_UNARY_FALSE(is<Derived2>(ptr.get()));
178 1 : REQUIRE_UNARY(ptr);
179 1 : }
180 3 : }
181 :
182 9 : WHEN("Base reference points to Derived1")
183 9 : {
184 3 : std::unique_ptr<Base> ptr = std::make_unique<Derived1>();
185 :
186 3 : THEN("Casting to base is also fine")
187 3 : {
188 1 : REQUIRE_UNARY(is<Base>(*ptr));
189 1 : REQUIRE_UNARY(ptr);
190 1 : }
191 3 : THEN("Casting to Derived1 is fine")
192 3 : {
193 1 : REQUIRE_UNARY(is<Derived1>(*ptr));
194 1 : REQUIRE_UNARY(ptr);
195 1 : }
196 3 : THEN("Casting to Derived2 doesn't work")
197 3 : {
198 1 : REQUIRE_UNARY_FALSE(is<Derived2>(*ptr));
199 1 : REQUIRE_UNARY(ptr);
200 1 : }
201 3 : }
202 :
203 9 : WHEN("unique_ptr to Base points to Derived1")
204 9 : {
205 3 : std::unique_ptr<Base> ptr = std::make_unique<Derived1>();
206 :
207 3 : THEN("Check is<Base> returns true")
208 3 : {
209 1 : REQUIRE_UNARY(is<Base>(ptr));
210 1 : REQUIRE_UNARY(ptr);
211 1 : }
212 3 : THEN("Check is<Derived1> returns true")
213 3 : {
214 1 : REQUIRE_UNARY(is<Derived1>(ptr));
215 1 : REQUIRE_UNARY(ptr);
216 1 : }
217 3 : THEN("Check is<Derived2> returns false")
218 3 : {
219 1 : REQUIRE_UNARY_FALSE(is<Derived2>(ptr));
220 1 : REQUIRE_UNARY(ptr);
221 1 : }
222 3 : }
223 9 : }
224 :
225 : TEST_CASE("TypeCasts: Testing downcast")
226 12 : {
227 12 : struct Base {
228 12 : virtual ~Base() = default;
229 12 : };
230 12 : struct Derived1 final : Base {
231 12 : ~Derived1() override = default;
232 12 : };
233 12 : struct Derived2 final : public Base {
234 12 : ~Derived2() override = default;
235 12 : };
236 :
237 12 : WHEN("Base pointer points to Derived1")
238 12 : {
239 4 : std::unique_ptr<Base> ptr = std::make_unique<Derived1>();
240 :
241 4 : THEN("Downcasting to Base works")
242 4 : {
243 1 : REQUIRE_UNARY(downcast<Base>(ptr.get()));
244 1 : REQUIRE_UNARY(ptr);
245 1 : }
246 4 : THEN("Downcasting to Derived1 works")
247 4 : {
248 1 : REQUIRE_UNARY(downcast<Derived1>(ptr.get()));
249 1 : REQUIRE_UNARY(ptr);
250 1 : }
251 4 : THEN("Safely downcasting to Derived1 works")
252 4 : {
253 1 : REQUIRE_UNARY(downcast_safe<Derived1>(ptr.get()));
254 1 : REQUIRE_UNARY(ptr);
255 1 : }
256 4 : THEN("Safely downcasting to Derived2 doesn't work")
257 4 : {
258 1 : REQUIRE_UNARY_FALSE(downcast_safe<Derived2>(ptr.get()));
259 1 : REQUIRE_UNARY(ptr);
260 1 : }
261 4 : }
262 :
263 12 : WHEN("Base reference points to Derived1")
264 12 : {
265 4 : std::unique_ptr<Base> ptr = std::make_unique<Derived1>();
266 :
267 4 : THEN("Downcasting to Base works")
268 4 : {
269 1 : REQUIRE_NOTHROW(downcast<Base>(*ptr));
270 1 : REQUIRE_UNARY(ptr);
271 1 : }
272 4 : THEN("Downcasting to Derived1 works")
273 4 : {
274 1 : REQUIRE_NOTHROW(downcast<Derived1>(*ptr));
275 1 : REQUIRE_UNARY(ptr);
276 1 : }
277 4 : THEN("Safely downcasting to Derived1 works")
278 4 : {
279 1 : REQUIRE_NOTHROW(downcast_safe<Derived1>(*ptr));
280 1 : REQUIRE_UNARY(ptr);
281 1 : }
282 4 : THEN("Safely downcasting to Derived2 throws")
283 4 : {
284 1 : REQUIRE_THROWS(downcast_safe<Derived2>(*ptr));
285 1 : REQUIRE_UNARY(ptr);
286 1 : }
287 4 : }
288 :
289 12 : WHEN("unique_ptr to Base points to Derived1")
290 12 : {
291 4 : std::unique_ptr<Base> ptr = std::make_unique<Derived1>();
292 :
293 4 : THEN("Downcasting to base works")
294 4 : {
295 1 : REQUIRE_UNARY(downcast<Base>(std::move(ptr)));
296 1 : REQUIRE_UNARY_FALSE(ptr);
297 1 : }
298 4 : THEN("Downcasting to Derived1 works")
299 4 : {
300 1 : REQUIRE_UNARY(downcast<Derived1>(std::move(ptr)));
301 1 : REQUIRE_UNARY_FALSE(ptr);
302 1 : }
303 4 : THEN("Safely downcasting to Derived1 works")
304 4 : {
305 1 : REQUIRE_UNARY(downcast_safe<Derived1>(std::move(ptr)));
306 1 : REQUIRE_UNARY_FALSE(ptr);
307 1 : }
308 4 : THEN("Safely downcasting to Derived2 doesn't work")
309 4 : {
310 1 : REQUIRE_UNARY_FALSE(downcast_safe<Derived2>(std::move(ptr)));
311 1 : REQUIRE_UNARY(ptr);
312 1 : }
313 4 : }
314 12 : }
315 :
316 : TEST_SUITE_END();
|