Skip to content

Commit db54fd1

Browse files
committed
Some tests!
Also fixed some bugs in the process.
1 parent f7d6be1 commit db54fd1

File tree

4 files changed

+359
-1
lines changed

4 files changed

+359
-1
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,6 @@
1919
*.exe
2020
*.out
2121
*.app
22+
23+
# Test artefacts
24+
test/bin

include/flags/flags.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ template <class E> struct flags {
7575
flags &operator=(std::initializer_list<enum_type> il) noexcept {
7676
clear();
7777
insert(il);
78+
return *this;
7879
}
7980

8081
template <class ... Args>
@@ -84,7 +85,8 @@ template <class E> struct flags {
8485
template <class FwIter>
8586
flags(FwIter b, FwIter e,
8687
typename convertible<decltype(*b)>::type = nullptr)
87-
noexcept(insert(std::declval<FwIter>(), std::declval<FwIter>()))
88+
noexcept(noexcept(std::declval<flags>().insert(std::declval<FwIter>(),
89+
std::declval<FwIter>())))
8890
: val_(0)
8991
{ insert(b, e); }
9092

test/Jamroot

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import testing ;
2+
3+
project flags_tests
4+
: requirements <warnings>all
5+
<cxxflags>-std=c++11
6+
<include>../include/
7+
: default-build <variant>release
8+
;
9+
10+
11+
lib boost_utf
12+
:
13+
: <name>boost_unit_test_framework
14+
;
15+
16+
17+
unit-test main-test
18+
: main-test.cpp boost_utf
19+
: <define>BOOST_TEST_DYN_LINK
20+
<define>BOOST_TEST_MODULE=enum_flags
21+
;

test/main-test.cpp

Lines changed: 332 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,332 @@
1+
#include <flags/flags.hpp>
2+
3+
#include <vector>
4+
5+
#include <boost/test/unit_test.hpp>
6+
7+
8+
enum class Enum : int {One = 1, Two = 2, Four = 4, Eight = 8};
9+
ALLOW_FLAGS_FOR_ENUM(Enum)
10+
11+
using Enums = flags::flags<Enum>;
12+
13+
14+
BOOST_AUTO_TEST_CASE(set_underlying_value) {
15+
Enums result;
16+
constexpr int random_number = 87;
17+
result.set_underlying_value(random_number);
18+
BOOST_CHECK(random_number == result.underlying_value());
19+
}
20+
21+
22+
BOOST_AUTO_TEST_CASE(empty_constructor) {
23+
Enums null{flags::empty};
24+
BOOST_CHECK(0 == null.underlying_value());
25+
}
26+
27+
28+
BOOST_AUTO_TEST_CASE(enum_constructor_and_assignment) {
29+
BOOST_CHECK(1 == static_cast<int>(Enum::One));
30+
Enums one = Enum::One;
31+
BOOST_CHECK(1 == one.underlying_value());
32+
one = Enum::One;
33+
BOOST_CHECK(1 == one.underlying_value());
34+
35+
BOOST_CHECK(2 == static_cast<int>(Enum::Two));
36+
Enums two = Enum::Two;
37+
BOOST_CHECK(2 == two.underlying_value());
38+
two = Enum::Two;
39+
BOOST_CHECK(2 == two.underlying_value());
40+
}
41+
42+
43+
BOOST_AUTO_TEST_CASE(equality) {
44+
const Enums one = Enum::One;
45+
const Enums two = Enum::Two;
46+
47+
BOOST_CHECK(one == one);
48+
BOOST_CHECK(two == two);
49+
50+
BOOST_CHECK(two != one);
51+
BOOST_CHECK(one != two);
52+
}
53+
54+
55+
BOOST_AUTO_TEST_CASE(copy_move_swap) {
56+
const Enums one = Enum::One;
57+
58+
Enums copy_constructed = one;
59+
BOOST_CHECK(one == copy_constructed);
60+
61+
Enums copy_assigned = Enum::Two;
62+
BOOST_CHECK(one != copy_assigned);
63+
copy_assigned = one;
64+
BOOST_CHECK(one == copy_assigned);
65+
66+
Enums move_constructed = std::move(copy_constructed);
67+
BOOST_CHECK(one == move_constructed);
68+
69+
Enums move_assigned = Enum::Two;
70+
BOOST_CHECK(one != move_assigned);
71+
move_assigned = std::move(move_constructed);
72+
BOOST_CHECK(one == move_assigned);
73+
74+
Enums left = Enum::One, right = Enum::Two;
75+
swap(left, right);
76+
BOOST_CHECK((2 == left.underlying_value())
77+
&& (1 == right.underlying_value()));
78+
left.swap(right);
79+
BOOST_CHECK((1 == left.underlying_value())
80+
&& (2 == right.underlying_value()));
81+
}
82+
83+
84+
BOOST_AUTO_TEST_CASE(initializer_list_and_variadic_constructor) {
85+
Enums il_constructed{Enum::One, Enum::Four, Enum::Eight};
86+
BOOST_CHECK((1 | 4 | 8) == il_constructed.underlying_value());
87+
88+
Enums il_assigned;
89+
il_assigned = {Enum::Two, Enum::Four, Enum::Eight};
90+
BOOST_CHECK((2 | 4 | 8) == il_assigned.underlying_value());
91+
92+
Enums var_constructed(Enum::One, Enum::Two, Enum::Eight);
93+
BOOST_CHECK((1 | 2 | 8) == var_constructed.underlying_value());
94+
}
95+
96+
97+
BOOST_AUTO_TEST_CASE(iterator_constructor) {
98+
std::vector<Enum> vec = {Enum::Two, Enum::Four, Enum::Eight};
99+
Enums iter_constructed{std::begin(vec), std::end(vec)};
100+
BOOST_CHECK((2 | 4 | 8) == iter_constructed.underlying_value());
101+
}
102+
103+
104+
BOOST_AUTO_TEST_CASE(bool_conversion_and_negation) {
105+
const Enums one = Enum::One;
106+
BOOST_CHECK(one);
107+
108+
const Enums zero{flags::empty};
109+
BOOST_CHECK(!zero);
110+
111+
auto not_one = ~one;
112+
BOOST_CHECK(~1 == not_one.underlying_value());
113+
}
114+
115+
116+
BOOST_AUTO_TEST_CASE(bit_and) {
117+
const Enum zero = static_cast<Enum>(0),
118+
one = static_cast<Enum>(1);
119+
const Enums fzero = zero,
120+
fone = one;
121+
122+
Enums result = zero & zero;
123+
BOOST_CHECK(0 == result.underlying_value());
124+
result = zero & one;
125+
BOOST_CHECK(0 == result.underlying_value());
126+
result = one & zero;
127+
BOOST_CHECK(0 == result.underlying_value());
128+
result = one & one;
129+
BOOST_CHECK(1 == result.underlying_value());
130+
131+
result = zero & fzero;
132+
BOOST_CHECK(0 == result.underlying_value());
133+
result = zero & fone;
134+
BOOST_CHECK(0 == result.underlying_value());
135+
result = one & fzero;
136+
BOOST_CHECK(0 == result.underlying_value());
137+
result = one & fone;
138+
BOOST_CHECK(1 == result.underlying_value());
139+
140+
result = fzero & zero;
141+
BOOST_CHECK(0 == result.underlying_value());
142+
result = fzero & one;
143+
BOOST_CHECK(0 == result.underlying_value());
144+
result = fone & zero;
145+
BOOST_CHECK(0 == result.underlying_value());
146+
result = fone & one;
147+
BOOST_CHECK(1 == result.underlying_value());
148+
149+
result = fzero & fzero;
150+
BOOST_CHECK(0 == result.underlying_value());
151+
result = fzero & fone;
152+
BOOST_CHECK(0 == result.underlying_value());
153+
result = fone & fzero;
154+
BOOST_CHECK(0 == result.underlying_value());
155+
result = fone & fone;
156+
BOOST_CHECK(1 == result.underlying_value());
157+
158+
result = zero;
159+
result &= zero;
160+
BOOST_CHECK(0 == result.underlying_value());
161+
result = zero;
162+
result &= one;
163+
BOOST_CHECK(0 == result.underlying_value());
164+
result = one;
165+
result &= zero;
166+
BOOST_CHECK(0 == result.underlying_value());
167+
result = one;
168+
result &= one;
169+
BOOST_CHECK(1 == result.underlying_value());
170+
171+
result = zero;
172+
result &= fzero;
173+
BOOST_CHECK(0 == result.underlying_value());
174+
result = zero;
175+
result &= fone;
176+
BOOST_CHECK(0 == result.underlying_value());
177+
result = one;
178+
result &= fzero;
179+
BOOST_CHECK(0 == result.underlying_value());
180+
result = one;
181+
result &= fone;
182+
BOOST_CHECK(1 == result.underlying_value());
183+
}
184+
185+
186+
BOOST_AUTO_TEST_CASE(bit_or) {
187+
const Enum zero = static_cast<Enum>(0);
188+
const Enum one = static_cast<Enum>(1);
189+
const Enums fzero = zero,
190+
fone = one;
191+
192+
Enums result = zero | zero;
193+
BOOST_CHECK(0 == result.underlying_value());
194+
result = zero | one;
195+
BOOST_CHECK(1 == result.underlying_value());
196+
result = one | zero;
197+
BOOST_CHECK(1 == result.underlying_value());
198+
result = one | one;
199+
BOOST_CHECK(1 == result.underlying_value());
200+
201+
result = zero | fzero;
202+
BOOST_CHECK(0 == result.underlying_value());
203+
result = zero | fone;
204+
BOOST_CHECK(1 == result.underlying_value());
205+
result = one | fzero;
206+
BOOST_CHECK(1 == result.underlying_value());
207+
result = one | fone;
208+
BOOST_CHECK(1 == result.underlying_value());
209+
210+
result = fzero | zero;
211+
BOOST_CHECK(0 == result.underlying_value());
212+
result = fzero | one;
213+
BOOST_CHECK(1 == result.underlying_value());
214+
result = fone | zero;
215+
BOOST_CHECK(1 == result.underlying_value());
216+
result = fone | one;
217+
BOOST_CHECK(1 == result.underlying_value());
218+
219+
result = fzero | fzero;
220+
BOOST_CHECK(0 == result.underlying_value());
221+
result = fzero | fone;
222+
BOOST_CHECK(1 == result.underlying_value());
223+
result = fone | fzero;
224+
BOOST_CHECK(1 == result.underlying_value());
225+
result = fone | fone;
226+
BOOST_CHECK(1 == result.underlying_value());
227+
228+
result = zero;
229+
result |= zero;
230+
BOOST_CHECK(0 == result.underlying_value());
231+
result = zero;
232+
result |= one;
233+
BOOST_CHECK(1 == result.underlying_value());
234+
result = one;
235+
result |= zero;
236+
BOOST_CHECK(1 == result.underlying_value());
237+
result = one;
238+
result |= one;
239+
BOOST_CHECK(1 == result.underlying_value());
240+
241+
result = zero;
242+
result |= fzero;
243+
BOOST_CHECK(0 == result.underlying_value());
244+
result = zero;
245+
result |= fone;
246+
BOOST_CHECK(1 == result.underlying_value());
247+
result = one;
248+
result |= fzero;
249+
BOOST_CHECK(1 == result.underlying_value());
250+
result = one;
251+
result |= fone;
252+
BOOST_CHECK(1 == result.underlying_value());
253+
}
254+
255+
256+
BOOST_AUTO_TEST_CASE(bit_xor) {
257+
const Enum zero = static_cast<Enum>(0);
258+
const Enum one = static_cast<Enum>(1);
259+
const Enums fzero = zero,
260+
fone = one;
261+
262+
Enums result = zero ^ zero;
263+
BOOST_CHECK(0 == result.underlying_value());
264+
result = zero ^ one;
265+
BOOST_CHECK(1 == result.underlying_value());
266+
result = one ^ zero;
267+
BOOST_CHECK(1 == result.underlying_value());
268+
result = one ^ one;
269+
BOOST_CHECK(0 == result.underlying_value());
270+
271+
result = zero ^ fzero;
272+
BOOST_CHECK(0 == result.underlying_value());
273+
result = zero ^ fone;
274+
BOOST_CHECK(1 == result.underlying_value());
275+
result = one ^ fzero;
276+
BOOST_CHECK(1 == result.underlying_value());
277+
result = one ^ fone;
278+
BOOST_CHECK(0 == result.underlying_value());
279+
280+
result = fzero ^ zero;
281+
BOOST_CHECK(0 == result.underlying_value());
282+
result = fzero ^ one;
283+
BOOST_CHECK(1 == result.underlying_value());
284+
result = fone ^ zero;
285+
BOOST_CHECK(1 == result.underlying_value());
286+
result = fone ^ one;
287+
BOOST_CHECK(0 == result.underlying_value());
288+
289+
result = fzero ^ fzero;
290+
BOOST_CHECK(0 == result.underlying_value());
291+
result = fzero ^ fone;
292+
BOOST_CHECK(1 == result.underlying_value());
293+
result = fone ^ fzero;
294+
BOOST_CHECK(1 == result.underlying_value());
295+
result = fone ^ fone;
296+
BOOST_CHECK(0 == result.underlying_value());
297+
298+
result = zero;
299+
result ^= zero;
300+
BOOST_CHECK(0 == result.underlying_value());
301+
result = zero;
302+
result ^= one;
303+
BOOST_CHECK(1 == result.underlying_value());
304+
result = one;
305+
result ^= zero;
306+
BOOST_CHECK(1 == result.underlying_value());
307+
result = one;
308+
result ^= one;
309+
BOOST_CHECK(0 == result.underlying_value());
310+
311+
result = zero;
312+
result ^= fzero;
313+
BOOST_CHECK(0 == result.underlying_value());
314+
result = zero;
315+
result ^= fone;
316+
BOOST_CHECK(1 == result.underlying_value());
317+
result = one;
318+
result ^= fzero;
319+
BOOST_CHECK(1 == result.underlying_value());
320+
result = one;
321+
result ^= fone;
322+
BOOST_CHECK(0 == result.underlying_value());
323+
}
324+
325+
326+
BOOST_AUTO_TEST_CASE(bitset) {
327+
auto a_bitset = (Enum::Two | Enum::Four | Enum::Eight).to_bitset();
328+
BOOST_CHECK((2 | 4 | 8) == a_bitset.to_ulong());
329+
330+
a_bitset = (decltype(a_bitset))(Enum::One | Enum::Four | Enum::Eight);
331+
BOOST_CHECK((1 | 4 | 8) == a_bitset.to_ulong());
332+
}

0 commit comments

Comments
 (0)