Repository: bitcoin/bitcoin
File: src/tinyformat.h (C/C++)

Code before:
#   ifdef __GXX_EXPERIMENTAL_CXX0X__
#       define TINYFORMAT_USE_VARIADIC_TEMPLATES
#   endif
#endif

#if defined(__GLIBCXX__) && __GLIBCXX__ < 20080201
//  std::showpos is broken on old libstdc++ as provided with macOS.  See
//  http://gcc.gnu.org/ml/libstdc++/2007-11/msg00075.html
#   define TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND
#endif

#ifdef __APPLE__
// Workaround macOS linker warning: Xcode uses different default symbol
// visibilities for static libs vs executables (see issue #25)
#   define TINYFORMAT_HIDDEN __attribute__((visibility("hidden")))
#else
#   define TINYFORMAT_HIDDEN
#endif

namespace tinyformat {

// Added for Bitcoin Core. Wrapper type for format strings to allow compile-time checks.
struct FormatString {
    const char* fmt;
    operator const char*() { return fmt; }
};

// 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.
template <unsigned num_params>
struct FormatStringCheck : FormatString {
    consteval FormatStringCheck(const char* str) : FormatString{util::ConstevalFormatString<num_params>{str}.fmt} {}
    FormatStringCheck(const std::string& str) : FormatString{str.c_str()} {}
    FormatStringCheck(FormatString str) : FormatString{str} {}
    FormatStringCheck(util::ConstevalFormatString<num_params> str) : FormatString{str.fmt} {}
};

// Added for Bitcoin Core
class format_error: public std::runtime_error
{
public:
    explicit format_error(const std::string &what): std::runtime_error(what) {
    }
};

//------------------------------------------------------------------------------
namespace detail {

// Test whether type T1 is convertible to type T2
template <typename T1, typename T2>

Review comment (suggestion):
Nit in 1d16d6e6bac994fed7c695f530b9984edcd290bd: I don't really see why this is useful. Maybe I am missing something, but everything compiles by just moving the two members to the derived struct:


```diff
diff --git a/src/tinyformat.h b/src/tinyformat.h
index 56c25d8f7f..6227cdeca0 100644
--- a/src/tinyformat.h
+++ b/src/tinyformat.h
@@ -179,21 +179,16 @@ namespace tfm = tinyformat;
 
 namespace tinyformat {
 
-// Added for Bitcoin Core. Wrapper type for format strings to allow compile-time checks.
-struct FormatString {
-    const char* fmt;
-    operator const char*() { return fmt; }
-};
-
 // 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.
 template <unsigned num_params>
-struct FormatStringCheck : FormatString {
-    consteval FormatStringCheck(const char* str) : FormatString{util::ConstevalFormatString<num_params>{str}.fmt} {}
-    FormatStringCheck(const std::string& str) : FormatString{str.c_str()} {}
-    FormatStringCheck(FormatString str) : FormatString{str} {}
-    FormatStringCheck(util::ConstevalFormatString<num_params> str) : FormatString{str.fmt} {}
+struct FormatStringCheck {
+    consteval FormatStringCheck(const char* str) : fmt{util::ConstevalFormatString<num_params>{str}.fmt} {}
+    FormatStringCheck(const std::string& str) : fmt{str.c_str()} {}
+    FormatStringCheck(util::ConstevalFormatString<num_params> str) : fmt{str.fmt} {}
+    const char* fmt;
+    operator const char*() { return fmt; }
 };
 
 // Added for Bitcoin Core


Code after:
#   ifdef __GXX_EXPERIMENTAL_CXX0X__
#       define TINYFORMAT_USE_VARIADIC_TEMPLATES
#   endif
#endif

#if defined(__GLIBCXX__) && __GLIBCXX__ < 20080201
//  std::showpos is broken on old libstdc++ as provided with macOS.  See
//  http://gcc.gnu.org/ml/libstdc++/2007-11/msg00075.html
#   define TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND
#endif

#ifdef __APPLE__
// Workaround macOS linker warning: Xcode uses different default symbol
// visibilities for static libs vs executables (see issue #25)
#   define TINYFORMAT_HIDDEN __attribute__((visibility("hidden")))
#else
#   define TINYFORMAT_HIDDEN
#endif

namespace tinyformat {

// 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.
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(util::ConstevalFormatString<num_params> str) : fmt{str.fmt} {}
    operator const char*() { return fmt; }
    const char* fmt;
};

// Added for Bitcoin Core
class format_error: public std::runtime_error
{
public:
    explicit format_error(const std::string &what): std::runtime_error(what) {
    }
};

//------------------------------------------------------------------------------
namespace detail {

// Test whether type T1 is convertible to type T2
template <typename T1, typename T2>
struct is_convertible
{
    private:
        // two types of different size
        struct fail { char dummy[2]; };