Vous avez reçu un message "Your GitLab account has been locked ..." ? Pas d'inquiétude : lisez cet article https://docs.gricad-pages.univ-grenoble-alpes.fr/help/unlock/

Commit d855a79e authored by EXT Arnaud Clère's avatar EXT Arnaud Clère
Browse files

Made Val moves explicit in bind() using &&

parent c5beadaa
......@@ -126,7 +126,7 @@ template<class TResult> using IsReader = typename std::enable_if<TResult::Mode==
template<class TResult> using IsWriter = typename std::enable_if<TResult::Mode==Write>::type;
template<class TResult, typename T, typename TEnabledIf=void> // least specialized definition
struct QBind { static TResult bind(Val<TResult> value, T&& t) { // t is a T&& or T& depending on call site // TODO Val&& to avoid temporary copies?
struct QBind { static TResult bind(Val<TResult>&& value, T&& t) { // t is a T&& or T& depending on call site
return t.bind(std::move(value)); // In case of error, define a T::bind(Val<TResult>) method or external QBind<TResult,Mode,T>::bind(Val<TResult>,T)
}};
......@@ -135,17 +135,17 @@ struct QBind { static TResult bind(Val<TResult> value, T&& t) { // t is a T&& or
// A QFold<TResult,T> would be equivalent to a Foldable allowing to fold T to any TResult without mandating a common Val/Seq structure
template<class TResult, typename T>
struct QBind<TResult, T&&, IsWriter<TResult>> { static TResult bind(Val<TResult> dst, T&& src) {
struct QBind<TResult, T&&, IsWriter<TResult>> { static TResult bind(Val<TResult>&& dst, T&& src) {
return dst.bind(src); // T&
}};
template<class TResult, typename T>
struct QBind<TResult, const T&, IsWriter<TResult>> { static TResult bind(Val<TResult> value, const T& t) {
struct QBind<TResult, const T&, IsWriter<TResult>> { static TResult bind(Val<TResult>&& value, const T& t) {
return value.bind(const_cast<T&>(t)); // T is not natively supported by TResult but t will not be modified anyway
}};
template<class TResult, typename T>
struct QBind<TResult, const T&, IsReader<TResult>> { static TResult bind(Val<TResult>, const T&) {
struct QBind<TResult, const T&, IsReader<TResult>> { static TResult bind(Val<TResult>&&, const T&) {
static_assert(TResult::Mode==Write,"Cannot Read from TResult into const T&"); return false;
}};
......@@ -288,7 +288,7 @@ private:
//! Base class for Writer classes that can exhibit high performance (they require no heap allocation and no lock thanks to move-semantics)
//! \warning
//! - it may be difficult to correctly implement a TResult derived from QBaseWriter with internal state (need to understand move semantics)
//! - TResult unsafeCopy copies do not share state (such as the whole path to the current value or errors or "choice" mode)
//! - TResult _unsafeCopy copies do not share state (such as the whole path to the current value or errors or "choice" mode)
//! - TResult are not pimpled (use QWriter+IWriter if needed)
template<class TResult_>
class QBaseWriter
......@@ -320,7 +320,7 @@ private:
template<typename T_> friend class Seq;
template<typename T_> friend class Rec;
TResult _unsafeCopy() { return TResult(*static_cast<TResult*>(this)); }
TResult _unsafeCopy() { return TResult(*static_cast<TResult*>(this)); } // TODO Check static_cast validity
};
// //////////////////////////////////////////////////////////////////////////
......@@ -352,7 +352,7 @@ struct IWriter
virtual bool _bind(qulonglong& n) { auto s(QUtf8String::number(n)); return _bind(s.constData()); } // handling all unsigned integral types
virtual bool _bind( qlonglong& n) { auto s(QUtf8String::number(n)); return _bind(s.constData()); } // handling all signed integral types
// TODO QChar, QDateTime, QDate, QTime, QUuid, QUrl, QRegularExpression
// TODO QChar, QDateTime, QDate, QTime, QUuid, QUrl, QRegularExpression, QMimeData
//! Write status for current value
virtual bool _isOk() { return true; }
......@@ -396,7 +396,7 @@ protected:
template<typename T> typename std::enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value, bool>::type _bind(T& t) { Q_ASSERT(impl); qulonglong u(t); return impl->_bind(u); }
template<typename T> typename std::enable_if<std::is_integral<T>::value && std:: is_signed<T>::value, bool>::type _bind(T& t) { Q_ASSERT(impl); qlonglong s(t); return impl->_bind(s); }
// TODO QChar, QDateTime, QDate, QTime, QUuid, QUrl, QRegularExpression
// TODO QChar, QDateTime, QDate, QTime, QUuid, QUrl, QRegularExpression, QMimeData
bool _item(QUtf8String& n) { Q_ASSERT(impl); return impl->_item(n.constData()); }
bool _item( ) { Q_ASSERT(impl); return impl->_item( ); }
......@@ -444,7 +444,7 @@ public:
template<typename T> QWritable(T& t) : f( /*captured T ref */[&t] (Val<TResult>&& v) { return v.bind(t); } ) {}
template<typename T> QWritable(T&& t) : f( /*captured T copy*/[ t] (Val<TResult>&& v) { return v.bind(t); } ) {}
TResult bind(Val<TResult> v) { return f(std::move(v)); }
TResult bind(Val<TResult>&& v) { return f(std::move(v)); }
};
// //////////////////////////////////////////////////////////////////////////
......@@ -482,7 +482,7 @@ struct IReader
return true;
}
// TODO QChar, QDateTime, QDate, QTime, QUuid, QUrl, QRegularExpression
// TODO QChar, QDateTime, QDate, QTime, QUuid, QUrl, QRegularExpression, QMimeData
//! Read status for current value
virtual bool _isOk() = 0;
......@@ -547,7 +547,7 @@ protected:
template<typename T> typename std::enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value, bool>::type _bind(T& t) { Q_ASSERT(impl); qulonglong u; if (impl->_bind(u)) { t=u; return true; } return false; }
template<typename T> typename std::enable_if<std::is_integral<T>::value && std:: is_signed<T>::value, bool>::type _bind(T& t) { Q_ASSERT(impl); qlonglong s; if (impl->_bind(s)) { t=s; return true; } return false; }
// TODO QChar, QDateTime, QDate, QTime, QUuid, QUrl, QRegularExpression
// TODO QChar, QDateTime, QDate, QTime, QUuid, QUrl, QRegularExpression, QMimeData
bool _item(QUtf8String& n) { Q_ASSERT(impl); return impl->_item(n); }
bool _item( ) { Q_ASSERT(impl); return impl->_item( ); }
......@@ -575,11 +575,11 @@ template<typename T> struct BindSupport<QReader<IReader>,T&,typename std::enable
// QBind<_,void> always succeeds
template<class TResult>
struct QBind<TResult, void, IsWriter<TResult>> { static TResult bind(Val<TResult> dst) {
struct QBind<TResult, void, IsWriter<TResult>> { static TResult bind(Val<TResult>&& dst) {
return dst.null();
}};
template<class TResult>
struct QBind<TResult, void, IsReader<TResult>> { static TResult bind(Val<TResult> src) {
struct QBind<TResult, void, IsReader<TResult>> { static TResult bind(Val<TResult>&& src) {
{
QScopedChoice<Val<TResult>> choice(src);
Seq<TResult> srcSeq; if ((srcSeq = src.sequence())) { return srcSeq.out(); }
......@@ -593,12 +593,12 @@ struct QBind<TResult, void, IsReader<TResult>> { static TResult bind(Val<TResult
#include <cstddef>
template<class TResult>
struct QBind<TResult, std::nullptr_t&> { static TResult bind(Val<TResult> value, std::nullptr_t&) {
struct QBind<TResult, std::nullptr_t&> { static TResult bind(Val<TResult>&& value, std::nullptr_t&) {
return value.null();
}};
template<class TResult, typename T, unsigned Size>
struct QBind<TResult, T(&)[Size], IsWriter<TResult>> { static TResult bind(Val<TResult> dst, T(& src)[Size]) {
struct QBind<TResult, T(&)[Size], IsWriter<TResult>> { static TResult bind(Val<TResult>&& dst, T(& src)[Size]) {
quint32 size=Size;
auto s(dst.sequence(&size));
for (auto&& t : src) {
......@@ -607,7 +607,7 @@ struct QBind<TResult, T(&)[Size], IsWriter<TResult>> { static TResult bind(Val<T
return s;
}};
template<class TResult, typename T, unsigned Size>
struct QBind<TResult, T(&)[Size], IsReader<TResult>> { static TResult bind(Val<TResult> src, T(& dst)[Size]) {
struct QBind<TResult, T(&)[Size], IsReader<TResult>> { static TResult bind(Val<TResult>&& src, T(& dst)[Size]) {
auto s(src.sequence());
Val<Seq<TResult>> i; unsigned j=0;
while ((i = s.item())) {
......@@ -624,7 +624,7 @@ struct QBind<TResult, T(&)[Size], IsReader<TResult>> { static TResult bind(Val<T
#include <QtCore/qstring.h>
template<class TResult>
struct QBind<TResult, QString&, IsReader<TResult>> { static TResult bind(Val<TResult> src, QString& dst) {
struct QBind<TResult, QString&, IsReader<TResult>> { static TResult bind(Val<TResult>&& src, QString& dst) {
QByteArray ba;
auto r = src.bind(ba); // FIXME QByteArray is raw data that does not necessarily represent a utf8 string
if (r) {
......@@ -636,7 +636,7 @@ struct QBind<TResult, QString&, IsReader<TResult>> { static TResult bind(Val<TRe
#include <QtCore/qvector.h>
template<class TResult, typename T>
struct QBind<TResult, QVector<T>&, IsWriter<TResult>> { static TResult bind(Val<TResult> dst, QVector<T>& src) {
struct QBind<TResult, QVector<T>&, IsWriter<TResult>> { static TResult bind(Val<TResult>&& dst, QVector<T>& src) {
quint32 size=src.size();
auto s(dst.sequence(&size));
for (auto&& t : src) {
......@@ -645,7 +645,7 @@ struct QBind<TResult, QVector<T>&, IsWriter<TResult>> { static TResult bind(Val<
return s;
}};
template<class TResult, typename T>
struct QBind<TResult, QVector<T>&, IsReader<TResult>> { static TResult bind(Val<TResult> src, QVector<T>& dst) {
struct QBind<TResult, QVector<T>&, IsReader<TResult>> { static TResult bind(Val<TResult>&& src, QVector<T>& dst) {
auto s(src.sequence());
Val<Seq<TResult>> i;
while ((i = s.item())) {
......@@ -659,7 +659,7 @@ struct QBind<TResult, QVector<T>&, IsReader<TResult>> { static TResult bind(Val<
#include <QtCore/qlist.h>
template<class TResult, typename T>
struct QBind<TResult, QList<T>&, IsWriter<TResult>> { static TResult bind(Val<TResult> dst, QList<T>& src) {
struct QBind<TResult, QList<T>&, IsWriter<TResult>> { static TResult bind(Val<TResult>&& dst, QList<T>& src) {
quint32 size=quint32(src.size());
auto s(dst.sequence(&size));
for (auto&& item : src) {
......@@ -668,7 +668,7 @@ struct QBind<TResult, QList<T>&, IsWriter<TResult>> { static TResult bind(Val<TR
return s;
}};
template<class TResult, typename T>
struct QBind<TResult, QList<T>&, IsReader<TResult>> { static TResult bind(Val<TResult> src, QList<T>& dst) {
struct QBind<TResult, QList<T>&, IsReader<TResult>> { static TResult bind(Val<TResult>&& src, QList<T>& dst) {
auto s(src.sequence());
Val<Seq<TResult>> i;
while ((i = s.item())) {
......@@ -682,7 +682,7 @@ struct QBind<TResult, QList<T>&, IsReader<TResult>> { static TResult bind(Val<TR
#include <QtCore/qmap.h>
template<class TResult, typename T>
struct QBind<TResult, QMap<QString,T>&, IsWriter<TResult>> { static TResult bind(Val<TResult> dst, QMap<QString,T>& src) {
struct QBind<TResult, QMap<QString,T>&, IsWriter<TResult>> { static TResult bind(Val<TResult>&& dst, QMap<QString,T>& src) {
quint32 size=quint32(src.size());
auto s(dst.record(&size));
for (QString key : src.keys()) {
......@@ -691,7 +691,7 @@ struct QBind<TResult, QMap<QString,T>&, IsWriter<TResult>> { static TResult bind
return s;
}};
template<class TResult, typename T>
struct QBind<TResult, QMap<QString,T>&, IsReader<TResult>> { static TResult bind(Val<TResult> src, QMap<QString,T>& dst) {
struct QBind<TResult, QMap<QString,T>&, IsReader<TResult>> { static TResult bind(Val<TResult>&& src, QMap<QString,T>& dst) {
auto s(src.record());
QUtf8String name; Val<Rec<TResult>> i;
while ((i = s.item(name))) {
......@@ -705,7 +705,7 @@ struct QBind<TResult, QMap<QString,T>&, IsReader<TResult>> { static TResult bind
#include <QtGui/qcolor.h>
template<class TResult>
struct QBind<TResult, QColor&, IsWriter<TResult>> { static TResult bind(Val<TResult> dst, QColor& src) {
struct QBind<TResult, QColor&, IsWriter<TResult>> { static TResult bind(Val<TResult>&& dst, QColor& src) {
return dst.record()
.bind("A",src.alpha())
.bind("R",src.red ())
......@@ -717,11 +717,11 @@ struct QBind<TResult, QColor&, IsWriter<TResult>> { static TResult bind(Val<TRes
// QBind specialization for generic Val<TDst> for a fixed set of possibly BindNative types
template<class TSrcResult, class TDst>
struct QBind<TSrcResult, Val<TDst>&&, IsWriter<TSrcResult>> { static TSrcResult bind(Val<TSrcResult> src, Val<TDst>&& dst) {
struct QBind<TSrcResult, Val<TDst>&&, IsWriter<TSrcResult>> { static TSrcResult bind(Val<TSrcResult>&& src, Val<TDst>&& dst) {
static_assert(true,"Cannot Read from TSrcResult with BindMode==Write, try swapping src and dst!"); Q_UNUSED(src); Q_UNUSED(dst);
}};
template<class TSrcResult, class TDst>
struct QBind<TSrcResult, Val<TDst>&&, IsReader<TSrcResult>> { static TSrcResult bind(Val<TSrcResult> src, Val<TDst>&& dst) {
struct QBind<TSrcResult, Val<TDst>&&, IsReader<TSrcResult>> { static TSrcResult bind(Val<TSrcResult>&& src, Val<TDst>&& dst) {
static_assert(TDst::Mode!=Read,"Cannot Read from TSrcResult to TDst with BindMode==Read");
TSrcResult srcRes;
......
......@@ -188,7 +188,7 @@ class QCborReader : public IReader
public:
QCborReader(QCborStreamReader* io) : io(io) { Q_ASSERT(io); }
struct Error { const char* error; qint64 index; QCborError cborError; template<class T> T bind(Val<T> value) { QUtf8String utf8(error); utf8.append(' ').append(QUtf8String::number(index)); return value.bind(utf8.constData()); } };
struct Error { const char* error; qint64 index; QCborError cborError; template<class T> T bind(Val<T>&& value) { QUtf8String utf8(error); utf8.append(' ').append(QUtf8String::number(index)); return value.bind(utf8.constData()); } };
QVector<Error> errors;
// Shortcuts
......
......@@ -101,7 +101,7 @@ class QJsonVisitor : public IReader
public:
QJsonVisitor(const QJsonValue* v) : json(v) { Q_ASSERT(v); }
struct Error { const char* error; QUtf8String path; template<class T> T bind(Val<T> value) { return value.bind(QUtf8String(error)+' '+path); } };
struct Error { const char* error; QUtf8String path; template<class T> T bind(Val<T>&& value) { return value.bind(QUtf8String(error)+' '+path); } };
QVector<Error> errors;
QUtf8String currentPath() {
......@@ -217,7 +217,7 @@ public:
QJsonReader(QIODevice* io) : io(io) { Q_ASSERT(io); }
struct Step { int index; const char* end; Step(int i=-1, const char* e=nullptr) : index(i), end(e) {} };
struct Error { const char* error; int line; int column; int index; template<class T> T bind(Val<T> value) { QUtf8String utf8(error); utf8.append(' ').append(QUtf8String::number(line)).append(':').append(QUtf8String::number(column)); return value.bind(utf8.constData()); } };
struct Error { const char* error; int line; int column; int index; template<class T> T bind(Val<T>&& value) { QUtf8String utf8(error); utf8.append(' ').append(QUtf8String::number(line)).append(':').append(QUtf8String::number(column)); return value.bind(utf8.constData()); } };
QVector<Error> errors;
// Shortcuts
......@@ -421,7 +421,7 @@ private:
#include <QtCore/qjsonobject.h>
template<class TResult>
struct QBind<TResult, QJsonValue&, IsWriter<TResult>> { static TResult bind(Val<TResult> dst, QJsonValue& src) {
struct QBind<TResult, QJsonValue&, IsWriter<TResult>> { static TResult bind(Val<TResult>&& dst, QJsonValue& src) {
if (src.isObject()) return dst.bind(src.toObject());
if (src.isArray ()) return dst.bind(src.toArray ());
if (src.isBool ()) return dst.bind(src.toBool ());
......@@ -430,7 +430,7 @@ struct QBind<TResult, QJsonValue&, IsWriter<TResult>> { static TResult bind(Val<
return dst.null();
}};
template<class TResult>
struct QBind<TResult, QJsonValue&, IsReader<TResult>> { static TResult bind(Val<TResult> src, QJsonValue& dst) {
struct QBind<TResult, QJsonValue&, IsReader<TResult>> { static TResult bind(Val<TResult>&& src, QJsonValue& dst) {
TResult r;
{
QScopedChoice<Val<TResult>> choice(src);
......@@ -445,7 +445,7 @@ struct QBind<TResult, QJsonValue&, IsReader<TResult>> { static TResult bind(Val<
}};
template<class TResult>
struct QBind<TResult, QJsonArray&, IsWriter<TResult>> { static TResult bind(Val<TResult> dst, QJsonArray& src) {
struct QBind<TResult, QJsonArray&, IsWriter<TResult>> { static TResult bind(Val<TResult>&& dst, QJsonArray& src) {
quint32 size=quint32(src.size());
auto s(dst.sequence(&size));
for (QJsonValue&& item : src) {
......@@ -454,7 +454,7 @@ struct QBind<TResult, QJsonArray&, IsWriter<TResult>> { static TResult bind(Val<
return s;
}};
template<class TResult>
struct QBind<TResult, QJsonArray&, IsReader<TResult>> { static TResult bind(Val<TResult> src, QJsonArray& dst) {
struct QBind<TResult, QJsonArray&, IsReader<TResult>> { static TResult bind(Val<TResult>&& src, QJsonArray& dst) {
auto s(src.sequence());
Val<Seq<TResult>> i;
while ((i = s.item())) {
......@@ -466,7 +466,7 @@ struct QBind<TResult, QJsonArray&, IsReader<TResult>> { static TResult bind(Val<
}};
template<class TResult>
struct QBind<TResult, QJsonObject&, IsWriter<TResult>> { static TResult bind(Val<TResult> dst, QJsonObject& src) {
struct QBind<TResult, QJsonObject&, IsWriter<TResult>> { static TResult bind(Val<TResult>&& dst, QJsonObject& src) {
quint32 size=quint32(src.size());
auto s(dst.record(&size));
for (QString key : src.keys()) {
......@@ -475,7 +475,7 @@ struct QBind<TResult, QJsonObject&, IsWriter<TResult>> { static TResult bind(Val
return s;
}};
template<class TResult>
struct QBind<TResult, QJsonObject&, IsReader<TResult>> { static TResult bind(Val<TResult> src, QJsonObject& dst) {
struct QBind<TResult, QJsonObject&, IsReader<TResult>> { static TResult bind(Val<TResult>&& src, QJsonObject& dst) {
auto s(src.record());
QByteArray k; Val<Rec<TResult>> i;
while ((i = s.item(k))) {
......
......@@ -97,7 +97,7 @@ public:
Q_ENABLE_MOVE_DEFAULT(QVariantVisitor)
QVariantVisitor(const QVariant* v) : value(v) { Q_ASSERT(v); }
struct Error { const char* error; QUtf8String path; template<class T> T bind(Val<T> value) { return value.bind(QUtf8String(error)+' '+path); } };
struct Error { const char* error; QUtf8String path; template<class T> T bind(Val<T>&& value) { return value.bind(QUtf8String(error)+' '+path); } };
QVector<Error> errors;
QUtf8String currentPath() {
......@@ -136,7 +136,7 @@ private:
//// QBind<TResult,QVariant&> example support for the fixed set of QVariantBuilder's BindNative types + other convenient types
template<class TResult>
struct QBind<TResult, QVariant&, IsWriter<TResult>> { static TResult bind(Val<TResult> dst, QVariant& src) {
struct QBind<TResult, QVariant&, IsWriter<TResult>> { static TResult bind(Val<TResult>&& dst, QVariant& src) {
if (src.type()==QVariant::List ) return dst.bind(src.value<QVariantList>()); // TODO QSequentialIterable ?
if (src.type()==QVariant::Map ) return dst.bind(src.value<QVariantMap >()); // TODO QAssociativeIterable ?
// TODO QVariant::Hash
......@@ -159,7 +159,7 @@ struct QBind<TResult, QVariant&, IsWriter<TResult>> { static TResult bind(Val<TR
}};
//template<class TResult>
//struct QBind<TResult, QVariant&, IsReader<TResult>> { static TResult bind(Val<TResult> src, QVariant& dst) {
//struct QBind<TResult, QVariant&, IsReader<TResult>> { static TResult bind(Val<TResult>&& src, QVariant& dst) {
// TResult r;
// {
// QScopedChoice<Val<TResult>> choice(src);
......
......@@ -67,7 +67,7 @@ struct Person
QString firstName, lastName; double height; int age; QVector<QString> phones; QString comments;
template<class TResult>
TResult bind(Val<TResult> value) { // since we only bind T& (no const T&), it works with TResult::Mode==Read as well as Write
TResult bind(Val<TResult>&& value) { // since we only bind T& (no const T&), it works with TResult::Mode==Read as well as Write
return value
.record()
.sequence("names")
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment