|
| 1 | +#include "common.hpp" |
| 2 | + |
| 3 | + |
| 4 | +// type traits |
| 5 | +static_assert(std::is_pod<Enums>::value, |
| 6 | + "Enums is not POD!"); |
| 7 | +static_assert(std::is_literal_type<Enums>::value, |
| 8 | + "Enums is not a literal type!"); |
| 9 | + |
| 10 | + |
| 11 | +// associated types |
| 12 | + |
| 13 | +// general |
| 14 | +static_assert(std::is_same<Enums::enum_type, Enum>::value, |
| 15 | + "Enums::enum_type is not Enum!"); |
| 16 | +static_assert(std::is_same<std::underlying_type<Enum>::type, |
| 17 | + Enums::underlying_type>::value, |
| 18 | + "Enums::underlying_type is different from " |
| 19 | + "underlying type of Enum!"); |
| 20 | +static_assert(std::is_same<std::make_unsigned<Enums::underlying_type>::type, |
| 21 | + Enums::impl_type>::value, |
| 22 | + "Enums::impl_type is not unsigned version of " |
| 23 | + "Enums::underlying_type!"); |
| 24 | + |
| 25 | +// iterator |
| 26 | +using Iterator = Enums::iterator; |
| 27 | + |
| 28 | +static_assert(std::is_literal_type<Iterator>::value, |
| 29 | + "Enums::iterator is not a literal type!"); |
| 30 | +static_assert(std::is_same<Enums::const_iterator, Iterator>::value, |
| 31 | + "Enums::const_iterator and Enums::iterator are different types!"); |
| 32 | +static_assert(std::is_same<Iterator::flags_type, Enums>::value, |
| 33 | + "Enums::iterator::flags_type is not Enums!"); |
| 34 | +static_assert(std::is_same<Iterator::iterator_category, |
| 35 | + std::forward_iterator_tag>::value, |
| 36 | + "Enums::iterator category is not forward iterator!"); |
| 37 | +static_assert(std::is_same<Iterator::value_type, Enum>::value, |
| 38 | + "Enums::iterator::value_type is not Enum!"); |
| 39 | +static_assert(std::is_same<Iterator::reference, const Enum>::value, |
| 40 | + "Enums::iterator::reference is not const Enum!"); |
| 41 | +// (const) forward iterator requirements |
| 42 | +static_assert(std::is_copy_constructible<Iterator>::value |
| 43 | + && std::is_copy_assignable<Iterator>::value |
| 44 | + && std::is_destructible<Iterator>::value |
| 45 | +// && std::is_same<decltype(*std::declval<Iterator &>()), |
| 46 | +// Iterator::reference>::value |
| 47 | + && std::is_same<decltype(++std::declval<Iterator &>()), |
| 48 | + Iterator &>::value, |
| 49 | + "Enums::iterator does not model Iterator!"); |
| 50 | +static_assert(std::is_convertible< |
| 51 | + decltype(std::declval<Iterator>() == std::declval<Iterator>()), |
| 52 | + bool>::value, |
| 53 | + "Enums::iterator does not model EqualityComparable!"); |
| 54 | +static_assert(std::is_convertible< |
| 55 | + decltype(std::declval<Iterator>() != std::declval<Iterator>()), |
| 56 | + bool>::value |
| 57 | + && std::is_convertible<decltype(*std::declval<Iterator &>()), |
| 58 | + Iterator::value_type>::value |
| 59 | + && std::is_convertible<decltype(*std::declval<Iterator &>()++), |
| 60 | + Iterator::value_type>::value, |
| 61 | + "Enums::iterator does not model InputIterator!"); |
| 62 | +static_assert(std::is_default_constructible<Iterator>::value |
| 63 | + && std::is_convertible<decltype(++std::declval<Iterator &>()), |
| 64 | + Iterator>::value |
| 65 | + && std::is_convertible<decltype(std::declval<Iterator &>()++), |
| 66 | + Iterator>::value, |
| 67 | + "Enums::iterator does not model ForwardIterator!"); |
| 68 | + |
| 69 | +// container |
| 70 | +static_assert(std::is_same<Enums::iterator::value_type, |
| 71 | + Enums::value_type>::value, |
| 72 | + "Enums::value_type is not Enums::iterator::value_type!"); |
| 73 | + |
| 74 | +static_assert(std::is_same<Enums::iterator::reference, Enums::reference>::value, |
| 75 | + "Enums::reference is not Enums::iterator::reference!"); |
| 76 | +static_assert(std::is_same<Enums::const_reference, Enums::reference>::value, |
| 77 | + "Enums::const_reference is not Enums::reference!"); |
| 78 | + |
| 79 | +static_assert(std::is_same<Enums::iterator::pointer, Enums::pointer>::value, |
| 80 | + "Enums::pointer is not Enums::iterator::pointer!"); |
| 81 | +static_assert(std::is_same<Enums::enum_type *, Enums::pointer>::value, |
| 82 | + "Enums::pointer is not Enum *!"); |
| 83 | +static_assert(std::is_same<const Enums::enum_type *, |
| 84 | + Enums::const_pointer>::value, |
| 85 | + "Enums::const_pointer is not const Enum *!"); |
| 86 | + |
| 87 | +static_assert(std::is_arithmetic<Enums::size_type>::value, |
| 88 | + "Enums::size_type is not arithmetic!"); |
| 89 | + |
| 90 | +static_assert(std::is_same<Enums::iterator::difference_type, |
| 91 | + Enums::difference_type>::value, |
| 92 | + "Enums::difference_type is not Enums::iterator::difference_type!" |
| 93 | + ); |
| 94 | +static_assert(std::is_signed<Enums::difference_type>::value, |
| 95 | + "Enums::difference_type is not signed!"); |
| 96 | + |
| 97 | + |
| 98 | +// constexpr construction |
| 99 | +constexpr Enums ec1(flags::empty); |
| 100 | +constexpr Enums ec2{flags::empty}; |
| 101 | +constexpr Enums vc1(Enum::One); |
| 102 | +constexpr auto vc2 = Enums(Enum::One); |
| 103 | + |
| 104 | + |
| 105 | +// constexpr logical operators |
| 106 | +constexpr bool l1 = static_cast<bool>(ec1); |
| 107 | +constexpr bool l2 = !ec1; |
| 108 | +constexpr bool l3 = ec1 == ec2; |
| 109 | +constexpr bool l4 = ec1 != ec2; |
| 110 | + |
| 111 | + |
| 112 | +// constexpr bitwise operators |
| 113 | +constexpr auto b1 = ~ec1; |
| 114 | + |
| 115 | +constexpr auto b2 = ec1 | ec2; |
| 116 | +constexpr auto b3 = ec1 | Enum::One; |
| 117 | +constexpr auto b4 = Enum::One | ec1; |
| 118 | +constexpr auto b5 = Enum::One | Enum::Two; |
| 119 | + |
| 120 | +constexpr auto b6 = ec1 & ec2; |
| 121 | +constexpr auto b7 = ec1 & Enum::One; |
| 122 | +constexpr auto b8 = Enum::One & ec1; |
| 123 | +constexpr auto b9 = Enum::One & Enum::Two; |
| 124 | + |
| 125 | +constexpr auto b10 = ec1 ^ ec2; |
| 126 | +constexpr auto b11 = ec1 & Enum::One; |
| 127 | +constexpr auto b12 = Enum::One ^ ec1; |
| 128 | +constexpr auto b13 = Enum::One ^ Enum::Two; |
| 129 | + |
| 130 | + |
| 131 | +// constexpr conversions |
| 132 | +constexpr auto cv1 = ec1.underlying_value(); |
| 133 | +static_assert(std::is_same<decltype(ec1.underlying_value()), |
| 134 | + Enums::underlying_type>::value, |
| 135 | + "Enums::underlying_value() did not return an object of type " |
| 136 | + "Enums::underlying_type!"); |
| 137 | +constexpr auto cv2 = ec1.to_bitset(); |
| 138 | +constexpr auto cv3 = static_cast<std::bitset<Enums::bit_size()>>(ec1); |
| 139 | +static_assert(std::is_same<decltype(cv2), decltype(cv3)>::value, |
| 140 | + "Bitset conversion functions return different types!"); |
| 141 | + |
| 142 | + |
| 143 | +// constexpr container functions |
| 144 | +constexpr bool cf1 = ec1.empty(); |
| 145 | +constexpr Enums::size_type cf2 = ec1.max_size(); |
| 146 | +constexpr Enums::iterator cf3 = ec1.find(Enum::One); |
| 147 | +constexpr Enums::size_type cf4 = ec1.count(Enum::One); |
0 commit comments