1#ifndef GIMBAL_API_GENERATORS_HPP
2#define GIMBAL_API_GENERATORS_HPP
10#define GBL_CHECK_C_CPP_TYPE_COMPAT(CppType, CType) \
11 GBL_STATIC_ASSERT_MSG(sizeof(CppType) == sizeof(CType), "sizeof(" #CppType ") != sizeof(" #CType")")
13#define GBL_ENUM_TUPLE_DECL_ENUM_CPP(cName, value, name, string) \
17 decltype(
auto) constptr_cast(
auto&& value) {
18 return &std::add_lvalue_reference_t<std::add_const_t<
decltype(value)>>(value);
22 To constptr_cast(
auto&& value) {
23 return static_cast<To
>(constptr_cast(std::forward<
decltype(value)>(value)));
27 template<
typename P,
typename CRTP>
31 const CRTP* derived(
void)
const {
return static_cast<const CRTP*
>(
this); }
32 CRTP* derived(
void) {
return static_cast<CRTP*
>(
this); }
36 constexpr static std::enable_if_t<std::same_as<T, P>, P*> primitive_cast(CRTP* pDerived)
noexcept {
return &*
static_cast<ThisType*
>(pDerived); }
38 constexpr const P* primitive_cast(
void)
const noexcept {
return reinterpret_cast<const P*
>(derived()->getPrimitiveAddress()); }
40 constexpr operator P()
const noexcept {
return static_cast<P
>(derived()->getPrimitiveValue()); }
41 constexpr P* operator&(
void)
noexcept {
return static_cast<P*
>(derived()->getPrimitiveAddress()); }
42 constexpr const P* operator&(
void)
const noexcept {
return static_cast<const P*
>(derived()->getPrimitiveAddress()); }
50 using PrimitiveType = P;
53 constexpr PrimitiveBase(P p)
noexcept: primitive_(std::move(p)) {}
55 constexpr P getPrimitiveValue(
void)
const noexcept {
return primitive_; }
56 constexpr const P* getPrimitiveAddress(
void)
const noexcept {
return &primitive_; }
57 constexpr P* getPrimitiveAddress(
void)
noexcept {
return &primitive_; }
61#define GBL_ENUM_TABLE_DECLARE_CPP_BEGIN(table) \
62 class GBL_EVAL(GBL_META_ENUM_TYPE_PROPERTY(table, NAME)) : \
63 public gimbal::PrimitiveBase<GBL_EVAL(GBL_META_ENUM_TYPE_PROPERTY(table, CNAME))> \
65 using CppType = GBL_EVAL(GBL_META_ENUM_TYPE_PROPERTY(table, NAME)); \
66 using CType = GBL_EVAL(GBL_META_ENUM_TYPE_PROPERTY(table, CNAME)); \
69 GBL_MAP_TUPLES(GBL_ENUM_TUPLE_DECL_ENUM_CPP, GBL_MAP_TUPLES(GBL_EVAL, GBL_META_ENUM_TUPLE_VALUE_ARRAY table)) \
71 constexpr GBL_EVAL(GBL_META_ENUM_TYPE_PROPERTY(table, NAME))(void) noexcept: gimbal::PrimitiveBase<CType>(static_cast<CType>(0)) {} \
72 constexpr GBL_EVAL(GBL_META_ENUM_TYPE_PROPERTY(table, NAME))(Value value) noexcept: CppType(static_cast<CType>(value)) {} \
73 constexpr GBL_EVAL(GBL_META_ENUM_TYPE_PROPERTY(table, NAME))(CType code) noexcept: gimbal::PrimitiveBase<CType>(code) {} \
74 constexpr operator Value() const noexcept { return getValue(); } \
75 constexpr CType getCode(void) const noexcept { return static_cast<CType>(getPrimitiveValue()); } \
76 constexpr Value getValue(void) const noexcept { return static_cast<Value>(getPrimitiveValue()); } \
77 const char* toString(void) const { \
78 const char* pStr = GBL_EVAL(GBL_META_ENUM_TYPE_PROPERTY(table, STRINGIFIER))(getCode()); \
79 if(strcmp(pStr, "") == 0) { \
80 throw std::runtime_error(std::string("Unhandled Enum Value ") + std::to_string(getCode())); \
84 constexpr GblEnum toInt(void) const noexcept { return static_cast<GblEnum>(getCode()); } \
85 constexpr bool isInRange(void) const noexcept { return false; } \
86 constexpr friend bool operator==(CppType rhs, Value lhs) { \
87 return rhs.getCode() == CppType(lhs); \
89 constexpr friend bool operator!=(CppType rhs, Value lhs) { \
90 return !(rhs == lhs); \
95#define GBL_ENUM_TABLE_DECLARE_CPP_END(table) \
97 GBL_CHECK_C_CPP_TYPE_COMPAT(GBL_EVAL(GBL_META_ENUM_TYPE_PROPERTY(table, NAME)), GBL_EVAL(GBL_META_ENUM_TYPE_PROPERTY(table, CNAME)));
99#define GBL_ENUM_TABLE_DECLARE_CPP(table) \
100 GBL_ENUM_TABLE_DECLARE_CPP_BEGIN(table) \
101 GBL_ENUM_TABLE_DECLARE_CPP_END(table)
Helper defines for struct, enum, flags, handle delcarations.