QForeachContainer: make it a move-only type

Honor the rule of five. Copy assignment was already disabled.
Disable also copy construction, but re-enable the move special
member functions.

This requires making the container non-const; to avoid detaches
and keep compatibility with containers that only have begin/end
(but not cbegin/cend), use qAsConst. This requires moving qAsConst
definition a bit up in the file.

Change-Id: I19cd74437cf69baceada9483920a21e96d7b1727
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Giuseppe D'Angelo 2016-11-09 17:40:14 +01:00
parent b2173b54ef
commit a35a01aaa2

View File

@ -917,25 +917,46 @@ QT_WARNING_DISABLE_MSVC(4530) /* C++ exception handler used, but unwind semantic
# endif
#endif
namespace QtPrivate {
template <typename T> struct QAddConst { typedef const T Type; };
}
// this adds const to non-const objects (like std::as_const)
template <typename T>
Q_DECL_CONSTEXPR typename QtPrivate::QAddConst<T>::Type &qAsConst(T &t) Q_DECL_NOTHROW { return t; }
// prevent rvalue arguments:
template <typename T>
void qAsConst(const T &&) Q_DECL_EQ_DELETE;
#ifndef QT_NO_FOREACH
namespace QtPrivate {
template <typename T>
class QForeachContainer {
QForeachContainer &operator=(const QForeachContainer &) Q_DECL_EQ_DELETE;
Q_DISABLE_COPY(QForeachContainer)
public:
QForeachContainer(const T &t) : c(t), i(c.begin()), e(c.end()) {}
QForeachContainer(T &&t) : c(std::move(t)), i(c.begin()), e(c.end()) {}
QForeachContainer(const QForeachContainer &other)
: c(other.c),
i(c.begin()),
e(c.end()),
control(other.control)
QForeachContainer(const T &t) : c(t), i(qAsConst(c).begin()), e(qAsConst(c).end()) {}
QForeachContainer(T &&t) : c(std::move(t)), i(qAsConst(c).begin()), e(qAsConst(c).end()) {}
QForeachContainer(QForeachContainer &&other)
: c(std::move(other.c)),
i(qAsConst(c).begin()),
e(qAsConst(c).end()),
control(std::move(other.control))
{
}
const T c;
QForeachContainer &operator=(QForeachContainer &&other)
{
c = std::move(other.c);
i = qAsConst(c).begin();
e = qAsConst(c).end();
control = std::move(other.control);
return *this;
}
T c;
typename T::const_iterator i, e;
int control = 1;
};
@ -1124,17 +1145,8 @@ template <typename T> struct QEnableIf<true, T> { typedef T Type; };
template <bool B, typename T, typename F> struct QConditional { typedef T Type; };
template <typename T, typename F> struct QConditional<false, T, F> { typedef F Type; };
template <typename T> struct QAddConst { typedef const T Type; };
}
// this adds const to non-const objects (like std::as_const)
template <typename T>
Q_DECL_CONSTEXPR typename QtPrivate::QAddConst<T>::Type &qAsConst(T &t) Q_DECL_NOTHROW { return t; }
// prevent rvalue arguments:
template <typename T>
void qAsConst(const T &&) Q_DECL_EQ_DELETE;
QT_END_NAMESPACE
// We need to keep QTypeInfo, QSysInfo, QFlags, qDebug & family in qglobal.h for compatibility with Qt 4.