1 | // =============================================================== // |
---|
2 | // // |
---|
3 | // File : arb_misc.cxx // |
---|
4 | // Purpose : misc that doesnt fit elsewhere // |
---|
5 | // // |
---|
6 | // Coded by Ralf Westram (coder@reallysoft.de) in October 2012 // |
---|
7 | // Institute of Microbiology (Technical University Munich) // |
---|
8 | // http://www.arb-home.de/ // |
---|
9 | // // |
---|
10 | // =============================================================== // |
---|
11 | |
---|
12 | #include "arb_misc.h" |
---|
13 | #include "arb_msg.h" |
---|
14 | #include "arb_file.h" |
---|
15 | #include "arb_string.h" |
---|
16 | |
---|
17 | #include <cmath> |
---|
18 | |
---|
19 | // AISC_MKPT_PROMOTE:#ifndef _GLIBCXX_CSTDLIB |
---|
20 | // AISC_MKPT_PROMOTE:#include <cstdlib> |
---|
21 | // AISC_MKPT_PROMOTE:#endif |
---|
22 | |
---|
23 | const char *GBS_readable_size(unsigned long long size, const char *unit_suffix) { |
---|
24 | // return human readable size information |
---|
25 | // returned string is maximal 6+strlen(unit_suffix) characters long |
---|
26 | // (using "b" as 'unit_suffix' produces '### b', '### Mb' etc) |
---|
27 | |
---|
28 | if (size<1000) return GBS_global_string("%llu %s", size, unit_suffix); |
---|
29 | |
---|
30 | const char *units = "kMGTPEZY"; // kilo, Mega, Giga, Tera, ... should be enough forever |
---|
31 | int i; |
---|
32 | |
---|
33 | for (i = 0; units[i]; ++i) { |
---|
34 | char unit = units[i]; |
---|
35 | if (size<1000*1024) { |
---|
36 | double amount = size/(double)1024; |
---|
37 | if (amount<10.0) return GBS_global_string("%4.2f %c%s", amount+0.005, unit, unit_suffix); |
---|
38 | if (amount<100.0) return GBS_global_string("%4.1f %c%s", amount+0.05, unit, unit_suffix); |
---|
39 | return GBS_global_string("%i %c%s", (int)(amount+0.5), unit, unit_suffix); |
---|
40 | } |
---|
41 | size /= 1024; // next unit |
---|
42 | } |
---|
43 | return GBS_global_string("MUCH %s", unit_suffix); |
---|
44 | } |
---|
45 | |
---|
46 | const char *GBS_readable_timediff(size_t seconds) { |
---|
47 | size_t mins = seconds/60; seconds -= mins * 60; |
---|
48 | size_t hours = mins/60; mins -= hours * 60; |
---|
49 | size_t days = hours/24; hours -= days * 24; |
---|
50 | |
---|
51 | const int MAXPRINT = 40; |
---|
52 | int printed = 0; |
---|
53 | static char buffer[MAXPRINT+1]; |
---|
54 | |
---|
55 | if (days>0) printed += sprintf(buffer+printed, "%zud", days); |
---|
56 | if (printed || hours>0) printed += sprintf(buffer+printed, "%zuh", hours); |
---|
57 | if (printed || mins>0) printed += sprintf(buffer+printed, "%zum", mins); |
---|
58 | |
---|
59 | printed += sprintf(buffer+printed, "%zus", seconds); |
---|
60 | |
---|
61 | arb_assert(printed>0 && printed<MAXPRINT); |
---|
62 | |
---|
63 | return buffer; |
---|
64 | } |
---|
65 | |
---|
66 | const char *ARB_float_2_ascii(const float f) { |
---|
67 | /*! calculate the "best" ascii representation for float 'f' |
---|
68 | * - smaller conversion error is better |
---|
69 | * - shorter representation is better (for equal conversion errors) |
---|
70 | */ |
---|
71 | |
---|
72 | const int MAXSIZE = 50; |
---|
73 | static char result[MAXSIZE]; |
---|
74 | char buffer[MAXSIZE]; |
---|
75 | |
---|
76 | int printed_e = snprintf(result, MAXSIZE, "%e", f); arb_assert(printed_e<MAXSIZE); |
---|
77 | float back_e = strtof(result, NULp); |
---|
78 | float diff_e = fabsf(f-back_e); |
---|
79 | |
---|
80 | int printed_g = snprintf(buffer, MAXSIZE, "%g", f); arb_assert(printed_g<MAXSIZE); |
---|
81 | float back_g = strtof(buffer, NULp); |
---|
82 | float diff_g = fabsf(f-back_g); |
---|
83 | |
---|
84 | if (diff_g<diff_e || (diff_g == diff_e && printed_g<printed_e)) { |
---|
85 | printed_e = printed_g; |
---|
86 | back_e = back_g; |
---|
87 | diff_e = diff_g; |
---|
88 | memcpy(result, buffer, printed_g+1); |
---|
89 | } |
---|
90 | |
---|
91 | int printed_f = snprintf(buffer, MAXSIZE, "%f", f); arb_assert(printed_f<MAXSIZE); |
---|
92 | float back_f = strtof(buffer, NULp); |
---|
93 | float diff_f = fabsf(f-back_f); |
---|
94 | |
---|
95 | if (diff_f<diff_e || (diff_f == diff_e && printed_f<printed_e)) { |
---|
96 | memcpy(result, buffer, printed_f+1); |
---|
97 | } |
---|
98 | |
---|
99 | return result; |
---|
100 | } |
---|
101 | |
---|
102 | const char *ARB_getenv_ignore_empty(const char *envvar) { |
---|
103 | const char *result = getenv(envvar); |
---|
104 | return (result && result[0]) ? result : NULp; |
---|
105 | } |
---|
106 | |
---|
107 | char *ARB_executable(const char *exe_name, const char *path) { |
---|
108 | char *buffer = ARB_alloc<char>(strlen(path)+1+strlen(exe_name)+1); |
---|
109 | const char *start = path; |
---|
110 | int found = 0; |
---|
111 | |
---|
112 | while (!found && start) { |
---|
113 | const char *colon = strchr(start, ':'); |
---|
114 | int len = colon ? (colon-start) : (int)strlen(start); |
---|
115 | |
---|
116 | memcpy(buffer, start, len); |
---|
117 | buffer[len] = '/'; |
---|
118 | strcpy(buffer+len+1, exe_name); |
---|
119 | |
---|
120 | found = GB_is_executablefile(buffer); |
---|
121 | start = colon ? colon+1 : NULp; |
---|
122 | } |
---|
123 | |
---|
124 | char *executable = found ? ARB_strdup(buffer) : NULp; |
---|
125 | free(buffer); |
---|
126 | return executable; |
---|
127 | } |
---|
128 | |
---|
129 | // -------------------------------------------------------------------------------- |
---|
130 | |
---|
131 | char ARB_path_contains_unwanted_chars(const char *path) { |
---|
132 | if (strchr(path, ' ') != NULp) { |
---|
133 | return ' '; |
---|
134 | } |
---|
135 | return 0; |
---|
136 | } |
---|
137 | |
---|
138 | void ARB_warn_about_unwanted_chars(const char *path, const char *path_description) { |
---|
139 | // annoy user with warnings if paths contain unwanted characters. |
---|
140 | // |
---|
141 | // motivation: I tried to fix some scripts to correctly handle the case |
---|
142 | // where arb is installed in a path containing spaces. |
---|
143 | // |
---|
144 | // Since that is a bottomless pit, I decided to deny spaces there. |
---|
145 | |
---|
146 | char unwantedChar = ARB_path_contains_unwanted_chars(path); |
---|
147 | if (unwantedChar) { |
---|
148 | GB_warningf( |
---|
149 | "arb may not work as expected, because\n" |
---|
150 | "%s\n" |
---|
151 | " (='%s')\n" |
---|
152 | "contains an unwanted character ('%c').", |
---|
153 | path_description, |
---|
154 | path, |
---|
155 | unwantedChar); |
---|
156 | } |
---|
157 | } |
---|
158 | |
---|
159 | // -------------------------------------------------------------------------------- |
---|
160 | |
---|
161 | #ifdef UNIT_TESTS |
---|
162 | #ifndef TEST_UNIT_H |
---|
163 | #include <test_unit.h> |
---|
164 | #endif |
---|
165 | |
---|
166 | #if 0 |
---|
167 | // simple test |
---|
168 | #define TEST_EXPECT_FLOAT_2_ASCII(f,a) TEST_EXPECT_EQUAL(ARB_float_2_ascii(f), a) |
---|
169 | #else |
---|
170 | // also test back-conversion (ascii->float->ascii) is stable |
---|
171 | #define TEST_EXPECT_FLOAT_2_ASCII(f,a) do{ \ |
---|
172 | TEST_EXPECT_EQUAL(ARB_float_2_ascii(f), a); \ |
---|
173 | TEST_EXPECT_EQUAL(ARB_float_2_ascii(strtof(a, NULp)), a); \ |
---|
174 | }while(0) |
---|
175 | #endif |
---|
176 | |
---|
177 | __ATTR__REDUCED_OPTIMIZE void TEST_float_2_ascii() { |
---|
178 | TEST_EXPECT_FLOAT_2_ASCII(3.141592e+00, "3.141592"); |
---|
179 | TEST_EXPECT_FLOAT_2_ASCII(3.141592, "3.141592"); |
---|
180 | TEST_EXPECT_FLOAT_2_ASCII(3.14159, "3.14159"); |
---|
181 | |
---|
182 | TEST_EXPECT_FLOAT_2_ASCII(0.1, "0.1"); |
---|
183 | TEST_EXPECT_FLOAT_2_ASCII(0.01, "0.01"); |
---|
184 | TEST_EXPECT_FLOAT_2_ASCII(0.001, "0.001"); |
---|
185 | TEST_EXPECT_FLOAT_2_ASCII(0.0001, "0.0001"); |
---|
186 | TEST_EXPECT_FLOAT_2_ASCII(0.00001, "1e-05"); |
---|
187 | TEST_EXPECT_FLOAT_2_ASCII(0.000001, "1e-06"); |
---|
188 | TEST_EXPECT_FLOAT_2_ASCII(0.0000001, "1e-07"); |
---|
189 | TEST_EXPECT_FLOAT_2_ASCII(0.00000001, "1e-08"); |
---|
190 | TEST_EXPECT_FLOAT_2_ASCII(0.000000001, "1e-09"); |
---|
191 | TEST_EXPECT_FLOAT_2_ASCII(0.0000000001, "1e-10"); |
---|
192 | TEST_EXPECT_FLOAT_2_ASCII(0.00000000001, "1e-11"); |
---|
193 | |
---|
194 | TEST_EXPECT_FLOAT_2_ASCII(10, "10"); |
---|
195 | TEST_EXPECT_FLOAT_2_ASCII(100, "100"); |
---|
196 | TEST_EXPECT_FLOAT_2_ASCII(1000, "1000"); |
---|
197 | TEST_EXPECT_FLOAT_2_ASCII(10000, "10000"); |
---|
198 | TEST_EXPECT_FLOAT_2_ASCII(100000, "100000"); |
---|
199 | TEST_EXPECT_FLOAT_2_ASCII(1000000, "1e+06"); |
---|
200 | TEST_EXPECT_FLOAT_2_ASCII(10000000, "1e+07"); |
---|
201 | TEST_EXPECT_FLOAT_2_ASCII(100000000, "1e+08"); |
---|
202 | TEST_EXPECT_FLOAT_2_ASCII(1000000000, "1e+09"); |
---|
203 | |
---|
204 | TEST_EXPECT_FLOAT_2_ASCII(3141592, "3.141592e+06"); |
---|
205 | TEST_EXPECT_FLOAT_2_ASCII(314159.2, "3.141592e+05"); |
---|
206 | TEST_EXPECT_FLOAT_2_ASCII(31415.92, "3.141592e+04"); |
---|
207 | TEST_EXPECT_FLOAT_2_ASCII(3141.592, "3141.592041"); |
---|
208 | TEST_EXPECT_FLOAT_2_ASCII(3141.592041, "3141.592041"); |
---|
209 | TEST_EXPECT_FLOAT_2_ASCII(314.1592, "314.159210"); |
---|
210 | TEST_EXPECT_FLOAT_2_ASCII(314.159210, "314.159210"); |
---|
211 | TEST_EXPECT_FLOAT_2_ASCII(31.41592, "31.415920"); |
---|
212 | TEST_EXPECT_FLOAT_2_ASCII(3.141592, "3.141592"); |
---|
213 | TEST_EXPECT_FLOAT_2_ASCII(.3141592, "3.141592e-01"); |
---|
214 | TEST_EXPECT_FLOAT_2_ASCII(.03141592, "3.141592e-02"); |
---|
215 | TEST_EXPECT_FLOAT_2_ASCII(.003141592, "3.141592e-03"); |
---|
216 | TEST_EXPECT_FLOAT_2_ASCII(.0003141592, "3.141592e-04"); |
---|
217 | TEST_EXPECT_FLOAT_2_ASCII(.00003141592, "3.141592e-05"); |
---|
218 | TEST_EXPECT_FLOAT_2_ASCII(M_PI, "3.141593"); |
---|
219 | |
---|
220 | TEST_EXPECT_FLOAT_2_ASCII(1/2.0, "0.5"); |
---|
221 | TEST_EXPECT_FLOAT_2_ASCII(1/3.0, "3.333333e-01"); |
---|
222 | TEST_EXPECT_FLOAT_2_ASCII(1/4.0, "0.25"); |
---|
223 | TEST_EXPECT_FLOAT_2_ASCII(1/5.0, "0.2"); |
---|
224 | TEST_EXPECT_FLOAT_2_ASCII(1/6.0, "1.666667e-01"); |
---|
225 | |
---|
226 | TEST_EXPECT_FLOAT_2_ASCII(37550000.0, "3.755e+07"); |
---|
227 | TEST_EXPECT_FLOAT_2_ASCII(3755000.0, "3.755e+06"); |
---|
228 | TEST_EXPECT_FLOAT_2_ASCII(375500.0, "375500"); |
---|
229 | TEST_EXPECT_FLOAT_2_ASCII(37550.0, "37550"); |
---|
230 | TEST_EXPECT_FLOAT_2_ASCII(3755.0, "3755"); |
---|
231 | TEST_EXPECT_FLOAT_2_ASCII(375.5, "375.5"); |
---|
232 | TEST_EXPECT_FLOAT_2_ASCII(37.55, "37.55"); |
---|
233 | TEST_EXPECT_FLOAT_2_ASCII(3.755, "3.755"); |
---|
234 | TEST_EXPECT_FLOAT_2_ASCII(0.3755, "0.3755"); |
---|
235 | TEST_EXPECT_FLOAT_2_ASCII(0.03755, "0.03755"); |
---|
236 | TEST_EXPECT_FLOAT_2_ASCII(0.003755, "0.003755"); |
---|
237 | TEST_EXPECT_FLOAT_2_ASCII(0.0003755, "0.0003755"); |
---|
238 | TEST_EXPECT_FLOAT_2_ASCII(0.00003755, "3.755e-05"); |
---|
239 | TEST_EXPECT_FLOAT_2_ASCII(0.000003755, "3.755e-06"); |
---|
240 | |
---|
241 | TEST_EXPECT_FLOAT_2_ASCII(1000.0*1000.0*1000.0, "1e+09"); |
---|
242 | TEST_EXPECT_FLOAT_2_ASCII(25000.0*25000.0*25000.0, "1.5625e+13"); |
---|
243 | } |
---|
244 | |
---|
245 | // ------------------------------------------------------------ |
---|
246 | // test to ensure sanitizers work as expected |
---|
247 | |
---|
248 | #if 0 |
---|
249 | void TEST_fail_address_sanitizer() { |
---|
250 | static int array[5]; |
---|
251 | array[2] = 1; |
---|
252 | array[5] = 1; // <- fails with AddressSanitizer |
---|
253 | |
---|
254 | printf("array[5]=%i\n", array[5]); |
---|
255 | } |
---|
256 | #endif |
---|
257 | |
---|
258 | #if 0 |
---|
259 | void TEST_fail_undef_sanitizer() { |
---|
260 | // error below are not reported if AddressSanitizer bails out (TEST_fail_address_sanitizer) |
---|
261 | int x = 7; |
---|
262 | int y1 = -1; |
---|
263 | |
---|
264 | int s = x<<y1; // runtime error with ubsan: shift exponent -1 is negative (does not terminate) |
---|
265 | printf("s=%i\n", s); |
---|
266 | |
---|
267 | int o = INT_MAX; |
---|
268 | int u = INT_MIN; |
---|
269 | o++; // runtime error: signed integer overflow |
---|
270 | u--; // runtime error: signed integer overflow |
---|
271 | printf("o=%i u=%i\n", o, u); |
---|
272 | |
---|
273 | #if 0 |
---|
274 | int y2 = 0; |
---|
275 | int z1 = x/y1; |
---|
276 | int z2 = x/y2; // runtime error with ubsan: division by zero (terminates with SEGV; also w/o sanitizers) |
---|
277 | printf("z1=%i z2=%i\n", z1, z2); |
---|
278 | #endif |
---|
279 | } |
---|
280 | #endif |
---|
281 | |
---|
282 | #if 0 |
---|
283 | void TEST_fail_leak_sanitizer() { |
---|
284 | int *p = new int[5]; // <- fails with LeakSanitizer (only reported if AddressSanitizer does not bail out (TEST_fail_address_sanitizer)) |
---|
285 | printf("p[3]=%i\n", p[3]); |
---|
286 | } |
---|
287 | #endif |
---|
288 | |
---|
289 | // ------------------------------------------------------------ |
---|
290 | |
---|
291 | #include "StrUniquifier.h" |
---|
292 | |
---|
293 | void TEST_StrUniquifier() { |
---|
294 | StrUniquifier uniq("->"); |
---|
295 | TEST_EXPECT_EQUAL(uniq.make_unique_key("hey"), "hey"); |
---|
296 | TEST_EXPECT_EQUAL(uniq.make_unique_key("hey"), "hey->2"); |
---|
297 | TEST_EXPECT_EQUAL(uniq.make_unique_key("Hey"), "Hey"); |
---|
298 | TEST_EXPECT_EQUAL(uniq.make_unique_key("Hey"), "Hey->2"); |
---|
299 | |
---|
300 | TEST_EXPECT_EQUAL(uniq.make_unique_key(""), ""); |
---|
301 | TEST_EXPECT_EQUAL(uniq.make_unique_key(""), "->2"); |
---|
302 | |
---|
303 | StrUniquifier fresh("."); |
---|
304 | TEST_EXPECT_EQUAL(fresh.make_unique_key(""), ""); |
---|
305 | TEST_EXPECT_EQUAL(fresh.make_unique_key(""), ".2"); |
---|
306 | } |
---|
307 | |
---|
308 | // ------------------------------------------------------------ |
---|
309 | |
---|
310 | #include <arb_error.h> |
---|
311 | #include <ErrorOrType.h> |
---|
312 | |
---|
313 | static const char *SOME_ERROR = "whatever"; |
---|
314 | |
---|
315 | #if defined(ASSERTION_USED) |
---|
316 | |
---|
317 | static void drop_unused_ARB_ERROR() { |
---|
318 | ARB_ERROR e0; |
---|
319 | } |
---|
320 | static void drop_ARB_ERROR() { |
---|
321 | ARB_ERROR e1 = SOME_ERROR; |
---|
322 | } |
---|
323 | static void overwrite_ARB_ERROR() { |
---|
324 | ARB_ERROR e1 = SOME_ERROR; |
---|
325 | ARB_ERROR e2 = SOME_ERROR; |
---|
326 | |
---|
327 | e1 = e2; // expect this command to trigger assertion |
---|
328 | ARB_SIGSEGV(true); // -> this is never reached |
---|
329 | } |
---|
330 | |
---|
331 | #endif |
---|
332 | |
---|
333 | static ARB_ERROR forwardError(ARB_ERROR err) { |
---|
334 | return err; |
---|
335 | } |
---|
336 | static ARB_ERROR annotateError(ARB_ERROR err) { |
---|
337 | if (err) { |
---|
338 | ARB_ERROR ann_err = GBS_global_string("annotated '%s'", err.deliver()); |
---|
339 | err = ann_err; |
---|
340 | } |
---|
341 | return err; |
---|
342 | } |
---|
343 | |
---|
344 | void TEST_misuse_ARB_ERROR_crashtest() { |
---|
345 | TEST_EXPECT_CODE_ASSERTION_FAILS(drop_unused_ARB_ERROR); |
---|
346 | TEST_EXPECT_CODE_ASSERTION_FAILS(drop_ARB_ERROR); |
---|
347 | TEST_EXPECT_CODE_ASSERTION_FAILS(overwrite_ARB_ERROR); |
---|
348 | } |
---|
349 | void TEST_ARB_ERROR() { |
---|
350 | // unused error: |
---|
351 | { |
---|
352 | ARB_ERROR e0; |
---|
353 | TEST_EXPECT_NULL(e0.deliver()); |
---|
354 | } |
---|
355 | |
---|
356 | // simple error delivery: |
---|
357 | { |
---|
358 | ARB_ERROR e1 = SOME_ERROR; |
---|
359 | TEST_EXPECT_EQUAL(e1.deliver(), SOME_ERROR); |
---|
360 | } |
---|
361 | |
---|
362 | // deliver reassigned error (copy ctor): |
---|
363 | { |
---|
364 | ARB_ERROR e1 = SOME_ERROR; |
---|
365 | ARB_ERROR e2(e1); |
---|
366 | TEST_EXPECT_EQUAL(e2.deliver(), SOME_ERROR); |
---|
367 | } |
---|
368 | // deliver reassigned error (also copy ctor): |
---|
369 | { |
---|
370 | ARB_ERROR e1 = SOME_ERROR; |
---|
371 | ARB_ERROR e2 = e1; // assign in definition == copy-ctor |
---|
372 | TEST_EXPECT_EQUAL(e2.deliver(), SOME_ERROR); |
---|
373 | } |
---|
374 | // deliver reassigned error (op=): |
---|
375 | { |
---|
376 | ARB_ERROR e1 = SOME_ERROR; |
---|
377 | ARB_ERROR e2; |
---|
378 | e2 = e1; // real assignment |
---|
379 | TEST_EXPECT_EQUAL(e2.deliver(), SOME_ERROR); |
---|
380 | } |
---|
381 | |
---|
382 | // deliver error forwarded through function: |
---|
383 | { |
---|
384 | ARB_ERROR e0; |
---|
385 | ARB_ERROR e1 = SOME_ERROR; |
---|
386 | ARB_ERROR f0 = forwardError(e0); |
---|
387 | ARB_ERROR f1 = forwardError(e1); |
---|
388 | TEST_EXPECT_NULL(f0.deliver()); |
---|
389 | TEST_EXPECT_EQUAL(f1.deliver(), SOME_ERROR); |
---|
390 | } |
---|
391 | // forward and annotate error: |
---|
392 | { |
---|
393 | ARB_ERROR e0; |
---|
394 | ARB_ERROR e1 = SOME_ERROR; |
---|
395 | ARB_ERROR a0 = annotateError(e0); |
---|
396 | ARB_ERROR a1 = annotateError(e1); |
---|
397 | TEST_EXPECT_NULL(a0.deliver()); |
---|
398 | TEST_EXPECT_EQUAL(a1.deliver(), "annotated 'whatever'"); |
---|
399 | } |
---|
400 | } |
---|
401 | |
---|
402 | typedef ErrorOr<int> ErrorOrInt; |
---|
403 | |
---|
404 | #if defined(ASSERTION_USED) |
---|
405 | |
---|
406 | static void drop_ErrorOr0() { |
---|
407 | ErrorOrInt e(NULp, 42); |
---|
408 | } |
---|
409 | static void drop_ErrorOr1() { |
---|
410 | ErrorOrInt e(SOME_ERROR, 0); |
---|
411 | } |
---|
412 | static void retrieve_unchecked_ErrorOr0() { |
---|
413 | ErrorOrInt e(NULp, 21); |
---|
414 | int v = e.getValue(); // getValue w/o previous mandatory hasError |
---|
415 | TEST_EXPECT_EQUAL(v, 21); |
---|
416 | } |
---|
417 | static void retrieve_unchecked_ErrorOr1() { |
---|
418 | ErrorOrInt e(SOME_ERROR, 0); |
---|
419 | ARB_ERROR ae = e.getError(); // getError w/o previous mandatory hasError |
---|
420 | TEST_REJECT_NULL(ae.deliver()); |
---|
421 | } |
---|
422 | |
---|
423 | #endif |
---|
424 | |
---|
425 | static ErrorOrInt generateErrorOr(int i) { |
---|
426 | return ErrorOrInt(NULp, i); |
---|
427 | } |
---|
428 | static ErrorOrInt generateErrorOr(const char *msg) { |
---|
429 | return ErrorOrInt(msg, -1); |
---|
430 | } |
---|
431 | |
---|
432 | void TEST_misuse_ErrorOr_crashtest() { |
---|
433 | TEST_EXPECT_CODE_ASSERTION_FAILS(drop_ErrorOr0); |
---|
434 | TEST_EXPECT_CODE_ASSERTION_FAILS(drop_ErrorOr1); |
---|
435 | TEST_EXPECT_CODE_ASSERTION_FAILS(retrieve_unchecked_ErrorOr0); |
---|
436 | TEST_EXPECT_CODE_ASSERTION_FAILS(retrieve_unchecked_ErrorOr1); |
---|
437 | } |
---|
438 | void TEST_ErrorOr() { |
---|
439 | // simple uses (create, check, use + destroy): |
---|
440 | { |
---|
441 | ErrorOrInt e(SOME_ERROR, 0); |
---|
442 | TEST_EXPECT(e.hasError()); |
---|
443 | TEST_EXPECT_EQUAL(e.getError().deliver(), SOME_ERROR); |
---|
444 | } |
---|
445 | { |
---|
446 | ErrorOrInt v(NULp, 7); |
---|
447 | TEST_EXPECT(v.hasValue()); |
---|
448 | TEST_EXPECT_EQUAL(v.getValue(), 7); |
---|
449 | } |
---|
450 | |
---|
451 | // test copy-construction: |
---|
452 | { |
---|
453 | ErrorOrInt e(SOME_ERROR, 0); |
---|
454 | ErrorOrInt c = e; |
---|
455 | TEST_EXPECT(c.hasError()); |
---|
456 | TEST_EXPECT_EQUAL(c.getError().deliver(), SOME_ERROR); |
---|
457 | } |
---|
458 | { |
---|
459 | ErrorOrInt v(NULp, 17); |
---|
460 | ErrorOrInt c = v; |
---|
461 | TEST_EXPECT(c.hasValue()); |
---|
462 | TEST_EXPECT_EQUAL(c.getValue(), 17); |
---|
463 | } |
---|
464 | { |
---|
465 | ErrorOrInt v = generateErrorOr(17); |
---|
466 | TEST_EXPECT(v.hasValue()); |
---|
467 | TEST_EXPECT_EQUAL(v.getValue(), 17); |
---|
468 | } |
---|
469 | { |
---|
470 | ErrorOrInt e = generateErrorOr(SOME_ERROR); |
---|
471 | TEST_EXPECT(e.hasError()); |
---|
472 | TEST_EXPECT_EQUAL(e.getError().deliver(), SOME_ERROR); |
---|
473 | } |
---|
474 | } |
---|
475 | |
---|
476 | #endif // UNIT_TESTS |
---|
477 | |
---|
478 | // -------------------------------------------------------------------------------- |
---|
479 | |
---|