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

Added _ before all Impl methods to enable calling the fluent interface directly from a QMovedResult

Added T>Cbor test
Attempted to add Json>Cbor which does not compile for now
parent 16658a19
......@@ -68,17 +68,18 @@ public:
Q_ENABLE_MOVE_DEFAULT(Val)
Val(T_&& out) { std::swap(m_out, out); }
using TResult = typename T_::TResult; //!< the start and end point of the traversal as well as the associated processing (see QJsonWriter for an example)
using TImpl = typename TResult::TImpl;
using TResult = typename T_::TResult; //!< the start and end point of the traversal as well as the associated processing (see QJsonWriter for an example)
using TImpl = typename TResult::TImpl;
//static constexpr BindMode Mode = TResult::Mode;
operator bool() { return m_out.operator bool(); } //!< to drive QBind<TResult,T>() traversal
TImpl* operator->() { return m_out.operator ->(); }
/**/ Seq<T_> sequence() { if (Q_LIKELY(m_out) && m_out->sequence()) return Seq<T_>(std::move(m_out)); return Seq<T_>(); }
/**/ T_ null() { if (Q_LIKELY(m_out) && m_out-> null()) return std::move(m_out) ; return T_ (); }
template<typename T> T_ bind(const T& t) { if (Q_LIKELY(m_out) && m_out-> bind(t)) return std::move(m_out) ; return T_ (); }
template<typename T> T_ bind( T& t) { if (Q_LIKELY(m_out) && m_out-> bind(t)) return std::move(m_out) ; return T_ (); }
template<typename T> T_ bind( T&& t) { if (Q_LIKELY(m_out) && m_out-> bind(t)) return std::move(m_out) ; return T_ (); }
/**/ Seq<T_> sequence() { if (Q_LIKELY(m_out) && m_out->_sequence()) return Seq<T_>(std::move(m_out)); return Seq<T_>(); }
/**/ T_ null() { if (Q_LIKELY(m_out) && m_out-> _null()) return std::move(m_out) ; return T_ (); }
template<typename T> T_ bind(const T& t) { if (Q_LIKELY(m_out) && m_out-> _bind(t)) return std::move(m_out) ; return T_ (); }
template<typename T> T_ bind( T& t) { if (Q_LIKELY(m_out) && m_out-> _bind(t)) return std::move(m_out) ; return T_ (); }
template<typename T> T_ bind( T&& t) { if (Q_LIKELY(m_out) && m_out-> _bind(t)) return std::move(m_out) ; return T_ (); }
private:
T_ m_out = T_(); //!< moved context of current traversal up to TResult that will reference the val itself (be it a QIODevice or QCborValue)
};
......@@ -90,16 +91,17 @@ public:
Q_ENABLE_MOVE_DEFAULT(Seq)
// T_ can be either a TResult or any combination of nested Seq or Rec like T_ = Rec<Seq<TResult>
using TResult = typename T_::TResult; //!< the start and end point of the traversal as well as the associated processing (see QJsonWriter for an example)
using TImpl = typename TResult::TImpl;
using TResult = typename T_::TResult; //!< the start and end point of the traversal as well as the associated processing (see QJsonWriter for an example)
using TImpl = typename TResult::TImpl;
//static constexpr BindMode Mode = T_::Mode;
Seq(T_&& out) { std::swap(m_out, out); }
operator bool() { return m_out.operator bool(); } //!< to drive QBind<TResult,T>() traversal
TImpl* operator->() { return m_out.operator ->(); }
Val<Seq<T_>> item() { if (Q_LIKELY(m_out) && m_out->item()) return Val<Seq<T_>>(std::move(*this)); return Seq<T_>(); }
T_ out() { if (Q_LIKELY(m_out) && m_out-> out()) return std::move(m_out) ; return T_ (); }
Val<Seq<T_>> item() { if (Q_LIKELY(m_out) && m_out->_item()) return Val<Seq<T_>>(std::move(*this)); return Seq<T_>(); }
T_ out() { if (Q_LIKELY(m_out) && m_out-> _out()) return std::move(m_out) ; return T_ (); }
operator TResult() { return out(); /* recursively calls operator TResult() as mandated by T_ */ }
TResult result() { return operator TResult(); }
......@@ -130,17 +132,17 @@ public:
operator bool() { return m; } //!< to drive QBind<TResult,T>() traversal
TImpl* operator->() { Q_ASSERT_X(m,Q_FUNC_INFO,"check operator bool() before calling operator->()"); return m; }
Val<TResult> value() { return Val<TResult>(std::move(*static_cast<TResult*>(this))); }
// Shortcuts
/**/ Seq<TResult> sequence() { return value().sequence(); }
/**/ TResult null() { return value(). null(); }
template<typename T> TResult bind( T& t) { return value(). bind(t); } // TODO only for readers ?
template<typename T> TResult bind(const T& t) { return value(). bind(t); }
template<typename T> TResult bind( T&& t) { return value(). bind(t); }
/**/ Seq<TResult> sequence() { return value().sequence(); } // if (Q_LIKELY(m) && m->_sequence()) return Seq<TResult>(std::move(*static_cast<TResult*>(this))); return Seq<TResult>(); }
/**/ TResult null() { return value(). null(); } // if (Q_LIKELY(m) && m-> _null()) return std::move(*static_cast<TResult*>(this)) ; return TResult (); }
template<typename T> TResult bind(const T& t) { return value(). bind(t); } // if (Q_LIKELY(m) && m-> _bind(t)) return std::move(*static_cast<TResult*>(this)) ; return TResult (); } // TODO only for readers ?
template<typename T> TResult bind( T& t) { return value(). bind(t); } // if (Q_LIKELY(m) && m-> _bind(t)) return std::move(*static_cast<TResult*>(this)) ; return TResult (); }
template<typename T> TResult bind( T&& t) { return value(). bind(t); } // if (Q_LIKELY(m) && m-> _bind(t)) return std::move(*static_cast<TResult*>(this)) ; return TResult (); }
protected:
QScopedResult(TImpl* result, bool owned) : m(result), m_owned(owned) {}
Val<TResult> value() { return Val<TResult>(std::move(*static_cast<TResult*>(this))); }
TImpl* m = nullptr;
bool m_owned = true; //!< for nested QBind only
};
......@@ -164,6 +166,13 @@ public:
TImpl* operator->() { return static_cast<TImpl*>(this); }
Val<TResult> value() { return Val<TResult>(std::move(*static_cast<TResult*>(this))); }
// Shortcuts
/**/ Seq<TResult> sequence() { return value().sequence(); } // if (static_cast<TImpl*>(this)->_sequence()) return Seq<TResult>(std::move(*static_cast<TResult*>(this))); return Seq<TResult>(); }
/**/ TResult null() { return value(). null(); } // if (static_cast<TImpl*>(this)-> _null()) return std::move(*static_cast<TResult*>(this)) ; return TResult (); }
template<typename T> TResult bind(const T& t) { return value(). bind(t); } // if (static_cast<TImpl*>(this)-> _bind(t)) return std::move(*static_cast<TResult*>(this)) ; return TResult (); } // TODO only for readers ?
template<typename T> TResult bind( T& t) { return value(). bind(t); } // if (static_cast<TImpl*>(this)-> _bind(t)) return std::move(*static_cast<TResult*>(this)) ; return TResult (); }
template<typename T> TResult bind( T&& t) { return value(). bind(t); } // if (static_cast<TImpl*>(this)-> _bind(t)) return std::move(*static_cast<TResult*>(this)) ; return TResult (); }
};
// //////////////////////////////////////////////////////////////////////////
......
......@@ -111,44 +111,46 @@ class CborWriter : public QMovedResult<CborWriter, BindMode::Write>
public:
Q_ENABLE_MOVE_DEFAULT(CborWriter)
CborWriter(QIODevice* io) : io(io) { Q_ASSERT(io); }
~CborWriter() { while (levels) out(); }
~CborWriter() { while (levels) _out(); }
operator bool() { return io; } // for QMovedResult
protected:
template<class T_> friend class Val; // calls methods below
bool sequence() { levels++;
io->putChar(cbor::IndefiniteLengthArrayByte);
return true; }
bool null() { io->putChar(cbor::NullByte);
return true; }
bool bind(const char* s) { putInteger (cbor::TextStringType, strlen(s));
io->write(s);
return true; }
bool _sequence() { levels++;
io->putChar(cbor::IndefiniteLengthArrayByte);
return true; }
bool _null() { io->putChar(cbor::NullByte);
return true; }
bool _bind(const char* s) { putInteger (cbor::TextStringType, strlen(s));
io->write(s);
return true; }
// Natively supported overloads
bool bind( float n) { io->putChar((cbor::SimpleTypesType << cbor::MajorTypeShift) | cbor::SinglePrecisionFloat);
union { float value; quint32 bits; } number;
number.value = n;
char bytes[sizeof(number.bits)];
qToBigEndian(number.bits, bytes);
io->write(bytes, sizeof(bytes));
return true; }
bool bind( double n) { io->putChar((cbor::SimpleTypesType << cbor::MajorTypeShift) | cbor::DoublePrecisionFloat);
union { double value; quint64 bits; } number;
number.value = n;
char bytes[sizeof(number.bits)];
qToBigEndian(number.bits, bytes);
io->write(bytes, sizeof(bytes));
return true; }
bool _bind( float n) { io->putChar((cbor::SimpleTypesType << cbor::MajorTypeShift) | cbor::SinglePrecisionFloat);
union { float value; quint32 bits; } number;
number.value = n;
char bytes[sizeof(number.bits)];
qToBigEndian(number.bits, bytes);
io->write(bytes, sizeof(bytes));
return true; }
bool _bind( double n) { io->putChar((cbor::SimpleTypesType << cbor::MajorTypeShift) | cbor::DoublePrecisionFloat);
union { double value; quint64 bits; } number;
number.value = n;
char bytes[sizeof(number.bits)];
qToBigEndian(number.bits, bytes);
io->write(bytes, sizeof(bytes));
return true; }
// Val<TResult> prevents QBind from getting out() of an outer Seq for instance
template<typename T> bool bind(const T& t) { return QBind<CborWriter,T>::bind(CborWriter(io).value(), const_cast<T&>(t)); } // t will not be modified anyway
template<typename T> bool bind( T& t) { return QBind<CborWriter,T>::bind(CborWriter(io).value(), t ); }
template<typename T> bool bind( T&& t) { return QBind<CborWriter,T>::bind(CborWriter(io).value(), t ); }
template<typename T> bool _bind(const T& t) { return QBind<CborWriter,T>::bind(CborWriter(io).value(), const_cast<T&>(t)); } // t will not be modified anyway
template<typename T> bool _bind( T& t) { return QBind<CborWriter,T>::bind(CborWriter(io).value(), t ); }
template<typename T> bool _bind( T&& t) { return QBind<CborWriter,T>::bind(CborWriter(io).value(), t ); }
template<class T_> friend class Seq; // calls methods below
bool item() { return true; }
bool out() { io->putChar(cbor::BreakByte); levels--; return true; }
bool _item() { return true; }
bool _out() { io->putChar(cbor::BreakByte); levels--; return true; }
private:
void putInteger(char majorType, quint64 n)
{
......
......@@ -73,24 +73,24 @@ public:
protected:
template<class T_> friend class Val; // calls methods below
bool record() { levels.push(Step("" )); return true; }
bool sequence() { levels.push(Step(nullptr)); return true; }
bool null() { set(QJsonValue () ); return true; }
bool bind(const char* s) { set(s ); return true; }
bool bind(double d) { set(d ); return true; }
bool bind(bool b) { set(b ); return true; }
bool _record() { levels.push(Step("" )); return true; }
bool _sequence() { levels.push(Step(nullptr)); return true; }
bool _null() { set(QJsonValue () ); return true; }
bool _bind(const char* s) { set(s ); return true; }
bool _bind(double d) { set(d ); return true; }
bool _bind(bool b) { set(b ); return true; }
template<typename T> bool bind(T t, std::enable_if_t<std::is_arithmetic<T>::value>* = nullptr) { return bind(double(t)); }
template<typename T> bool _bind(T t, std::enable_if_t<std::is_arithmetic<T>::value>* = nullptr) { return _bind(double(t)); }
// Val<TResult> prevents QBind from getting out() of an outer Seq for instance
template<typename T> bool bind(const T& t) { return QBind<QJsonBuilder,T>::bind(QJsonBuilder(this).value(), const_cast<T&>(t)); } // t will not be modified anyway
template<typename T> bool bind( T& t) { return QBind<QJsonBuilder,T>::bind(QJsonBuilder(this).value(), t ); }
template<typename T> bool bind( T&& t) { return QBind<QJsonBuilder,T>::bind(QJsonBuilder(this).value(), t ); }
template<typename T> bool _bind(const T& t) { return QBind<QJsonBuilder,T>::bind(QJsonBuilder(this).value(), const_cast<T&>(t)); } // t will not be modified anyway
template<typename T> bool _bind( T& t) { return QBind<QJsonBuilder,T>::bind(QJsonBuilder(this).value(), t ); }
template<typename T> bool _bind( T&& t) { return QBind<QJsonBuilder,T>::bind(QJsonBuilder(this).value(), t ); }
template<class T_> friend class Seq; // calls methods below
bool item(const char* key=nullptr) { levels.last().key=key; return true; }
bool out() { auto level = levels.pop(); set(level.key ? QJsonValue(level.object) : QJsonValue(level.array)); return true; }
bool _item(const char* key=nullptr) { levels.last().key=key; return true; }
bool _out() { auto level = levels.pop(); set(level.key ? QJsonValue(level.object) : QJsonValue(level.array)); return true; }
private:
void set(QJsonValue v) {
if (levels.isEmpty()) {
......@@ -129,32 +129,32 @@ public:
protected:
template<class T_> friend class Val; // calls methods below
bool sequence() { levels.push(Step{"","]"});
io->write( "[" ); return true; }
bool null() { io->write( "null" ); return true; }
bool bind(const char* s) { io->write( "\"" );
io->write( s ); // TODO escape
io->write( "\"" ); return true; }
bool _sequence() { levels.push(Step{"","]"});
io->write ( "[" ); return true; }
bool _null() { io->write ( "null" ); return true; }
bool _bind(const char* s) { io->write ( "\"" );
io->write ( s ); // TODO escape
io->write ( "\"" ); return true; }
// Natively supported overloads
bool bind( float n) { io->write(QByteArray::number(n, 'g', std::numeric_limits< float>::max_digits10)); return true; }
bool bind( double n) { io->write(QByteArray::number(n, 'g', std::numeric_limits<double>::max_digits10)); return true; }
bool bind(qulonglong n) { io->write(QByteArray::number(n )); return true; }
bool bind( qlonglong n) { io->write(QByteArray::number(n )); return true; }
bool _bind( float n) { io->write(QByteArray::number(n, 'g', std::numeric_limits< float>::max_digits10)); return true; }
bool _bind( double n) { io->write(QByteArray::number(n, 'g', std::numeric_limits<double>::max_digits10)); return true; }
bool _bind(qulonglong n) { io->write(QByteArray::number(n )); return true; }
bool _bind( qlonglong n) { io->write(QByteArray::number(n )); return true; }
// This dispatch would be more simple with C++17 constexpr if
template<typename T> bool bind(T t, std::enable_if_t<std::is_integral<T>::value && std::is_unsigned<T>::value>* = nullptr) { return bind(qulonglong(t)); }
template<typename T> bool bind(T t, std::enable_if_t<std::is_integral<T>::value && std:: is_signed<T>::value>* = nullptr) { return bind( qlonglong(t)); }
template<typename T> bool _bind(T t, std::enable_if_t<std::is_integral<T>::value && std::is_unsigned<T>::value>* = nullptr) { return _bind(qulonglong(t)); }
template<typename T> bool _bind(T t, std::enable_if_t<std::is_integral<T>::value && std:: is_signed<T>::value>* = nullptr) { return _bind( qlonglong(t)); }
// Val<TResult> prevents QBind from getting out() of an outer Seq for instance
template<typename T> bool bind(const T& t) { return QBind<QJsonWriter,T>::bind(QJsonWriter(this).value(), const_cast<T&>(t)); } // t will not be modified anyway
template<typename T> bool bind( T& t) { return QBind<QJsonWriter,T>::bind(QJsonWriter(this).value(), t ); }
template<typename T> bool bind( T&& t) { return QBind<QJsonWriter,T>::bind(QJsonWriter(this).value(), t ); }
template<typename T> bool _bind(const T& t) { return QBind<QJsonWriter,T>::bind(QJsonWriter(this).value(), const_cast<T&>(t)); } // t will not be modified anyway
template<typename T> bool _bind( T& t) { return QBind<QJsonWriter,T>::bind(QJsonWriter(this).value(), t ); }
template<typename T> bool _bind( T&& t) { return QBind<QJsonWriter,T>::bind(QJsonWriter(this).value(), t ); }
template<class T_> friend class Seq; // calls methods below
bool item() { io->write(levels.last().sep); levels.last().sep = ","; return this; }
bool out() { io->write(levels.pop() .end) ; return this; }
bool _item() { io->write(levels.last().sep); levels.last().sep = ","; return this; }
bool _out() { io->write(levels.pop() .end) ; return this; }
};
QJsonWriter::QJsonWriter(QIODevice* io) : QScopedResult(new QJsonWriterImpl(io), true) {}
......@@ -183,86 +183,92 @@ public:
protected:
template<class T_> friend class Val; // calls methods below
bool sequence() { if (get('[', "[{\"ntf-0123456789.")) {
levels.push(Step{-1,"]"});
return true;
}
return false; }
bool null() { if (get('n', "[{\"ntf-0123456789.") &&
get('u', "[{\"" ) &&
get('l', "[{\"" ) &&
get('l', "[{\"" )) {
return true;
}
return false; }
bool bind(QByteArray& s) { if (get('"', "[{\"ntf-0123456789.")) {
s.clear();
char c;
while ((c = getCharInString()) != '\0') {
s.append(c);
}
return get('"');
}
return false; }
bool _sequence() { if (get('[', "[{\"ntf-0123456789.")) {
levels.push(Step{-1,"]"});
return true;
}
return false; }
bool _null() { if (get('n', "[{\"ntf-0123456789.") &&
get('u', "[{\"" ) &&
get('l', "[{\"" ) &&
get('l', "[{\"" )) {
return true;
}
return false; }
bool _bind(QByteArray& s) { if ( get('"', "[{\"ntf-0123456789.")) {
s.clear();
char c;
while ((c = getCharInString()) != '\0') {
s.append(c);
}
return get('"');
}
return false; }
// Natively supported overloads
bool bind( double& n) { qlonglong ll=0; double d=0; int digit;
bool isNegative = get('-', "[{\"0123456789.");
if ((digit = getDigit()) < 0) {
return false; // do not accept no digit otherwise we may accept an empty mantissa or string!
}
do { // TODO detect overflow
ll=ll*10+digit; d=d*10+digit;
}
while (0 <= (digit = getDigit())); // accept many leading '0' which is more permissive than JSON
if ( get('.')) {
// roughly
// d = ll;
// m_stream >> decimal // except it would eat exponent
// d += decimal
double decimal=.1;
while (0 <= (digit = getDigit())) {
d+=decimal*digit; decimal/=10;
}
}
if ( get('e') || get('E')) {
qlonglong exponent = 0;
bool isNegativeExponent = get('-');
get('+');
while (0 <= (digit = getDigit())) {
exponent=exponent*10+digit; // TODO detect overflow
}
// TODO detect overflow
d *=10^(isNegativeExponent ? -exponent : exponent);
}
// TODO if (!next(",]}") {}
n = isNegative ? -d : d;
return true; }
bool _bind( double& n) { qlonglong ll=0; double d=0; int digit;
bool isNegative = get('-', "[{\"0123456789.");
if ((digit = getDigit()) < 0) {
return false; // do not accept no digit otherwise we may accept an empty mantissa or string!
}
do { // TODO detect overflow
ll=ll*10+digit; d=d*10+digit;
}
while (0 <= (digit = getDigit())); // accept many leading '0' which is more permissive than JSON
if ( get('.')) {
// roughly
// d = ll;
// m_stream >> decimal // except it would eat exponent
// d += decimal
double decimal=.1;
while (0 <= (digit = getDigit())) {
d+=decimal*digit; decimal/=10;
}
}
if ( get('e') || get('E')) {
qlonglong exponent = 0;
bool isNegativeExponent = get('-');
get('+');
while (0 <= (digit = getDigit())) {
exponent=exponent*10+digit; // TODO detect overflow
}
// TODO detect overflow
d *=10^(isNegativeExponent ? -exponent : exponent);
}
// TODO if (!next(",]}") {}
n = isNegative ? -d : d;
return true; }
// Val<TResult> prevents QBind from getting out() of an outer Seq for instance
template<typename T> bool bind(T& t) { return QBind<QJsonReader,T>::bind(QJsonReader(this).value(), t); }
public:
template<typename T> bool _bind(T& t) { return QBind<QJsonReader,T>::bind(QJsonReader(this).value(), t); }
protected:
// TODO static_assert on const T& and T&& ?
template<class T_> friend class Seq; // calls methods below
// bool item(QByteArray& key) would require to cache key:value pairs coming out of order wrt to T items() calls
bool item() { Step& level = levels.last();
if (-1 < level.index && !get(',',level.end)) {
return false;
}
level.index++;
return true; }
bool out() { auto level = levels.pop();
while (get(',', level.end)) {
skipItem();
}
return get(*level.end, "}"); }
bool _item() { Step& level = levels.last();
if (-1 < level.index && !get(',',level.end)) {
return false;
}
level.index++;
return true; }
bool _out() { auto level = levels.pop();
while (get(',', level.end)) {
skipItem();
}
return get(*level.end, "}"); }
private:
int getDigit() {
return '0' <= nextChar() && nextChar() <= '9' ? (getChar())-'0' : -1;
int getDigit(int base = 10) { Q_ASSERT(0<base);
int digit;
if ( 0 <= (digit=nextChar()-'0' ) && digit < base && base <= 10) { getChar(); return digit; }
if (10 <= (digit=nextChar()-'a'+10) && digit < base && base <= 36) { getChar(); return digit; }
if (10 <= (digit=nextChar()-'A'+10) && digit < base && base <= 36) { getChar(); return digit; }
return -1;
}
char getCharInString()
{
......@@ -270,7 +276,7 @@ private:
return '\0';
}
if (get('\\')) {
bool isHex; unsigned hex;
unsigned hex = 0;
switch (getChar())
{
case'\\': return '\\';
......@@ -282,13 +288,11 @@ private:
case 't': return '\t';
case '/': return '/';
case 'u': {
QByteArray read;
read.push_back(getChar());
read.push_back(getChar());
read.push_back(getChar());
read.push_back(getChar());
hex = read.toUInt(&isHex, 16);
if (isHex) {
int digits = 0, digit;
while ((digits++ < 4) && (0 <= (digit=getDigit(16)))) {
hex = 16*hex + digit;
}
if (digits==4) {
return hex;
}
return '?';
......@@ -325,10 +329,10 @@ private:
bool skipItem() {
QByteArray ba; double d;
return
( sequence() && out() )
|| bind(ba)
|| bind(d)
|| null()
( _sequence() && _out() )
|| _bind(ba)
|| _bind(d)
|| _null()
;
}
};
......
......@@ -85,19 +85,19 @@ public:
protected:
template<class T_> friend class Val; // enables calling methods below through operator->()
bool sequence() { io->write("["); return true; }
bool null() { return true; }
bool bind(const char* s) { io->write( s ); return true; }
bool _sequence() { io->write("["); return true; }
bool _null() { return true; }
bool _bind(const char* s) { io->write( s ); return true; }
// Val<TResult> prevents QBind from getting out() of an outer Seq for instance
template<typename T> bool bind(const T& t) { return QBind<TResult,T>::bind(Val<TResult>(TResult(io)), const_cast<T&>(t)); } // t will not be modified anyway
template<typename T> bool bind( T& t) { return QBind<TResult,T>::bind(Val<TResult>(TResult(io)), t ); }
template<typename T> bool bind( T&& t) { return QBind<TResult,T>::bind(Val<TResult>(TResult(io)), t ); }
template<typename T> bool _bind(const T& t) { return QBind<TResult,T>::bind(Val<TResult>(TResult(io)), const_cast<T&>(t)); } // t will not be modified anyway
template<typename T> bool _bind( T& t) { return QBind<TResult,T>::bind(Val<TResult>(TResult(io)), t ); }
template<typename T> bool _bind( T&& t) { return QBind<TResult,T>::bind(Val<TResult>(TResult(io)), t ); }
template<class T_> friend class Seq; // enables calling methods below through operator->()
bool item() { io->write(" "); return true; }
bool out() { io->write("]"); return true; }
bool _item() { io->write(" "); return true; }
bool _out() { io->write("]"); return true; }
private:
QIODevice* io = nullptr; // for QMovedResult
};
......@@ -121,7 +121,7 @@ private:
groupWarmup=(previousTotal==0 || abs(groupTotal-previousTotal)*100/previousTotal > 1); \
previousTotal=groupTotal; \
groupTotal=0; \
if (!previousTotal) { fprintf(results,"group "); fprintf(samples, "group |%s\n", group); } else fprintf(results,"%-10s",group);
if (!previousTotal) { fprintf(results,"group "); fprintf(samples, "group |%s\n", group); } else fprintf(results,"%-10s",group);
#define GROUP_STOP \
if (!previousTotal) fprintf(results,"|total(usecs)|variation(%%)\n"); else fprintf(results,"|%12lld|%3lld\n", groupTotal, previousTotal ? abs(groupTotal-previousTotal)*100/previousTotal : 0); \
......@@ -131,7 +131,7 @@ QElapsedTimer item;
#define START item.start(); for (int i=0; i<123; ++i)
#define STOP(label,result) { \
auto usecs=item.nsecsElapsed()/1000/123; groupTotal+=usecs; \
if (!previousTotal) { fprintf(results,"|%16s", label); fprintf(samples, "%-16s|%s\n", label, qPrintable(result)); } else fprintf(results,"|%16lld", usecs); }
if (!previousTotal) { fprintf(results,"|%14s", label); fprintf(samples, "%-14s|%s\n", label, qPrintable(result)); } else fprintf(results,"|%14lld", usecs); }
int main()
{
......@@ -164,7 +164,7 @@ int main()
QBuffer b;
b.open(QIODevice::ReadWrite);
GROUP("<<atoms")
GROUP("<atoms")
{
START {
s.clear();
......@@ -177,7 +177,7 @@ int main()
STOP("QDebug",s);
START {
b.seek(0); b.buffer().clear();
TextWriter(&b).value()
TextWriter(&b)
.sequence()
.bind(123)
.bind(text)
......@@ -195,7 +195,7 @@ int main()
STOP("Json",QString::fromUtf8(b.buffer()));
START {
b.seek(0); b.buffer().clear();
CborWriter(&b).value()
CborWriter(&b)
.sequence()
.bind(1.333333333333f)
.bind(text)
......@@ -211,12 +211,12 @@ int main()
STOP("QWritable","");
START {
b.seek(0); b.buffer().clear();
CborWriter(&b).value().bind(writables);
CborWriter(&b).bind(writables);
}
STOP("QWritable>Cbor",QString::fromUtf8(b.buffer().toHex()));
}
GROUP_STOP;
GROUP("<<doubles")
GROUP("<doubles")
{
START {
s.clear();
......@@ -229,7 +229,7 @@ int main()
STOP("QDebug",s);
START {
b.seek(0); b.buffer().clear();
TextWriter(&b).value().bind(transform);
TextWriter(&b).bind(transform);
}
STOP("Text",QString::fromUtf8(b.buffer()));
START {
......@@ -239,7 +239,7 @@ int main()
STOP("Json",b.buffer())
START {
b.seek(0); b.buffer().clear();
CborWriter(&b).value().bind(transform);
CborWriter(&b).bind(transform);
}
STOP("Cbor",QString::fromUtf8(b.buffer().toHex()));
QWritable<CborWriter> writable;
......@@ -249,12 +249,12 @@ int main()
STOP("QWritable","");
START {
b.seek(0); b.buffer().clear();
CborWriter(&b).