From f3f2f27d67e509908f87a9771e0a04bfa3b88fc5 Mon Sep 17 00:00:00 2001 From: fabienfl Date: Tue, 29 Sep 2020 20:18:39 +0200 Subject: [PATCH] OrcLib: Utils: add EnumFlags.h --- src/OrcLib/CMakeLists.txt | 1 + src/OrcLib/Utils/EnumFlags.h | 85 ++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 src/OrcLib/Utils/EnumFlags.h diff --git a/src/OrcLib/CMakeLists.txt b/src/OrcLib/CMakeLists.txt index 3d8ad087..6cd12fad 100644 --- a/src/OrcLib/CMakeLists.txt +++ b/src/OrcLib/CMakeLists.txt @@ -605,6 +605,7 @@ set(SRC_UTILITIES "OrcResult.h" "Flags.cpp" "Flags.h" + "Utils/EnumFlags.h" "Utils/Guard.h" "Utils/Iconv.cpp" "Utils/Iconv.h" diff --git a/src/OrcLib/Utils/EnumFlags.h b/src/OrcLib/Utils/EnumFlags.h new file mode 100644 index 00000000..c10ac836 --- /dev/null +++ b/src/OrcLib/Utils/EnumFlags.h @@ -0,0 +1,85 @@ +#pragma once + +// +// Define operators to enable combining enum class values as flags. +// +// To enable EnumFlags features use: +// +// namespace Foo { +// ... +// ENABLE_BITMASK_OPERATORS(FilesystemAttributes); +// } +// +// From http://blog.bitwigglers.org/using-enum-classes-as-type-safe-bitmasks/ +// + +#include + +namespace Orc { + +template +struct EnableBitMaskOperators +{ + static const bool enable = false; +}; + +template +typename std::enable_if::enable, bool>::type constexpr operator&(Enum lhs, Enum rhs) +{ + using underlying = typename std::underlying_type::type; + return static_cast(lhs) & static_cast(rhs); +} + +template +typename std::enable_if::enable, bool>::type constexpr operator&=(Enum& lhs, Enum rhs) +{ + using underlying = typename std::underlying_type::type; + lhs = static_cast(lhs) & static_cast(rhs); + return lhs; +} + +template +typename std::enable_if::enable, Enum>::type constexpr operator|(Enum lhs, Enum rhs) +{ + using underlying = typename std::underlying_type::type; + return static_cast(static_cast(lhs) | static_cast(rhs)); +} + +template +typename std::enable_if::enable, Enum>::type constexpr operator|=(Enum& lhs, Enum rhs) +{ + using underlying = typename std::underlying_type::type; + lhs = static_cast(static_cast(lhs) | static_cast(rhs)); + return lhs; +} + +template +typename std::enable_if::enable, Enum>::type constexpr operator^(Enum lhs, Enum rhs) +{ + using underlying = typename std::underlying_type::type; + return static_cast(static_cast(lhs) ^ static_cast(rhs)); +} + +template +typename std::enable_if::enable, Enum>::type constexpr operator^=(Enum& lhs, Enum rhs) +{ + using underlying = typename std::underlying_type::type; + lhs = static_cast(static_cast(lhs) ^ static_cast(rhs)); + return lhs; +} + +template +typename std::enable_if::enable, Enum>::type constexpr operator~(Enum value) +{ + using underlying = typename std::underlying_type::type; + return static_cast(static_cast(value)); +} + +#define ENABLE_BITMASK_OPERATORS(x) \ + template <> \ + struct EnableBitMaskOperators \ + { \ + static const bool enable = true; \ + }; + +} // namespace Orc