File indexing completed on 2024-11-16 09:44:28
0001
0002
0003
0004
0005 #pragma once
0006 #include <cstdint>
0007 #include <cxxabi.h>
0008 #include <string>
0009
0010 namespace JTypeInfo {
0011
0012 #if __cplusplus >= 201703L
0013 template <typename, typename=void>
0014 struct is_parseable : std::false_type {};
0015
0016 template <typename T>
0017 struct is_parseable<T, std::void_t<decltype(std::declval<std::istream>() >> std::declval<T&>())>> : std::true_type {};
0018
0019 template <typename, typename=void>
0020 struct is_serializable : std::false_type {};
0021
0022 template <typename T>
0023 struct is_serializable<T, std::void_t<decltype(std::declval<std::ostream>() << std::declval<T>())>> : std::true_type {};
0024 #endif
0025
0026
0027 template<typename T>
0028 std::string demangle() {
0029
0030
0031
0032
0033 int status = -1;
0034 auto cstr = abi::__cxa_demangle(typeid(T).name(), NULL, NULL, &status);
0035 std::string type(cstr);
0036 free(cstr);
0037 if (status != 0) type = typeid(T).name();
0038 return type;
0039 }
0040
0041
0042 inline std::string demangle_current_exception_type() {
0043
0044 int status = -1;
0045 auto cstr = abi::__cxa_demangle(abi::__cxa_current_exception_type()->name(), NULL, NULL, &status);
0046 std::string type(cstr);
0047 free(cstr);
0048 if (status != 0) type = abi::__cxa_current_exception_type()->name();
0049 return type;
0050 }
0051
0052
0053
0054
0055 #define NAME_OF(T) #T
0056
0057
0058
0059
0060
0061 #define NAME_OF_THIS JTypeInfo::demangle<decltype(*this)>()
0062
0063
0064 template<typename T>
0065 const char* builtin_typename() {
0066
0067
0068
0069 if (typeid(T) == typeid(int) || typeid(T) == typeid(int32_t)) {
0070 return "int";
0071 } else if (typeid(T) == typeid(unsigned int) || typeid(T) == typeid(uint32_t)) {
0072 return "uint";
0073 } else if (typeid(T) == typeid(long) || typeid(T) == typeid(int64_t)) {
0074 return "long";
0075 } else if (typeid(T) == typeid(unsigned long) || typeid(T) == typeid(uint64_t)) {
0076 return "ulong";
0077 } else if (typeid(T) == typeid(short) || typeid(T) == typeid(int16_t)) {
0078 return "short";
0079 } else if (typeid(T) == typeid(unsigned short) || typeid(T) == typeid(uint16_t)) {
0080 return "ushort";
0081 } else if (typeid(T) == typeid(float)) {
0082 return "float";
0083 } else if (typeid(T) == typeid(double)) {
0084 return "double";
0085 } else if (typeid(T) == typeid(std::string) || typeid(T) == typeid(const char*) || typeid(T) == typeid(char*)) {
0086 return "string";
0087 } else {
0088 return "unknown";
0089 }
0090 };
0091
0092 inline std::string to_string_with_si_prefix(float val) {
0093
0094
0095
0096
0097
0098 const char* units = "";
0099 if (val > 1.5E9) {
0100 val /= 1.0E9;
0101 units = "G";
0102 } else if (val > 1.5E6) {
0103 val /= 1.0E6;
0104 units = "M";
0105 } else if (val > 1.5E3) {
0106 val /= 1.0E3;
0107 units = "k";
0108 } else if (val < 1.0E-7) {
0109 units = "";
0110 } else if (val < 1.0E-4) {
0111 val *= 1.0E6;
0112 units = "u";
0113 } else if (val < 1.0E-1) {
0114 val *= 1.0E3;
0115 units = "m";
0116 }
0117 char str[256];
0118 snprintf(str, 256, "%3.1f %s", val, units);
0119 return std::string(str);
0120 }
0121
0122
0123 }