aboutsummaryrefslogtreecommitdiffstats
path: root/bindings/cpp/include/serd/Flags.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'bindings/cpp/include/serd/Flags.hpp')
-rw-r--r--bindings/cpp/include/serd/Flags.hpp88
1 files changed, 88 insertions, 0 deletions
diff --git a/bindings/cpp/include/serd/Flags.hpp b/bindings/cpp/include/serd/Flags.hpp
new file mode 100644
index 00000000..a332ee73
--- /dev/null
+++ b/bindings/cpp/include/serd/Flags.hpp
@@ -0,0 +1,88 @@
+// Copyright 2019-2021 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
+
+#ifndef SERD_FLAGS_HPP
+#define SERD_FLAGS_HPP
+
+#include <type_traits>
+
+namespace serd {
+
+/**
+ @defgroup serdpp_flags Flags
+ @ingroup serdpp
+ @{
+*/
+
+/**
+ Type-safe bit flags
+
+ This is a minimal interface for type-safe bit flags, which only allows
+ values from the corresponding flags enum to be set. It functions like a
+ normal unsigned integer bit field, but attempting to get or set a flag with
+ the incorrect type will fail to compile.
+
+ @tparam Flag Strong enumeration type for flag values.
+*/
+template<class Flag>
+class Flags
+{
+public:
+ static_assert(std::is_enum<Flag>::value, "");
+
+ using Value = std::make_unsigned_t<std::underlying_type_t<Flag>>;
+
+ /// Construct with no flags set
+ constexpr Flags() noexcept = default;
+
+ /// Construct from a raw bit field value
+ constexpr explicit Flags(const Value value) noexcept
+ : _value{value}
+ {}
+
+ /// Construct from a single flag
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ constexpr Flags(const Flag f) noexcept
+ : _value{static_cast<Value>(f)}
+ {}
+
+ /// Set a flag
+ constexpr Flags operator|(const Flag rhs) const noexcept
+ {
+ return Flags{_value | static_cast<Value>(rhs)};
+ }
+
+ /// Set all the flags from another set of flags
+ constexpr Flags operator|(const Flags rhs) const noexcept
+ {
+ return Flags{_value | rhs._value};
+ }
+
+ /// Return true if only the given flag is set
+ constexpr bool operator==(const Flag rhs) const noexcept
+ {
+ return _value == static_cast<Value>(rhs);
+ }
+
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ constexpr operator Value() const noexcept { return _value; }
+
+private:
+ Value _value{};
+};
+
+/// Make a new Flags by combining two individual flags
+template<class Flag>
+inline constexpr Flags<Flag>
+operator|(const Flag lhs, const Flag rhs) noexcept
+{
+ return Flags<Flag>{lhs} | rhs;
+}
+
+/**
+ @}
+*/
+
+} // namespace serd
+
+#endif // SERD_FLAGS_HPP