Commit 1d59218e authored by EXT Arnaud Clère's avatar EXT Arnaud Clère

Added back capturing lambda support for concision now that safety is

fixed
parent 45b10848
......@@ -172,8 +172,12 @@ template<class T_> class Seq; //!< a Sequence data structure defined below
template<class T_> class Val; //!< a choice of sequence(), record(), null(), or any value with at least a textual representation and possibly binary ones
// Custom bind support
template<typename T> using QBindFunction = Cursor (*)(T &,Val<Cursor>&&);
template<class Ts> using QBindSeqFunction = Seq<Cursor>(*)(Ts&,Seq<Cursor>&&);
#ifndef NO_COMPILER_RTTI_OR_EXCEPTIONS
template<typename T> using QBindFunction = Cursor (*)(T &,Val<Cursor>&&) ;
template<class Ts> using QBindSeqFunction = Seq<Cursor>(*)(Ts&,Seq<Cursor>&&) ;
#endif
/**/ using QBindLambda = std::function< Cursor ( Val<Cursor>&&)>;
/**/ using QBindSeqLambda = std::function<Seq<Cursor> ( Seq<Cursor>&&)>;
template<class T_> class Val
{
......@@ -197,6 +201,7 @@ public:
template<typename T> T_ bind (T& t, T&& defaultT) { return outer->_bind(QBindDefault<T>{t,defaultT})? std::move(outer) : T_ (); }
// Custom bind support
/**/ T_ bindWith( QBindLambda customBind) { return customBind( std::move(unsafeThis())) ? std::move(outer) : T_(); }
template<typename T> T_ bind (T& t, QBindFunction<T> customBind) { return customBind(t, std::move(unsafeThis())) ? std::move(outer) : T_(); }
// Literal metadata support
......@@ -240,6 +245,7 @@ public:
template<typename T> Rec<T_> bind (T& t, T&& defaultT) { return item().bind(t,std::forward<T>(defaultT)); }
// Custom bind support
/**/ Seq<T_> bindWith( QBindSeqLambda customBind) { return bool(customBind( std::move(unsafeThis()))) ? std::move(*this) : Seq<T_>(); }
template<class Ts> Seq<T_> bind (Ts& ts, QBindSeqFunction<Ts> customBind) { return bool(customBind(ts, std::move(unsafeThis()))) ? std::move(*this) : Seq<T_>(); }
template<class Ts> Seq<T_> forEach (Ts& ts, TResult(*)( typename Ts::value_type&, Val<TResult>&&)
, bool (*)(const typename Ts::value_type&) = [](const typename Ts::value_type&) { return true; });
......@@ -281,7 +287,8 @@ public:
template<typename T> Rec<T_> bind (QName n, T& t, T&& defaultT) { return item(n).bind(t,std::forward<T>(defaultT)); }
// Custom bind support
template<typename T> Rec<T_> bind (QName n, T& t, QBindFunction<T> customBind) { return item(n).bind(t, customBind); }
/**/ Rec<T_> bindWith(QName n, QBindLambda customBind) { return item(n).bindWith( customBind); }
template<typename T> Rec<T_> bind (QName n, T& t, QBindFunction<T> customBind) { return item(n).bind (t, customBind); }
private:
template<typename T, class TResult, typename TEnabledIf> friend struct QBind;
Val<TResult> unsafeItem(QUtf8String& n) noexcept { return outer->_item(n) ? Val<TResult>(outer._unsafeCopy()) : Val<TResult>(); }
......
......@@ -64,8 +64,8 @@ class QModelWriter : public IWriter
public:
QModelWriter(QAbstractItemModel* m, bool rowFirst=true) : m(m), rowFirst(rowFirst), w(&io) { Q_ASSERT(m); }
Seq<Cursor> sequence( ) { return Cursor(this).value().sequence(); }
Val<Cursor> meta ( QMetaData&& m) { return Cursor(this).value().meta(m); }
Seq<Cursor> sequence( ) { return Cursor(this).value().sequence(); }
Val<Cursor> meta (QMetaData&& m) { return Cursor(this).value().meta(m); }
protected:
void _meta(QMetaData& meta) {
if (T==d) {
......
......@@ -989,7 +989,7 @@ void doGuiExample() {
QModelWriter<>(& tableModel ).meta({{qmColumns , "names,age"} }).bind(persons);
// Various possible designs for flexible custom bind
#if 0
#if 1
// Design that works for Read/Write but requires several cumbersome functions
QModelWriter<>(&customModel).sequence().forEach(persons, [](Person& p, Val<Cursor>&& item)->Cursor {
return item
......@@ -1004,13 +1004,13 @@ void doGuiExample() {
});
#else
// More expressive design similar to Python list comprehensions that does not work by default for Read/Write
QModelWriter<>(&customModel).sequence().bind(persons, +[](QList<Person>& t, Seq<Cursor>&& s) { // See https://stackoverflow.com/questions/18889028/a-positive-lambda-what-sorcery-is-this
for (auto&& person : t) { // Read would require looping while !s.item()
QModelWriter<>(&customModel).sequence().bindWith([&](Seq<Cursor>&& s) { // See https://stackoverflow.com/questions/18889028/a-positive-lambda-what-sorcery-is-this
for (auto&& person : persons) { // Read would require looping while !s.item()
s = s // To keep working with the active Cursor
.record()
.bind("first name" , person.firstName)
.bind("office phone", person.phones, +[](QVector<Phone>& t, Val<Cursor>&& v) {
for (auto&& phone : t) {
.bind("first name", person.firstName)
.bindWith("office phone", [&](Val<Cursor>&& v) {
for (auto&& phone : person.phones) {
if (phone._t == Phone::Office) {
return v.bind(phone._n);
}
......
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