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 e2e2a17d authored by EXT Arnaud Clère's avatar EXT Arnaud Clère
Browse files

Use a QValueEnd type with jus the bool result to hide QValueStatus

undesirable methods like value() that allowed to concatenate QValues in,
say, a JSON stream
parent c50b87ac
...@@ -465,7 +465,7 @@ private: ...@@ -465,7 +465,7 @@ private:
template<> template<>
struct QTransmogrifier<QCborValue> { struct QTransmogrifier<QCborValue> {
static QValueStatus zap(QValue&& v, QCborValue&& j) { static QValueEnd zap(QValue&& v, QCborValue&& j) {
if (v->mode()==Write) { if (v->mode()==Write) {
if (j.isMap ()) return v.bind(j.toMap ()); if (j.isMap ()) return v.bind(j.toMap ());
if (j.isArray ()) return v.bind(j.toArray ()); if (j.isArray ()) return v.bind(j.toArray ());
...@@ -480,7 +480,7 @@ struct QTransmogrifier<QCborValue> { ...@@ -480,7 +480,7 @@ struct QTransmogrifier<QCborValue> {
} }
else { Q_ASSERT_X(false, Q_FUNC_INFO, "Unsupported v->mode()"); return v.any(); } else { Q_ASSERT_X(false, Q_FUNC_INFO, "Unsupported v->mode()"); return v.any(); }
} }
static QValueStatus zap(QValue&& v, QCborValue& j) { static QValueEnd zap(QValue&& v, QCborValue& j) {
if (v->mode()==Write) { if (v->mode()==Write) {
return zap(std::move(v),std::move(j)); return zap(std::move(v),std::move(j));
} }
...@@ -507,7 +507,7 @@ struct QTransmogrifier<QCborValue> { ...@@ -507,7 +507,7 @@ struct QTransmogrifier<QCborValue> {
template<> template<>
struct QTransmogrifier<QCborArray> { struct QTransmogrifier<QCborArray> {
static QValueStatus zap(QValue&& v, QCborArray&& j) { static QValueEnd zap(QValue&& v, QCborArray&& j) {
if (v->mode()==Write) { if (v->mode()==Write) {
quint32 size=quint32(j.size()); quint32 size=quint32(j.size());
auto s(v.sequence(&size)); auto s(v.sequence(&size));
...@@ -518,7 +518,7 @@ struct QTransmogrifier<QCborArray> { ...@@ -518,7 +518,7 @@ struct QTransmogrifier<QCborArray> {
} }
else { Q_ASSERT_X(false, Q_FUNC_INFO, "Unsupported v->mode()"); return v.any(); } else { Q_ASSERT_X(false, Q_FUNC_INFO, "Unsupported v->mode()"); return v.any(); }
} }
static QValueStatus zap(QValue&& v, QCborArray& j) { static QValueEnd zap(QValue&& v, QCborArray& j) {
if (v->mode()==Write) { if (v->mode()==Write) {
return zap(std::move(v),std::move(j)); return zap(std::move(v),std::move(j));
} }
...@@ -538,7 +538,7 @@ struct QTransmogrifier<QCborArray> { ...@@ -538,7 +538,7 @@ struct QTransmogrifier<QCborArray> {
template<> template<>
struct QTransmogrifier<QCborMap> { struct QTransmogrifier<QCborMap> {
static QValueStatus zap(QValue&& v, QCborMap&& j) { static QValueEnd zap(QValue&& v, QCborMap&& j) {
if (v->mode()==Write) { if (v->mode()==Write) {
quint32 size=quint32(j.size()); quint32 size=quint32(j.size());
auto r(v.record(&size)); auto r(v.record(&size));
...@@ -553,7 +553,7 @@ struct QTransmogrifier<QCborMap> { ...@@ -553,7 +553,7 @@ struct QTransmogrifier<QCborMap> {
} }
else { Q_ASSERT_X(false, Q_FUNC_INFO, "Unsupported v->mode()"); return v.any(); } else { Q_ASSERT_X(false, Q_FUNC_INFO, "Unsupported v->mode()"); return v.any(); }
} }
static QValueStatus zap(QValue&& v, QCborMap& j) { static QValueEnd zap(QValue&& v, QCborMap& j) {
if (v->mode()==Write) { if (v->mode()==Write) {
return zap(std::move(v),std::move(j)); return zap(std::move(v),std::move(j));
} }
......
...@@ -65,7 +65,7 @@ public: ...@@ -65,7 +65,7 @@ public:
QValue value ( ) { return QValueStatus(this).value(); } QValue value ( ) { return QValueStatus(this).value(); }
QSequence sequence(quint32* s=nullptr) { return QValueStatus(this).value().sequence(s); } QSequence sequence(quint32* s=nullptr) { return QValueStatus(this).value().sequence(s); }
template<typename T> QValueStatus zap(T&& t) { return QValueStatus(this).value().bind(std::forward<T>(t)); } template<typename T> QValueEnd zap(T&& t) { return QValueStatus(this).value().bind(std::forward<T>(t)); }
protected: protected:
friend class QValueStatus; friend class QValueStatus;
bool trySequence(quint32* s=nullptr) { if (s) *io << *s; return true; } bool trySequence(quint32* s=nullptr) { if (s) *io << *s; return true; }
......
...@@ -240,7 +240,7 @@ public: ...@@ -240,7 +240,7 @@ public:
} }
struct Step { int index; const char* end; QMap<QIdentifier,QJsonValue/*TODO QVariant for meta() support*/> cachedItems; Step(int i=-1, const char* e=nullptr) : index(i), end(e) {} }; struct Step { int index; const char* end; QMap<QIdentifier,QJsonValue/*TODO QVariant for meta() support*/> cachedItems; Step(int i=-1, const char* e=nullptr) : index(i), end(e) {} };
struct Error { QIdentifierLiteral error; int line; int column; int index; QValueStatus zap(QValue&& value) { QByteArray u(error.utf8()); u.append(' ').append(QByteArray::number(line)).append(':').append(QByteArray::number(column)); return value.bind(QUtf8Data(u)); } }; struct Error { QIdentifierLiteral error; int line; int column; int index; QValueEnd zap(QValue&& value) { QByteArray u(error.utf8()); u.append(' ').append(QByteArray::number(line)).append(':').append(QByteArray::number(column)); return value.bind(QUtf8Data(u)); } };
QVector<Error> errors; QVector<Error> errors;
// Shortcuts // Shortcuts
...@@ -523,7 +523,7 @@ private: ...@@ -523,7 +523,7 @@ private:
template<> template<>
struct QTransmogrifier<QJsonValue> { struct QTransmogrifier<QJsonValue> {
static QValueStatus zap(QValue&& v, QJsonValue&& j) { static QValueEnd zap(QValue&& v, QJsonValue&& j) {
if (v->mode()==Write) { if (v->mode()==Write) {
if (j.isObject()) return v.bind(j.toObject()); if (j.isObject()) return v.bind(j.toObject());
if (j.isArray ()) return v.bind(j.toArray ()); if (j.isArray ()) return v.bind(j.toArray ());
...@@ -536,7 +536,7 @@ struct QTransmogrifier<QJsonValue> { ...@@ -536,7 +536,7 @@ struct QTransmogrifier<QJsonValue> {
} }
else { Q_ASSERT_X(false, Q_FUNC_INFO, "Unsupported v->mode()"); return v.any(); } else { Q_ASSERT_X(false, Q_FUNC_INFO, "Unsupported v->mode()"); return v.any(); }
} }
static QValueStatus zap(QValue&& v, QJsonValue& j) { static QValueEnd zap(QValue&& v, QJsonValue& j) {
if (v->mode()==Write) { if (v->mode()==Write) {
return zap(std::move(v),std::move(j)); return zap(std::move(v),std::move(j));
} }
...@@ -561,7 +561,7 @@ struct QTransmogrifier<QJsonValue> { ...@@ -561,7 +561,7 @@ struct QTransmogrifier<QJsonValue> {
template<> template<>
struct QTransmogrifier<QJsonArray> { struct QTransmogrifier<QJsonArray> {
static QValueStatus zap(QValue&& v, QJsonArray&& j) { static QValueEnd zap(QValue&& v, QJsonArray&& j) {
if (v->mode()==Write) { if (v->mode()==Write) {
quint32 size=quint32(j.size()); quint32 size=quint32(j.size());
auto s(v.sequence(&size)); auto s(v.sequence(&size));
...@@ -572,7 +572,7 @@ struct QTransmogrifier<QJsonArray> { ...@@ -572,7 +572,7 @@ struct QTransmogrifier<QJsonArray> {
} }
else { Q_ASSERT_X(false, Q_FUNC_INFO, "Unsupported v->mode()"); return v.any(); } else { Q_ASSERT_X(false, Q_FUNC_INFO, "Unsupported v->mode()"); return v.any(); }
} }
static QValueStatus zap(QValue&& v, QJsonArray& j) { static QValueEnd zap(QValue&& v, QJsonArray& j) {
if (v->mode()==Write) { if (v->mode()==Write) {
return zap(std::move(v),std::move(j)); return zap(std::move(v),std::move(j));
} }
...@@ -592,7 +592,7 @@ struct QTransmogrifier<QJsonArray> { ...@@ -592,7 +592,7 @@ struct QTransmogrifier<QJsonArray> {
template<> template<>
struct QTransmogrifier<QJsonObject> { struct QTransmogrifier<QJsonObject> {
static QValueStatus zap(QValue&& v, QJsonObject&& j) { static QValueEnd zap(QValue&& v, QJsonObject&& j) {
if (v->mode()==Write) { if (v->mode()==Write) {
quint32 size=quint32(j.size()); quint32 size=quint32(j.size());
auto s(v.record(&size)); auto s(v.record(&size));
...@@ -604,7 +604,7 @@ struct QTransmogrifier<QJsonObject> { ...@@ -604,7 +604,7 @@ struct QTransmogrifier<QJsonObject> {
} }
else { Q_ASSERT_X(false, Q_FUNC_INFO, "Unsupported v->mode()"); return v.any(); } else { Q_ASSERT_X(false, Q_FUNC_INFO, "Unsupported v->mode()"); return v.any(); }
} }
static QValueStatus zap(QValue&& v, QJsonObject& j) { static QValueEnd zap(QValue&& v, QJsonObject& j) {
if (v->mode()==Write) { if (v->mode()==Write) {
return zap(std::move(v),std::move(j)); return zap(std::move(v),std::move(j));
} }
......
...@@ -237,6 +237,8 @@ template<class T_> class QVal; ...@@ -237,6 +237,8 @@ template<class T_> class QVal;
#include <type_traits> #include <type_traits>
template<class T> using RemoveCvRef = typename std::remove_cv<typename std::remove_reference<T>::type>::type; template<class T> using RemoveCvRef = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
struct QValueEnd { bool isValid = false; };
//! A QValueStatus is a move-only, non-owning pointer to QAbstractValue //! A QValueStatus is a move-only, non-owning pointer to QAbstractValue
//! //!
//! Its public interface only allows checking the status of resulting QAbstractValue operation(s) using operator bool() and to handleError(). //! Its public interface only allows checking the status of resulting QAbstractValue operation(s) using operator bool() and to handleError().
...@@ -264,6 +266,7 @@ public: ...@@ -264,6 +266,7 @@ public:
explicit operator bool() const noexcept { return impl && impl->isValid(); } //!< Drives QTransmogrifier<T>::bind() traversal explicit operator bool() const noexcept { return impl && impl->isValid(); } //!< Drives QTransmogrifier<T>::bind() traversal
QValueStatus* operator ->() noexcept { return this; } QValueStatus* operator ->() noexcept { return this; }
QVal<QValueStatus> value() noexcept ; QVal<QValueStatus> value() noexcept ;
operator QValueEnd() { return QValueEnd{impl!=nullptr}; }
QValueErrorHandler setErrorHandler(QValueErrorHandler newHandler = nullptr) { return Q_LIKELY(impl) ? impl->setErrorHandler(newHandler) : nullptr; } QValueErrorHandler setErrorHandler(QValueErrorHandler newHandler = nullptr) { return Q_LIKELY(impl) ? impl->setErrorHandler(newHandler) : nullptr; }
bool handleError(QIdentifierLiteral name, QString context = QString()) { return Q_LIKELY(impl) ? impl->handleError(name, context) : false; } bool handleError(QIdentifierLiteral name, QString context = QString()) { return Q_LIKELY(impl) ? impl->handleError(name, context) : false; }
...@@ -321,11 +324,11 @@ using QRecord = QRec<QValueStatus>; ...@@ -321,11 +324,11 @@ using QRecord = QRec<QValueStatus>;
#include <functional> #include <functional>
#ifndef NO_COMPILER_RTTI_OR_EXCEPTIONS #ifndef NO_COMPILER_RTTI_OR_EXCEPTIONS
template<typename T> using QValFunction = QValueStatus(*)(T &,QValue &&) ; template<typename T> using QValFunction = QValueEnd(*)(T &,QValue &&) ;
template<class Ts> using QSeqFunction = QSequence (*)(Ts&,QSequence&&) ; template<class Ts> using QSeqFunction = QSequence(*)(Ts&,QSequence&&) ;
#endif #endif
/**/ using QValLambda = std::function<QValueStatus(QValue &&)>; /**/ using QValLambda = std::function<QValueEnd(QValue &&)>;
/**/ using QSeqLambda = std::function<QSequence (QSequence&&)>; /**/ using QSeqLambda = std::function<QSequence(QSequence&&)>;
template<class T_> class QVal template<class T_> class QVal
{ {
...@@ -354,8 +357,8 @@ public: ...@@ -354,8 +357,8 @@ public:
template<typename T> T_ bind(T& t, T&& defaultT) { return outer->tryBind(QDefaultValue<T>{t,defaultT}) ? std::move(outer) : T_(); } template<typename T> T_ bind(T& t, T&& defaultT) { return outer->tryBind(QDefaultValue<T>{t,defaultT}) ? std::move(outer) : T_(); }
// Custom bind support // Custom bind support
/**/ T_ with( QValLambda customBind) { return customBind( std::move(unsafeThis())) ? std::move(outer) : T_(); } /**/ T_ with( QValLambda customBind) { return customBind( std::move(unsafeThis())).isValid ? std::move(outer) : T_(); }
template<typename T> T_ with(T& t, QValFunction<T> customBind) { return customBind(t, std::move(unsafeThis())) ? std::move(outer) : T_(); } template<typename T> T_ with(T& t, QValFunction<T> customBind) { return customBind(t, std::move(unsafeThis())).isValid ? std::move(outer) : T_(); }
// Literal metadata support // Literal metadata support
QVal<T_> meta(const char* n, const char* m) { return meta(QIdentifierLiteral(n),QAsciiData(m)); } QVal<T_> meta(const char* n, const char* m) { return meta(QIdentifierLiteral(n),QAsciiData(m)); }
...@@ -385,7 +388,7 @@ public: ...@@ -385,7 +388,7 @@ public:
explicit operator bool() const noexcept { return outer.operator bool(); } //!< Drives QTransmogrifier<T>::bind() traversal explicit operator bool() const noexcept { return outer.operator bool(); } //!< Drives QTransmogrifier<T>::bind() traversal
QValueStatus* operator->() noexcept { return outer.operator ->(); } QValueStatus* operator->() noexcept { return outer.operator ->(); }
operator QValueStatus() { return out(); /* calls T_::operator QValueStatus() if T_ != QValueStatus */ } operator QValueEnd() { return out(); /* calls T_::operator QValueEnd() if T_ != QValueEnd */ }
/**/ T_ out() { return outer-> tryOut() ? std::move(outer) : T_ (); } /**/ T_ out() { return outer-> tryOut() ? std::move(outer) : T_ (); }
QVal<QSeq<T_>> item() { return outer->tryItem() ? QVal<QSeq<T_>>(std::move(*this)) : QVal<QSeq<T_>>(); } QVal<QSeq<T_>> item() { return outer->tryItem() ? QVal<QSeq<T_>>(std::move(*this)) : QVal<QSeq<T_>>(); }
...@@ -430,7 +433,7 @@ public: ...@@ -430,7 +433,7 @@ public:
explicit operator bool() const noexcept { return outer.operator bool(); } //!< Drives QTransmogrifier<T>::bind() traversal explicit operator bool() const noexcept { return outer.operator bool(); } //!< Drives QTransmogrifier<T>::bind() traversal
QValueStatus* operator->() noexcept { return outer.operator ->(); } QValueStatus* operator->() noexcept { return outer.operator ->(); }
operator QValueStatus() { return out(); /* calls T_::operator QValueStatus() if T_ != QValueStatus */ } operator QValueEnd() { return out(); /* calls T_::operator QValueEnd() if T_ != QValueEnd */ }
/**/ T_ out ( ) { return outer->tryOut ( ) ? std::move(outer) : T_ (); } /**/ T_ out ( ) { return outer->tryOut ( ) ? std::move(outer) : T_ (); }
QVal<QRec<T_>> item(QIdentifier& n) { return outer->tryItem( n ) ? QVal<QRec<T_>>(std::move(*this)) : QVal<QRec<T_>>(); } QVal<QRec<T_>> item(QIdentifier& n) { return outer->tryItem( n ) ? QVal<QRec<T_>>(std::move(*this)) : QVal<QRec<T_>>(); }
...@@ -475,13 +478,13 @@ private: ...@@ -475,13 +478,13 @@ private:
//! //!
template<typename T, typename TEnabledIf=void> template<typename T, typename TEnabledIf=void>
struct QTransmogrifier { struct QTransmogrifier {
static QValueStatus zap(QValue&& value, T& t) { return t .zap(std::move(value)); } // In case of error, define a T::bind(QValue) method or external QTransmogrifier<T>::bind(QValue,T&) static QValueEnd zap(QValue&& value, T& t) { return t .zap(std::move(value)); } // In case of error, define a T::bind(QValue) method or external QTransmogrifier<T>::bind(QValue,T&)
static QValueStatus zap(QValue&& value,const T& t) { return const_cast<T&>(t).zap(std::move(value)); } // In case of error, define a T::bind(QValue) method or external QTransmogrifier<T>::bind(QValue,const T&) static QValueEnd zap(QValue&& value,const T& t) { return const_cast<T&>(t).zap(std::move(value)); } // In case of error, define a T::bind(QValue) method or external QTransmogrifier<T>::bind(QValue,const T&)
static QValueStatus zap(QValue&& value, T&& t) { return t .zap(std::move(value)); } // In case of error, define a T::bind(QValue) method or external QTransmogrifier<T>::bind(QValue,T&&) static QValueEnd zap(QValue&& value, T&& t) { return t .zap(std::move(value)); } // In case of error, define a T::bind(QValue) method or external QTransmogrifier<T>::bind(QValue,T&&)
}; };
template<class T> template<class T>
bool QValueStatus::tryBind(BindGeneric, T&& t) { return bool(QTransmogrifier<RemoveCvRef<T>>::zap(QValue(_unsafeCopy()),std::forward<T>(t))); } bool QValueStatus::tryBind(BindGeneric, T&& t) { return QTransmogrifier<RemoveCvRef<T>>::zap(QValue(_unsafeCopy()),std::forward<T>(t)).isValid; }
// ////////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////////
// Base QAbstractValue implementations for Read and Write QValueMode // Base QAbstractValue implementations for Read and Write QValueMode
...@@ -806,7 +809,7 @@ public: ...@@ -806,7 +809,7 @@ public:
template<typename T> QBindable(T& t) : f(/*captured T ref */[&t] (QValue&& v) { return v.bind(t); } ) {} template<typename T> QBindable(T& t) : f(/*captured T ref */[&t] (QValue&& v) { return v.bind(t); } ) {}
template<typename T> QBindable(T&& t) : f(/*captured T copy*/[ t] (QValue&& v) { return v.bind(t); } ) {} template<typename T> QBindable(T&& t) : f(/*captured T copy*/[ t] (QValue&& v) { return v.bind(t); } ) {}
QValueStatus zap(QValue&& v) { return f(std::move(v)); } QValueEnd zap(QValue&& v) { return f(std::move(v)); }
}; };
// ////////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////////
...@@ -852,7 +855,7 @@ QSeq<T_> QSeq<T_>::forEach(Ts& ts, ...@@ -852,7 +855,7 @@ QSeq<T_> QSeq<T_>::forEach(Ts& ts,
// For Q_DEFINE_ZAP_WITH_METAOBJECT below // For Q_DEFINE_ZAP_WITH_METAOBJECT below
template<class T> template<class T>
QValueStatus qMetaZap(QValue&& v, T* t) { QValueEnd qMetaZap(QValue&& v, T* t) {
auto rw = v->mode(); auto rw = v->mode();
auto mo = T::staticMetaObject; auto mo = T::staticMetaObject;
auto r = v.meta(qmName,QAsciiData(mo.className())).record(); auto r = v.meta(qmName,QAsciiData(mo.className())).record();
...@@ -923,11 +926,11 @@ QValueStatus qMetaZap(QValue&& v, T* t) { ...@@ -923,11 +926,11 @@ QValueStatus qMetaZap(QValue&& v, T* t) {
} }
//! Default bind(QValue&&) based on static QMetaObject reflection //! Default bind(QValue&&) based on static QMetaObject reflection
#define Q_DEFINE_ZAP_WITH_METAOBJECT(Class) QValueStatus zap(QValue&& v) { return qMetaZap<Class>(std::move(v), this); } #define Q_DEFINE_ZAP_WITH_METAOBJECT(Class) QValueEnd zap(QValue&& v) { return qMetaZap<Class>(std::move(v), this); }
template<typename T> template<typename T>
struct QTransmogrifier<QDefaultValue<T>> { struct QTransmogrifier<QDefaultValue<T>> {
static QValueStatus zap(QValue&& v, QDefaultValue<T>&& t) { static QValueEnd zap(QValue&& v, QDefaultValue<T>&& t) {
if (v->mode()!=Read) { if (v->mode()!=Read) {
return v.bind(t.value); return v.bind(t.value);
} else { } else {
...@@ -945,10 +948,10 @@ struct QTransmogrifier<QDefaultValue<T>> { ...@@ -945,10 +948,10 @@ struct QTransmogrifier<QDefaultValue<T>> {
template<typename T> template<typename T>
struct QTransmogrifier<T, typename std::enable_if<std::is_unsigned<T>::value && std::is_integral<T>::value && !std::is_same<T,bool>::value>::type> { struct QTransmogrifier<T, typename std::enable_if<std::is_unsigned<T>::value && std::is_integral<T>::value && !std::is_same<T,bool>::value>::type> {
static QValueStatus zap(QValue&& v, T&& t) { static QValueEnd zap(QValue&& v, T&& t) {
return v.bind(quint64(t)); return v.bind(quint64(t));
} }
static QValueStatus zap(QValue&& v, T& t) { static QValueEnd zap(QValue&& v, T& t) {
if (v->mode()==Write) { if (v->mode()==Write) {
return bind(std::move(v),T(t)); return bind(std::move(v),T(t));
} }
...@@ -960,10 +963,10 @@ struct QTransmogrifier<T, typename std::enable_if<std::is_unsigned<T>::value && ...@@ -960,10 +963,10 @@ struct QTransmogrifier<T, typename std::enable_if<std::is_unsigned<T>::value &&
}; };
template<typename T> template<typename T>
struct QTransmogrifier<T, typename std::enable_if<std::is_signed<T>::value && std::is_integral<T>::value && !std::is_same<T,bool>::value>::type> { struct QTransmogrifier<T, typename std::enable_if<std::is_signed<T>::value && std::is_integral<T>::value && !std::is_same<T,bool>::value>::type> {
static QValueStatus zap(QValue&& v, T&& t) { static QValueEnd zap(QValue&& v, T&& t) {
return v.bind(qint64(t)); return v.bind(qint64(t));
} }
static QValueStatus zap(QValue&& v, T& t) { static QValueEnd zap(QValue&& v, T& t) {
if (v->mode()==Write) { if (v->mode()==Write) {
return bind(std::move(v),T(t)); return bind(std::move(v),T(t));
} }
...@@ -978,7 +981,7 @@ struct QTransmogrifier<T, typename std::enable_if<std::is_signed<T>::value && st ...@@ -978,7 +981,7 @@ struct QTransmogrifier<T, typename std::enable_if<std::is_signed<T>::value && st
template<typename T, unsigned Size> template<typename T, unsigned Size>
struct QTransmogrifier<T[Size]> { struct QTransmogrifier<T[Size]> {
static QValueStatus zap(QValue&& v, T(& ts)[Size]) { static QValueEnd zap(QValue&& v, T(& ts)[Size]) {
if (v->mode()==Write) { if (v->mode()==Write) {
quint32 size=Size; quint32 size=Size;
auto s(v.sequence(&size)); auto s(v.sequence(&size));
...@@ -1008,7 +1011,7 @@ struct QTransmogrifier<T[Size]> { ...@@ -1008,7 +1011,7 @@ struct QTransmogrifier<T[Size]> {
template<typename T> template<typename T>
struct QTransmogrifier<QVector<T>> { struct QTransmogrifier<QVector<T>> {
static QValueStatus zap(QValue&& v, QVector<T>&& ts) { static QValueEnd zap(QValue&& v, QVector<T>&& ts) {
if (v->mode()==Write) { if (v->mode()==Write) {
quint32 size=ts.size(); quint32 size=ts.size();
auto s(v.sequence(&size)); auto s(v.sequence(&size));
...@@ -1019,7 +1022,7 @@ struct QTransmogrifier<QVector<T>> { ...@@ -1019,7 +1022,7 @@ struct QTransmogrifier<QVector<T>> {
} }
else { Q_ASSERT_X(!v, Q_FUNC_INFO, "Unsupported v->mode()"); return v.any(); } else { Q_ASSERT_X(!v, Q_FUNC_INFO, "Unsupported v->mode()"); return v.any(); }
} }
static QValueStatus zap(QValue&& v, QVector<T>& ts) { static QValueEnd zap(QValue&& v, QVector<T>& ts) {
if (v->mode()==Write) { if (v->mode()==Write) {
quint32 size=ts.size(); quint32 size=ts.size();
auto s(v.sequence(&size)); auto s(v.sequence(&size));
...@@ -1054,7 +1057,7 @@ struct QTransmogrifier<QVector<T>> { ...@@ -1054,7 +1057,7 @@ struct QTransmogrifier<QVector<T>> {
template<typename T> template<typename T>
struct QTransmogrifier<QList<T>> { struct QTransmogrifier<QList<T>> {
static QValueStatus zap(QValue&& v, QList<T>&& ts) { static QValueEnd zap(QValue&& v, QList<T>&& ts) {
if (v->mode()==Write) { if (v->mode()==Write) {
quint32 size=quint32(ts.size()); quint32 size=quint32(ts.size());
auto s(v.sequence(&size)); auto s(v.sequence(&size));
...@@ -1065,7 +1068,7 @@ struct QTransmogrifier<QList<T>> { ...@@ -1065,7 +1068,7 @@ struct QTransmogrifier<QList<T>> {
} }
else { Q_ASSERT_X(!v, Q_FUNC_INFO, "Unsupported v->mode()"); return v.any(); } else { Q_ASSERT_X(!v, Q_FUNC_INFO, "Unsupported v->mode()"); return v.any(); }
} }
static QValueStatus zap(QValue&& v, QList<T>& ts) { static QValueEnd zap(QValue&& v, QList<T>& ts) {
if (v->mode()==Write) { if (v->mode()==Write) {
quint32 size=quint32(ts.size()); quint32 size=quint32(ts.size());
auto s(v.sequence(&size)); auto s(v.sequence(&size));
...@@ -1101,7 +1104,7 @@ struct QTransmogrifier<QList<T>> { ...@@ -1101,7 +1104,7 @@ struct QTransmogrifier<QList<T>> {
template<typename T> template<typename T>
struct QTransmogrifier<QMap<QString,T>> { struct QTransmogrifier<QMap<QString,T>> {
static QValueStatus zap(QValue&& v, QMap<QString,T>&& ts) { static QValueEnd zap(QValue&& v, QMap<QString,T>&& ts) {
if (v->mode()==Write) { if (v->mode()==Write) {
quint32 size=quint32(ts.size()); quint32 size=quint32(ts.size());
auto s(v.record(&size)); auto s(v.record(&size));
...@@ -1112,7 +1115,7 @@ struct QTransmogrifier<QMap<QString,T>> { ...@@ -1112,7 +1115,7 @@ struct QTransmogrifier<QMap<QString,T>> {
} }
else { Q_ASSERT_X(!v, Q_FUNC_INFO, "Unsupported v->mode()"); return v.any(); } else { Q_ASSERT_X(!v, Q_FUNC_INFO, "Unsupported v->mode()"); return v.any(); }
} }
static QValueStatus zap(QValue&& v, QMap<QString,T>& ts) { static QValueEnd zap(QValue&& v, QMap<QString,T>& ts) {
if (v->mode()==Write) { if (v->mode()==Write) {
quint32 size=quint32(ts.size()); quint32 size=quint32(ts.size());
auto s(v.record(&size)); auto s(v.record(&size));
...@@ -1140,7 +1143,7 @@ struct QTransmogrifier<QMap<QString,T>> { ...@@ -1140,7 +1143,7 @@ struct QTransmogrifier<QMap<QString,T>> {
template<> //!< \remark Enumerating types where BindSupport<_> = BindNative with C++11 seems hard, so we just handle the set of default QAbstractValue BindNative types template<> //!< \remark Enumerating types where BindSupport<_> = BindNative with C++11 seems hard, so we just handle the set of default QAbstractValue BindNative types
struct QTransmogrifier<QValue> { struct QTransmogrifier<QValue> {
static QValueStatus zap(QValue&& src, QValue&& dst) { static QValueEnd zap(QValue&& src, QValue&& dst) {
if (src->mode()==Read && dst->mode()==Write) { if (src->mode()==Read && dst->mode()==Write) {
QValueStatus srcRes; QValueStatus srcRes;
auto suspended = src->setErrorHandler(); auto suspended = src->setErrorHandler();
...@@ -1196,7 +1199,7 @@ struct QTransmogrifier<QValue> { ...@@ -1196,7 +1199,7 @@ struct QTransmogrifier<QValue> {
else if (src->mode()==Write && dst->mode()==Read) { return zap(std::move(dst),std::move(src)); } // To return reader's QValueStatus instead of writer's QValueStatus since it should contain more information (mismatches, etc.) else if (src->mode()==Write && dst->mode()==Read) { return zap(std::move(dst),std::move(src)); } // To return reader's QValueStatus instead of writer's QValueStatus since it should contain more information (mismatches, etc.)
else { Q_ASSERT_X(!src || !dst, Q_FUNC_INFO, "Unsupported src->mode() and dst->mode()"); return src.null(); } else { Q_ASSERT_X(!src || !dst, Q_FUNC_INFO, "Unsupported src->mode() and dst->mode()"); return src.null(); }
} }
static QValueStatus zap(QValue&& v1, QValue& v2) { static QValueEnd zap(QValue&& v1, QValue& v2) {
return zap(std::move(v1),std::move(v2)); return zap(std::move(v1),std::move(v2));
} }
}; };
...@@ -99,7 +99,7 @@ struct Person ...@@ -99,7 +99,7 @@ struct Person
{ {
QString firstName, lastName; double height; int age; QVector<QString> phones; QString comments; QList<Person> children; QString firstName, lastName; double height; int age; QVector<QString> phones; QString comments; QList<Person> children;
QValueStatus zap(QValue&& value) { // works with value->mode()==Read as well as Write QValueEnd zap(QValue&& value) { // works with value->mode()==Read as well as Write
return value return value
.record("Person") // aggregates a usually small number of named items in any order (Person is an optional meta-name for the record that may be ignored) .record("Person") // aggregates a usually small number of named items in any order (Person is an optional meta-name for the record that may be ignored)
.sequence("names") // aggregates any number of items in a fixed order, just to illustrate a basic mapping between struct Person and a more general data schema .sequence("names") // aggregates any number of items in a fixed order, just to illustrate a basic mapping between struct Person and a more general data schema
...@@ -247,8 +247,8 @@ Each specialization must implement at least the bind() method for lvalue referen ...@@ -247,8 +247,8 @@ Each specialization must implement at least the bind() method for lvalue referen
references to support temporaries, and for const lvalue reference to efficiently support copyable types. references to support temporaries, and for const lvalue reference to efficiently support copyable types.
```cpp ```cpp
template<> struct QTransmogrifier<QColor> { template<> struct QTransmogrifier<QColor> {
static QValueStatus zap(QValue&& v, QColor&& c) { QColor copy(c); return bind(std::move(v),copy); } // supports writing temporaries and const QColor& static QValueEnd zap(QValue&& v, QColor&& c) { QColor copy(c); return bind(std::move(v),copy); } // supports writing temporaries and const QColor&
static QValueStatus zap(QValue&& v, QColor& c) { static QValueEnd zap(QValue&& v, QColor& c) {
if (!c.isValid()) { if (!c.isValid()) {
return v.null(); return v.null();
} }
......
...@@ -84,7 +84,7 @@ struct Person ...@@ -84,7 +84,7 @@ struct Person
{ {
int id; QString firstName, lastName; double height; int age; QVector<Phone> phones; QString comments; QList<Person> children; int id; QString firstName, lastName; double height; int age; QVector<Phone> phones; QString comments; QList<Person> children;
QValueStatus zap(QValue&& value) { // works with value->mode()==Read as well as Write QValueEnd zap(QValue&& value) { // works with value->mode()==Read as well as Write
return value return value
.record("Person") .record("Person")
.sequence("names") .sequence("names")
...@@ -137,7 +137,7 @@ struct PersonsView ...@@ -137,7 +137,7 @@ struct PersonsView
{ {
QList<Person>& persons; QList<Person>& persons;
QValueStatus zap(QValue&& value) { QValueEnd zap(QValue&& value) {
return value return value
.meta(qmChildren,"children") .meta(qmChildren,"children")
.meta(qmColumns ,"names,height,age,phones,comments") // to optimize multi-dimensional data formats .meta(qmColumns ,"names,height,age,phones,comments") // to optimize multi-dimensional data formats
...@@ -151,7 +151,7 @@ struct PersonsTable { ...@@ -151,7 +151,7 @@ struct PersonsTable {
QList<Person>& persons; QList<Person>& persons;
PersonsTable(QList<Person>& ps) : persons(ps) {} PersonsTable(QList<Person>& ps) : persons(ps) {}
QValueStatus zap(<