/* SPDX-License-Identifier: LGPL-2.1-or-later */ /* * Copyright (C) 2020, Google Inc. * * flags.h - Type-safe enum-based bitfields */ #pragma once #include namespace libcamera { template class Flags { public: static_assert(std::is_enum::value, "Flags<> template parameter must be an enum"); using Type = std::underlying_type_t; constexpr Flags() : value_(0) { } constexpr Flags(E flag) : value_(static_cast(flag)) { } constexpr Flags &operator&=(E flag) { value_ &= static_cast(flag); return *this; } constexpr Flags &operator&=(Flags other) { value_ &= other.value_; return *this; } constexpr Flags &operator|=(E flag) { value_ |= static_cast(flag); return *this; } constexpr Flags &operator|=(Flags other) { value_ |= other.value_; return *this; } constexpr Flags &operator^=(E flag) { value_ ^= static_cast(flag); return *this; } constexpr Flags &operator^=(Flags other) { value_ ^= other.value_; return *this; } constexpr bool operator==(E flag) { return value_ == static_cast(flag); } constexpr bool operator==(Flags other) { return value_ == static_cast(other); } constexpr bool operator!=(E flag) { return value_ != static_cast(flag); } constexpr bool operator!=(Flags other) { return value_ != static_cast(other); } constexpr explicit operator Type() const { return value_; } constexpr explicit operator bool() const { return !!value_; } constexpr Flags operator&(E flag) const { return Flags(static_cast(value_ & static_cast(flag))); } constexpr Flags operator&(Flags other) const { return Flags(static_cast(value_ & other.value_)); } constexpr Flags operator|(E flag) const { return Flags(static_cast(value_ | static_cast(flag))); } constexpr Flags operator|(Flags other) const { return Flags(static_cast(value_ | other.value_)); } constexpr Flags operator^(E flag) const { return Flags(static_cast(value_ ^ static_cast(flag))); } constexpr Flags operator^(Flags other) const { return Flags(static_cast(value_ ^ other.value_)); } constexpr Flags operator~() const { return Flags(static_cast(~value_)); } constexpr bool operator!() const { return !value_; } private: Type value_; }; #ifndef __DOXYGEN__ template struct flags_enable_operators { static const bool enable = false; }; template typename std::enable_if_t::enable, Flags> operator|(E lhs, E rhs) { using type = std::underlying_type_t; return Flags(static_cast(static_cast(lhs) | static_cast(rhs))); } template typename std::enable_if_t::enable, Flags> operator&(E lhs, E rhs) { using type = std::underlying_type_t; return Flags(static_cast(static_cast(lhs) & static_cast(rhs))); } template typename std::enable_if_t::enable, Flags> operator^(E lhs, E rhs) { using type = std::underlying_type_t; return Flags(static_cast(static_cast(lhs) ^ static_cast(rhs))); } template typename std::enable_if_t::enable, Flags> operator~(E rhs) { using type = std::underlying_type_t; return Flags(static_cast(~static_cast(rhs))); } #define LIBCAMERA_FLAGS_ENABLE_OPERATORS(_enum) \ template<> \ struct flags_enable_operators<_enum> { \ static const bool enable = true; \ }; #else /* __DOXYGEN__ */ #define LIBCAMERA_FLAGS_ENABLE_OPERATORS(_enum) #endif /* __DOXYGEN__ */ } /* namespace libcamera */