C++ static array of enum?

My goal is to loop through all enum elements of any given enum.

So I have the following enum set up:

UENUM()
namespace ERoomISMCReferencedQuadrant 
{
	enum Type
	{
		NorthEast,
		SouthEast,
		SouthWest,
		NorthWest
	};
}

I know I can define a nice readable type of a TArray w/the a fixed size of 4 for memory / performance improvements like so:

typedef TArray<ERoomISMCReferencedQuadrant::Type, TFixedAllocator<4>> TArrayERoomISMCReferencedQuadrant;

I know I can make a method that will generate this array with all enums like so:

TArrayERoomISMCReferencedQuadrant GetERoomISMCReferenedQuadrants();
{
	TArrayERoomISMCReferencedQuadrant result;
	result.Add(ERoomISMCReferencedQuadrant::NorthEast);
	result.Add(ERoomISMCReferencedQuadrant::SouthEast);
	result.Add(ERoomISMCReferencedQuadrant::SouthWest);
	result.Add(ERoomISMCReferencedQuadrant::NorthWest);
	return result;
}

But is there a better way? Doing this the array would have to be generated every time and it is not static. If I have a lot of enums I would have to create a method for each one. Perhaps I need to make a templated version of it or perhaps there is already support for what I’m trying to do. My goal is to eventually just loop through all enums like so:

for (auto e : SomeEnumArray)
{
	CallSomeMethod(e);
}

Hi,

It’s not directly what you’re looking for, but you can achieve iteration over a given UENUM’s enumerators by using the FOREACH_ENUM_* macros. These get generated automatically for each UENUM type:

#define MY_LOOP_BODY(val) CallSomeMethod(val);
    FOREACH_ENUM_EROOMISMCREFERENCEDQUADRANT(MY_LOOP_BODY)
#undef MY_LOOP_BODY

Steve

This might not be exactly what you want but you can create static arrays like this:

UENUM(BlueprintType)
namespace EObjective
{
	enum Type
	{
		// Numeric
		CaptureReactor = 0		UMETA(DisplayName = "Capture Reactor"),
		CaptureFlag 			UMETA(DisplayName = "Capture Flag"),
		PickUpReactor			UMETA(DisplayName = "Pick Up Reactor"),
		PickUpFlag				UMETA(DisplayName = "Pick Up Flag"),

		// This must always be at the end
		Max						UMETA(DisplayName = "Invalid")
	};
}

Then:

UPROPERTY(EditDefaultsOnly, Category = Rewards)
int32 ObjectiveRewards[EObjective::Max];

The only drawback I know is that you can’t expose the static array into BluePrints. But you can make a function like:

UFUNCTION(BlueprintCallable, Category = Rewards)
int32 YourClass::GetObjectiveReward(EObjective::Type inObjectiveType) const
{
	return ObjectiveRewards[inObjectiveType];
}

The great thing about this way is that the Editor automatically shows the static array in a very readable way. Instead of a typical TArray where it would show

ObjectiveRewards
0: 40
1: 250
2: 400
3: 70

it shows the enum name + value:

ObjectiveRewards
CaptureReactor: 40
CaptureFlag : 250
PickUpReactor: 400
PickUpFlag: 70

You can iterate through the array:

for(int32 i  = 0; i < EObjective::Type::Max; ++i)
{
	UE_LOG(LogTemp, Log, TEXT("Array value: %d"), ObjectiveRewards[i]);
}

I created a helper function:

	template<typename T>
	TArray<T> EnumGetList(const FString& enumName)
	{
		TArray<T> lResult;
		UEnum* pEnum = FindObject<UEnum>(ANY_PACKAGE, *enumName, true);
		for (int i = 0; i <= pEnum->GetMaxEnumValue(); ++i)
		{
			if (pEnum->IsValidEnumValue(i))
				lResult.Add(static_cast<T>(i));
		}
		return lResult;
	}

An use it like this:

auto lEnums = Utilities::Conversion::EnumGetList<EMyEnum>(TEXT("EMyEnum"));

for (auto i : lEnums)
{
	MyFunction(...)
}