add same bitfields member functions

This commit is contained in:
BlackMATov
2020-12-18 21:14:56 +07:00
parent 9775ee4524
commit 4e1d8b5644
2 changed files with 118 additions and 1 deletions

View File

@@ -18,7 +18,6 @@ namespace enum_hpp::bitflags
using underlying_type = std::underlying_type_t<Enum>; using underlying_type = std::underlying_type_t<Enum>;
bitflags() = default; bitflags() = default;
bitflags(const bitflags&) = default; bitflags(const bitflags&) = default;
bitflags& operator=(const bitflags&) = default; bitflags& operator=(const bitflags&) = default;
@@ -39,6 +38,25 @@ namespace enum_hpp::bitflags
constexpr enum_type as_enum() const noexcept { constexpr enum_type as_enum() const noexcept {
return static_cast<enum_type>(flags_); return static_cast<enum_type>(flags_);
} }
constexpr bool has(bitflags flags) const noexcept {
return flags.flags_ == (flags_ & flags.flags_);
}
constexpr bitflags& set(bitflags flags) noexcept {
flags_ |= flags.flags_;
return *this;
}
constexpr bitflags& toggle(bitflags flags) noexcept {
flags_ ^= flags.flags_;
return *this;
};
constexpr bitflags& clear(bitflags flags) noexcept {
flags_ &= ~flags.flags_;
return *this;
}
private: private:
underlying_type flags_{}; underlying_type flags_{};
}; };

View File

@@ -17,7 +17,9 @@ namespace
none = 0, none = 0,
read = 1 << 0, read = 1 << 0,
write = 1 << 1, write = 1 << 1,
execute = 1 << 2,
read_write = read | write, read_write = read | write,
all = read_write | execute
}; };
ENUM_HPP_REGISTER_BITFLAGS_OPERATORS(access) ENUM_HPP_REGISTER_BITFLAGS_OPERATORS(access)
@@ -26,6 +28,38 @@ namespace
TEST_CASE("enum_bitflags") { TEST_CASE("enum_bitflags") {
namespace bf = enum_hpp::bitflags; namespace bf = enum_hpp::bitflags;
SUBCASE("ctors") {
{
constexpr bf::bitflags<access> f;
STATIC_CHECK(!f);
STATIC_CHECK(f.as_raw() == 0x0);
STATIC_CHECK(f.as_enum() == access::none);
}
{
constexpr bf::bitflags f = access::read_write;
STATIC_CHECK(!!f);
STATIC_CHECK(f.as_raw() == 0x3);
STATIC_CHECK(f.as_enum() == access::read_write);
}
{
constexpr bf::bitflags<access> f{0x3};
STATIC_CHECK(!!f);
STATIC_CHECK(f.as_raw() == 0x3);
STATIC_CHECK(f.as_enum() == access::read_write);
}
{
constexpr bf::bitflags f = access::read | access::write;
constexpr bf::bitflags g = f;
STATIC_CHECK(g.as_raw() == 0x3);
}
{
constexpr bf::bitflags f = access::read | access::write;
bf::bitflags<access> g;
g = f;
CHECK(g.as_raw() == 0x3);
}
}
SUBCASE("enum_operators") { SUBCASE("enum_operators") {
STATIC_CHECK((~access::read) == bf::bitflags<access>(0xFE)); STATIC_CHECK((~access::read) == bf::bitflags<access>(0xFE));
STATIC_CHECK((access::read | access::write) == bf::bitflags<access>(0x3)); STATIC_CHECK((access::read | access::write) == bf::bitflags<access>(0x3));
@@ -177,6 +211,71 @@ TEST_CASE("enum_bitflags") {
} }
} }
SUBCASE("has") {
constexpr bf::bitflags f = access::read_write;
STATIC_CHECK(f.has(access::read));
STATIC_CHECK(f.has(access::read_write));
STATIC_CHECK(f.has(access::read | access::write));
STATIC_CHECK_FALSE(f.has(access::execute));
STATIC_CHECK_FALSE(f.has(access::read | access::execute));
}
SUBCASE("set") {
bf::bitflags<access> f;
CHECK(&f == &f.set(access::read));
CHECK(f.has(access::read));
CHECK(&f == &f.set(access::read | access::write));
CHECK(f.has(access::read | access::write));
CHECK_FALSE(f.has(access::execute));
}
SUBCASE("toggle") {
bf::bitflags f = access::read_write;
CHECK(&f == &f.toggle(access::read));
CHECK_FALSE(f.has(access::read));
CHECK(f.has(access::write));
CHECK_FALSE(f.has(access::execute));
CHECK(&f == &f.toggle(access::read | access::write));
CHECK(f.has(access::read));
CHECK_FALSE(f.has(access::write));
CHECK_FALSE(f.has(access::execute));
CHECK(&f == &f.toggle(access::execute));
CHECK(f.has(access::read));
CHECK_FALSE(f.has(access::write));
CHECK(f.has(access::execute));
}
SUBCASE("clear") {
{
bf::bitflags f = access::all;
CHECK(&f == &f.clear(access::read));
CHECK_FALSE(f.has(access::read));
CHECK(f.has(access::write));
CHECK(f.has(access::execute));
CHECK(&f == &f.clear(access::read | access::execute));
CHECK_FALSE(f.has(access::read));
CHECK(f.has(access::write));
CHECK_FALSE(f.has(access::execute));
}
{
bf::bitflags f = access::all;
CHECK(&f == &f.clear(access::write | access::execute));
CHECK(f.has(access::read));
CHECK_FALSE(f.has(access::write));
CHECK_FALSE(f.has(access::execute));
CHECK(&f == &f.clear(access::read | access::execute));
CHECK_FALSE(f.has(access::read));
CHECK_FALSE(f.has(access::write));
CHECK_FALSE(f.has(access::execute));
}
}
SUBCASE("any") { SUBCASE("any") {
STATIC_CHECK_FALSE(bf::any(access::none)); STATIC_CHECK_FALSE(bf::any(access::none));
STATIC_CHECK(bf::any(access::read)); STATIC_CHECK(bf::any(access::read));