refactor: Introduce struct to hold a runtime format string

This brings the format types closer to the standard library types:

* FormatStringCheck corresponds to std::basic_format_string, with
  compile-time checks done via ConstevalFormatString
* RuntimeFormat corresponds to std::runtime_format, with no compile-time
  checks done.

Also, it documents where no compile-time checks are done.
This commit is contained in:
MarcoFalke
2024-12-07 11:49:48 +01:00
parent fa6adb0134
commit fa3efb5729
5 changed files with 33 additions and 20 deletions

View File

@@ -142,6 +142,7 @@ namespace tfm = tinyformat;
//------------------------------------------------------------------------------
// Implementation details.
#include <algorithm>
#include <attributes.h> // Added for Bitcoin Core
#include <iostream>
#include <sstream>
#include <stdexcept> // Added for Bitcoin Core
@@ -179,13 +180,19 @@ namespace tfm = tinyformat;
namespace tinyformat {
// Added for Bitcoin Core. Similar to std::runtime_format from C++26.
struct RuntimeFormat {
const std::string& fmt; // Not a string view, because tinyformat requires a c_str
explicit RuntimeFormat(LIFETIMEBOUND const std::string& str) : fmt{str} {}
};
// Added for Bitcoin Core. Wrapper for checking format strings at compile time.
// Unlike ConstevalFormatString this supports std::string for runtime string
// formatting without compile time checks.
// Unlike ConstevalFormatString this supports RunTimeFormat-wrapped std::string
// for runtime string formatting without compile time checks.
template <unsigned num_params>
struct FormatStringCheck {
consteval FormatStringCheck(const char* str) : fmt{util::ConstevalFormatString<num_params>{str}.fmt} {}
FormatStringCheck(const std::string& str) : fmt{str.c_str()} {}
FormatStringCheck(LIFETIMEBOUND const RuntimeFormat& run) : fmt{run.fmt.c_str()} {}
FormatStringCheck(util::ConstevalFormatString<num_params> str) : fmt{str.fmt} {}
operator const char*() { return fmt; }
const char* fmt;