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

Changed IBindable to more "Qt" QWritable that is a shared const copy of T...

Changed IBindable to more "Qt" QWritable that is a shared const copy of T (although not convertible to another TResult, so sharing is not that interesting)
parent 7009b185
......@@ -107,7 +107,8 @@ private:
// QBind<TResult,T>
template<class TResult, typename T>
struct QBind {
struct QBind
{
static TResult bind(Val<TResult> value, T 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)
}
......@@ -115,7 +116,7 @@ struct QBind {
// T partial specializations generic on TResult (not always on TResult::Mode)
#include <QtCore/qvector.h>
#include <QtCore/qstring.h>
template<class TResult>
struct QBind<TResult, QString> { static TResult bind(Val<TResult> value, QString s) {
......@@ -123,6 +124,8 @@ struct QBind<TResult, QString> { static TResult bind(Val<TResult> value, QString
return value.bind(s.toUtf8().constData());
}};
#include <QtCore/qvector.h>
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");
......@@ -133,26 +136,13 @@ struct QBind<TResult, QVector<T>> { static TResult bind(Val<TResult> value, QVec
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>
#include <cstddef>
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(); }
template<class TResult>
struct QBind<TResult, std::nullptr_t> { static TResult bind(Val<TResult> value, std::nullptr_t) {
return value.null();
}};
// //////////////////////////////////////////////////////////////////////////
// TResult example implementation
......@@ -224,57 +214,38 @@ private:
};
// //////////////////////////////////////////////////////////////////////////
// Deferred bind
// Deferred Write bind
#include <memory>
#include <QtCore/qshareddata.h>
#include <cstddef>
//! A shared const copy of T that can be bound to a TResult where Mode == Write
//! \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>
class QWritable
{
struct Writable;
std::shared_ptr<const Writable> m_writable; //!< Copyable, moveable
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;
};
template<typename T>
QWritable(T t) : m_writable(std::make_shared<const Copy< T>>(std::move(t))) {}
QWritable( ) : m_writable(std::make_shared<const Copy<std::nullptr_t>>(nullptr )) {}
// 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)); }
TResult bind(Val<TResult> v) { return m_writable->writeTo(std::move(v)); }
private:
std::unique_ptr<IBindable<TResult>> p;
struct Writable {
virtual ~Writable() = default;
virtual TResult writeTo(Val<TResult> v) const = 0;
};
template<typename T>
struct Copy : Writable {
Copy(T&& value) : m_t(std::move(value)) {}
TResult writeTo(Val<TResult> v) const override { return v.bind(m_t); }
private:
const T m_t;
};
};
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
......@@ -365,11 +336,11 @@ int main()
;
}
STOP("Cbor",QString::fromUtf8(b.buffer().toHex()));
QBindables<QJsonWriter> args;
QVector<QWritable<QJsonWriter>> args;
START {
args.clear();
args.emplace_back(1.333333333333f);
args.emplace_back(text);
args.append(1.333333333333f);
args.append(text);
}
STOP("QBindable","");
START {
......
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