diff --git a/src/openrct2/core/FlagHolder.hpp b/src/openrct2/core/FlagHolder.hpp index 5e2fee481d..e41305563d 100644 --- a/src/openrct2/core/FlagHolder.hpp +++ b/src/openrct2/core/FlagHolder.hpp @@ -16,6 +16,14 @@ struct FlagHolder { THolderType holder{}; + FlagHolder() = default; + + template + FlagHolder(TTypes... types) + : holder(EnumsToFlags(types...)) + { + } + constexpr void clearAll() { holder = 0; @@ -31,9 +39,35 @@ struct FlagHolder return (holder & EnumToFlag(flag)) != 0; } - constexpr void set(TEnumType flag) + template + [[nodiscard]] constexpr bool hasAny(TTypes... types) const { - holder |= EnumToFlag(flag); + return (holder & EnumsToFlags(types...)) != 0; + } + + template + [[nodiscard]] constexpr bool hasAll(TTypes... types) const + { + return (holder & EnumsToFlags(types...)) == EnumsToFlags(types...); + } + + template + constexpr void set(TTypes... types) + { + holder |= EnumsToFlags(types...); + } + + /** + * For situations where you don’t know upfront whether to set or unset the flag, + * e.g. in game actions where this is passed as a variable. + * Otherwise, use set/unset, which are slightly more efficient. + */ + constexpr void set(TEnumType flag, bool on) + { + if (on) + set(flag); + else + unset(flag); } constexpr void unset(TEnumType flag) @@ -41,6 +75,12 @@ struct FlagHolder holder &= ~EnumToFlag(flag); } + template + constexpr void unset(TTypes... types) + { + holder &= ~EnumsToFlags(types...); + } + constexpr void flip(TEnumType flag) { holder ^= EnumToFlag(flag);