Minor StrFmt fix

Added fmt_unveil<f16>
Added enum helper (experimental)
This commit is contained in:
Nekotekina 2017-05-14 23:29:33 +03:00
parent 88fef183a3
commit 3a1f1dbc1a

View file

@ -15,7 +15,7 @@ namespace fmt
template <typename T, typename> template <typename T, typename>
struct fmt_unveil struct fmt_unveil
{ {
static_assert(sizeof(T) > 0, "fmt_unveil<>: cannot pass forward-declared object"); static_assert(sizeof(T) > 0, "fmt_unveil<> error: incomplete type");
using type = T; using type = T;
@ -59,13 +59,24 @@ struct fmt_unveil<T, std::enable_if_t<std::is_floating_point<T>::value && sizeof
{ {
using type = T; using type = T;
// Convert FP to f64 and reinterpret (TODO?) // Convert FP to f64 and reinterpret as u64
static inline u64 get(const f64 arg) static inline u64 get(const f64& arg)
{ {
return *reinterpret_cast<const u64*>(reinterpret_cast<const u8*>(&arg)); return *reinterpret_cast<const u64*>(reinterpret_cast<const u8*>(&arg));
} }
}; };
template <>
struct fmt_unveil<f16, void>
{
using type = f16;
static inline u64 get(const f16& arg)
{
return fmt_unveil<f64>::get(arg.operator float());
}
};
template <typename T> template <typename T>
struct fmt_unveil<T, std::enable_if_t<std::is_enum<T>::value>> struct fmt_unveil<T, std::enable_if_t<std::is_enum<T>::value>>
{ {
@ -126,15 +137,27 @@ struct fmt_class_string
return *reinterpret_cast<const T*>(static_cast<std::uintptr_t>(arg)); return *reinterpret_cast<const T*>(static_cast<std::uintptr_t>(arg));
} }
// Enum -> string function type
using convert_t = const char*(*)(T value);
// Enum -> string function registered
static convert_t convert_enum;
// Helper function (safely converts arg to enum value) // Helper function (safely converts arg to enum value)
static SAFE_BUFFERS FORCE_INLINE void format_enum(std::string& out, u64 arg, const char* (*get)(T value)) static SAFE_BUFFERS FORCE_INLINE void format_enum(std::string& out, u64 arg, convert_t convert)
{ {
// Save convert function
if (convert_enum == nullptr)
{
convert_enum = convert;
}
const auto value = static_cast<std::underlying_type_t<T>>(arg); const auto value = static_cast<std::underlying_type_t<T>>(arg);
// Check narrowing // Check narrowing
if (static_cast<u64>(value) == arg) if (static_cast<u64>(value) == arg)
{ {
if (const char* str = get(static_cast<T>(value))) if (const char* str = convert(static_cast<T>(value)))
{ {
out += str; out += str;
return; return;
@ -180,6 +203,9 @@ struct fmt_class_string
static constexpr const char* unknown = nullptr; static constexpr const char* unknown = nullptr;
}; };
template <typename T, typename V>
const char*(*fmt_class_string<T, V>::convert_enum)(T) = nullptr;
template <> template <>
struct fmt_class_string<const void*, void> struct fmt_class_string<const void*, void>
{ {