ReflectedEnum.h
// ReflectedEnum.h
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2022
@import "IObject.h"
@import "ReflectedType.h"
namespace ceda
{
/*
Example:
$enum+ EColour
{
red = 10,
-green = 20,
default blue = 30 : ["sky"]
};
GetCount() = 3
GetValue(0) = 10
GetValue(1) = 20
GetValue(2) = 30
GetString(0) = "red"
GetString(1) = "green"
GetString(2) = "blue"
GetEnable(0) = true
GetEnable(1) = false
GetEnable(2) = true
*/
$struct+ ReflectedEnumTag <<os>>
{
$ConstStringZ GetName() const { return name; }
void Write(xostream& os) const;
//////////////// State //////////////////
ConstStringZ name;
const octet_t* metaData;
int32 value;
bool enable;
};
$enum+ class EReflectedEnumFlagBits
{
AsClass, // If bit is set then it's an enum class
ValuesRedefined, // If bit is unset then for all i tags[i].value == i
ValuesDisabled // If bit is unset then for all i tags[i].enable == true
};
$struct+ ReflectedEnum <<os>>
{
bool operator<(const ReflectedEnum& rhs) const { return this < &rhs; }
bool operator==(const ReflectedEnum& rhs) const { return this == &rhs; }
$ConstStringZ GetName() const { return name; }
$bool IsEnumClass() const { return (flags & (1 << EReflectedEnumFlagBits::AsClass)) != 0; }
// Returns true if the enum values have been redefined (i.e. they are not simply 0,1,2...)
$bool ValuesRedefined() const { return (flags & (1 << EReflectedEnumFlagBits::ValuesRedefined)) != 0; }
// Returns true if any of the enum tags have been disabled
$bool ValuesDisabled() const { return (flags & (1 << EReflectedEnumFlagBits::ValuesDisabled)) != 0; }
// Returns the number of distinct enum values
$int32 GetCount() const { return count; }
// Returns the ith enum value, which is just i if the enum values are simply 0,1,2,...
$int32 GetValue(int32 i) const { return tags[i].value; }
// Returns true if the ith enum value is enabled (i.e. no deprecated)
$bool GetEnable(int32 i) const { return tags[i].enable; }
// Returns the ith enum string
$ConstStringZ GetString(int32 i) const { return tags[i].name; }
// This checks whether the tag value exists, regardless of whether it has been disabled
$bool IsValidValue(int32 v) const
{
if (ValuesRedefined())
{
for (int i=0 ; i < count ; ++i)
{
if (tags[i].value == v) return true;
}
return false;
}
else
{
return 0 <= v && v < count;
}
}
void Write(xostream& os) const;
//////////////// State //////////////////
uint32 flags;
@if (!CEDA_ENABLE_STRING_TABLES)
{
const octet_t* byteCode;
}
ConstStringZ name;
const octet_t* metaData;
ConstStringZ const* stringTable;
int32 count;
const ReflectedEnumTag* tags;
int32 defaultIndex;
};
template<typename T>
struct GetReflectedType_class<T, std::enable_if_t<!std::is_const<T>::value && !std::is_volatile<T>::value && IsReflectedEnum<T>::value>>
{
static inline ReflectedType get()
{
ReflectedType r;
r.tag = EReflectedTypeTag::Enum;
r.Enum = &GetReflectedEnum<T>();
return r;
}
};
} // namespace ceda