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

Start removing templates where they are optional: Cur<> => Cursor

parent 7d378bb2
......@@ -252,14 +252,11 @@ private:
T_ outer = T_();
};
//! Interface for Cur<> TImpl with a fixed subset of BindNative types and just a few optional methods
struct IBind;
//! A non-owning pointer to TImpl that transparently bypasses invalid calls to TImpl
//! \remark Can be used to easily implement Reader/Writers adding shortcut methods using Cur((TImpl*)this)
//! \warning Cur bypasses calls to a nullptr==impl
//! \remark A nullptr==impl results from using the same intermediate Val/Seq/Rec twice (a programmer error) or from runtime impl errors
template<class TImpl = IBind> //!< Processing associated to the traversal
template<class TImpl> //!< Processing associated to the traversal
class Cur
{
Q_DISABLE_COPY(Cur)
......@@ -306,34 +303,13 @@ private:
};
// //////////////////////////////////////////////////////////////////////////
// Base Cur<TImpl> implementations for BindMode Read and Write
// Base Cur<TImpl> implementations for Read and Write BindMode
//#include <QtCore/qfloat16.h>
//#include <QtCore/qdatetime.h>
//#include <QtCore/quuid.h>
template<> struct BindSupport<IBind,const char*> : BindNative {};
template<> struct BindSupport<IBind,QUtf8String> : BindNative {};
template<> struct BindSupport<IBind, QString> : BindNative {};
template<> struct BindSupport<IBind, QChar> : BindNative {};
template<> struct BindSupport<IBind, bool> : BindNative {};
template<> struct BindSupport<IBind, qint8> : BindNative {};
template<> struct BindSupport<IBind, quint8> : BindNative {};
template<> struct BindSupport<IBind, qint16> : BindNative {};
template<> struct BindSupport<IBind, quint16> : BindNative {};
template<> struct BindSupport<IBind, qint32> : BindNative {};
template<> struct BindSupport<IBind, quint32> : BindNative {};
template<> struct BindSupport<IBind, qint64> : BindNative {};
template<> struct BindSupport<IBind, quint64> : BindNative {};
//template<> struct BindSupport<IBind, qfloat16> : BindNative {};
template<> struct BindSupport<IBind, float> : BindNative {};
template<> struct BindSupport<IBind, double> : BindNative {};
//template<> struct BindSupport<IBind, QDate> : BindNative {};
//template<> struct BindSupport<IBind, QDateTime> : BindNative {};
//template<> struct BindSupport<IBind, QTime> : BindNative {};
//template<> struct BindSupport<IBind, QUuid> : BindNative {};
template<> struct BindSupport<IBind, QByteArray> : BindNative {};
//! Interface for Cursor TImpl with a fixed subset of BindNative types and just a few optional methods
struct IBind {
virtual ~IBind() = default;
......@@ -408,6 +384,30 @@ struct IBind {
virtual void _reportError(const char*) {}
};
template<> struct BindSupport<IBind,const char*> : BindNative {};
template<> struct BindSupport<IBind,QUtf8String> : BindNative {};
template<> struct BindSupport<IBind, QString> : BindNative {};
template<> struct BindSupport<IBind, QChar> : BindNative {};
template<> struct BindSupport<IBind, bool> : BindNative {};
template<> struct BindSupport<IBind, qint8> : BindNative {};
template<> struct BindSupport<IBind, quint8> : BindNative {};
template<> struct BindSupport<IBind, qint16> : BindNative {};
template<> struct BindSupport<IBind, quint16> : BindNative {};
template<> struct BindSupport<IBind, qint32> : BindNative {};
template<> struct BindSupport<IBind, quint32> : BindNative {};
template<> struct BindSupport<IBind, qint64> : BindNative {};
template<> struct BindSupport<IBind, quint64> : BindNative {};
//template<> struct BindSupport<IBind, qfloat16> : BindNative {};
template<> struct BindSupport<IBind, float> : BindNative {};
template<> struct BindSupport<IBind, double> : BindNative {};
//template<> struct BindSupport<IBind, QDate> : BindNative {};
//template<> struct BindSupport<IBind, QDateTime> : BindNative {};
//template<> struct BindSupport<IBind, QTime> : BindNative {};
//template<> struct BindSupport<IBind, QUuid> : BindNative {};
template<> struct BindSupport<IBind, QByteArray> : BindNative {};
using Cursor = Cur<IBind>; //!< \remark It would be possible to implement Cursor without templates nor BindSupport by defining all IBind overloads
static char *qulltoa2(char *p, qulonglong n, int base=10)
{
*--p = '\0';
......@@ -496,7 +496,6 @@ struct IWriter : public IBind
virtual bool _any() { return _null(); }
};
template<typename T> struct BindSupport<IWriter,T> : BindSupport<IBind,T> {};
//! Base IBind implementations with BindMode::Read
struct IReader : public IBind
......@@ -584,13 +583,13 @@ struct IReader : public IBind
#include <QtCore/qatomic.h>
class QLogger : public Cur<>
class QLogger : public Cursor
{
static QAtomicPointer<IWriter> s_impl;
public:
static IWriter* setWriter(IWriter* i) { return s_impl.fetchAndStoreOrdered(i); }
QLogger() : Cur<>(s_impl) {}
QLogger() : Cursor(s_impl) {}
};
QAtomicPointer<IWriter> QLogger::s_impl = nullptr;
......@@ -685,7 +684,7 @@ struct QBind<TResult, T[Size]> {
#include <QtCore/qstring.h>
template<class TResult> //=Cur<>
template<class TResult> //=Cursor
struct QBind<TResult, QString> {
static TResult bind(Val<TResult>&& v, QString&& s) {
return v.bind(s.toUtf8().constData());
......@@ -812,7 +811,7 @@ struct QBind<TResult, QMap<QString,T>> {
#include <QtGui/qcolor.h>
template<class TResult> //= Cur<>
template<class TResult> //= Cursor
struct QBind<TResult, QColor> {
static TResult bind(Val<TResult>&& v, QColor&& src) {
return v.record()
......@@ -827,21 +826,21 @@ struct QBind<TResult, QColor> {
};
// --------------------------------------------------------------------------
// QBind specialization for generic Val<Cur<>> for a fixed set of possibly BindNative types
// QBind specialization for generic Val<Cursor> for a fixed set of possibly BindNative types
template<> //!< \remark Enumerating types where BindSupport<Cur<TImpl>,_> = BindNative with C++11 seems hard, so we just handle the set of default IBind BindNative types
struct QBind<Cur<>, Val<Cur<>>> {
static Cur<> bind(Val<Cur<>>&& src, Val<Cur<>>&& dst) {
struct QBind<Cursor, Val<Cursor>> {
static Cursor bind(Val<Cursor>&& src, Val<Cursor>&& dst) {
if (src->mode()==Read && dst->mode()==Write) {
Cur<> srcRes;
Cursor srcRes;
{
QScopedChoice<Val<Cur<>>> choice(src);
Seq<Cur<>> srcSeq; Seq<Cur<>> dstSeq;
QScopedChoice<Val<Cursor>> choice(src);
Seq<Cursor> srcSeq; Seq<Cursor> dstSeq;
if ( (srcSeq = src.sequence())) {
/**/ dstSeq = dst.sequence();
Val<Cur<>> srcVal; Val<Cur<>> dstVal;
while((srcVal = srcSeq.unsafeItem())) { // using item()'s Val<Seq<Cur<>> would cause an infinite compiler loop to generate corresponding QBind<Val<Seq<Seq<...>>,_> functions
Val<Cursor> srcVal; Val<Cursor> dstVal;
while((srcVal = srcSeq.unsafeItem())) { // using item()'s Val<Seq<Cursor> would cause an infinite compiler loop to generate corresponding QBind<Val<Seq<Seq<...>>,_> functions
dstVal = dstSeq.unsafeItem();
srcSeq = srcVal.bind(std::move(dstVal));
}
......@@ -849,11 +848,11 @@ struct QBind<Cur<>, Val<Cur<>>> {
/**/ dstSeq.out();
return srcSeq.out();
}
Rec<Cur<>> srcRec; Rec<Cur<>> dstRec;
Rec<Cursor> srcRec; Rec<Cursor> dstRec;
if ( (srcRec = src.record())) {
/**/ dstRec = dst.record();
QUtf8String srcKey; Val<Cur<>> srcVal; Val<Cur<>> dstVal;
QUtf8String srcKey; Val<Cursor> srcVal; Val<Cursor> dstVal;
while((srcVal = srcRec.unsafeItem(srcKey))) {
dstVal = dstRec.unsafeItem(srcKey);
srcRec = srcVal.bind(std::move(dstVal));
......@@ -865,7 +864,7 @@ struct QBind<Cur<>, Val<Cur<>>> {
bool b; if ((srcRes = src.bind(b))) { dst.bind(b); return srcRes; }
quint64 u; if ((srcRes = src.bind(u))) { dst.bind(u); return srcRes; } // TODO optimize to smaller types where possible?
// NB following numeric types can only be handled if Cur<> refuses to lose sign or digits...
// NB following numeric types can only be handled if Cursor refuses to lose sign or digits...
qint64 l; if ((srcRes = src.bind(l))) { dst.bind(l); return srcRes; }
double d; if ((srcRes = src.bind(d))) { dst.bind(d); return srcRes; } // TODO optimize to smaller types where possible?
// TODO other native types we do not want to treat as text: QDateTime, QUrl, ? (fractions, ...)
......@@ -875,10 +874,10 @@ struct QBind<Cur<>, Val<Cur<>>> {
/**/ dst.null();
return srcRes;
}
else if (src->mode()==Write && dst->mode()==Read) { return bind(std::move(dst),std::move(src)); } // To return reader's Cur<> instead of writer's Cur<> since it should contain more information (mismatches, etc.)
else if (src->mode()==Write && dst->mode()==Read) { return bind(std::move(dst),std::move(src)); } // To return reader's Cursor instead of writer's Cursor 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(); }
}
static Cur<> bind(Val<Cur<>>&& v1, Val<Cur<>>& v2) {
static Cursor bind(Val<Cursor>&& v1, Val<Cursor>& v2) {
return bind(std::move(v1),std::move(v2));
}
};
......@@ -108,11 +108,11 @@ public:
QCborWriter(QIODevice* io) : io(io) { Q_ASSERT(io); }
// Shortcuts
/**/ Val<Cur<>> value ( ) { return Cur<>(this).value(); }
/**/ Val<Cur<>> meta ( QMetaData&& m) { return Cur<>(this).value().meta ( m); }
/**/ Val<Cur<>> meta ( QMetaData& m) { return Cur<>(this).value().meta ( m); }
/**/ Seq<Cur<>> sequence(quint32* s=nullptr) { return Cur<>(this).value().sequence ( s); }
template<typename T> Cur<> bind ( T&& t) { return Cur<>(this).value().bind(std::forward<T>(t)); }
/**/ Val<Cursor> value ( ) { return Cursor(this).value(); }
/**/ Val<Cursor> meta ( QMetaData&& m) { return Cursor(this).value().meta ( m); }
/**/ Val<Cursor> meta ( QMetaData& m) { return Cursor(this).value().meta ( m); }
/**/ Seq<Cursor> sequence(quint32* s=nullptr) { return Cursor(this).value().sequence ( s); }
template<typename T> Cursor bind ( T&& t) { return Cursor(this).value().bind(std::forward<T>(t)); }
protected:
bool _isOk() { return io; }
......@@ -172,7 +172,7 @@ private:
}
QIODevice* io;
std::vector<bool> levels; //!< minimal dynamic context to ensure well-formedness in case TResult is abandoned: true indicates Definite levels with prefixed size
std::vector<bool> levels; //!< minimal dynamic context to ensure well-formedness in case Cursor is abandoned: true indicates Definite levels with prefixed size
};
// --------------------------------------------------------------------------
......@@ -191,11 +191,11 @@ public:
QVector<Error> errors;
// Shortcuts
/**/ Val<Cur<>> value ( ) { return Cur<>(this).value() ; }
/**/ Val<Cur<>> meta ( QMetaData&& m) { return Cur<>(this).value().meta ( m); }
/**/ Val<Cur<>> meta ( QMetaData& m) { return Cur<>(this).value().meta ( m); }
/**/ Seq<Cur<>> sequence(quint32* s=nullptr) { return Cur<>(this).value().sequence ( s); }
template<typename T> Cur<> bind ( T&& t) { return Cur<>(this).value().bind(std::forward<T>(t)); }
/**/ Val<Cursor> value ( ) { return Cursor(this).value() ; }
/**/ Val<Cursor> meta ( QMetaData&& m) { return Cursor(this).value().meta ( m); }
/**/ Val<Cursor> meta ( QMetaData& m) { return Cursor(this).value().meta ( m); }
/**/ Seq<Cursor> sequence(quint32* s=nullptr) { return Cursor(this).value().sequence ( s); }
template<typename T> Cursor bind ( T&& t) { return Cursor(this).value().bind(std::forward<T>(t)); }
protected:
bool _sequence(quint32* =nullptr) { skipTag(); if (io->isArray () && io->enterContainer()) { return true; } _reportError(qBindExpectedSequence); return false; }
bool _record (quint32* =nullptr) { skipTag(); if (io->isMap () && io->enterContainer()) { return true; } _reportError(qBindExpectedRecord ); return false; }
......@@ -328,11 +328,11 @@ public:
QCborBuilder(QCborValue* v) : cbor(v) { Q_ASSERT(v); }
// Shortcuts
/**/ Val<Cur<>> value ( ) { return Cur<>(this).value(); }
/**/ Val<Cur<>> meta ( QMetaData&& m) { return Cur<>(this).value().meta ( m); }
/**/ Val<Cur<>> meta ( QMetaData& m) { return Cur<>(this).value().meta ( m); }
/**/ Seq<Cur<>> sequence(quint32* s=nullptr) { return Cur<>(this).value().sequence ( s); }
template<typename T> Cur<> bind ( T&& t) { return Cur<>(this).value().bind(std::forward<T>(t)); }
/**/ Val<Cursor> value ( ) { return Cursor(this).value(); }
/**/ Val<Cursor> meta ( QMetaData&& m) { return Cursor(this).value().meta ( m); }
/**/ Val<Cursor> meta ( QMetaData& m) { return Cursor(this).value().meta ( m); }
/**/ Seq<Cursor> sequence(quint32* s=nullptr) { return Cursor(this).value().sequence ( s); }
template<typename T> Cursor bind ( T&& t) { return Cursor(this).value().bind(std::forward<T>(t)); }
protected:
bool _sequence(quint32* s=nullptr) { Q_UNUSED(s); levels.push(Step(nullptr)); return true; }
bool _record (quint32* s=nullptr) { Q_UNUSED(s); levels.push(Step("" )); return true; }
......
......@@ -67,7 +67,7 @@ public:
Val<Cur<QDataWriter>> meta ( QMetaData& m) { return Cur<QDataWriter>(this).value().meta (m); }
Seq<Cur<QDataWriter>> sequence(quint32* s=nullptr) { return Cur<QDataWriter>(this).value().sequence(s); }
template<typename T> Cur<> bind(T&& t) { return Cur<>(this).value().bind(std::forward<T>(t)); } //!< Only the standard Cur<> is compatible with QWritable
template<typename T> Cursor bind(T&& t) { return Cursor(this).value().bind(std::forward<T>(t)); } //!< Only the standard Cursor is compatible with QWritable
protected:
friend class Cur<QDataWriter>;
bool _sequence(quint32* s=nullptr) { if (s) *io << *s; return true; }
......@@ -86,7 +86,7 @@ protected:
private:
QDataStream* io;
};
template<typename T> struct BindSupport<QDataWriter,T> : BindSupport<IWriter,T> {};
template<typename T> struct BindSupport<QDataWriter,T> : BindSupport<IBind,T> {};
// TODO BindNative other types that should bind specifically for compatibility with QDataStream
template<> struct BindSupport<QDataWriter, QColor> : BindNative {};
......
......@@ -59,9 +59,9 @@ public:
QJsonBuilder(QJsonValue* v) : json(v) { Q_ASSERT(v); }
// Shortcuts
/**/ Val<Cur<>> value ( ) { return Cur<>(this).value(); }
/**/ Seq<Cur<>> sequence(quint32* s=nullptr) { return Cur<>(this).value().sequence ( s); }
template<typename T> Cur<> bind ( T&& t) { return Cur<>(this).value().bind(std::forward<T>(t)); }
/**/ Val<Cursor> value ( ) { return Cursor(this).value(); }
/**/ Seq<Cursor> sequence(quint32* s=nullptr) { return Cursor(this).value().sequence ( s); }
template<typename T> Cursor bind ( T&& t) { return Cursor(this).value().bind(std::forward<T>(t)); }
protected:
bool _sequence(quint32* s=nullptr) { Q_UNUSED(s); levels.push(Step(nullptr)); return true; }
bool _record (quint32* s=nullptr) { Q_UNUSED(s); levels.push(Step("" )); return true; }
......@@ -114,9 +114,9 @@ public:
}
// Shortcuts
/**/ Val<Cur<>> value ( ) { return Cur<>(this).value(); }
/**/ Seq<Cur<>> sequence(quint32* s=nullptr) { return Cur<>(this).value().sequence ( s); }
template<typename T> Cur<> bind ( T&& t) { return Cur<>(this).value().bind(std::forward<T>(t)); }
/**/ Val<Cursor> value ( ) { return Cursor(this).value(); }
/**/ Seq<Cursor> sequence(quint32* s=nullptr) { return Cursor(this).value().sequence ( s); }
template<typename T> Cursor bind ( T&& t) { return Cursor(this).value().bind(std::forward<T>(t)); }
protected:
bool _sequence(quint32* s=nullptr) { Q_UNUSED(s); if (current()->isArray ()) { steps.push(Step()); return true; } _reportError(qBindExpectedSequence); return false; }
bool _record (quint32* s=nullptr) { Q_UNUSED(s); if (current()->isObject()) { steps.push(Step()); return true; } _reportError(qBindExpectedRecord ); return false; }
......@@ -155,9 +155,9 @@ public:
~QJsonWriter() { for (auto&& level : levels) io->write(level.end); }
// Shortcuts
/**/ Val<Cur<>> value ( ) { return Cur<>(this).value(); }
/**/ Seq<Cur<>> sequence(quint32* s=nullptr) { return Cur<>(this).value().sequence ( s); }
template<typename T> Cur<> bind ( T&& t) { return Cur<>(this).value().bind(std::forward<T>(t)); }
/**/ Val<Cursor> value ( ) { return Cursor(this).value(); }
/**/ Seq<Cursor> sequence(quint32* s=nullptr) { return Cursor(this).value().sequence ( s); }
template<typename T> Cursor bind ( T&& t) { return Cursor(this).value().bind(std::forward<T>(t)); }
protected:
bool _sequence(quint32* s=nullptr) { Q_UNUSED(s); levels.push(Step{"","]"}); return io->write("["); }
bool _record (quint32* s=nullptr) { Q_UNUSED(s); levels.push(Step{"","}"}); return io->write("{"); }
......@@ -205,7 +205,7 @@ private:
}
QIODevice* io;
QStack<Step> levels = QStack<Step>(); // TODO Replace with std::vector<bool> for performance //!< minimal dynamic context to implement out() and ensure well-formedness in case TResult is abandoned
QStack<Step> levels = QStack<Step>(); // TODO Replace with std::vector<bool> for performance //!< minimal dynamic context to implement out() and ensure well-formedness in case Cursor is abandoned
};
// --------------------------------------------------------------------------
......@@ -221,9 +221,9 @@ public:
QVector<Error> errors;
// Shortcuts
/**/ Val<Cur<>> value ( ) { return Cur<>(this).value(); }
/**/ Seq<Cur<>> sequence(quint32* s=nullptr) { return Cur<>(this).value().sequence(s); }
template<typename T> Cur<> bind ( T&& t) { return Cur<>(this).value().bind(std::forward<T>(t)); }
/**/ Val<Cursor> value ( ) { return Cursor(this).value(); }
/**/ Seq<Cursor> sequence(quint32* s=nullptr) { return Cursor(this).value().sequence(s); }
template<typename T> Cursor bind ( T&& t) { return Cursor(this).value().bind(std::forward<T>(t)); }
protected:
bool _sequence(quint32* =nullptr) { if (get('[', "[{\"ntf-0123456789.")) { levels.push(Step(-1,"]")); return true; } _reportError(qBindExpectedSequence); return false; }
bool _record (quint32* =nullptr) { if (get('{', "[{\"ntf-0123456789.")) { levels.push(Step(-1,"}")); return true; } _reportError(qBindExpectedRecord ); return false; }
......@@ -407,7 +407,7 @@ private:
};
// //////////////////////////////////////////////////////////////////////////
// QBind<TResult,QJson*> support
// QBind<_,QJson*> support
#include <QtCore/qjsonvalue.h>
#include <QtCore/qjsonarray.h>
......
......@@ -61,7 +61,7 @@ class QModelWriter : public IWriter
public:
QModelWriter(QAbstractItemModel* m) : m(m) { Q_ASSERT(m); }
Val<Cur<>> meta(QMetaData&& m) { return Cur<>(this).value().meta(m); }
Val<Cursor> meta(QMetaData&& m) { return Cursor(this).value().meta(m); }
protected:
void _meta(QMetaData& meta) {
if (meta.find(qmChildren)!=meta.end()) {
......
......@@ -55,9 +55,9 @@ public:
~QVariantBuilder() { while (!levels.isEmpty()) _out(); }
// Shortcuts
/**/ Val<Cur<>> value ( ) { return Cur<>(this).value(); }
/**/ Seq<Cur<>> sequence(quint32* s=nullptr) { return Cur<>(this).value().sequence ( s); }
template<typename T> Cur<> bind ( T&& t) { return Cur<>(this).value().bind(std::forward<T>(t)); }
/**/ Val<Cursor> value ( ) { return Cursor(this).value(); }
/**/ Seq<Cursor> sequence(quint32* s=nullptr) { return Cursor(this).value().sequence ( s); }
template<typename T> Cursor bind ( T&& t) { return Cursor(this).value().bind(std::forward<T>(t)); }
protected:
template<typename T>
bool _bind ( T&& t) { set(QVariant::fromValue(t)); return true; }
......@@ -132,8 +132,8 @@ private:
};
// TODO BindNative other QVariant-supported types?
//// //////////////////////////////////////////////////////////////////////////
//// QBind<TResult,QVariant&> example support for the fixed set of QVariantBuilder's BindNative types + other convenient types
// //////////////////////////////////////////////////////////////////////////
// QBind<TResult,QVariant&> example support for the fixed set of QVariantBuilder's BindNative types + other convenient types
template<class TResult>
struct QBind<TResult, QVariant> {
......
......@@ -60,7 +60,7 @@
#include <QtWidgets/qapplication.h>
// //////////////////////////////////////////////////////////////////////////
// QBind<_,T> basic example using an internal bind<TResult> method
// QBind<_,T> basic example using an internal bind method
struct Person
{
......@@ -97,7 +97,7 @@ QDataStream &operator<<(QDataStream &out, const Person &p)
}
// //////////////////////////////////////////////////////////////////////////
// QBind<TResult,_> basic implementation example
// IBind basic implementation example
#include <type_traits>
#include <QtCore/qiodevice.h>
......@@ -110,9 +110,9 @@ public:
TextWriter(QIODevice* io) : io(io) { Q_ASSERT(io); }
// Shortcuts
/**/ Val<Cur<>> value ( ) { return Cur<>(this).value(); }
/**/ Seq<Cur<>> sequence(quint32* s=nullptr) { return Cur<>(this).value().sequence ( s); }
template<typename T> Cur<> bind ( T&& t) { return Cur<>(this).value().bind(std::forward<T>(t)); }
/**/ Val<Cursor> value ( ) { return Cursor(this).value(); }
/**/ Seq<Cursor> sequence(quint32* s=nullptr) { return Cursor(this).value().sequence ( s); }
template<typename T> Cursor bind ( T&& t) { return Cursor(this).value().bind(std::forward<T>(t)); }
protected:
bool _isOk() { return io; }
......@@ -298,7 +298,7 @@ int main(int argc, char *argv[])
<< color;
}
STOP("QDataStream",QString::fromUtf8(b.buffer().toHex()));
QWritable<Cur<>> writables[5];
QWritable<Cursor> writables[5];
START {
writables[0] = 1.333333333333f;
writables[1] = PI;
......@@ -377,7 +377,7 @@ int main(int argc, char *argv[])
};
}
STOP("QDataStream",QString::fromUtf8(b.buffer().toHex()));
QWritable<Cur<>> writable;
QWritable<Cursor> writable;
START {
writable = transform;
}
......@@ -462,7 +462,7 @@ int main(int argc, char *argv[])
d << person;
}
STOP("QDataStream",QString::fromUtf8(b.buffer().toHex()));
QWritable<Cur<>> writable;
QWritable<Cursor> writable;
START {
writable = person;
}
......
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