From e26ca864be23eadd038f54f708cfab9c4b50db57 Mon Sep 17 00:00:00 2001 From: Maxime Arthaud Date: Wed, 29 Nov 2023 09:29:02 -0800 Subject: [PATCH] Move Flags.h under utils/EnumBitSet.h Summary: Let's move Flags.h under a directory since it's not entirely related to the abstract interpretation library. Let's also rename it EnumBitSet, since "Flags" is pretty generic and confusing. EnumBitSet more clearly conveys it's semantic: it represent a set of enum values stored as a bitset. Reviewed By: arnaudvenet Differential Revision: D51666349 fbshipit-source-id: 37dba9c6f18a2de4fa4c341c2479ab7f6eb48acf --- include/sparta/Flags.h | 152 ----------------------------- include/sparta/utils/EnumBitSet.h | 156 ++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+), 152 deletions(-) delete mode 100644 include/sparta/Flags.h create mode 100644 include/sparta/utils/EnumBitSet.h diff --git a/include/sparta/Flags.h b/include/sparta/Flags.h deleted file mode 100644 index f65b52d..0000000 --- a/include/sparta/Flags.h +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include -#include - -namespace sparta { - -/** - * A set of flags. - * - * `Flags` can be used to store an OR-combination of enum values, where - * `Enum` is an enum class type. `Enum` underlying values must be a power of 2. - */ -template -class Flags final { - static_assert(std::is_enum_v, "Enum must be an enumeration type"); - static_assert( - std::is_unsigned_v>, - "The underlying type of Enum must be an unsigned arithmetic type"); - - public: - using EnumType = Enum; - using IntT = std::underlying_type_t; - - public: - Flags() = default; - - /* implicit */ constexpr Flags(Enum flag) : value_(static_cast(flag)) {} - - /* implicit */ constexpr Flags(std::initializer_list flags) - : value_(0) { - for (auto flag : flags) { - value_ |= static_cast(flag); - } - } - - constexpr Flags& operator&=(Enum flag) { - value_ &= static_cast(flag); - return *this; - } - - constexpr Flags& operator&=(Flags flags) { - value_ &= flags.value_; - return *this; - } - - constexpr Flags& operator|=(Enum flag) { - value_ |= static_cast(flag); - return *this; - } - - constexpr Flags& operator|=(Flags flags) { - value_ |= flags.value_; - return *this; - } - - constexpr Flags& operator^=(Enum flag) { - value_ ^= static_cast(flag); - return *this; - } - - constexpr Flags& operator^=(Flags flags) { - value_ ^= flags.value_; - return *this; - } - - constexpr Flags operator&(Enum flag) const { - return Flags(value_ & static_cast(flag)); - } - - constexpr Flags operator&(Flags flags) const { - return Flags(value_ & flags.value_); - } - - constexpr Flags operator|(Enum flag) const { - return Flags(value_ | static_cast(flag)); - } - - constexpr Flags operator|(Flags flags) const { - return Flags(value_ | flags.value_); - } - - constexpr Flags operator^(Enum flag) const { - return Flags(value_ ^ static_cast(flag)); - } - - constexpr Flags operator^(Flags flags) const { - return Flags(value_ ^ flags.value_); - } - - constexpr Flags operator~() const { return Flags(~value_); } - - explicit constexpr operator bool() const { return value_ != 0; } - - constexpr bool operator!() const { return value_ == 0; } - - constexpr bool operator==(Flags flags) const { - return value_ == flags.value_; - } - - constexpr bool operator!=(Flags flags) const { - return value_ != flags.value_; - } - - constexpr bool test(Enum flag) const { - if (static_cast(flag) == 0) { - return value_ == 0; - } else { - return (value_ & static_cast(flag)) == static_cast(flag); - } - } - - constexpr Flags& set(Enum flag, bool on = true) { - if (on) { - value_ |= static_cast(flag); - } else { - value_ &= ~static_cast(flag); - } - return *this; - } - - constexpr bool empty() const { return value_ == 0; } - - constexpr void clear() { value_ = 0; } - - constexpr bool is_subset_of(Flags flags) const { - return (value_ | flags.value_) == flags.value_; - } - - constexpr bool has_single_bit() const { - return (value_ && !(value_ & (value_ - 1))); - } - - constexpr IntT encode() const { return value_; } - - static constexpr Flags decode(IntT encoding) { return Flags(encoding); } - - private: - explicit constexpr Flags(IntT value) : value_(value) {} - - private: - IntT value_ = 0; -}; - -} // namespace sparta diff --git a/include/sparta/utils/EnumBitSet.h b/include/sparta/utils/EnumBitSet.h new file mode 100644 index 0000000..3ef82f8 --- /dev/null +++ b/include/sparta/utils/EnumBitSet.h @@ -0,0 +1,156 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include + +namespace sparta { + +/** + * A set of enum values. + * + * `EnumBitSet` can be used to store an OR-combination of enum values, + * where `Enum` is an enum class type. `Enum` underlying values must be a power + * of 2. + */ +template +class EnumBitSet final { + static_assert(std::is_enum_v, "Enum must be an enumeration type"); + static_assert( + std::is_unsigned_v>, + "The underlying type of Enum must be an unsigned arithmetic type"); + + public: + using EnumType = Enum; + using IntT = std::underlying_type_t; + + public: + EnumBitSet() = default; + + /* implicit */ constexpr EnumBitSet(Enum value) + : value_(static_cast(value)) {} + + /* implicit */ constexpr EnumBitSet(std::initializer_list set) + : value_(0) { + for (auto value : set) { + value_ |= static_cast(value); + } + } + + constexpr EnumBitSet& operator&=(Enum value) { + value_ &= static_cast(value); + return *this; + } + + constexpr EnumBitSet& operator&=(EnumBitSet set) { + value_ &= set.value_; + return *this; + } + + constexpr EnumBitSet& operator|=(Enum value) { + value_ |= static_cast(value); + return *this; + } + + constexpr EnumBitSet& operator|=(EnumBitSet set) { + value_ |= set.value_; + return *this; + } + + constexpr EnumBitSet& operator^=(Enum value) { + value_ ^= static_cast(value); + return *this; + } + + constexpr EnumBitSet& operator^=(EnumBitSet set) { + value_ ^= set.value_; + return *this; + } + + constexpr EnumBitSet operator&(Enum value) const { + return EnumBitSet(value_ & static_cast(value)); + } + + constexpr EnumBitSet operator&(EnumBitSet set) const { + return EnumBitSet(value_ & set.value_); + } + + constexpr EnumBitSet operator|(Enum value) const { + return EnumBitSet(value_ | static_cast(value)); + } + + constexpr EnumBitSet operator|(EnumBitSet set) const { + return EnumBitSet(value_ | set.value_); + } + + constexpr EnumBitSet operator^(Enum value) const { + return EnumBitSet(value_ ^ static_cast(value)); + } + + constexpr EnumBitSet operator^(EnumBitSet set) const { + return EnumBitSet(value_ ^ set.value_); + } + + constexpr EnumBitSet operator~() const { return EnumBitSet(~value_); } + + explicit constexpr operator bool() const { return value_ != 0; } + + constexpr bool operator!() const { return value_ == 0; } + + constexpr bool operator==(EnumBitSet set) const { + return value_ == set.value_; + } + + constexpr bool operator!=(EnumBitSet set) const { + return value_ != set.value_; + } + + constexpr bool test(Enum value) const { + if (static_cast(value) == 0) { + return value_ == 0; + } else { + return (value_ & static_cast(value)) == static_cast(value); + } + } + + constexpr EnumBitSet& set(Enum value, bool on = true) { + if (on) { + value_ |= static_cast(value); + } else { + value_ &= ~static_cast(value); + } + return *this; + } + + constexpr bool empty() const { return value_ == 0; } + + constexpr void clear() { value_ = 0; } + + constexpr bool is_subset_of(EnumBitSet set) const { + return (value_ | set.value_) == set.value_; + } + + constexpr bool has_single_bit() const { + return (value_ && !(value_ & (value_ - 1))); + } + + constexpr IntT encode() const { return value_; } + + static constexpr EnumBitSet decode(IntT encoding) { + return EnumBitSet(encoding); + } + + private: + explicit constexpr EnumBitSet(IntT value) : value_(value) {} + + private: + IntT value_ = 0; +}; + +} // namespace sparta