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

Fixed default QBind impl to move Val<>

Added IBindable based on vector and unique_ptr (not very Qt) but demonstrates delayed QBind<TResult,T> feasibility
parent f6b257d8
......@@ -109,7 +109,7 @@ private:
template<class TResult, typename T>
struct QBind {
static TResult bind(Val<TResult> value, T t) {
return t.bind(value); // In case of error, define a T::bind(Val<TResult>) method or an external QBind<TResult,T>::bind(Val<TResult>,T)
return t.bind(std::move(value)); // In case of error, define a T::bind(Val<TResult>) method or an external QBind<TResult,T>::bind(Val<TResult>,T)
}
};
......@@ -126,13 +126,33 @@ struct QBind<TResult, QString> { static TResult bind(Val<TResult> value, QString
template<class TResult, typename T>
struct QBind<TResult, QVector<T>> { static TResult bind(Val<TResult> value, QVector<T> vector) {
static_assert(TResult::Mode==Write,"not implemented");
auto s = value.sequence();
auto s(value.sequence());
for (auto&& d : vector) {
s = s.bind(d);
}
return s;
}};
template<class TResult, typename T>
struct QBind<TResult, std::vector<T>> { static TResult bind(Val<TResult> value, std::vector<T> vector) {
auto s(value.sequence());
// for (typename TCollection::iterator userItem = userCollection.begin(); userItem != userCollection.end(); ++userItem)
for (auto&& d : vector) {
s = s.bind(d);
}
return s;
}};
#include <memory>
template<class TResult, typename T>
struct QBind<TResult, std::unique_ptr<T>> { static TResult bind(Val<TResult> value, std::unique_ptr<T>& ptr) {
static_assert(TResult::Mode==Write,"not implemented");
if (ptr) { value.bind(*ptr); }
else { value.null(); }
}};
// //////////////////////////////////////////////////////////////////////////
// TResult example implementation
......@@ -203,6 +223,58 @@ private:
};
};
// //////////////////////////////////////////////////////////////////////////
// Deferred bind
#include <memory>
#include <QtCore/qshareddata.h>
//! \see https://stackoverflow.com/questions/18856824/ad-hoc-polymorphism-and-heterogeneous-containers-with-value-semantics
template<class TResult>
class IBindable
{
public:
virtual ~IBindable() {}
virtual TResult bind(Val<TResult>&& v) = 0;
virtual std::unique_ptr<IBindable<TResult>> clone() const = 0;
};
template<class TResult, typename T>
class QBindableCopy : public IBindable<TResult>
{
public:
template <typename ...Ts> QBindableCopy( Ts&&...ts )
: t( std::forward<Ts>(ts)... ) {}
virtual TResult bind(Val<TResult>&& v) override { return v.bind(t); }
virtual std::unique_ptr<IBindable<TResult>> clone() const override
{
return std::make_unique<QBindableCopy<TResult,T>>( t ); // This is C++14
// This is the C++11 way to do it:
// return std::unique_ptr<QBindableCopy<TResult,T> >( new QBindableCopy<TResult,T>(t) );
}
private:
T t;
};
// TODO Use QSharedDataPointer for COW semantic and clone
//! Copies a T providing a bind<TResult> method for later use
template<class TResult>
class QBindableClone
{
public:
template <typename T> QBindableClone( T t ) : p( std::make_unique<QBindableCopy<TResult,T>>( std::move(t) ) ) {}
QBindableClone (const QBindableClone& other) : p( other.p->clone() ) {}
QBindableClone ( QBindableClone&& other) noexcept : p( std::move(other.p) ) {}
QBindableClone& operator=(QBindableClone other) { swap(other ); }
void swap ( QBindableClone& other) noexcept { p .swap(other.p); }
TResult bind(Val<TResult> v) { return p->bind(std::move(v)); }
private:
std::unique_ptr<IBindable<TResult>> p;
};
template<class TResult>
using QBindables = std::vector<QBindableClone<TResult>>;
// //////////////////////////////////////////////////////////////////////////
// Tests and Benchmarks
// NB: It is not possible to use QBENCHMARK to item qDebug because it installs a specific handler
......@@ -293,6 +365,18 @@ int main()
;
}
STOP("Cbor",QString::fromUtf8(b.buffer().toHex()));
QBindables<QJsonWriter> args;
START {
args.clear();
args.emplace_back(1.333333333333f);
args.emplace_back(text);
}
STOP("QBindable","");
START {
b.seek(0); b.buffer().clear();
QJsonWriter(&b).begin().bind(args);
}
STOP("QBindable>Json",QString::fromUtf8(b.buffer()));
}
GROUP_STOP;
GROUP("Format << doubles")
......
Supports Markdown
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