From df9980ee3e2e853cec7f20516a55c7f4195575e3 Mon Sep 17 00:00:00 2001 From: heinrich5991 Date: Tue, 14 May 2024 10:17:02 +0200 Subject: [PATCH] =?UTF-8?q?Optimize=20`str=5Fformat(=E2=80=A6,=20=E2=80=A6?= =?UTF-8?q?,=20"%d",=20=E2=80=A6)`=20using=20templates?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This would make the function `str_from_int` unnecessary, at least user-facing. Advantage: User doesn't have to care about `str_from_int`/`str_format` distinction. Disadvantage: We're adding some template programming to `system.h`, potentially slowing all compilation. --- CMakeLists.txt | 6 +++++- src/base/system.cpp | 19 ++++++++++++------- src/base/system.h | 33 +++++++++++++++++++++++++-------- 3 files changed, 42 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ad42e0ee7..5ce17050a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -319,7 +319,11 @@ if(NOT MSVC AND NOT HAIKU) add_cxx_compiler_flag_if_supported(OUR_FLAGS_OWN -Wno-psabi) # parameter passing for argument of type ‘__gnu_cxx::__normal_iterator*, std::vector, std::allocator > > >’ changed in GCC 7.1 add_cxx_compiler_flag_if_supported(OUR_FLAGS_OWN -Wno-unused-parameter) add_cxx_compiler_flag_if_supported(OUR_FLAGS_OWN -Wno-missing-field-initializers) - add_cxx_compiler_flag_if_supported(OUR_FLAGS_OWN -Wformat=2) # Warn about format strings. + if(CMAKE_BUILD_TYPE STREQUAL DEBUG) + add_cxx_compiler_flag_if_supported(OUR_FLAGS_OWN -Wformat=2) # Warn about format strings. + else() + add_cxx_compiler_flag_if_supported(OUR_FLAGS_OWN -Wno-format) # Don't warn about format strings in release mode since our `str_format` optimization is incompatible with it. + endif() add_c_compiler_flag_if_supported(OUR_FLAGS_DEP -Wno-implicit-function-declaration) add_cxx_compiler_flag_if_supported(OUR_FLAGS_OWN -Wno-nullability-completeness) # Mac OS build on github add_cxx_compiler_flag_if_supported(OUR_FLAGS_OWN -Wduplicated-cond) diff --git a/src/base/system.cpp b/src/base/system.cpp index 0048d3fb7..616d1d060 100644 --- a/src/base/system.cpp +++ b/src/base/system.cpp @@ -2784,6 +2784,15 @@ int str_format_v(char *buffer, int buffer_size, const char *format, va_list args return str_utf8_fix_truncation(buffer); } +int str_format_int(char *buffer, size_t buffer_size, int value) +{ + buffer[0] = '\0'; // Fix false positive clang-analyzer-core.UndefinedBinaryOperatorResult when using result + auto result = std::to_chars(buffer, buffer + buffer_size - 1, value); + result.ptr[0] = '\0'; + return result.ptr - buffer; +} + +#undef str_format int str_format(char *buffer, int buffer_size, const char *format, ...) { va_list args; @@ -2792,6 +2801,9 @@ int str_format(char *buffer, int buffer_size, const char *format, ...) va_end(args); return length; } +#if !defined(CONF_DEBUG) +#define str_format str_format_opt +#endif const char *str_trim_words(const char *str, int words) { @@ -3639,13 +3651,6 @@ bool str_tofloat(const char *str, float *out) return true; } -void str_from_int(int value, char *buffer, size_t buffer_size) -{ - buffer[0] = '\0'; // Fix false positive clang-analyzer-core.UndefinedBinaryOperatorResult when using result - auto result = std::to_chars(buffer, buffer + buffer_size - 1, value); - result.ptr[0] = '\0'; -} - int str_utf8_comp_nocase(const char *a, const char *b) { int code_a; diff --git a/src/base/system.h b/src/base/system.h index 257cde71d..38ad314fc 100644 --- a/src/base/system.h +++ b/src/base/system.h @@ -1229,6 +1229,31 @@ int str_format_v(char *buffer, int buffer_size, const char *format, va_list args int str_format(char *buffer, int buffer_size, const char *format, ...) GNUC_ATTRIBUTE((format(printf, 3, 4))); +#if !defined(CONF_DEBUG) +int str_format_int(char *buffer, size_t buffer_size, int value); + +template +int str_format_opt(char *buffer, int buffer_size, const char *format, Args... args) +{ + return str_format(buffer, buffer_size, format, args...); +} + +template<> +inline int str_format_opt(char *buffer, int buffer_size, const char *format, int val) +{ + if(strcmp(format, "%d") == 0) + { + return str_format_int(buffer, buffer_size, val); + } + else + { + return str_format(buffer, buffer_size, format, val); + } +} + +#define str_format str_format_opt +#endif + /** * Trims specific number of words at the start of a string. * @@ -2098,14 +2123,6 @@ int64_t str_toint64_base(const char *str, int base = 10); float str_tofloat(const char *str); bool str_tofloat(const char *str, float *out); -void str_from_int(int value, char *buffer, size_t buffer_size); - -template -void str_from_int(int value, char (&dst)[N]) -{ - str_from_int(value, dst, N); -} - /** * Determines whether a character is whitespace. *