[UE4]Enum Class Flag
概要
ENUM_CLASS_FLAGS, EnumHasAllFlags, EnumHasAnyFlags の利用によるEnum Flag記述の簡単化
経緯
ENUM_CLASS_FLAGS() マクロで、Enumに演算子を付与できる。
これそのものの説明については、下記ページが詳しい。
上記ページでは EFlags::None の定義と、それを使ったフラグ確認処理が例示されている。
ここで、 ENUM_CLASS_FLAGS の定義のある EnumClassFlags.h を見に行くと
フラグ確認用のテンプレート関数である EnumHasAllFlags と EnumHasAnyFlags が定義されている。(UE4.17以降で確認)
これらを用いれば、 EFlags::None との比較を都度書く手間を省ける。
使用例
// 様々な属性
enum class Attr : uint8
{
None = 0,
Sexy = 1 << 0,
Trendy = 1 << 1,
Christy = 1 << 2,
Gravity = 1 << 3,
Nasty = 1 << 4,
EURO_BOYS = Sexy | Trendy | Christy | Gravity
};
// 演算子を付与してくれるマクロ
ENUM_CLASS_FLAGS(Attr)
// 簡単な拡張:過不足なく満たすかどうか
template<typename Enum>
inline bool EnumHasJustFlags(Enum Flags, Enum Contains)
{
// 全てのフラグを持ち、関係ないフラグは持たない
return EnumHasAllFlags(Flags, Contains) && !EnumHasAnyFlags(Flags, ~Contains);
}
class Test
{
public:
Test() {
Attr group_a = Attr::Sexy | Attr::Trendy;
Attr group_b = Attr::Nasty;
Attr group_c = Attr::Sexy | Attr::Trendy | Attr::Christy | Attr::Gravity;
Attr group_d = Attr::Sexy | Attr::Trendy | Attr::Christy | Attr::Gravity | Attr::Nasty;
// Test Any
if (EnumHasAnyFlags(group_a, Attr::EURO_BOYS)) {
// フラグを部分的に持つので、ここに届く。
UE_LOG(LogTemp, Warning, TEXT("check."));
}
if (EnumHasAnyFlags(group_b, Attr::EURO_BOYS)) {
// フラグを一つも持っていないので、ここには届かない。
UE_LOG(LogTemp, Warning, TEXT("check."));
}
// Test All
if (EnumHasAllFlags(group_c, Attr::EURO_BOYS)) {
// 必要なフラグを全て持っているので、ここに届く。
UE_LOG(LogTemp, Warning, TEXT("check."));
}
if (EnumHasAllFlags(group_d, Attr::EURO_BOYS)) {
// 関係ないフラグも持っているが、必要なフラグは全て持っているので、ここに届く。
UE_LOG(LogTemp, Warning, TEXT("check."));
}
// Test Just
if (EnumHasJustFlags(group_a, Attr::EURO_BOYS)) {
// 必要なフラグが不足しているので、ここには届かない。
UE_LOG(LogTemp, Warning, TEXT("check."));
}
if (EnumHasJustFlags(group_c, Attr::EURO_BOYS)) {
// 必要なフラグを全て持ち、関係ないフラグを持っていないので、ここに届く。
UE_LOG(LogTemp, Warning, TEXT("check."));
}
if (EnumHasJustFlags(group_d, Attr::EURO_BOYS)) {
// 必要なフラグを全て持っているが、関係ないフラグも持っているので、ここには届かない。
UE_LOG(LogTemp, Warning, TEXT("check."));
}
}
};
Test test;
以上