Created
April 27, 2022 14:37
-
-
Save connornishijima/72aa18928ab96de299faefdc78dc3d9f to your computer and use it in GitHub Desktop.
Compact universal "to_string()" conversion
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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