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

cosmetic changes

parent 76fdafd6
......@@ -55,7 +55,9 @@ protected: \
#include <QtCore/qbytearray.h>
using Name = const char*; // utf8 encoded
using QUtf8String = QByteArray; //!< QByteArray explicitely utf8 encoded at source level
using Name = const char*; //!< String literal explicitely utf8 encoded
// //////////////////////////////////////////////////////////////////////////
// Standard error names
......@@ -72,12 +74,12 @@ static Name qBindIgnoredCharacter = "Ignored character";
static Name qBindIgnoredBytes = "Ignored bytes" ;
template<class T>
class ScopedChoice //!< for accurate error reporting
class QScopedChoice //!< for accurate error reporting
{
Q_DISABLE_COPY(ScopedChoice)
Q_DISABLE_COPY(QScopedChoice)
public:
ScopedChoice(T& t) : t(t) { if(t) t->setChoice(true ); }
~ScopedChoice() { if(t) t->setChoice(false); }
QScopedChoice(T& t) : t(t) { if(t) t->setChoice(true ); }
~QScopedChoice() { if(t) t->setChoice(false); }
private:
T& t;
};
......@@ -112,7 +114,7 @@ static Name qmChildren = "children";
#include <type_traits>
template<class T_> class Val;
enum BindMode { Read=0, Write=1 }; //!< drives QBind::bind() traversal and processing (the design would support others like Append)
enum BindMode { Read=0, Write=1 }; //!< Specifies QBind::bind traversal and processing (the design would support other BindMode like Append or Diff)
template<class TResult> using IsReader = typename std::enable_if<TResult::Mode==Read >::type;
template<class TResult> using IsWriter = typename std::enable_if<TResult::Mode==Write>::type;
......@@ -152,7 +154,7 @@ struct QBind<TResult, const T&, IsReader<TResult>> { static TResult bind(Val<TRe
struct BindNative {};
struct BindGeneric {};
template<class TImpl, typename T, typename TEnabledIf=void> struct BindSupport : BindGeneric {};
template<class TImpl, typename T, typename TEnabledIf=void> struct BindSupport : BindGeneric {}; //!< Specifies whether Val calls TImpl::_bind or QBind<TImpl,T>::bind
template<class TImpl> struct BindSupport<TImpl,void> : BindGeneric {};
......@@ -192,7 +194,7 @@ 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)
};
template<class T_> T_ Val<T_>::bind(const char* const& t/*, IsWriter<typename T_::TResult>* =nullptr*/) { const char* s(t); return bind(s) ; } // special handling of both (const char*)'s const& and && as copying a const char* costs so few
//template<class T_> T_ Val<T_>::bind(const char* const& t, IsReader<typename T_::TResult>* =nullptr ) { QByteArray s ; return bind(s) && s==t; } // special handling of both (const char*)'s const& and && for Reader
//template<class T_> T_ Val<T_>::bind(const char* const& t, IsReader<typename T_::TResult>* =nullptr ) { QUtf8String s ; return bind(s) && s==t; } // special handling of both (const char*)'s const& and && for Reader
template<class T_> class Seq
{
......@@ -275,23 +277,26 @@ private:
T_ m_out = T_();
};
//! Base class for TResult classes that require a single heap allocation (and lock), but:
// //////////////////////////////////////////////////////////////////////////
// Base TResult implementations
//! Base class for Reader classes that require a single heap allocation (and lock), but:
//! - are simple to implement
//! - hide implementation methods from the fluent interface
//! - are de facto pimpled
template<class TResult_, class TImpl_, BindMode Mode_>
class QScopedResult
template<class TResult_, class TImpl_>
class QBaseReader
{
protected:
QScopedResult(const QScopedResult &o) : m(o.m), m_owned(false) {}
QScopedResult &operator=(const QScopedResult &) = delete;
QBaseReader(const QBaseReader &o) : m(o.m), m_owned(false) {}
QBaseReader &operator=(const QBaseReader &) = delete;
public:
Q_ENABLE_MOVE(QScopedResult, std::swap(m, o.m); std::swap(m_owned, o.m_owned); )
~QScopedResult() { if (m && m_owned) delete m; }
Q_ENABLE_MOVE(QBaseReader, std::swap(m, o.m); std::swap(m_owned, o.m_owned); )
~QBaseReader() { if (m && m_owned) delete m; }
using TResult = TResult_;
using TImpl = TImpl_ ;
static constexpr BindMode Mode = Mode_;
static constexpr BindMode Mode = BindMode::Read;
/**/ 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; }
......@@ -308,7 +313,7 @@ public:
void reportError(const char* error) { if (m) m->reportError(error); }
protected:
QScopedResult(TImpl* result, bool owned) : m(result), m_owned(owned) {}
QBaseReader(TImpl* result, bool owned) : m(result), m_owned(owned) {}
private:
template<typename T_> friend class Val;
template<typename T_> friend class Seq;
......@@ -319,17 +324,17 @@ private:
bool m_owned = true ; //!< for nested QBind only
};
//! Base class for Writer classes that can exhibit high performance (they require no heap allocation and no lock)
//! 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 QMovedWriter with internal state (need to understand move semantics)
//! - 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 are not pimpled (use QScopedResult if needed)
//! - TResult are not pimpled (use QBaseReader if needed)
template<class TResult_>
class QMovedWriter
class QBaseWriter
{
Q_PROTECTED_COPY(QMovedWriter)
Q_PROTECTED_COPY(QBaseWriter)
public:
Q_ENABLE_MOVE_DEFAULT(QMovedWriter)
Q_ENABLE_MOVE_DEFAULT(QBaseWriter)
using TResult = TResult_;
using TImpl = TResult_;
......@@ -347,9 +352,9 @@ public:
/**/ TResult null ( ) { return value().null ( ); }
template<typename T> TResult bind ( T&& t) { return value().bind(std::forward<T>(t)); }
void reportError(const char*) {} // a TResult with BindMode::Write will not encounter bind mismatches but only write errors independent from the current state
void reportError(const char*) {} //!< \warning Not implemented since a TResult with BindMode::Write will not encounter bind mismatches but only write errors independent from the current state
protected:
void setChoice(bool) {} // not implemented like reportError
void setChoice(bool) {} //!< \warning Not implemented like reportError(const char*)
private:
friend struct IWriter;
template<typename T_> friend class Val;
......@@ -359,11 +364,9 @@ private:
};
// //////////////////////////////////////////////////////////////////////////
// Writer with a fixed subset of scalar types
// This erases the TResult for code that do not know it like tracepoints
// without sacrificing performance by resorting to opaque pointers like QWritable that require heap allocation
// QWriter with a fixed subset of scalar types
//! Interface for runtime QWriter implementations
struct IWriter
{
virtual ~IWriter() = default;
......@@ -403,18 +406,21 @@ struct IWriter
// TODO QChar, QDateTime, QDate, QTime, QUuid, QUrl, QRegularExpression
};
class Writer : public QMovedWriter<Writer>
//! Writer with standard native types that replaces compile-time TResult with runtime IWriter
//! \remark Useful for code that do not know the Writer in advance like QLogger defined below
//! \remark Can be used to easily implement Writers as IWriter and shortcut methods using QWriter((IWriter*)this)
class QWriter : public QBaseWriter<QWriter>
{
protected:
Writer(const Writer &o) : QMovedWriter(), impl(o.impl) {}
Writer &operator=(const Writer &) = delete;
QWriter(const QWriter &o) : QBaseWriter(), impl(o.impl) {}
QWriter &operator=(const QWriter &) = delete;
public:
Q_ENABLE_MOVE(Writer, std::swap(impl, o.impl); )
Writer(IWriter* i) : impl(i) { Q_ASSERT(impl); }
Q_ENABLE_MOVE(QWriter, std::swap(impl, o.impl); )
QWriter(IWriter* i) : impl(i) { Q_ASSERT(impl); }
operator bool() { return impl && impl->_isOk(); } // for QMovedWriter
operator bool() { return impl && impl->_isOk(); } // for QBaseWriter
protected:
friend class QMovedWriter<Writer>;
friend class QBaseWriter<QWriter>;
template<class T_> friend class Val; // enables calling methods below
void _meta ( MetaData& m) { Q_ASSERT(impl); impl->_meta ( m); }
......@@ -436,41 +442,41 @@ protected:
// TODO QChar, QDateTime, QDate, QTime, QUuid, QUrl, QRegularExpression
template<class T_> friend class Seq; // enables calling methods below
template<class T_> friend class Rec; // calls methods below
template<class T_> friend class Rec;
bool _item(QByteArray& k) { Q_ASSERT(impl); return impl->_item(k); }
bool _item( ) { Q_ASSERT(impl); return impl->_item( ); }
bool _out ( ) { Q_ASSERT(impl); return impl->_out ( ); }
private:
IWriter* impl = nullptr; // this state has noticeable performance cost but guarantees well-formedness through a unique valid instance of Writer (with impl != nullptr)
IWriter* impl = nullptr; // this state has noticeable performance cost but guarantees well-formedness through a unique valid instance of QWriter (with impl != nullptr)
};
template<> struct BindSupport<Writer,QByteArray&> : BindNative {};
template<> struct BindSupport<Writer, QString&> : BindNative {};
template<> struct BindSupport<Writer,const char*> : BindNative {};
template<> struct BindSupport<Writer, bool&> : BindNative {};
template<> struct BindSupport<Writer, float&> : BindNative {};
template<> struct BindSupport<Writer, double&> : BindNative {};
template<typename T> struct BindSupport<Writer,T&,typename std::enable_if<std::is_integral<T>::value>::type> : BindNative {};
template<> struct BindSupport<QWriter,QByteArray&> : BindNative {};
template<> struct BindSupport<QWriter, QString&> : BindNative {};
template<> struct BindSupport<QWriter,const char*> : BindNative {};
template<> struct BindSupport<QWriter, bool&> : BindNative {};
template<> struct BindSupport<QWriter, float&> : BindNative {};
template<> struct BindSupport<QWriter, double&> : BindNative {};
template<typename T> struct BindSupport<QWriter,T&,typename std::enable_if<std::is_integral<T>::value>::type> : BindNative {};
#include <QtCore/qatomic.h>
class Logger : public Writer
class QLogger : public QWriter
{
static QAtomicPointer<IWriter> s_impl;
public:
static IWriter* setWriter(IWriter* i) { return s_impl.fetchAndStoreOrdered(i); }
Logger() : Writer(s_impl) {}
QLogger() : QWriter(s_impl) {}
};
QAtomicPointer<IWriter> Logger::s_impl = nullptr;
QAtomicPointer<IWriter> QLogger::s_impl = nullptr;
// //////////////////////////////////////////////////////////////////////////
// Deferred write support
#include <functional>
//! A QBind<TResult,T> with T erased and captured by reference or copy (for rvalue references) that can later be bound with a TResult which Mode == Write
//! A QBind<TResult,T> polymorphic in T (erased at compile-time) which is captured by reference or copy (for rvalue references) to be bound later with a TResult which Mode == Write
//! \warning a T&& may be allocated dynamically if its size exceeds compiler's Small Function Optimization
//! \warning copying should be forced using QWritable(T(t)) if QWritable::bind() must be called after t is destructed like when queued to another thread
template<class TResult, typename = IsWriter<TResult>>
......@@ -491,14 +497,14 @@ public:
#include <QtCore/qbuffer.h>
template<class TWriter, typename = IsWriter<TWriter>>
class Utf8Result
class QUtf8Result
{
public:
template<typename T> Utf8Result(T&& t) : m_writer(&m_result) { m_result.open(QIODevice::WriteOnly); m_writer.bind(std::forward<T>(t)); }
operator QByteArray() const { return m_result.buffer(); }
template<typename T> QUtf8Result(T&& t) : writer(&result) { result.open(QIODevice::WriteOnly); writer.bind(std::forward<T>(t)); }
operator QUtf8String() const { return result.buffer(); }
private:
QBuffer m_result;
TWriter m_writer;
QBuffer result;
TWriter writer;
};
// //////////////////////////////////////////////////////////////////////////
......@@ -511,7 +517,7 @@ struct QBind<TResult, void, IsWriter<TResult>> { static TResult bind(Val<TResult
template<class TResult>
struct QBind<TResult, void, IsReader<TResult>> { static TResult bind(Val<TResult> src) {
{
ScopedChoice<Val<TResult>> choice(src);
QScopedChoice<Val<TResult>> choice(src);
Seq<TResult> srcSeq; if ((srcSeq = src.sequence())) { return srcSeq.out(); }
Rec<TResult> srcRec; if ((srcRec = src.record ())) { return srcRec.out(); }
/**/TResult srcRes; QString t; if ((srcRes = src.bind (t))) { return srcRes ; } // TODO QByteArray?
......@@ -705,7 +711,7 @@ struct QBind<TSrcResult, Val<TDst>&&, IsReader<TSrcResult>> { static TSrcResult
TSrcResult srcRes;
{
ScopedChoice<Val<TSrcResult>> choice(src);
QScopedChoice<Val<TSrcResult>> choice(src);
Seq<TSrcResult> srcSeq; Seq<TDst> dstSeq;
if ( (srcSeq = src.sequence())) {
/**/ dstSeq = dst.sequence();
......
......@@ -108,13 +108,13 @@ public:
CborWriter(QIODevice* io) : io(io) { Q_ASSERT(io); }
// Shortcuts
/**/ Val<Writer> value ( ) { return Writer(this).value ( ); }
/**/ Val<Writer> meta ( MetaData&& m) { return Writer(this).meta ( m); }
/**/ Val<Writer> meta ( MetaData& m) { return Writer(this).meta ( m); }
/**/ Seq<Writer> sequence(quint32* s=nullptr) { return Writer(this).sequence ( s); }
/**/ Rec<Writer> record (quint32* s=nullptr) { return Writer(this).record ( s); }
/**/ Writer null ( ) { return Writer(this).null ( ); }
template<typename T> Writer bind ( T&& t) { return Writer(this).bind(std::forward<T>(t)); }
/**/ Val<QWriter> value ( ) { return QWriter(this).value ( ); }
/**/ Val<QWriter> meta ( MetaData&& m) { return QWriter(this).meta ( m); }
/**/ Val<QWriter> meta ( MetaData& m) { return QWriter(this).meta ( m); }
/**/ Seq<QWriter> sequence(quint32* s=nullptr) { return QWriter(this).sequence ( s); }
/**/ Rec<QWriter> record (quint32* s=nullptr) { return QWriter(this).record ( s); }
/**/ QWriter null ( ) { return QWriter(this).null ( ); }
template<typename T> QWriter bind ( T&& t) { return QWriter(this).bind(std::forward<T>(t)); }
protected:
bool _isOk() { return io; }
......@@ -189,16 +189,16 @@ private:
#include <QtCore/qstack.h>
class QCborReaderImpl;
class QCborReader : public QScopedResult<QCborReader, QCborReaderImpl, BindMode::Read>
class QCborReader : public QBaseReader<QCborReader, QCborReaderImpl>
{
Q_PROTECTED_COPY(QCborReader)
public:
Q_ENABLE_MOVE_DEFAULT(QCborReader)
QCborReader(QCborStreamReader* io);
private:
friend class QScopedResult<QCborReader, QCborReaderImpl, BindMode::Read>;
friend class QBaseReader<QCborReader, QCborReaderImpl>;
friend class QCborReaderImpl; // uses method below
QCborReader(QCborReaderImpl* outer) : QScopedResult(outer, false) {}
QCborReader(QCborReaderImpl* outer) : QBaseReader(outer, false) {}
};
class QCborReaderImpl
{
......@@ -212,10 +212,10 @@ public:
struct Error { const char* error; qint64 index; template<class T> T bind(Val<T> value) { QByteArray ba(error); ba.append(' ').append(QByteArray::number(index)); return value.bind(ba.constData()); } };
QVector<Error> errors;
protected:
friend class ScopedChoice<Val<QCborReader>>;
friend class QScopedChoice<Val<QCborReader>>;
void setChoice(bool v) { isChoice=v; }
friend class QScopedResult<QCborReader, QCborReaderImpl, BindMode::Read>;
friend class QBaseReader<QCborReader, QCborReaderImpl>;
void reportError(const char* error) { if (!isChoice) errors.append(Error{ error, io->currentOffset() }); }
template<class T_> friend class Val; // calls methods below
......@@ -336,7 +336,7 @@ private:
reportError(qBindExpectedDecimal); return false;
}
};
QCborReader::QCborReader(QCborStreamReader* io) : QScopedResult(new QCborReaderImpl(io), true) {}
QCborReader::QCborReader(QCborStreamReader* io) : QBaseReader(new QCborReaderImpl(io), true) {}
template<> struct BindSupport<QCborReaderImpl, void> : BindNative {};
template<> struct BindSupport<QCborReaderImpl, QString&> : BindNative {};
template<> struct BindSupport<QCborReaderImpl,QByteArray&> : BindNative {};
......
......@@ -55,8 +55,8 @@
// - use compatible ByteOrder, FloatingPointPrecision, and Version
class DataWriter
: public IWriter // allows runtime flexibility using a compile-time Writer
, public QMovedWriter<DataWriter> // allows using QDataStream << for small numeric types and more performance by removing an indirection level
: public IWriter // allows runtime flexibility using a compile-time QWriter
, public QBaseWriter<DataWriter> // allows using QDataStream << for small numeric types and more performance by removing an indirection level
{
protected:
DataWriter(const DataWriter &o) : io(o.io) {}
......@@ -65,12 +65,12 @@ public:
Q_ENABLE_MOVE(DataWriter, std::swap(io, o.io); )
DataWriter(QDataStream* io) : io(io) { Q_ASSERT(io); }
operator bool() { return io && io->status()==QDataStream::Ok; } // for QMovedWriter
operator bool() { return io && io->status()==QDataStream::Ok; } // for QBaseWriter
protected:
friend class QMovedWriter<DataWriter>;
friend class QBaseWriter<DataWriter>;
template<class T_> friend class Val; // calls methods below
bool _isOk() { return io && io->status()==QDataStream::Ok; } // for QMovedWriter
bool _isOk() { return io && io->status()==QDataStream::Ok; } // for QBaseWriter
bool _sequence(quint32* rows=nullptr) { if (rows) *io << *rows; return true; }
bool _record (quint32* cols=nullptr) { if (cols) *io << *cols; return true; }
......
......@@ -61,7 +61,7 @@ public:
QJsonBuilder(QJsonValue* v) : value(v) { Q_ASSERT(v); }
// Shortcuts
template<typename T> Writer bind ( T&& t) { return Writer(this).bind(std::forward<T>(t)); }
template<typename T> QWriter bind ( T&& t) { return QWriter(this).bind(std::forward<T>(t)); }
protected:
virtual bool _sequence(quint32* rows=nullptr) { Q_UNUSED(rows); levels.push(Step(nullptr)); return true; }
virtual bool _record (quint32* cols=nullptr) { Q_UNUSED(cols); levels.push(Step("" )); return true; }
......@@ -96,16 +96,16 @@ private:
// --------------------------------------------------------------------------
class JsonVisitorImpl;
class QJsonVisitor : public QScopedResult<QJsonVisitor, JsonVisitorImpl, BindMode::Read>
class QJsonVisitor : public QBaseReader<QJsonVisitor, JsonVisitorImpl>
{
Q_PROTECTED_COPY(QJsonVisitor)
public:
Q_ENABLE_MOVE_DEFAULT(QJsonVisitor)
QJsonVisitor(const QJsonValue* v);
private:
friend class QScopedResult<QJsonVisitor, JsonVisitorImpl, BindMode::Read>;
friend class QBaseReader<QJsonVisitor, JsonVisitorImpl>;
friend class JsonVisitorImpl; // uses method below
QJsonVisitor(JsonVisitorImpl* outer) : QScopedResult(outer, false) {}
QJsonVisitor(JsonVisitorImpl* outer) : QBaseReader(outer, false) {}
};
class JsonVisitorImpl
{
......@@ -133,7 +133,7 @@ public:
protected:
void setChoice(bool v) { isChoice=v; }
friend class QScopedResult<QJsonVisitor, JsonVisitorImpl, BindMode::Read>;
friend class QBaseReader<QJsonVisitor, JsonVisitorImpl>;
void reportError(const char* error) { if (!isChoice) errors.append(Error{ error, currentPath() }); }
template<class T_> friend class Val; // calls methods below
......@@ -161,7 +161,7 @@ private:
QStack<Step> steps = QStack<Step>();
bool isChoice = false;
};
QJsonVisitor::QJsonVisitor(const QJsonValue* v) : QScopedResult(new JsonVisitorImpl(v), true) {}
QJsonVisitor::QJsonVisitor(const QJsonValue* v) : QBaseReader(new JsonVisitorImpl(v), true) {}
template<> struct BindSupport<JsonVisitorImpl, QString&> : BindNative {};
template<> struct BindSupport<JsonVisitorImpl, bool&> : BindNative {};
template<> struct BindSupport<JsonVisitorImpl, double&> : BindNative {};
......@@ -177,13 +177,13 @@ public:
~QJsonWriter() { for (auto&& level : levels) io->write(level.end); }
// Shortcuts
/**/ Val<Writer> value ( ) { return Writer(this).value ( ); }
/**/ Val<Writer> meta ( MetaData&& m) { return Writer(this).meta ( m); }
/**/ Val<Writer> meta ( MetaData& m) { return Writer(this).meta ( m); }
/**/ Seq<Writer> sequence(quint32* s=nullptr) { return Writer(this).sequence ( s); }
/**/ Rec<Writer> record (quint32* s=nullptr) { return Writer(this).record ( s); }
/**/ Writer null ( ) { return Writer(this).null ( ); }
template<typename T> Writer bind ( T&& t) { return Writer(this).bind(std::forward<T>(t)); }
/**/ Val<QWriter> value ( ) { return QWriter(this).value ( ); }
/**/ Val<QWriter> meta ( MetaData&& m) { return QWriter(this).meta ( m); }
/**/ Val<QWriter> meta ( MetaData& m) { return QWriter(this).meta ( m); }
/**/ Seq<QWriter> sequence(quint32* s=nullptr) { return QWriter(this).sequence ( s); }
/**/ Rec<QWriter> record (quint32* s=nullptr) { return QWriter(this).record ( s); }
/**/ QWriter null ( ) { return QWriter(this).null ( ); }
template<typename T> QWriter bind ( T&& t) { return QWriter(this).bind(std::forward<T>(t)); }
protected:
bool _sequence(quint32* rows=nullptr) { Q_UNUSED(rows); levels.push(Step{"","]"}); return io->write("["); }
bool _record (quint32* cols=nullptr) { Q_UNUSED(cols); levels.push(Step{"","}"}); return io->write("{"); }
......@@ -243,16 +243,16 @@ private:
// --------------------------------------------------------------------------
class QJsonReaderImpl;
class QJsonReader : public QScopedResult<QJsonReader, QJsonReaderImpl, BindMode::Read>
class QJsonReader : public QBaseReader<QJsonReader, QJsonReaderImpl>
{
Q_PROTECTED_COPY(QJsonReader)
public:
Q_ENABLE_MOVE_DEFAULT(QJsonReader)
QJsonReader(QIODevice* io);
private:
friend class QScopedResult<QJsonReader, QJsonReaderImpl, BindMode::Read>;
friend class QBaseReader<QJsonReader, QJsonReaderImpl>;
friend class QJsonReaderImpl; // uses method below
QJsonReader(QJsonReaderImpl* outer) : QScopedResult(outer, false) {}
QJsonReader(QJsonReaderImpl* outer) : QBaseReader(outer, false) {}
};
class QJsonReaderImpl
{
......@@ -270,10 +270,10 @@ public:
struct Error { const char* error; int line; int column; int index; template<class T> T bind(Val<T> value) { QByteArray ba(error); ba.append(' ').append(QByteArray::number(line)).append(':').append(QByteArray::number(column)); return value.bind(ba.constData()); } };
QVector<Error> errors;
protected:
friend class ScopedChoice<Val<QJsonReader>>;
friend class QScopedChoice<Val<QJsonReader>>;
void setChoice(bool v) { isChoice=v; }
friend class QScopedResult<QJsonReader, QJsonReaderImpl, BindMode::Read>;
friend class QBaseReader<QJsonReader, QJsonReaderImpl>;
void reportError(const char* error) { if (!isChoice) errors.append(Error{ error, line, column, index }); }
template<class T_> friend class Val; // calls methods below
......@@ -451,7 +451,7 @@ private:
return false;
}
};
QJsonReader::QJsonReader(QIODevice* io) : QScopedResult(new QJsonReaderImpl(io), true) {}
QJsonReader::QJsonReader(QIODevice* io) : QBaseReader(new QJsonReaderImpl(io), true) {}
template<> struct BindSupport<QJsonReaderImpl, void> : BindNative {};
template<> struct BindSupport<QJsonReaderImpl,QByteArray&> : BindNative {};
template<> struct BindSupport<QJsonReaderImpl, bool&> : BindNative {};
......@@ -479,7 +479,7 @@ template<class TResult>
struct QBind<TResult, QJsonValue&, IsReader<TResult>> { static TResult bind(Val<TResult> src, QJsonValue& dst) {
TResult r;
{
ScopedChoice<Val<TResult>> choice(src);
QScopedChoice<Val<TResult>> choice(src);
QJsonArray a; if ((r = src.bind(a))) { dst = a ; return r; }
QJsonObject o; if ((r = src.bind(o))) { dst = o ; return r; }
QString t; if ((r = src.bind(t))) { dst = QJsonValue(t); return r; }
......
......@@ -55,13 +55,13 @@ public:
~QVariantBuilder() { while (!levels.isEmpty()) _out(); }
// Shortcuts
/**/ Val<Writer> value ( ) { return Writer(this).value ( ); }
/**/ Val<Writer> meta ( MetaData&& m) { return Writer(this).meta ( m); }
/**/ Val<Writer> meta ( MetaData& m) { return Writer(this).meta ( m); }
/**/ Seq<Writer> sequence(quint32* s=nullptr) { return Writer(this).sequence ( s); }
/**/ Rec<Writer> record (quint32* s=nullptr) { return Writer(this).record ( s); }
/**/ Writer null ( ) { return Writer(this).null ( ); }
template<typename T> Writer bind ( T&& t) { return Writer(this).bind(std::forward<T>(t)); }
/**/ Val<QWriter> value ( ) { return QWriter(this).value ( ); }
/**/ Val<QWriter> meta ( MetaData&& m) { return QWriter(this).meta ( m); }
/**/ Val<QWriter> meta ( MetaData& m) { return QWriter(this).meta ( m); }
/**/ Seq<QWriter> sequence(quint32* s=nullptr) { return QWriter(this).sequence ( s); }
/**/ Rec<QWriter> record (quint32* s=nullptr) { return QWriter(this).record ( s); }
/**/ QWriter null ( ) { return QWriter(this).null ( ); }
template<typename T> QWriter bind ( T&& t) { return QWriter(this).bind(std::forward<T>(t)); }
protected:
template<typename T>
bool _bind ( T& t) { set(QVariant::fromValue(t)); return true; }
......@@ -95,16 +95,16 @@ private:
// --------------------------------------------------------------------------
class VariantVisitorImpl;
class QVariantVisitor : public QScopedResult<QVariantVisitor, VariantVisitorImpl, BindMode::Read>
class QVariantVisitor : public QBaseReader<QVariantVisitor, VariantVisitorImpl>
{
Q_PROTECTED_COPY(QVariantVisitor)
public:
Q_ENABLE_MOVE_DEFAULT(QVariantVisitor)
QVariantVisitor(const QVariant* v);
private:
friend class QScopedResult<QVariantVisitor, VariantVisitorImpl, BindMode::Read>;
friend class QBaseReader<QVariantVisitor, VariantVisitorImpl>;
friend class VariantVisitorImpl; // uses method below
QVariantVisitor(VariantVisitorImpl* outer) : QScopedResult(outer, false) {}
QVariantVisitor(VariantVisitorImpl* outer) : QBaseReader(outer, false) {}
};
class VariantVisitorImpl
{
......@@ -130,10 +130,10 @@ public:
return path;
}
protected:
friend class ScopedChoice<Val<QVariantVisitor>>;
friend class QScopedChoice<Val<QVariantVisitor>>;
void setChoice(bool v) { isChoice=v; }
friend class QScopedResult<QVariantVisitor, VariantVisitorImpl, BindMode::Read>;
friend class QBaseReader<QVariantVisitor, VariantVisitorImpl>;
void reportError(const char* error) { if (!isChoice) errors.append(Error{ error, currentPath() }); }
template<class T_> friend class Val; // calls methods below
......@@ -158,7 +158,7 @@ private:
QStack<Step> steps = QStack<Step>();
bool isChoice = false;
};
QVariantVisitor::QVariantVisitor(const QVariant* v) : QScopedResult(new VariantVisitorImpl(v), true) {}
QVariantVisitor::QVariantVisitor(const QVariant* v) : QBaseReader(new VariantVisitorImpl(v), true) {}
template<> struct BindSupport<VariantVisitorImpl, bool&> : BindNative {};
template<> struct BindSupport<VariantVisitorImpl,qulonglong&> : BindNative {};
template<> struct BindSupport<VariantVisitorImpl, qlonglong&> : BindNative {};
......@@ -195,7 +195,7 @@ struct QBind<TResult, QVariant&, IsWriter<TResult>> { static TResult bind(Val<TR
//struct QBind<TResult, QVariant&, IsReader<TResult>> { static TResult bind(Val<TResult> src, QVariant& dst) {
// TResult r;
// {
// ScopedChoice<Val<TResult>> choice(src);
// QScopedChoice<Val<TResult>> choice(src);
// QVariantList a; if ((r = src.bind(a))) { dst = a ; return r; } // NB We cannot try QStringList before QVariantList as it will always work with our logical model...
// QVariantMap o; if ((r = src.bind(o))) { dst = o ; return r; }
// bool b; if ((r = src.bind(b))) { dst = QVariant(b); return r; }
......
......@@ -97,35 +97,34 @@ QDataStream &operator<<(QDataStream &out, const Person &p)
#include <QtCore/qiodevice.h>
#include <QtCore/qbuffer.h>
class TextWriter : public QMovedWriter<TextWriter>
class TextWriter : public QBaseWriter<TextWriter>
{
Q_PROTECTED_COPY(TextWriter)
public:
Q_ENABLE_MOVE_DEFAULT(TextWriter) // for QMovedWriter
Q_ENABLE_MOVE_DEFAULT(TextWriter) // for QBaseWriter
TextWriter(QIODevice* io) : io(io) { Q_ASSERT(io); }
operator bool() { return io; } // for QMovedWriter
operator bool() { return io; } // for QBaseWriter
protected:
friend class QMovedWriter<TextWriter>;
friend class QBaseWriter<TextWriter>;
template<class T_> friend class Val; // enables calling methods below
template<class T_> friend class Seq;
template<class T_> friend class Rec;
bool _sequence(quint32* cols=nullptr) { Q_UNUSED(cols); return io->write("["); }
bool _record (quint32* rows=nullptr) { Q_UNUSED(rows); return io->write("["); }
bool _null ( ) { return true ; }
bool _bind ( const char* s) { return io->write( s ); }
template<class T_> friend class Seq; // enables calling methods below
template<class T_> friend class Rec; // calls methods below
bool _item(QByteArray& k) { return io->write(" ") && io->write(k) && io->write(":"); }
bool _item( ) { return io->write(" ") ; }
bool _out ( ) { return io->write("]") ; }
private:
QIODevice* io = nullptr; // for QMovedWriter
QIODevice* io = nullptr; // for QBaseWriter