FlagSet_test.cc
Go to the documentation of this file.
1 /**
2  * @file FlagSet_test.cc
3  * @brief Test for the util::flags::FlagSet class
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  * @date January 25, 2017
6  *
7  *
8  */
9 
10 // Boost libraries
11 /*
12  * Boost: define the name of the module;
13  * and do that before the inclusion of Boost unit test headers
14  * because it will change what they provide.
15  * Among the those, there is a main() function and some wrapping catching
16  * unhandled exceptions and considering them test failures, and probably more.
17  * This also makes fairly complicate to receive parameters from the command line
18  * (for example, a random seed).
19  */
20 #define BOOST_TEST_MODULE ( trajectorypointflags_test )
21 #include "boost/test/unit_test.hpp"
22 
23 // LArSoft libraries
25 
26 // C/C++ standard library
27 #include <set>
28 #include <array>
29 #include <algorithm> // std::copy()
30 #include <iostream> // std::cout
31 
32 //------------------------------------------------------------------------------
33 
34 namespace MyFlags {
35 
36  using Storage_t = unsigned short;
38 
39  constexpr MyFlag_t F0 { 0 };
40  constexpr MyFlag_t F1 { 1 };
41  constexpr MyFlag_t F2 { 2 };
42  constexpr MyFlag_t F3 { 3 };
43  constexpr MyFlag_t F4 { 4 };
44  constexpr MyFlag_t F5 { 5 };
45  constexpr MyFlag_t F6 { 6 };
46  constexpr MyFlag_t F7 { 7 };
47  constexpr MyFlag_t F8 [[gnu::unused]] { 8 };
48 
49 } // namespace MyFlags
50 
51 
52 template <typename FlagSet>
54  FlagSet const& flags,
55  std::set<typename FlagSet::Flag_t> const& defined,
56  std::set<typename FlagSet::Flag_t> const& set
57 ) {
58 
59  using FlagIndex_t = typename FlagSet::FlagIndex_t;
60  using Flag_t = typename FlagSet::Flag_t;
61 
62  for (FlagIndex_t i = 0; i <= flags.capacity(); ++i) {
63 
64  Flag_t flag { i };
65 
66  BOOST_TEST_MESSAGE(" flag #" << i);
67 
68  bool const isFlag = (i < flags.size());
69  bool const isDefined = (defined.count(i) > 0);
70  bool const isSet = (set.count(i) > 0);
71 
72  BOOST_TEST(flags.isFlag(i) == isFlag);
73  BOOST_TEST(flags.isFlag(flag) == isFlag);
74 
75  // In fact, the fact that the flag is not supported does not mean it can't
76  // be used. But not with test().
77  if (!isFlag) {
78  BOOST_CHECK_THROW(flags.test(i), typename FlagSet::OutOfRangeError);
79  BOOST_CHECK_THROW(flags.test(flag), typename FlagSet::OutOfRangeError);
80  continue;
81  }
82  else if (!isDefined) {
83  BOOST_CHECK_THROW(flags.test(i), typename FlagSet::FlagNotDefinedError);
84  BOOST_CHECK_THROW
85  (flags.test(flag), typename FlagSet::FlagNotDefinedError);
86  }
87  else {
88  BOOST_TEST(flags.test(i) == isSet);
89  BOOST_TEST(flags.test(flag) == isSet);
90  }
91 
92  BOOST_TEST(flags.isUndefined(i) == !isDefined);
93  BOOST_TEST(flags.isDefined(i) == isDefined);
94  BOOST_TEST(flags.isUndefined(flag) == !isDefined);
95  BOOST_TEST(flags.isDefined(flag) == isDefined);
96 
97  if (isDefined) {
98  // if the flag is undefined, so it the result of get()
99  BOOST_TEST(flags.get(i) == isSet);
100  BOOST_TEST(flags.get(flag) == isSet);
101 
102  BOOST_TEST(flags.isSet(i) == isSet);
103  BOOST_TEST(flags.isUnset(i) == !isSet);
104  BOOST_TEST(flags.isSet(flag) == isSet);
105  BOOST_TEST(flags.isUnset(flag) == !isSet);
106  }
107  else {
108  BOOST_TEST(!flags.isSet(i));
109  BOOST_TEST(!flags.isUnset(i));
110  BOOST_TEST(!flags.isSet(flag));
111  BOOST_TEST(!flags.isUnset(flag));
112  }
113  } // for
114 
115 } // CheckFlags()
116 
117 
118 //------------------------------------------------------------------------------
119 //--- Test code
120 //
121 
123 
124  // make sure the object is aware of having allocated flags enough
125  static_assert(util::flags::FlagSet<4U>::capacity() >= 4,
126  "Capacity mismatch for util::flags::FlagSet<4U>");
127  static_assert(util::flags::FlagSet<8U>::capacity() >= 8,
128  "Capacity mismatch for util::flags::FlagSet<8U>");
129  static_assert(util::flags::FlagSet<12U>::capacity() >= 12,
130  "Capacity mismatch for util::flags::FlagSet<12U>");
131  static_assert(util::flags::FlagSet<16U>::capacity() >= 16,
132  "Capacity mismatch for util::flags::FlagSet<16U>");
133  static_assert(util::flags::FlagSet<32U>::capacity() >= 32,
134  "Capacity mismatch for util::flags::FlagSet<32U>");
135 
136  // make sure the object is as small as possible
137  static_assert(sizeof(util::flags::FlagSet<4U>) == 2, // ideally it would be 1
138  "Capacity mismatch for util::flags::FlagSet<4U>");
139  static_assert(sizeof(util::flags::FlagSet<8U>) == 2,
140  "Capacity mismatch for util::flags::FlagSet<8U>");
141  static_assert(sizeof(util::flags::FlagSet<12U>) == 4, // ideally it would be 3
142  "Capacity mismatch for util::flags::FlagSet<12U>");
143  static_assert(sizeof(util::flags::FlagSet<16U>) == 4,
144  "Capacity mismatch for util::flags::FlagSet<16U>");
145  static_assert(sizeof(util::flags::FlagSet<32U>) == 8,
146  "Capacity mismatch for util::flags::FlagSet<32U>");
147 
148 
150 
151  constexpr FlagSet_t flags0;
152  static_assert(flags0.size() == 7U, "Invalid size.");
153 
154  static_assert(!flags0.isDefined(MyFlags::F0), "Unexpected flag #0 definition.");
155  static_assert(!flags0.isDefined(MyFlags::F1), "Unexpected flag #1 definition.");
156  static_assert(!flags0.isDefined(MyFlags::F2), "Unexpected flag #2 definition.");
157  static_assert(!flags0.isDefined(MyFlags::F3), "Unexpected flag #3 definition.");
158  static_assert(!flags0.isDefined(MyFlags::F4), "Unexpected flag #4 definition.");
159  static_assert(!flags0.isDefined(MyFlags::F5), "Unexpected flag #5 definition.");
160  static_assert(!flags0.isDefined(MyFlags::F6), "Unexpected flag #6 definition.");
161  static_assert(!flags0.isDefined(MyFlags::F7), "Unexpected flag #7 definition.");
162  static_assert(!flags0.isSet(MyFlags::F0), "Unexpected flag #0 value.");
163  static_assert(!flags0.isSet(MyFlags::F1), "Unexpected flag #1 value.");
164  static_assert(!flags0.isSet(MyFlags::F2), "Unexpected flag #2 value.");
165  static_assert(!flags0.isSet(MyFlags::F3), "Unexpected flag #3 value.");
166  static_assert(!flags0.isSet(MyFlags::F4), "Unexpected flag #4 value.");
167  static_assert(!flags0.isSet(MyFlags::F5), "Unexpected flag #5 value.");
168  static_assert(!flags0.isSet(MyFlags::F6), "Unexpected flag #6 value.");
169  static_assert(!flags0.isSet(MyFlags::F7), "Unexpected flag #7 value.");
170  static_assert(!flags0.isUnset(MyFlags::F0), "Unexpected flag #0 value.");
171  static_assert(!flags0.isUnset(MyFlags::F1), "Unexpected flag #1 value.");
172  static_assert(!flags0.isUnset(MyFlags::F2), "Unexpected flag #2 value.");
173  static_assert(!flags0.isUnset(MyFlags::F3), "Unexpected flag #3 value.");
174  static_assert(!flags0.isUnset(MyFlags::F4), "Unexpected flag #4 value.");
175  static_assert(!flags0.isUnset(MyFlags::F5), "Unexpected flag #5 value.");
176  static_assert(!flags0.isUnset(MyFlags::F6), "Unexpected flag #6 value.");
177  static_assert(!flags0.isUnset(MyFlags::F7), "Unexpected flag #7 value.");
178 
179  constexpr FlagSet_t flags1(MyFlags::F7, MyFlags::F6);
180  static_assert(flags1.size() == 7U, "Invalid size.");
181 
182  static_assert(!flags1.isDefined(MyFlags::F0), "Unexpected flag #0 definition.");
183  static_assert(!flags1.isDefined(MyFlags::F1), "Unexpected flag #1 definition.");
184  static_assert(!flags1.isDefined(MyFlags::F2), "Unexpected flag #2 definition.");
185  static_assert(!flags1.isDefined(MyFlags::F3), "Unexpected flag #3 definition.");
186  static_assert(!flags1.isDefined(MyFlags::F4), "Unexpected flag #4 definition.");
187  static_assert(!flags1.isDefined(MyFlags::F5), "Unexpected flag #5 definition.");
188  static_assert( flags1.isDefined(MyFlags::F6), "Unexpected flag #6 definition.");
189  static_assert( flags1.isDefined(MyFlags::F7), "Unexpected flag #7 definition.");
190  static_assert(!flags1.isSet(MyFlags::F0), "Unexpected flag #0 value.");
191  static_assert(!flags1.isSet(MyFlags::F1), "Unexpected flag #1 value.");
192  static_assert(!flags1.isSet(MyFlags::F2), "Unexpected flag #2 value.");
193  static_assert(!flags1.isSet(MyFlags::F3), "Unexpected flag #3 value.");
194  static_assert(!flags1.isSet(MyFlags::F4), "Unexpected flag #4 value.");
195  static_assert(!flags1.isSet(MyFlags::F5), "Unexpected flag #5 value.");
196  static_assert( flags1.isSet(MyFlags::F6), "Unexpected flag #6 value.");
197  static_assert( flags1.isSet(MyFlags::F7), "Unexpected flag #7 value.");
198  static_assert(!flags1.isUnset(MyFlags::F0), "Unexpected flag #0 value.");
199  static_assert(!flags1.isUnset(MyFlags::F1), "Unexpected flag #1 value.");
200  static_assert(!flags1.isUnset(MyFlags::F2), "Unexpected flag #2 value.");
201  static_assert(!flags1.isUnset(MyFlags::F3), "Unexpected flag #3 value.");
202  static_assert(!flags1.isUnset(MyFlags::F4), "Unexpected flag #4 value.");
203  static_assert(!flags1.isUnset(MyFlags::F5), "Unexpected flag #5 value.");
204  static_assert(!flags1.isUnset(MyFlags::F6), "Unexpected flag #6 value.");
205  static_assert(!flags1.isUnset(MyFlags::F7), "Unexpected flag #7 value.");
206 
207 
208 
209 } // FlagSetStaticTest()
210 
211 
212 void FlagSetTest() {
213 
215  using Flag_t = FlagSet_t::Flag_t;
216 
217 
218  // the last flag is "unsupported"
219  // BUG the double brace syntax is required to work around clang bug 21629
220  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
221 // std::array<Flag_t, 3> const indices = { 4, MyFlags::F6, 7 };
222  std::array<Flag_t, 3> const indices = {{ 4, MyFlags::F6, 7 }};
223 
224  std::set<Flag_t> defined, set;
225 
226  BOOST_TEST_MESSAGE("Default construction");
227  FlagSet_t flags;
228  std::cout << " => " << flags << std::endl;
229  CheckFlags(flags, defined, set);
230 
231  BOOST_TEST_MESSAGE("Single bit set");
232  flags.set(1);
233  defined.insert(1);
234  set.insert(1);
235  std::cout << " => " << flags << std::endl;
236  CheckFlags(flags, defined, set);
237 
238  BOOST_TEST_MESSAGE("Two more bits set (one set again)");
239  flags.set(5, MyFlags::F7, MyFlags::F3, 1);
240  defined.insert(3);
241  defined.insert(5);
242  defined.insert(7);
243  set.insert(3);
244  set.insert(5);
245  set.insert(7);
246  std::cout << " => " << flags << std::endl;
247  CheckFlags(flags, defined, set);
248 
249  BOOST_TEST_MESSAGE("Bits set from a list of bits to set");
250  flags.rangeSet(indices.begin(), indices.end());
251  std::for_each(indices.begin(), indices.end(),
252  [&defined](auto flag){ defined.insert(flag); }
253  );
254  std::for_each
255  (indices.begin(), indices.end(), [&set](auto flag){ set.insert(flag); });
256  std::cout << " => " << flags << std::endl;
257  CheckFlags(flags, defined, set);
258 
259  BOOST_TEST_MESSAGE("Undefine bits");
260  flags.remove(2, 3, MyFlags::F4); // flag 2 was already not defined
261  defined.erase(3);
262  defined.erase(4);
263  set.erase(4);
264  std::cout << " => " << flags << std::endl;
265  CheckFlags(flags, defined, set);
266 
267  BOOST_TEST_MESSAGE("Unset bits");
268  flags.unset(MyFlags::F7, 5);
269  set.erase(7);
270  set.erase(5);
271  std::cout << " => " << flags << std::endl;
272  CheckFlags(flags, defined, set);
273 
274  BOOST_TEST_MESSAGE("Unset bit range");
275  flags.rangeUnset(indices.begin(), indices.end());
276  std::for_each(indices.begin(), indices.end(),
277  [&defined](auto flag){ defined.insert(flag); }
278  );
279  std::for_each(indices.begin(), indices.end(),
280  [&set](auto flag){ set.erase(flag); }
281  );
282  std::cout << " => " << flags << std::endl;
283  CheckFlags(flags, defined, set);
284 
285  flags.clear();
286  CheckFlags(flags, {}, {});
287  flags.set (MyFlags::F1);
288  flags.unset(MyFlags::F4);
289  flags.unset(MyFlags::F5);
290 
291  /*
292  * constexpr bool all(Bits_t bits) const
293  * constexpr bool any(Bits_t bits) const
294  * constexpr bool none(Bits_t bits) const
295  */
296 
297  // Reminder: undefined flags will always contribute a "false".
298  // flag 1 is set
299  BOOST_TEST( flags.all (MyFlags::F1));
300  BOOST_TEST( flags.any (MyFlags::F1));
301  BOOST_TEST(!flags.none(MyFlags::F1));
302 
303  // flag 1 is set, flag 4 is unset
304  BOOST_TEST(!flags.all (MyFlags::F1 + MyFlags::F4));
305  BOOST_TEST( flags.any (MyFlags::F1 + MyFlags::F4));
306  BOOST_TEST(!flags.none(MyFlags::F1 + MyFlags::F4));
307 
308  // flag 1 is set, flag 3 is undefined (had been defined and set though)
309  BOOST_TEST(!flags.all (MyFlags::F1 + MyFlags::F3));
310  BOOST_TEST( flags.any (MyFlags::F1 + MyFlags::F3));
311  BOOST_TEST(!flags.none(MyFlags::F1 + MyFlags::F3));
312 
313  // flag 4 is unset, flag 3 is undefined (had been defined though)
314  BOOST_TEST(!flags.all (MyFlags::F3 + MyFlags::F4));
315  BOOST_TEST(!flags.any (MyFlags::F3 + MyFlags::F4));
316  BOOST_TEST(!flags.none(MyFlags::F3 + MyFlags::F4));
317 
318  // flag 3 is undefined (had been defined though)
319  BOOST_TEST(!flags.all (MyFlags::F3));
320  BOOST_TEST(!flags.any (MyFlags::F3));
321  BOOST_TEST(!flags.none(MyFlags::F3));
322 
323  // flag 4 is unset
324  BOOST_TEST(!flags.all (MyFlags::F4));
325  BOOST_TEST(!flags.any (MyFlags::F4));
326  BOOST_TEST( flags.none(MyFlags::F4));
327 
328  /*
329  * constexpr bool anySet(Mask_t const& mask) const
330  * constexpr bool match(Mask_t const& mask) const
331  */
332  BOOST_TEST( flags.match (flags.mask()));
333  BOOST_TEST(!flags.match (flags.mask() - MyFlags::F6)); // also unset F6
334  BOOST_TEST(!flags.match (flags.mask() + MyFlags::F5)); // set F5
335  BOOST_TEST(!flags.match (flags.mask() + MyFlags::F6)); // also set F6
336  BOOST_TEST(!flags.match (flags.mask() - MyFlags::F1 + MyFlags::F6));
337  BOOST_TEST( flags.anySet (flags.mask()));
338  BOOST_TEST( flags.anySet (flags.mask() - MyFlags::F6));
339  BOOST_TEST( flags.anySet (flags.mask() + MyFlags::F5));
340  BOOST_TEST( flags.anySet (flags.mask() + MyFlags::F6));
341  BOOST_TEST(!flags.anySet (flags.mask() - MyFlags::F1 + MyFlags::F6));
342  BOOST_TEST(!flags.noneSet(flags.mask()));
343  BOOST_TEST(!flags.noneSet(flags.mask() - MyFlags::F6));
344  BOOST_TEST(!flags.noneSet(flags.mask() + MyFlags::F5));
345  BOOST_TEST(!flags.noneSet(flags.mask() + MyFlags::F6));
346  BOOST_TEST( flags.noneSet(flags.mask() - MyFlags::F1 + MyFlags::F6));
347 
348 } // FlagSetTest()
349 
350 
351 //------------------------------------------------------------------------------
353 
354  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
355  using MyMask_t = util::flags::BitMask<unsigned int>;
356  constexpr MyMask_t DefaultMask [[maybe_unused]] (MyMask_t::fromValues, 0x0300U);
357  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
358 
359 } // BitMaskDocTest_ConstructorFromValues1()
360 
361 
363 
364  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
365  using MyMask_t = util::flags::BitMask<unsigned int>;
366  constexpr MyMask_t DefaultMask [[maybe_unused]] (MyMask_t::fromValues, 0x0300U, 0x0200U);
367  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
368 
369 } // BitMaskDocTest_ConstructorFromValues2()
370 
371 
373 
376 
377 } // BitMaskDocTest()
378 
379 
380 //------------------------------------------------------------------------------
381 
383 
385 
386  constexpr Mask_t maskA(Mask_t::fromValues, 0b011'011'011, 0b001'001'001);
387  constexpr Mask_t maskB(Mask_t::fromValues, 0b000'111'111, 0b000'000'111);
388  constexpr Mask_t::Bits_t bitsB (0b000'000'111);
389 
390  /*
391  * constexpr mergeIntoMask(Mask_t baseMask, Mask_t mask)
392  */
393  constexpr Mask_t maskMAB(Mask_t::fromValues, 0b011'111'111, 0b001'000'111);
394  static_assert(Mask_t::mergeIntoMask(maskA, maskB) == maskMAB,
395  "mergeIntoMask(Mask_t, Mask_t) failure");
396  static_assert
397  (maskA + maskB == maskMAB, "maskA + maskB failure");
398 
399  constexpr Mask_t maskMBA(Mask_t::fromValues, 0b011'111'111, 0b001'001'101);
400  static_assert(Mask_t::mergeIntoMask(maskB, maskA) == maskMBA,
401  "mergeIntoMask(Mask_t, Mask_t) failure");
402  static_assert
403  (maskB + maskA == maskMBA, "maskB + maskA failure");
404 
405  /*
406  * mergeIntoMask(Mask_t baseMask, Bits_t bits)
407  */
408  constexpr Mask_t maskMAbB(Mask_t::fromValues, 0b011'011'111, 0b001'001'111);
409  static_assert(Mask_t::mergeIntoMask(maskA, bitsB) == maskMAbB,
410  "mergeIntoMask(Mask_t, Bits_t) failure");
411  static_assert
412  (maskA + bitsB == maskMAbB, "maskA + bitsB failure");
413 
414  constexpr Mask_t maskMbBA(Mask_t::fromValues, 0b011'011'111, 0b001'001'101);
415  static_assert(bitsB + maskA == maskMbBA, "bitsB + maskA failure");
416 
417  /*
418  * combineWithMask(Mask_t A, Mask_t B)
419  */
420  constexpr Mask_t maskCAB(Mask_t::fromValues, 0b011'111'111, 0b001'001'111);
421  static_assert(Mask_t::combineWithMask(maskA, maskB) == maskCAB,
422  "combineWithMask(Mask_t, Mask_t) failure");
423  static_assert
424  ((maskA | maskB) == maskCAB, "maskA | maskB failure");
425 
426  constexpr Mask_t maskCBA(Mask_t::fromValues, 0b011'111'111, 0b001'001'111);
427  static_assert(Mask_t::combineWithMask(maskB, maskA) == maskCBA,
428  "combineWithMask(Mask_t, Mask_t) failure");
429  static_assert
430  ((maskB | maskA) == maskCBA, "maskB | maskA failure");
431 
432  /*
433  * combineWithMask(Mask_t mask, Bits_t bits)
434  */
435  constexpr Mask_t maskCAbB(Mask_t::fromValues, 0b011'011'111, 0b001'001'111);
436  static_assert(Mask_t::combineWithMask(maskA, bitsB) == maskCAbB,
437  "combineWithMask(Mask_t, Bits_t) failure");
438  static_assert
439  ((maskA | bitsB) == maskCAbB, "maskA | bitsB failure");
440 
441  constexpr Mask_t maskCbBA(Mask_t::fromValues, 0b011'011'111, 0b001'001'111);
442  static_assert
443  ((bitsB | maskA) == maskCbBA, "bitsB | maskA failure");
444 
445  /*
446  * intersectWithMask(Mask_t A, Mask_t B)
447  */
448  constexpr Mask_t maskIAB(Mask_t::fromValues, 0b011'111'111, 0b001'000'101);
449  static_assert(Mask_t::intersectWithMask(maskA, maskB) == maskIAB,
450  "intersectWithMask(Mask_t, Mask_t) failure");
451  static_assert((maskA & maskB) == maskIAB, "maskA & maskB failure");
452 
453  constexpr Mask_t maskIBA(Mask_t::fromValues, 0b011'111'111, 0b001'000'101);
454  static_assert(Mask_t::intersectWithMask(maskB, maskA) == maskIBA,
455  "intersectWithMask(Mask_t, Mask_t) failure");
456  static_assert((maskB & maskA) == maskIBA, "maskB & maskA failure");
457 
458  /*
459  * intersectWithMask(Mask_t mask, Bits_t bits)
460  */
461  constexpr Mask_t maskIAbB(Mask_t::fromValues, 0b011'011'111, 0b001'001'101);
462  static_assert(Mask_t::intersectWithMask(maskA, bitsB) == maskIAbB,
463  "intersectWithMask(Mask_t, Bits_t) failure");
464  static_assert
465  ((maskA & bitsB) == maskIAbB, "maskA & bitsB failure");
466 
467  constexpr Mask_t maskIbBA(Mask_t::fromValues, 0b011'011'111, 0b001'001'101);
468  static_assert((bitsB & maskA) == maskIbBA, "bitsB & maskA failure");
469 
470  /*
471  * unsetMask(Mask_t A, Mask_t B)
472  */
473  constexpr Mask_t maskUAB(Mask_t::fromValues, 0b011'111'111, 0b001'001'000);
474  static_assert(Mask_t::unsetMask(maskA, maskB) == maskUAB,
475  "unsetMask(Mask_t, Mask_t) failure");
476  static_assert((maskA - maskB) == maskUAB, "maskA - maskB failure");
477 
478  constexpr Mask_t maskUBA(Mask_t::fromValues, 0b011'111'111, 0b000'000'110);
479  static_assert(Mask_t::unsetMask(maskB, maskA) == maskUBA,
480  "unsetMask(Mask_t, Mask_t) failure");
481  static_assert((maskB - maskA) == maskUBA, "maskB - maskA failure");
482 
483  /*
484  * unsetMask(Mask_t mask, Bits_t bits)
485  */
486  constexpr Mask_t maskUAbB(Mask_t::fromValues, 0b011'011'111, 0b001'001'000);
487  static_assert(Mask_t::unsetMask(maskA, bitsB) == maskUAbB,
488  "unsetMask(Mask_t, Bits_t) failure");
489  static_assert((maskA - bitsB) == maskUAbB, "maskA - bitsB failure");
490 
491  constexpr Mask_t maskUbBA(Mask_t::fromValues, 0b011'011'111, 0b000'000'110);
492  static_assert((bitsB - maskA) == maskUbBA, "bitsB - maskA failure");
493 
494  /*
495  * negateMask(Mask_t mask)
496  */
497  constexpr Mask_t maskNA(Mask_t::fromValues, 0b011'011'011, 0b010'010'010);
498  static_assert
499  (Mask_t::negateMask(maskA) == maskNA, "negateMask(Mask_t) failure");
500  static_assert(~maskA == maskNA, "~mask failure");
501 
502  /*
503  * negateMask(Bits_t bits)
504  */
505  constexpr Mask_t maskNbB(Mask_t::fromValues, 0b000'000'111, 0b000'000'000);
506  static_assert
507  (Mask_t::negateMask(bitsB) == maskNbB, "negateMask(Bits_t) failure");
508 // static_assert(~bitsB == maskNbB, "~bits failure");
509 
510  /*
511  * unary operator+
512  */
513  constexpr Mask_t maskbB(Mask_t::fromValues, 0b000'000'111, 0b000'000'111);
514  static_assert(+maskA == maskA, "+mask failure");
515  static_assert(+bitsB == maskbB, "+bits failure");
516 
517  /*
518  * unary operator-
519  */
520  static_assert(maskA + (-bitsB) == maskA - bitsB, "-bits failure");
521 
522 
523 } // BitMaskCombineTests()
524 
525 
526 
527 //------------------------------------------------------------------------------
528 void SetUnsetTest() {
529 
531 
533 
534  std::cout << "Testing Set()/Unset() on " << mask << std::endl;
535 
536  BOOST_TEST(!mask.isDefined(0));
537  BOOST_TEST( mask.isDefined(1));
538  BOOST_TEST( mask.isDefined(2));
539  BOOST_TEST(!mask.isDefined(3));
540 
541  BOOST_TEST(!mask.isSet(0));
542  BOOST_TEST( mask.isSet(1));
543  BOOST_TEST(!mask.isSet(2));
544  BOOST_TEST(!mask.isSet(3));
545 
546  BOOST_TEST(!mask.isUnset(0));
547  BOOST_TEST(!mask.isUnset(1));
548  BOOST_TEST( mask.isUnset(2));
549  BOOST_TEST(!mask.isUnset(3));
550 
551 
552 } // SetUnsetTest()
553 
554 
555 //------------------------------------------------------------------------------
556 //--- registration of tests
557 
558 BOOST_AUTO_TEST_CASE(BitMaskTestCase) {
559 
561  BitMaskDocTest();
562 
563 } // BOOST_AUTO_TEST_CASE(FlagSetTestCase)
564 
565 
566 BOOST_AUTO_TEST_CASE(FlagSetTestCase) {
567 
569  FlagSetTest();
570  SetUnsetTest();
571 
572 } // BOOST_AUTO_TEST_CASE(FlagSetTestCase)
void BitMaskDocTest_ConstructorFromValues1()
constexpr MyFlag_t F8[[gnu::unused]]
Definition: FlagSet_test.cc:47
Type identifying a flag. Operations are implemented as free functions.
Definition: BitMask.h:89
BOOST_AUTO_TEST_CASE(BitMaskTestCase)
constexpr MyFlag_t F0
Definition: FlagSet_test.cc:39
constexpr MyFlag_t F4
Definition: FlagSet_test.cc:43
A class containing a set of flags.
Definition: FlagSet.h:41
void BitMaskDocTest_ConstructorFromValues2()
constexpr MyFlag_t F2
Definition: FlagSet_test.cc:41
Class holding flags.
A class containing a set of flags.
Definition: BitMask.h:420
constexpr BitMask< Storage > Set(Flag_t< Storage > flag)
Returns a bit mask which sets the specified flag.
void FlagSetStaticTest()
void BitMaskCombineTests()
constexpr std::array< std::size_t, geo::vect::dimension< Vector >)> indices()
Returns a sequence of indices valid for a vector of the specified type.
void SetUnsetTest()
constexpr MyFlag_t F5
Definition: FlagSet_test.cc:44
unsigned short Storage_t
Definition: FlagSet_test.cc:36
constexpr MyFlag_t F1
Definition: FlagSet_test.cc:40
constexpr MyFlag_t F6
Definition: FlagSet_test.cc:45
constexpr MyFlag_t F3
Definition: FlagSet_test.cc:42
constexpr MyFlag_t F7
Definition: FlagSet_test.cc:46
void CheckFlags(FlagSet const &flags, std::set< typename FlagSet::Flag_t > const &defined, std::set< typename FlagSet::Flag_t > const &set)
Definition: FlagSet_test.cc:53
void BitMaskDocTest()
constexpr BitMask< Storage > Unset(Flag_t< Storage > flag)
Returns a bit mask which unsets the specified flag.
QTextStream & endl(QTextStream &s)
void FlagSetTest()