diff --git a/src/util/stringformat.h b/src/util/stringformat.h new file mode 100644 index 000000000000..7d7e32e7e0ba --- /dev/null +++ b/src/util/stringformat.h @@ -0,0 +1,43 @@ +#pragma once + +#include +#include +#include + +namespace { + +// taken from Qt +template +static constexpr bool is_convertible_to_view_or_qstring_v = + std::is_convertible_v || + std::is_convertible_v || + std::is_convertible_v; + +// check if we can call QString::number(T) with T +template +static constexpr bool is_number_compatible_v = + std::is_invocable_v()))(T), T>; + +// always false, used for static_assert and workaround for compilers without +// https://cplusplus.github.io/CWG/issues/2518.html +template +static constexpr bool always_false_v = false; +} // namespace + +// Try to convert T to a type that would be accepted by QString::args(Args&&...) +template +auto convertToQStringConvertible(T&& arg) { + if constexpr (is_convertible_to_view_or_qstring_v) { + // no need to do anything, just return verbatim + return std::forward(arg); + } else if constexpr (is_number_compatible_v) { + return QString::number(std::forward(arg)); + } else { + // static_assert(always_false_v, "Unsupported type for QString::arg"); + static_assert(false, "Unsupported type for QString::arg"); + // unreachable, but returning a QString results in a better error message + // because the log won't be spammed with all the QString::arg overloads + // it couldn't match with `void`. + return QString(); + } +}