Skip to content

Instantly share code, notes, and snippets.

@connornishijima
Created April 27, 2022 14:37
Show Gist options
  • Save connornishijima/72aa18928ab96de299faefdc78dc3d9f to your computer and use it in GitHub Desktop.
Save connornishijima/72aa18928ab96de299faefdc78dc3d9f to your computer and use it in GitHub Desktop.
Compact universal "to_string()" conversion
// Allows for a "print()" function that accepts char* to take any common variable type
// Also allows you to detect the type of any variable if that type was first defined
// in a MAKE_TYPE_INFO(type) macro
// @lixielabs 4/27/22
template <typename t_type> struct type_info { static const char * name; }; // Define type_info
template <typename t_type> const char * type_info<t_type>::name = "unknown"; // Set default state
#define TYPE_NAME(var) type_info< typeof(var) >::name // Macro to parse variable type name
#define MAKE_TYPE_INFO(type) template <> const char * type_info<type>::name = #type; // Macro to define variable type name
MAKE_TYPE_INFO( float ) // Set up definitions for floats and doubles
MAKE_TYPE_INFO( double )
#define FLOAT_PRECISION 3 // Decimal places of float to parse
template <typename T> // Template allows ambiguous variable type as parameter
const char* to_string(T t) {
const char* type_name = TYPE_NAME(t); // No longer ambiguous now
if (strcmp(type_name, "float") == 0 || strcmp(type_name, "double") == 0) { // Is this floating-point?
char* str = (char*)malloc(sizeof(char) * (FLOAT_PRECISION + 10));
sprintf(str, "%.*f", FLOAT_PRECISION, t);
return str;
}
else{ // Any numeric variable that isn't a floating point is sprinted in a int64_t context to allow most common bit depths and signed/unsigned without issue
char* str = (char*)malloc(sizeof(char) * 11);
sprintf(str, "%lld", (long long)t);
return str;
}
}
// Numbers and strings don't seem to mix with this template method, so only three string overloads are needed:
const char* to_string(char* message) { return message; }
const char* to_string(const char* message) { return message; }
const char* to_string(String message) {
char* str = (char*)malloc(message.length() + 1);
strcpy(str, message.c_str());
return str;
}
// -------------------------------------------------------------------
// -------------------------------------------------------------------
// -------------------------------------------------------------------
to_string(123); // uint8_t
to_string(-12345); // int16_t
to_string(12.345); // float
to_string(true); // bool
to_string("HI"); // const char* (passthrough)
to_string(String("HI")); // String (passthrough)
// All are returned as char*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment