QDebug: make std::optional stream operator SCARY
Piggy-back on the recently-added, type-erased, std::tuple stream operator to handle std::optional the same way. While std::optional doesn't support the Tuple Protocol, and we therefore can't use putTuple() directly, we can still use putTupleImplImpl() if we set up its arguments manually. [ChangeLog][Potentially Source-Incompatible Changes][QDebug] The std::optional streaming operator is now a member of QDebug, not a free function. This breaks users that rely on the exact definition of the operator (e.g. `operator<<(d, opt)`). A backwards-compatible fix is to call the operator with infix notation (d << opt) only, and to avoid const QDebug objects. Pick-to: 6.9 Change-Id: Ib040d65953ca9d3892aee5bdb597d6d30a9694b1 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
This commit is contained in:
parent
ec011141b8
commit
08320bfe2b
@ -1258,10 +1258,9 @@ QDebug &QDebug::putTupleLikeImplImpl(const char *ns, const char *what,
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
\since 6.7
|
\since 6.7
|
||||||
\fn template <class T> QDebug operator<<(QDebug debug, const std::optional<T> &opt)
|
\fn template <class T, QDebug::if_streamable<T>> QDebug::operator<<(const std::optional<T> &opt)
|
||||||
\relates QDebug
|
|
||||||
|
|
||||||
Writes the contents of \a opt (or \c nullopt if not set) to \a debug.
|
Writes the contents of \a opt (or \c nullopt if not set) to this stream.
|
||||||
\c T needs to support streaming into QDebug.
|
\c T needs to support streaming into QDebug.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -299,6 +299,16 @@ public:
|
|||||||
return putTupleLike("std", "tuple", t);
|
return putTupleLike("std", "tuple", t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, if_streamable<T> = true>
|
||||||
|
QDebug &operator<<(const std::optional<T> &o)
|
||||||
|
{
|
||||||
|
if (!o)
|
||||||
|
return *this << std::nullopt;
|
||||||
|
StreamTypeErased s = &streamTypeErased<std::remove_cv_t<T>>;
|
||||||
|
const void *d = std::addressof(*o);
|
||||||
|
return putTupleLikeImplImpl("std", "optional", 1, &s, &d);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using if_ordering_type = std::enable_if_t<QtOrderingPrivate::is_ordering_type_v<T>, bool>;
|
using if_ordering_type = std::enable_if_t<QtOrderingPrivate::is_ordering_type_v<T>, bool>;
|
||||||
@ -490,16 +500,6 @@ inline QDebugIfHasDebugStreamContainer<QMultiHash<Key, T>, Key, T> operator<<(QD
|
|||||||
return QtPrivate::printAssociativeContainer(std::move(debug), "QMultiHash", hash);
|
return QtPrivate::printAssociativeContainer(std::move(debug), "QMultiHash", hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline QDebugIfHasDebugStream<T> operator<<(QDebug debug, const std::optional<T> &opt)
|
|
||||||
{
|
|
||||||
if (!opt)
|
|
||||||
return debug << std::nullopt;
|
|
||||||
const QDebugStateSaver saver(debug);
|
|
||||||
debug.nospace() << "std::optional(" << *opt << ')';
|
|
||||||
return debug;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T1, class T2>
|
template <class T1, class T2>
|
||||||
inline QDebugIfHasDebugStream<T1, T2> operator<<(QDebug debug, const std::pair<T1, T2> &pair)
|
inline QDebugIfHasDebugStream<T1, T2> operator<<(QDebug debug, const std::pair<T1, T2> &pair)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user