Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
branch-case-test.cpp
Go to the documentation of this file.
1/*
2 BranchCase(Test) - verify parsing textual specifications
3
4 Copyright (C)
5 2024, Hermann Vosseler <Ichthyostega@web.de>
6
7  **Lumiera** is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version. See the file COPYING for further details.
11
12* *****************************************************************/
13
20#include "lib/test/run.hpp"
21//#include "lib/test/test-helper.hpp"
23#include "lib/branch-case.hpp"
24#include "lib/format-obj.hpp"
26
27
28namespace lib {
29namespace test{
30
31
32 /********************************************************/
37 class BranchCase_test : public Test
38 {
39
40 virtual void
41 run (Arg)
42 {
46 }
47
48
50 void
52 {
53 using Branch = BranchCase<char,ushort>;
54 Branch branch{1, 42}; // construct for second branch (#1) to hold ushort(42)
55 CHECK (1 == branch.selected());
56 CHECK (42 == branch.get<1>()); // direct access with known branch-nr
57 CHECK ('*' == branch.get<0>()); // Warning: no protection against accessing the wrong branch
58
59 int val{-5};
60 auto visitor = [&](auto& it){ val = it;};
61 branch.accept (visitor);
62 CHECK (42 == val);
63 }
64
65
70 void
72 {
73 using Branch = BranchCase<ushort,double>;
74 CHECK (sizeof(double)+sizeof(size_t) <= sizeof(Branch));
75 CHECK (sizeof(double) == Branch::SIZ);
76
77 double phi{(1+sqrt(5))/2};
78 Branch b1{1,phi};
79 CHECK (1 == b1.selected());
80 CHECK (phi == b1.get<1>());
81
82 auto p = reinterpret_cast<size_t*> (&b1);
83 CHECK (1 == *p);
84 CHECK (phi == * reinterpret_cast<double*>(p+1));
85
86 // force-place a differently constructed object at the same location
87 new(p) Branch{0,42};
88 CHECK (0 == b1.selected());
89 CHECK (42 == b1.get<0>());
90 CHECK (0 == *p);
91 CHECK (42 == * reinterpret_cast<ushort*>(p+1));
92 }
93
94
95
99 void
101 {
102 using Branch = BranchCase<char,string>;
103 CHECK (sizeof(string)+sizeof(size_t) <= sizeof(Branch));
104
105 // use generic to-String visitor to display contents
106 auto render = [](auto const& it) -> string { return util::toString(it); };
107
108 Branch b1{1, "evil"};
109 CHECK ( 1 == b1.TOP );
110 CHECK ( 1 == b1.selected());
111 CHECK ("evil" == b1.get<1>());
112 CHECK ("evil" == b1.accept(render));
113
114 Branch b2{0,42};
115 CHECK ( 0 == b2.selected());
116 CHECK ('*' == b2.get<0>());
117 CHECK ("*" == b2.accept(render));
118
119 Branch b3{b1};
120 CHECK (1 == b3.selected());
121 CHECK ("evil" == b3.accept(render));
122
123 b3 = b2;
124 CHECK ( 0 == b3.selected());
125 CHECK ("*" == b3.accept(render));
126 CHECK ("*" == b2.accept(render));
127 CHECK ("evil" == b1.accept(render));
128
129 b3 = move(b1);
130 CHECK ( 1 == b3.selected() );
131 CHECK ( 0 == b2.selected() );
132 CHECK ("evil" == b3.accept(render));
133 CHECK ("*" == b2.accept(render));
134 CHECK ("" == b1.accept(render)); // ◁——————————— warning: moved-away string is "implementation defined"
135
136 swap (b3,b2);
137 CHECK ( 0 == b3.selected());
138 CHECK ( 1 == b2.selected());
139 CHECK ("*" == b3.accept(render));
140 CHECK ("evil" == b2.accept(render));
141 CHECK ("" == b1.accept(render));
142
143 //_______________________________
144 // verify proper payload lifecycle
145 seedRand();
146 Dummy::checksum() = 0;
147 { // track instances by checksum...
148 Dummy dummy;
149 auto rr = dummy.getVal();
150 CHECK (rr == Dummy::checksum());
151 CHECK (rr > 0);
152
153 using BB = BranchCase<string,Dummy>;
154 BB bb1{1, dummy};
155 CHECK (bb1.get<1>().getVal() == rr);
156 CHECK (2*rr == Dummy::checksum()); // got two instances due to copy-init
157
158 BB bb2{0, "dummy"};
159 CHECK (2*rr == Dummy::checksum());
160
161 swap (bb1,bb2);
162 CHECK (bb1.get<0>() == "dummy");
163 CHECK (bb2.get<1>().getVal() == rr);
164 CHECK (2*rr == Dummy::checksum());
165
166 bb1 = bb2;
167 CHECK (bb1.get<1>().getVal() == rr);
168 CHECK (3*rr == Dummy::checksum()); // assignment by copy
169
170 bb2 = move(bb1); // move-assignment
171 CHECK (2*rr == Dummy::checksum()); // existing instance destroyed properly
172 CHECK (bb2.get<1>().getVal() == rr);
173 CHECK (bb1.get<1>().getVal() == Dummy::DEFUNCT);
174
175 bb2 = BB{1,Dummy()}; // wipes out the other copy
176 auto rr2 = bb2.get<1>().getVal(); // but implants a different one
177 CHECK (rr+rr2 == Dummy::checksum());
178 CHECK (rr == dummy.getVal());
179 }// leave scope: invoke dtors here
180
181 CHECK (0 == Dummy::checksum());
182 }
183 };
184
185 LAUNCHER (BranchCase_test, "unit common");
186
187
188}} // namespace lib::test
189
A Sum Type (variant) to capture values from a branched evaluation.
A Sum Type to hold alternative results from a branched evaluation.
A Dummy object for tests.
static constexpr int DEFUNCT
static long & checksum()
Helpers typically used while writing tests.
Simple functions to represent objects, for debugging and diagnostics.
unsigned short int ushort
Definition integral.hpp:34
Implementation namespace for support and library code.
Test runner and basic definitions for tests.
std::string toString(TY const &val) noexcept
get some string representation of any object, reliably.
Simplistic test class runner.
#define LAUNCHER(_TEST_CLASS_, _GROUPS_)
Definition run.hpp:116
unittest helper code: test dummy objects to track instances.