mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 12:07:45 +00:00
AK+Format: Add SFINAE wrapper 'FormatIfSupported'.
This commit is contained in:
parent
afef05ece2
commit
2217d6b560
2 changed files with 61 additions and 1 deletions
44
AK/Format.h
44
AK/Format.h
|
@ -41,7 +41,9 @@ class FormatParser;
|
||||||
class FormatBuilder;
|
class FormatBuilder;
|
||||||
|
|
||||||
template<typename T, typename = void>
|
template<typename T, typename = void>
|
||||||
struct Formatter;
|
struct Formatter {
|
||||||
|
using __no_formatter_defined = void;
|
||||||
|
};
|
||||||
|
|
||||||
constexpr size_t max_format_arguments = 256;
|
constexpr size_t max_format_arguments = 256;
|
||||||
|
|
||||||
|
@ -346,6 +348,44 @@ template<typename... Parameters>
|
||||||
void dbgln(const char* fmtstr, const Parameters&... parameters) { dbgln(StringView { fmtstr }, parameters...); }
|
void dbgln(const char* fmtstr, const Parameters&... parameters) { dbgln(StringView { fmtstr }, parameters...); }
|
||||||
inline void dbgln() { raw_dbg("\n"); }
|
inline void dbgln() { raw_dbg("\n"); }
|
||||||
|
|
||||||
|
template<typename T, typename = void>
|
||||||
|
struct HasFormatter : TrueType {
|
||||||
|
};
|
||||||
|
template<typename T>
|
||||||
|
struct HasFormatter<T, typename Formatter<T>::__no_formatter_defined> : FalseType {
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class FormatIfSupported {
|
||||||
|
public:
|
||||||
|
explicit FormatIfSupported(const T& value)
|
||||||
|
: m_value(value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const T& value() const { return m_value; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const T& m_value;
|
||||||
|
};
|
||||||
|
template<typename T, bool Supported = false>
|
||||||
|
struct __FormatIfSupported : Formatter<StringView> {
|
||||||
|
void format(TypeErasedFormatParams& params, FormatBuilder& builder, const FormatIfSupported<T>&)
|
||||||
|
{
|
||||||
|
Formatter<StringView>::format(params, builder, "?");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<typename T>
|
||||||
|
struct __FormatIfSupported<T, true> : Formatter<T> {
|
||||||
|
void format(TypeErasedFormatParams& params, FormatBuilder& builder, const FormatIfSupported<T>& value)
|
||||||
|
{
|
||||||
|
Formatter<T>::format(params, builder, value.value());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<typename T>
|
||||||
|
struct Formatter<FormatIfSupported<T>> : __FormatIfSupported<T, HasFormatter<T>::value> {
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace AK
|
} // namespace AK
|
||||||
|
|
||||||
#ifndef KERNEL
|
#ifndef KERNEL
|
||||||
|
@ -361,3 +401,5 @@ using AK::warnln;
|
||||||
using AK::dbgln;
|
using AK::dbgln;
|
||||||
using AK::new_dbg;
|
using AK::new_dbg;
|
||||||
using AK::raw_dbg;
|
using AK::raw_dbg;
|
||||||
|
|
||||||
|
using AK::FormatIfSupported;
|
||||||
|
|
|
@ -196,4 +196,22 @@ TEST_CASE(format_character)
|
||||||
EXPECT_EQ(String::formatted("{}", true ? a : 'b'), "a");
|
EXPECT_EQ(String::formatted("{}", true ? a : 'b'), "a");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct A {
|
||||||
|
};
|
||||||
|
struct B {
|
||||||
|
};
|
||||||
|
template<>
|
||||||
|
struct AK::Formatter<B> : Formatter<StringView> {
|
||||||
|
void format(TypeErasedFormatParams& params, FormatBuilder& builder, B)
|
||||||
|
{
|
||||||
|
Formatter<StringView>::format(params, builder, "B");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_CASE(format_if_supported)
|
||||||
|
{
|
||||||
|
EXPECT_EQ(String::formatted("{}", FormatIfSupported { A {} }), "?");
|
||||||
|
EXPECT_EQ(String::formatted("{}", FormatIfSupported { B {} }), "B");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_MAIN(Format)
|
TEST_MAIN(Format)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue