feat(reflect-cpp): Switched from glaze -> reflect cpp
A bug was discovered in glaze which prevented valid toml output. We have switched to toml++ and reflect-cpp. The interface has remained the same so this should not break any code
This commit is contained in:
258
build-config/reflect-cpp/include/rfl/thirdparty/enchantum/details/enchantum_clang.hpp
vendored
Normal file
258
build-config/reflect-cpp/include/rfl/thirdparty/enchantum/details/enchantum_clang.hpp
vendored
Normal file
@@ -0,0 +1,258 @@
|
||||
#pragma once
|
||||
#if __clang_major__ < 20
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wenum-constexpr-conversion"
|
||||
#endif
|
||||
|
||||
#include "../common.hpp"
|
||||
#include "generate_arrays.hpp"
|
||||
#include "string_view.hpp"
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace enchantum {
|
||||
namespace details {
|
||||
|
||||
#if __clang_major__ >= 20
|
||||
|
||||
template<typename T, auto V, typename = void>
|
||||
inline constexpr bool is_valid_cast = false;
|
||||
|
||||
template<typename T, auto V>
|
||||
inline constexpr bool is_valid_cast<T, V, std::void_t<std::integral_constant<T, static_cast<T>(V)>>> = true;
|
||||
|
||||
template<typename T, std::underlying_type_t<T> max_range = 1>
|
||||
constexpr auto valid_cast_range()
|
||||
{
|
||||
if constexpr (max_range >= 0) {
|
||||
if constexpr (max_range <= ENCHANTUM_MAX_RANGE) {
|
||||
// this tests whether `static_cast`ing max_range is valid
|
||||
// because C style enums stupidly is like a bit field
|
||||
// `enum E { a,b,c,d = 3};` is like a bitfield `struct E { int val : 2;}`
|
||||
// which means giving E.val a larger than 2 bit value is UB so is it for enums
|
||||
// and gcc and msvc ignore this (for good)
|
||||
// while clang makes it a subsituation failure which we can check for
|
||||
// using std::inegral_constant makes sure this is a constant expression situation
|
||||
// for SFINAE to occur
|
||||
if constexpr (is_valid_cast<T, max_range>)
|
||||
return valid_cast_range<T, max_range * 2>();
|
||||
else
|
||||
return max_range - 1;
|
||||
}
|
||||
else {
|
||||
return max_range - 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if constexpr (max_range >= ENCHANTUM_MIN_RANGE) {
|
||||
// this tests whether `static_cast`ing max_range is valid
|
||||
// because C style enums stupidly is like a bit field
|
||||
// `enum E { a,b,c,d = 3};` is like a bitfield `struct E { int val : 2;}`
|
||||
// which means giving E.val a larger than 2 bit value is UB so is it for enums
|
||||
// and gcc and msvc ignore this (for good)
|
||||
// while clang makes it a subsituation failure which we can check for
|
||||
// using std::inegral_constant makes sure this is a constant expression situation
|
||||
// for SFINAE to occur
|
||||
if constexpr (is_valid_cast<T, max_range>)
|
||||
return valid_cast_range<T, max_range * 2>();
|
||||
else
|
||||
return max_range / 2;
|
||||
}
|
||||
else {
|
||||
return max_range / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
template<typename T, std::underlying_type_t<T> max_range = 1>
|
||||
constexpr auto valid_cast_range()
|
||||
{
|
||||
if constexpr (max_range >= 0)
|
||||
return ENCHANTUM_MAX_RANGE;
|
||||
else
|
||||
return ENCHANTUM_MIN_RANGE;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace details
|
||||
|
||||
template<UnscopedEnum E>
|
||||
requires SignedEnum<E> && (!EnumFixedUnderlying<E>)
|
||||
struct enum_traits<E> {
|
||||
static constexpr auto max = details::valid_cast_range<E>();
|
||||
static constexpr decltype(max) min = details::valid_cast_range<E, -1>();
|
||||
};
|
||||
|
||||
template<UnscopedEnum E>
|
||||
requires UnsignedEnum<E> && (!EnumFixedUnderlying<E>)
|
||||
struct enum_traits<E> {
|
||||
static constexpr auto max = details::valid_cast_range<E>();
|
||||
static constexpr decltype(max) min = 0;
|
||||
};
|
||||
|
||||
namespace details {
|
||||
|
||||
template<typename _>
|
||||
constexpr auto type_name_func() noexcept
|
||||
{
|
||||
// constexpr auto f() [with _ = Scoped]
|
||||
//return __PRETTY_FUNCTION__;
|
||||
constexpr auto funcname = string_view(
|
||||
__PRETTY_FUNCTION__ + (sizeof("auto enchantum::details::type_name_func() [_ = ") - 1));
|
||||
// (sizeof("auto __cdecl enchantum::details::type_name_func<") - 1)
|
||||
constexpr auto size = funcname.size() - (sizeof("]") - 1);
|
||||
std::array<char, size> ret;
|
||||
auto* const ret_data = ret.data();
|
||||
const auto* const funcname_data = funcname.data();
|
||||
for (std::size_t i = 0; i < size; ++i)
|
||||
ret_data[i] = funcname_data[i];
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline constexpr auto type_name = type_name_func<T>();
|
||||
|
||||
|
||||
template<auto Enum>
|
||||
constexpr auto enum_in_array_name() noexcept
|
||||
{
|
||||
// constexpr auto f() [with auto _ = (
|
||||
//constexpr auto f() [Enum = (Scoped)0]
|
||||
string_view s = __PRETTY_FUNCTION__ + (sizeof("auto enchantum::details::enum_in_array_name() [Enum = ") - 1);
|
||||
s.remove_suffix(sizeof("]") - 1);
|
||||
|
||||
if constexpr (ScopedEnum<decltype(Enum)>) {
|
||||
if (s[s.size() - 2] == ')') {
|
||||
s.remove_prefix(sizeof("(") - 1);
|
||||
s.remove_suffix(sizeof(")0") - 1);
|
||||
return s;
|
||||
}
|
||||
else {
|
||||
return s.substr(0, s.rfind("::"));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (s[s.size() - 2] == ')') {
|
||||
s.remove_prefix(sizeof("(") - 1);
|
||||
s.remove_suffix(sizeof(")0") - 1);
|
||||
}
|
||||
if (const auto pos = s.rfind("::"); pos != s.npos)
|
||||
return s.substr(0, pos);
|
||||
return string_view();
|
||||
}
|
||||
}
|
||||
|
||||
template<auto... Vs>
|
||||
constexpr auto var_name() noexcept
|
||||
{
|
||||
// "auto enchantum::details::var_name() [Vs = <(A)0, a, b, c, e, d, (A)6>]"
|
||||
#define SZC(x) (sizeof(x) - 1)
|
||||
constexpr auto funcsig_off = SZC("auto enchantum::details::var_name() [Vs = <");
|
||||
return string_view(__PRETTY_FUNCTION__ + funcsig_off, SZC(__PRETTY_FUNCTION__) - funcsig_off - SZC(">]"));
|
||||
#undef SZC
|
||||
}
|
||||
|
||||
|
||||
template<auto Copy>
|
||||
inline constexpr auto static_storage_for = Copy;
|
||||
|
||||
template<typename E, typename Pair, bool ShouldNullTerminate>
|
||||
constexpr auto reflect() noexcept
|
||||
{
|
||||
constexpr auto Min = enum_traits<E>::min;
|
||||
constexpr auto Max = enum_traits<E>::max;
|
||||
|
||||
constexpr auto elements = []() {
|
||||
constexpr auto Array = details::generate_arrays<E, Min, Max>();
|
||||
auto str = [Array]<std::size_t... Idx>(std::index_sequence<Idx...>) {
|
||||
return details::var_name<Array[Idx]...>();
|
||||
}(std::make_index_sequence<Array.size()>());
|
||||
|
||||
struct RetVal {
|
||||
std::array<Pair, decltype(Array){}.size()> pairs{};
|
||||
std::size_t total_string_length = 0;
|
||||
std::size_t valid_count = 0;
|
||||
} ret;
|
||||
|
||||
std::size_t index = 0;
|
||||
constexpr auto enum_in_array_name = details::enum_in_array_name<E{}>();
|
||||
constexpr auto enum_in_array_len = enum_in_array_name.size();
|
||||
|
||||
// ((anonymous namespace)::A)0
|
||||
// (anonymous namespace)::a
|
||||
|
||||
// this is needed to determine whether the above are cast expression if 2 braces are
|
||||
// next to eachother then it is a cast but only for anonymoused namespaced enums
|
||||
constexpr std::size_t index_check = !enum_in_array_name.empty() && enum_in_array_name.front() == '(' ? 1 : 0;
|
||||
while (index < Array.size()) {
|
||||
if (str[index_check] == '(') {
|
||||
str.remove_prefix(sizeof("(") - 1 + enum_in_array_len + sizeof(")0") - 1); // there is atleast 1 base 10 digit
|
||||
//if(!str.empty())
|
||||
// std::cout << "after str \"" << str << '"' << '\n';
|
||||
if (const auto commapos = str.find(','); commapos != str.npos)
|
||||
str.remove_prefix(commapos + 2);
|
||||
//std::cout << "strsize \"" << str.size() << '"' << '\n';
|
||||
}
|
||||
else {
|
||||
if constexpr (enum_in_array_len != 0) {
|
||||
str.remove_prefix(enum_in_array_len + (sizeof("::") - 1));
|
||||
}
|
||||
if constexpr (details::prefix_length_or_zero<E> != 0) {
|
||||
str.remove_prefix(details::prefix_length_or_zero<E>);
|
||||
}
|
||||
const auto commapos = str.find(',');
|
||||
|
||||
const auto name = str.substr(0, commapos);
|
||||
|
||||
ret.pairs[ret.valid_count] = Pair{Array[index], name};
|
||||
ret.total_string_length += name.size() + ShouldNullTerminate;
|
||||
|
||||
if (commapos != str.npos)
|
||||
str.remove_prefix(commapos + 2); // skip comma and space
|
||||
++ret.valid_count;
|
||||
}
|
||||
++index;
|
||||
}
|
||||
return ret;
|
||||
}();
|
||||
|
||||
constexpr auto strings = [elements]() {
|
||||
std::array<char, elements.total_string_length> strings;
|
||||
for (std::size_t _i = 0, index = 0; _i < elements.valid_count; ++_i) {
|
||||
const auto& [_, s] = elements.pairs[_i];
|
||||
for (std::size_t i = 0; i < s.size(); ++i)
|
||||
strings[index++] = s[i];
|
||||
|
||||
if constexpr (ShouldNullTerminate)
|
||||
strings[index++] = '\0';
|
||||
}
|
||||
return strings;
|
||||
}();
|
||||
|
||||
std::array<Pair, elements.valid_count> ret;
|
||||
constexpr const auto* str = static_storage_for<strings>.data();
|
||||
for (std::size_t i = 0, string_index = 0; i < elements.valid_count; ++i) {
|
||||
const auto& [e, s] = elements.pairs[i];
|
||||
auto& [re, rs] = ret[i];
|
||||
re = e;
|
||||
|
||||
rs = {str + string_index, str + string_index + s.size()};
|
||||
string_index += s.size() + ShouldNullTerminate;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
|
||||
|
||||
//template<Enum E>
|
||||
//constexpr std::size_t enum_count = details::enum_count<E>;
|
||||
|
||||
|
||||
} // namespace enchantum
|
||||
|
||||
#if __clang_major__ < 20
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
178
build-config/reflect-cpp/include/rfl/thirdparty/enchantum/details/enchantum_gcc.hpp
vendored
Normal file
178
build-config/reflect-cpp/include/rfl/thirdparty/enchantum/details/enchantum_gcc.hpp
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
#include "../common.hpp"
|
||||
#include "generate_arrays.hpp"
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <utility>
|
||||
|
||||
#include "string_view.hpp"
|
||||
|
||||
namespace enchantum {
|
||||
|
||||
namespace details {
|
||||
|
||||
|
||||
template<typename _>
|
||||
constexpr auto type_name_func() noexcept
|
||||
{
|
||||
// constexpr auto f() [with _ = Scoped]
|
||||
//return __PRETTY_FUNCTION__;
|
||||
constexpr auto funcname = string_view(
|
||||
__PRETTY_FUNCTION__ + (sizeof("constexpr auto enchantum::details::type_name_func() [with _ = ") - 1));
|
||||
// (sizeof("auto __cdecl enchantum::details::type_name_func<") - 1)
|
||||
constexpr auto size = funcname.size() - (sizeof("]") - 1);
|
||||
std::array<char, size> ret;
|
||||
auto* const ret_data = ret.data();
|
||||
const auto* const funcname_data = funcname.data();
|
||||
for (std::size_t i = 0; i < size; ++i)
|
||||
ret_data[i] = funcname_data[i];
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline constexpr auto type_name = type_name_func<T>();
|
||||
|
||||
|
||||
template<auto Enum>
|
||||
constexpr auto enum_in_array_name() noexcept
|
||||
{
|
||||
// constexpr auto f() [with auto _ = (
|
||||
//constexpr auto f() [with auto _ = (Scoped)0]
|
||||
string_view s = __PRETTY_FUNCTION__ +
|
||||
sizeof("constexpr auto enchantum::details::enum_in_array_name() [with auto Enum = ") - 1;
|
||||
s.remove_suffix(sizeof("]") - 1);
|
||||
|
||||
if constexpr (ScopedEnum<decltype(Enum)>) {
|
||||
if (s.front() == '(') {
|
||||
s.remove_prefix(1);
|
||||
s.remove_suffix(sizeof(")0") - 1);
|
||||
return s;
|
||||
}
|
||||
else {
|
||||
return s.substr(0, s.rfind("::"));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (s.front() == '(') {
|
||||
s.remove_prefix(1);
|
||||
s.remove_suffix(sizeof(")0") - 1);
|
||||
}
|
||||
if (const auto pos = s.rfind("::"); pos != s.npos)
|
||||
return s.substr(0, pos);
|
||||
return string_view();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Enum>
|
||||
constexpr auto length_of_enum_in_template_array_if_casting() noexcept
|
||||
{
|
||||
if constexpr (ScopedEnum<Enum>) {
|
||||
return details::enum_in_array_name<Enum{}>().size();
|
||||
}
|
||||
else {
|
||||
constexpr auto s = enum_in_array_name<Enum{}>().size();
|
||||
constexpr auto& tyname = type_name<Enum>;
|
||||
constexpr auto str = string_view(tyname.data(), tyname.size());
|
||||
if (constexpr auto pos = str.rfind("::"); pos != str.npos) {
|
||||
return s + str.substr(pos).size();
|
||||
}
|
||||
else {
|
||||
return s + tyname.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<auto... Vs>
|
||||
constexpr auto var_name() noexcept
|
||||
{
|
||||
//constexpr auto f() [with auto _ = std::array<E, 6>{std::__array_traits<E, 6>::_Type{a, b, c, e, d, (E)6}}]
|
||||
#define SZC(x) (sizeof(x) - 1)
|
||||
constexpr std::size_t funcsig_off = SZC("constexpr auto enchantum::details::var_name() [with auto ...Vs = {");
|
||||
return std::string_view(__PRETTY_FUNCTION__ + funcsig_off, SZC(__PRETTY_FUNCTION__) - funcsig_off - SZC("}]"));
|
||||
}
|
||||
|
||||
|
||||
template<auto Copy>
|
||||
inline constexpr auto static_storage_for = Copy;
|
||||
|
||||
template<typename E, typename Pair, bool ShouldNullTerminate>
|
||||
constexpr auto reflect() noexcept
|
||||
{
|
||||
constexpr auto Min = enum_traits<E>::min;
|
||||
constexpr auto Max = enum_traits<E>::max;
|
||||
|
||||
constexpr auto elements = []() {
|
||||
constexpr auto length_of_enum_in_template_array_casting = details::length_of_enum_in_template_array_if_casting<E>();
|
||||
constexpr auto Array = details::generate_arrays<E, Min, Max>();
|
||||
auto str = [Array]<std::size_t... Idx>(std::index_sequence<Idx...>) {
|
||||
return details::var_name<Array[Idx]...>();
|
||||
}(std::make_index_sequence<Array.size()>());
|
||||
struct RetVal {
|
||||
std::array<Pair, Array.size()> pairs{};
|
||||
std::size_t total_string_length = 0;
|
||||
std::size_t valid_count = 0;
|
||||
} ret;
|
||||
std::size_t index = 0;
|
||||
constexpr auto enum_in_array_len = enum_in_array_name<E{}>().size();
|
||||
while (index < Array.size()) {
|
||||
if (str.front() == '(') {
|
||||
str.remove_prefix(sizeof("(") - 1 + length_of_enum_in_template_array_casting + sizeof(")0") -
|
||||
1); // there is atleast 1 base 10 digit
|
||||
//if(!str.empty())
|
||||
// std::cout << "after str \"" << str << '"' << '\n';
|
||||
|
||||
if (const auto commapos = str.find(','); commapos != str.npos)
|
||||
str.remove_prefix(commapos + 2);
|
||||
|
||||
//std::cout << "strsize \"" << str.size() << '"' << '\n';
|
||||
}
|
||||
else {
|
||||
if constexpr (enum_in_array_len != 0)
|
||||
str.remove_prefix(enum_in_array_len + sizeof("::") - 1);
|
||||
if constexpr (details::prefix_length_or_zero<E> != 0) {
|
||||
str.remove_prefix(details::prefix_length_or_zero<E>);
|
||||
}
|
||||
const auto commapos = str.find(',');
|
||||
|
||||
const auto name = str.substr(0, commapos);
|
||||
|
||||
ret.pairs[ret.valid_count] = Pair{Array[index], name};
|
||||
ret.total_string_length += name.size() + ShouldNullTerminate;
|
||||
|
||||
if (commapos != str.npos)
|
||||
str.remove_prefix(commapos + 2);
|
||||
++ret.valid_count;
|
||||
}
|
||||
++index;
|
||||
}
|
||||
return ret;
|
||||
}();
|
||||
|
||||
constexpr auto strings = [elements]() {
|
||||
std::array<char, elements.total_string_length> strings;
|
||||
for (std::size_t _i = 0, index = 0; _i < elements.valid_count; ++_i) {
|
||||
const auto& [_, s] = elements.pairs[_i];
|
||||
for (std::size_t i = 0; i < s.size(); ++i)
|
||||
strings[index++] = s[i];
|
||||
|
||||
if constexpr (ShouldNullTerminate)
|
||||
strings[index++] = '\0';
|
||||
}
|
||||
return strings;
|
||||
}();
|
||||
|
||||
std::array<Pair, elements.valid_count> ret;
|
||||
constexpr const auto* str = static_storage_for<strings>.data();
|
||||
for (std::size_t i = 0, string_index = 0; i < elements.valid_count; ++i) {
|
||||
const auto& [e, s] = elements.pairs[i];
|
||||
auto& [re, rs] = ret[i];
|
||||
re = e;
|
||||
|
||||
rs = {str + string_index, str + string_index + s.size()};
|
||||
string_index += s.size() + ShouldNullTerminate;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
|
||||
} // namespace enchantum
|
||||
158
build-config/reflect-cpp/include/rfl/thirdparty/enchantum/details/enchantum_msvc.hpp
vendored
Normal file
158
build-config/reflect-cpp/include/rfl/thirdparty/enchantum/details/enchantum_msvc.hpp
vendored
Normal file
@@ -0,0 +1,158 @@
|
||||
#pragma once
|
||||
#include "../common.hpp"
|
||||
#include "generate_arrays.hpp"
|
||||
#include "string_view.hpp"
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
|
||||
namespace enchantum {
|
||||
|
||||
namespace details {
|
||||
|
||||
#define SZC(x) (sizeof(x) - 1)
|
||||
template<typename>
|
||||
constexpr auto type_name_func_size() noexcept
|
||||
{
|
||||
// (sizeof("auto __cdecl enchantum::details::type_name_func<") - 1)
|
||||
return SZC(__FUNCSIG__) - SZC("auto __cdecl enchantum::details::type_name_func_size<enum ") -
|
||||
SZC(">(void) noexcept");
|
||||
}
|
||||
|
||||
template<auto Enum>
|
||||
constexpr auto enum_in_array_name() noexcept
|
||||
{
|
||||
string_view s = __FUNCSIG__ + sizeof("auto __cdecl enchantum::details::enum_in_array_name<") - 1;
|
||||
s.remove_suffix(sizeof(">(void) noexcept") - 1);
|
||||
|
||||
if constexpr (ScopedEnum<decltype(Enum)>) {
|
||||
if (s.front() == '(') {
|
||||
s.remove_prefix(sizeof("(enum ") - 1);
|
||||
s.remove_suffix(sizeof(")0x0") - 1);
|
||||
return s;
|
||||
}
|
||||
return s.substr(0, s.rfind("::"));
|
||||
}
|
||||
else {
|
||||
if (s.front() == '(') {
|
||||
s.remove_prefix(sizeof("(enum ") - 1);
|
||||
s.remove_suffix(sizeof(")0x0") - 1);
|
||||
}
|
||||
if (const auto pos = s.rfind("::"); pos != s.npos)
|
||||
return s.substr(0, pos);
|
||||
return string_view();
|
||||
}
|
||||
}
|
||||
|
||||
template<auto Array>
|
||||
constexpr auto var_name() noexcept
|
||||
{
|
||||
//auto __cdecl f<class std::array<enum `anonymous namespace'::UnscopedAnon,32>{enum `anonymous-namespace'::UnscopedAnon
|
||||
|
||||
using T = typename decltype(Array)::value_type;
|
||||
#define SZC(x) (sizeof(x) - 1)
|
||||
std::size_t funcsig_off = SZC("auto __cdecl enchantum::details::var_name<class std::array<enum ");
|
||||
constexpr auto type_name_len = enchantum::details::type_name_func_size<T>();
|
||||
funcsig_off += type_name_len + SZC(",");
|
||||
constexpr auto Size = Array.size();
|
||||
// clang-format off
|
||||
funcsig_off += Size < 10 ? 1
|
||||
: Size < 100 ? 2
|
||||
: Size < 1000 ? 3
|
||||
: Size < 10000 ? 4
|
||||
: Size < 100000 ? 5
|
||||
: Size < 1000000 ? 6
|
||||
: Size < 10000000 ? 7
|
||||
: Size < 100000000 ? 8
|
||||
: Size < 1000000000 ? 9
|
||||
: 10;
|
||||
// clang-format on
|
||||
funcsig_off += SZC(">{enum ") + type_name_len;
|
||||
return string_view(__FUNCSIG__ + funcsig_off, SZC(__FUNCSIG__) - funcsig_off - (sizeof("}>(void) noexcept") - 1));
|
||||
}
|
||||
#undef SZC
|
||||
|
||||
|
||||
template<auto Copy>
|
||||
inline constexpr auto static_storage_for = Copy;
|
||||
|
||||
template<typename E, typename Pair, auto Array, bool ShouldNullTerminate>
|
||||
constexpr auto get_elements()
|
||||
{
|
||||
constexpr auto type_name_len = details::type_name_func_size<E>();
|
||||
|
||||
auto str = var_name<Array>();
|
||||
struct RetVal {
|
||||
std::array<Pair, Array.size()> pairs{};
|
||||
std::size_t total_string_length = 0;
|
||||
std::size_t valid_count = 0;
|
||||
} ret;
|
||||
std::size_t index = 0;
|
||||
constexpr auto enum_in_array_len = details::enum_in_array_name<E{}>().size();
|
||||
while (index < Array.size()) {
|
||||
if (str.front() == '(') {
|
||||
str.remove_prefix(sizeof("(enum ") - 1 + type_name_len + sizeof(")0x0") - 1); // there is atleast 1 base 16 hex digit
|
||||
|
||||
if (const auto commapos = str.find(','); commapos != str.npos)
|
||||
str.remove_prefix(commapos + 1);
|
||||
}
|
||||
else {
|
||||
if constexpr (enum_in_array_len != 0)
|
||||
str.remove_prefix(enum_in_array_len + sizeof("::") - 1);
|
||||
|
||||
if constexpr (details::prefix_length_or_zero<E> != 0)
|
||||
str.remove_prefix(details::prefix_length_or_zero<E>);
|
||||
|
||||
const auto commapos = str.find(',');
|
||||
|
||||
const auto name = str.substr(0, commapos);
|
||||
|
||||
ret.pairs[ret.valid_count] = Pair{Array[index], name};
|
||||
ret.total_string_length += name.size() + ShouldNullTerminate;
|
||||
|
||||
if (commapos != str.npos)
|
||||
str.remove_prefix(commapos + 1);
|
||||
++ret.valid_count;
|
||||
}
|
||||
++index;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename E, typename Pair, bool ShouldNullTerminate>
|
||||
constexpr auto reflect() noexcept
|
||||
{
|
||||
constexpr auto Min = enum_traits<E>::min;
|
||||
constexpr auto Max = enum_traits<E>::max;
|
||||
|
||||
constexpr auto elements = details::get_elements<E, Pair, details::generate_arrays<E, Min, Max>(), ShouldNullTerminate>();
|
||||
|
||||
constexpr auto strings = [elements]() {
|
||||
std::array<char, elements.total_string_length> strings;
|
||||
for (std::size_t _i = 0, index = 0; _i < elements.valid_count; ++_i) {
|
||||
const auto& [_, s] = elements.pairs[_i];
|
||||
for (std::size_t i = 0; i < s.size(); ++i)
|
||||
strings[index++] = s[i];
|
||||
|
||||
if constexpr (ShouldNullTerminate)
|
||||
strings[index++] = '\0';
|
||||
}
|
||||
return strings;
|
||||
}();
|
||||
|
||||
std::array<Pair, elements.valid_count> ret;
|
||||
constexpr const auto* str = static_storage_for<strings>.data();
|
||||
for (std::size_t i = 0, string_index = 0; i < elements.valid_count; ++i) {
|
||||
const auto& [e, s] = elements.pairs[i];
|
||||
auto& [re, rs] = ret[i];
|
||||
re = e;
|
||||
|
||||
rs = {str + string_index, str + string_index + s.size()};
|
||||
string_index += s.size() + ShouldNullTerminate;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
} // namespace details
|
||||
|
||||
|
||||
} // namespace enchantum
|
||||
20
build-config/reflect-cpp/include/rfl/thirdparty/enchantum/details/format_util.hpp
vendored
Normal file
20
build-config/reflect-cpp/include/rfl/thirdparty/enchantum/details/format_util.hpp
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
#include "../enchantum.hpp"
|
||||
#include <string>
|
||||
|
||||
namespace enchantum {
|
||||
namespace details {
|
||||
template<Enum E>
|
||||
std::string format(E e) noexcept
|
||||
{
|
||||
if constexpr (is_bitflag<E>) {
|
||||
if (const auto name = enchantum::to_string_bitflag(e); !name.empty())
|
||||
return std::string(name.data(), name.size());
|
||||
}
|
||||
else {
|
||||
if (const auto name = enchantum::to_string(e); !name.empty())
|
||||
return std::string(name.data(), name.size());
|
||||
}
|
||||
return std::to_string(+enchantum::to_underlying(e)); // promote using + to select int overload if to underlying returns char
|
||||
}
|
||||
} // namespace details
|
||||
} // namespace enchantum
|
||||
63
build-config/reflect-cpp/include/rfl/thirdparty/enchantum/details/generate_arrays.hpp
vendored
Normal file
63
build-config/reflect-cpp/include/rfl/thirdparty/enchantum/details/generate_arrays.hpp
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
#include "../common.hpp"
|
||||
#include <array>
|
||||
#include <climits>
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
|
||||
namespace enchantum::details {
|
||||
|
||||
template<typename E, typename = void>
|
||||
inline constexpr std::size_t prefix_length_or_zero = 0;
|
||||
|
||||
template<typename E>
|
||||
inline constexpr auto prefix_length_or_zero<E, decltype((void)enum_traits<E>::prefix_length)> = std::size_t{
|
||||
enum_traits<E>::prefix_length};
|
||||
|
||||
template<typename Enum, auto Min, decltype(Min) Max>
|
||||
constexpr auto generate_arrays()
|
||||
{
|
||||
#if defined __clang__ && __clang_major__ >= 20
|
||||
if constexpr (BitFlagEnum<Enum>) {
|
||||
if constexpr (EnumFixedUnderlying<Enum>) {
|
||||
constexpr std::size_t bits = sizeof(Enum) * CHAR_BIT;
|
||||
std::array<Enum, bits + 1> ret{}; // 0 value reflected
|
||||
for (std::size_t i = 0; i < bits; ++i)
|
||||
ret[i + 1] = static_cast<Enum>(static_cast<std::make_unsigned_t<std::underlying_type_t<Enum>>>(1) << i);
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
constexpr auto bits =
|
||||
[]() {
|
||||
auto copy = (Max > Min ? Max - Min : Min - Max); // handle negative;
|
||||
std::size_t count = 0;
|
||||
do
|
||||
++count;
|
||||
while (copy >>= 1);
|
||||
return count;
|
||||
}();
|
||||
std::array<Enum, bits + 1> b{}; // 0 value reflected
|
||||
for (std::size_t i = 0; i < bits; ++i)
|
||||
b[i + 1] = static_cast<Enum>(static_cast<std::make_unsigned_t<std::underlying_type_t<Enum>>>(1) << i);
|
||||
return b;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if constexpr (BitFlagEnum<Enum>) {
|
||||
constexpr std::size_t bits = sizeof(Enum) * CHAR_BIT;
|
||||
std::array<Enum, bits + 1> ret{}; // 0 value reflected
|
||||
for (std::size_t i = 0; i < bits; ++i)
|
||||
ret[i + 1] = static_cast<Enum>(static_cast<std::make_unsigned_t<std::underlying_type_t<Enum>>>(1) << i);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
static_assert(Min < Max, "enum_traits::min must be less than enum_traits::max");
|
||||
std::array<Enum, (Max - Min) + 1> array;
|
||||
auto* const array_data = array.data();
|
||||
for (std::size_t i = 0, size = array.size(); i < size; ++i)
|
||||
array_data[i] = static_cast<Enum>(static_cast<decltype(Min)>(i) + Min);
|
||||
return array;
|
||||
}
|
||||
}
|
||||
} // namespace enchantum::details
|
||||
19
build-config/reflect-cpp/include/rfl/thirdparty/enchantum/details/optional.hpp
vendored
Normal file
19
build-config/reflect-cpp/include/rfl/thirdparty/enchantum/details/optional.hpp
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef ENCHANTUM_CONFIG_FILE
|
||||
#include ENCHANTUM_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#ifndef ENCHANTUM_ALIAS_OPTIONAL
|
||||
#include <optional>
|
||||
#endif
|
||||
|
||||
|
||||
namespace enchantum {
|
||||
#ifdef ENCHANTUM_ALIAS_OPTIONAL
|
||||
ENCHANTUM_ALIAS_OPTIONAL;
|
||||
#else
|
||||
using ::std::optional;
|
||||
#endif
|
||||
|
||||
} // namespace enchantum
|
||||
20
build-config/reflect-cpp/include/rfl/thirdparty/enchantum/details/string_view.hpp
vendored
Normal file
20
build-config/reflect-cpp/include/rfl/thirdparty/enchantum/details/string_view.hpp
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#ifdef ENCHANTUM_CONFIG_FILE
|
||||
#include ENCHANTUM_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#ifndef ENCHANTUM_ALIAS_STRING_VIEW
|
||||
#include <string_view>
|
||||
#endif
|
||||
|
||||
|
||||
namespace enchantum {
|
||||
#ifdef ENCHANTUM_ALIAS_STRING_VIEW
|
||||
ENCHANTUM_ALIAS_STRING_VIEW;
|
||||
#else
|
||||
using ::std::string_view;
|
||||
#endif
|
||||
|
||||
} // namespace enchantum
|
||||
Reference in New Issue
Block a user