Last active
July 21, 2024 13:41
-
-
Save wention/2b3d9d6d500ab92c36ffd0f08f44c047 to your computer and use it in GitHub Desktop.
CPP Check if Type has qdebug stream operator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <QDebug> | |
#include <QRectF> | |
template<typename T, typename = void> | |
struct has_qdebug_stream_operator : std::false_type {}; | |
template<typename T> | |
struct has_qdebug_stream_operator<T, std::void_t<decltype(std::declval<QDebug>() << std::declval<T>())>> : std::true_type {}; | |
template<typename T> | |
typename std::enable_if_t<has_qdebug_stream_operator<T>::value> | |
qprint(T& v) { | |
QString s; | |
QDebug ds(&s); | |
ds << v; | |
std::cout << s.toStdString() << std::endl; | |
}; | |
struct B {}; | |
#define SHOW(...) std::cout << #__VA_ARGS__ << " = " << __VA_ARGS__ << std::endl; | |
int main(int argc, char* argv[]){ | |
auto b = QRect(0, 0, 10, 10); | |
qprint(b); | |
SHOW(has_qdebug_stream_operator<int>::value); | |
SHOW(has_qdebug_stream_operator<B>::value); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// QT FMT | |
#include <fmt/ranges.h> | |
#include <QString> | |
#include <QStringList> | |
#include <QRectF> | |
#include <QDebug> | |
template <typename T> | |
constexpr T any_true(const T& t) | |
{ | |
return t; | |
} | |
// 2.递归函数 | |
template <typename T, typename ... Args> | |
constexpr T any_true(const T& head, const Args... args) | |
{ | |
return head || any_true<T>(args...); | |
} | |
template <typename T, typename...X> | |
struct is_instantiation_of_any { | |
static const bool value = any_true(std::is_same_v<T, X>...); | |
}; | |
template<typename T, typename = void> | |
struct has_qdebug_stream_operator : std::false_type {}; | |
template<typename T> | |
struct has_qdebug_stream_operator<T, | |
std::enable_if_t<is_instantiation_of_any<T, | |
QRect, | |
QRectF | |
>::value, std::void_t<decltype(std::declval<QDebug>() << std::declval<T>())>> | |
> : std::true_type {}; | |
// format QString | |
template <> struct fmt::formatter<QString>: formatter<string_view> { | |
auto format(QString s, format_context& ctx) const -> decltype(ctx.out()) { | |
return formatter<string_view>::format(qUtf8Printable(s), ctx); | |
} | |
}; | |
// format other qtype | |
template <typename T> | |
struct fmt::formatter<T, std::enable_if_t<has_qdebug_stream_operator<T>::value, char>>: formatter<string_view> { | |
auto format(const T& t, format_context& ctx) const -> decltype(ctx.out()) { | |
QString s; | |
QDebug ds(&s); | |
ds << t; | |
return formatter<string_view>::format(qUtf8Printable(s), ctx); | |
} | |
}; | |
#define QFMT(...) QString::fromStdString(fmt::format(## __VA_ARGS__)) | |
#define CFMT(...) fmt::format(## __VA_ARGS__).c_str() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment