Skip to content

Instantly share code, notes, and snippets.

@mciantyre
Created March 16, 2018 22:55
Show Gist options
  • Save mciantyre/cdf0b8e1e74a5ad2cf8d8914938e0ea0 to your computer and use it in GitHub Desktop.
Save mciantyre/cdf0b8e1e74a5ad2cf8d8914938e0ea0 to your computer and use it in GitHub Desktop.
Code: Safer configuration and exception masks in C++
#include <cstdint>
enum class ValidationExceptions : uint32_t
{
COMP_NO_EXCEPTION = 0,
COMP_DIV_BY_ZERO = 1,
COMP_EXCEEDS_MIN = 2,
COMP_EXCEEDS_MAX = 4,
COMP_NOT_ENOUGH = 8,
};
template <typename Flag>
struct Mask
{
using This = Mask<Flag>;
uint32_t mask;
/* 1 */ constexpr Mask() : mask(0) {}
/* 2 */ constexpr Mask(Flag flag) : mask(static_cast<uint32_t>(flag)) {}
constexpr This& operator|=(This that)
{
this->mask |= that.mask;
return *this;
}
constexpr This& operator&=(This that)
{
this->mask &= that.mask;
return *this;
}
friend constexpr const This operator|(This lhs, This rhs)
{
lhs |= rhs;
return lhs;
}
friend constexpr const This operator&(This lhs, This rhs)
{
lhs &= rhs;
return lhs;
}
explicit operator bool() const { return mask > 0; }
};
using ValidationMask = Mask<ValidationExceptions>;
static_assert(
(ValidationMask(ValidationExceptions::COMP_NOT_ENOUGH) | ValidationExceptions::COMP_DIV_BY_ZERO).mask == (static_cast<uint32_t>(ValidationExceptions::COMP_NOT_ENOUGH) | static_cast<uint32_t>(ValidationExceptions::COMP_DIV_BY_ZERO)),
"Failed to OR mask and flag"
);
static_assert(
(ValidationMask(ValidationExceptions::COMP_NOT_ENOUGH) & ValidationExceptions::COMP_DIV_BY_ZERO).mask == (static_cast<uint32_t>(ValidationExceptions::COMP_NOT_ENOUGH) & static_cast<uint32_t>(ValidationExceptions::COMP_DIV_BY_ZERO)),
"Failed to AND mask and flag"
);
int main(int argc, const char * argv[]) {
int denom = 0;
ValidationMask mask;
if (0 == denom)
{
mask |= ValidationExceptions::COMP_DIV_BY_ZERO;
}
ValidationMask anotherMask(ValidationExceptions::COMP_NOT_ENOUGH);
mask &= anotherMask;
if (mask & ValidationExceptions::COMP_DIV_BY_ZERO)
{
// Log an exception
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment