Home | History | Annotate | Download | only in fs.enum
      1 #ifndef TEST_BITMASK_TYPE_HPP
      2 #define TEST_BITMASK_TYPE_HPP
      3 
      4 #include <type_traits>
      5 #include <cassert>
      6 
      7 #include "test_macros.h"
      8 
      9 
     10 template <class EnumType, EnumType Val1, EnumType Val2,
     11           class UT = typename std::underlying_type<EnumType>::type,
     12           UT UVal1 = static_cast<UT>(Val1),
     13           UT UVal2 = static_cast<UT>(Val2),
     14           UT UZero = static_cast<UT>(0),
     15           EnumType Zero = static_cast<EnumType>(0)
     16         >
     17 struct check_bitmask_type {
     18 
     19   static constexpr UT dcast(EnumType e) { return static_cast<UT>(e); }
     20   static constexpr UT unpromote(decltype((~UZero)) promoted) { return static_cast<UT>(promoted); }
     21   // We need two values that are non-zero and share at least one bit.
     22   static_assert(Val1 != Zero && Val2 != Zero, "");
     23   static_assert(Val1 != Val2, "");
     24   static_assert((UVal1 & UVal2) == 0, "");
     25 
     26 
     27   static bool check()
     28   {
     29     {
     30       EnumType ValRef = Val1;
     31       ASSERT_SAME_TYPE(EnumType, decltype(Val1 & Val2));
     32       ASSERT_SAME_TYPE(EnumType, decltype(Val1 | Val2));
     33       ASSERT_SAME_TYPE(EnumType, decltype(Val1 ^ Val2));
     34       ASSERT_SAME_TYPE(EnumType, decltype((~Val1)));
     35       ASSERT_SAME_TYPE(EnumType&, decltype(ValRef &= Val2));
     36       ASSERT_SAME_TYPE(EnumType&, decltype(ValRef |= Val2));
     37       ASSERT_SAME_TYPE(EnumType&, decltype(ValRef ^= Val2));
     38     }
     39 
     40     static_assert((Val1 & Zero) == Zero, "");
     41     static_assert((Val1 & Val1) == Val1, "");
     42     static_assert(dcast(Val1 & Val2) == (UVal1 & UVal2), "");
     43 
     44     static_assert((Val1 | Zero) == Val1, "");
     45     static_assert(dcast(Val1 | Val2) == (UVal1 | UVal2), "");
     46 
     47     static_assert((Val1 ^ Zero) == Val1, "");
     48     static_assert(dcast(Val1 ^ Val2) == (UVal1 ^ UVal2), "");
     49 
     50     static_assert(dcast(~Zero) == unpromote(~UZero), "");
     51     static_assert(dcast(~Val1) == unpromote(~UVal1), "");
     52 
     53     {
     54       EnumType e = Val1;
     55       EnumType& eref = (e &= Val2);
     56       assert(&eref == &e);
     57       assert(dcast(eref) == (UVal1 & UVal2));
     58     }
     59     {
     60       EnumType e = Val1;
     61       EnumType& eref = (e |= Val2);
     62       assert(&eref == &e);
     63       assert(dcast(eref) == (UVal1 | UVal2));
     64     }
     65     {
     66       EnumType e = Val1;
     67       EnumType& eref = (e ^= Val2);
     68       assert(&eref == &e);
     69       assert(dcast(eref) == (UVal1 ^ UVal2));
     70     }
     71     return true;
     72   }
     73 };
     74 
     75 #endif // TEST_BITMASK_TYPE
     76