Library: implement model-binding with generic-λ

Basically the implementation is already in place;
yet for better error messages we need to find out if the given functor
can handle the model present at this stage. Since generic-λ are not
functions by themselves (but rather templates), we need to ''probe''
with the expected argument and see if instantiation is possible.

⚠ NOTE: still a strange bug related to using the same Syntax several times
This commit is contained in:
Fischlurch 2025-01-25 03:40:41 +01:00
parent 860e2fa226
commit 57dc56f5c6
3 changed files with 54 additions and 39 deletions

View file

@ -168,23 +168,21 @@ namespace util {
// namespace {
// /** handle all regular "function-like" entities */
// template<typename SRC, typename F, typename SEL =void>
// struct FunDetector
// {
// using Sig = typename _Fun<F>::Sig;
// };
//
// /** handle a generic lambda, accepting a reference to the `SRC` iterator */
// template<typename SRC, typename F>
// struct FunDetector<SRC, F, lib::meta::disable_if<_Fun<F>> >
// {
// using Arg = std::add_lvalue_reference_t<SRC>;
// using Ret = decltype(std::declval<F>() (std::declval<Arg>()));
// using Sig = Ret(Arg);
// };
// }
namespace {
/** helper to detect return type of a possibly generic λ */
template<typename ARG, typename FUN, typename SEL =void>
struct _ProbeFunReturn
{
static_assert (!sizeof(ARG),
"Model binding must accept preceding model result.");
};
template<typename ARG, typename FUN>
struct _ProbeFunReturn<ARG,FUN, std::void_t<decltype(std::declval<FUN>() (std::declval<ARG>()))>>
{ // probe the λ with ARG to force template instantiation
using Ret = decltype(std::declval<FUN>() (std::declval<ARG>()));
};
}
/**
* Adapt by applying a result-transforming function after a successful parse.
@ -197,12 +195,8 @@ namespace util {
adaptConnex (CON&& connex, BIND&& modelBinding)
{
using RX = typename CON::Result;
// using Arg = lib::meta::_FunArg<BIND>;
// static_assert (std::is_constructible_v<Arg,RX>,
// "Model binding must accept preceding model result.");
// using AdaptedRes = typename _Fun<BIND>::Ret;
using Arg = std::add_lvalue_reference_t<RX>;
using AdaptedRes = decltype(modelBinding (std::declval<Arg>() ));
using Arg = std::add_rvalue_reference_t<RX>;
using AdaptedRes = typename _ProbeFunReturn<Arg,BIND>::Ret;
return Connex{[origConnex = forward<CON>(connex)
,binding = forward<BIND>(modelBinding)
]
@ -217,6 +211,7 @@ namespace util {
}
/* ===== building structured models ===== */
/**

View file

@ -573,7 +573,6 @@ namespace test {
auto syntax1 = accept(word).seq(word)
.bind([](Mod1 res)
{
// auto& [a,b] = res;
return res.get<0>().str() +"-"+ res.get<1>().str();
});
@ -582,10 +581,22 @@ namespace test {
syntax1.parse(s1);
CHECK (syntax1.success());
auto res1 = syntax1.getResult();
SHOW_TYPE(decltype(res1))
CHECK (showType<decltype(res1)>() == "string");
SHOW_EXPR(res1)
CHECK (res == "ham-actor"_expect);
CHECK (showType<decltype(res1)>() == "string"); // surprise! it is a simple string (as returned from λ)
CHECK (res1 == "ham-actor"_expect);
// 💡 shortcut for RegExp match groups...
auto syntax1b = accept("(\\w+) (\\w+)");
CHECK (accept(syntax1b).bindMatch( ).parse(s1).getResult() == "ham actor"_expect );
CHECK (accept(syntax1b).bindMatch(1).parse(s1).getResult() == "ham"_expect );
CHECK (accept(syntax1b).bindMatch(2).parse(s1).getResult() == "actor"_expect );
CHECK (accept(syntax1b).bindMatch(3).parse(s1).getResult() == ""_expect );
auto wordEx = accept(word).bindMatch();
auto syntax1c = accept(wordEx)
.seq(wordEx)
.bind([](SeqModel<string,string> m)
{ return m.get<0>() +"-"+ m.get<1>(); });
SHOW_EXPR(syntax1c.parse(s1).getResult())
}
};

View file

@ -57066,7 +57066,7 @@
</html>
</richcontent>
</node>
<node CREATED="1737763165990" ID="ID_1051966220" MODIFIED="1737763211832" TEXT="wichtig: static-assertion bieten">
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1737763165990" ID="ID_1051966220" MODIFIED="1737775439645" TEXT="wichtig: static-assertion bieten">
<richcontent TYPE="NOTE"><html>
<head>
@ -57078,27 +57078,32 @@
</body>
</html>
</richcontent>
<node CREATED="1737766232691" ID="ID_1413683857" MODIFIED="1737766240549" TEXT="Ha! die ist schon da">
<node COLOR="#2d40b2" CREATED="1737766232691" ID="ID_1413683857" MODIFIED="1737775474932" TEXT="Ha! die ist schon da">
<icon BUILTIN="ksmiletris"/>
<icon BUILTIN="button_cancel"/>
</node>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1737766241770" ID="ID_1746968965" MODIFIED="1737766267762" TEXT="nicht so einfach ... &#x3bb;-generic ist keine Funktion">
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1737766241770" ID="ID_1746968965" MODIFIED="1737775404274" TEXT="nicht so einfach ... &#x3bb;-generic ist keine Funktion">
<icon BUILTIN="messagebox_warning"/>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1737768448186" ID="ID_446285333" MODIFIED="1737768487565" TEXT="die probe-Technik anwenden (&#x27f5; iterExplorer)">
<icon BUILTIN="help"/>
<node BACKGROUND_COLOR="#e6c69a" COLOR="#990033" CREATED="1737768448186" ID="ID_446285333" MODIFIED="1737775431794" TEXT="die probe-Technik anwenden (&#x27f5; iterExplorer)">
<icon BUILTIN="yes"/>
</node>
<node COLOR="#5b280f" CREATED="1737768488844" ID="ID_95454385" MODIFIED="1737768511897" TEXT="damit kann man aber keine static-assertion-failure provozieren">
<node COLOR="#5b280f" CREATED="1737768488844" ID="ID_95454385" MODIFIED="1737775464243" TEXT="damit kann man aber keine static-assertion-failure provozieren">
<icon BUILTIN="button_cancel"/>
</node>
<node CREATED="1737768513367" ID="ID_262683040" MODIFIED="1737768519412" TEXT="ja dann....">
<node CREATED="1737768521376" ID="ID_1251164571" MODIFIED="1737768535589" TEXT="entweder gar keine &#x3bb;-generic unterst&#xfc;tzen"/>
<node CREATED="1737768536342" ID="ID_1137963941" MODIFIED="1737768552975" TEXT="oder gleich immer das Probing auf alle anwenden"/>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1737768555555" ID="ID_3235456" MODIFIED="1737768583613" TEXT="oder ein Probing-Tempalte schreiben">
<node COLOR="#5b280f" CREATED="1737768521376" ID="ID_1251164571" MODIFIED="1737775396510" TEXT="entweder gar keine &#x3bb;-generic unterst&#xfc;tzen">
<icon BUILTIN="button_cancel"/>
</node>
<node COLOR="#5b280f" CREATED="1737768536342" ID="ID_1137963941" MODIFIED="1737775396509" TEXT="oder gleich immer das Probing auf alle anwenden">
<icon BUILTIN="button_cancel"/>
</node>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1737768555555" ID="ID_3235456" MODIFIED="1737775400170" TEXT="oder ein Probing-Tempalte schreiben">
<icon BUILTIN="forward"/>
</node>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1737763306315" ID="ID_556563323" MODIFIED="1737763342424">
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1737763306315" ID="ID_556563323" MODIFIED="1737776731540">
<richcontent TYPE="NODE"><html>
<head>
@ -57110,7 +57115,7 @@
</body>
</html>
</richcontent>
<icon BUILTIN="flag-yellow"/>
<icon BUILTIN="pencil"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1737509793049" ID="ID_1532451583" MODIFIED="1737763426814" TEXT="komplexere F&#xe4;lle testen">
@ -57124,6 +57129,10 @@
<node CREATED="1737768409191" ID="ID_46123353" MODIFIED="1737768426237" TEXT="&#x3bb;-generic funktionieren nicht wie gew&#xfc;nscht"/>
<node CREATED="1737768426892" ID="ID_1722753025" MODIFIED="1737768440774" TEXT="und sonst mu&#xdf; man immer die Model-Namen ganz anschreiben"/>
</node>
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1737776743702" ID="ID_1501521982" MODIFIED="1737776790953" TEXT="sonderbares Verhalten mit zwe sub-Syntax-Klauseln und Binder">
<icon BUILTIN="broken-line"/>
<node CREATED="1737776795928" ID="ID_935270717" MODIFIED="1737776813345" TEXT="es kommt zweimal der bind-match vom ersten Wort"/>
</node>
</node>
</node>
<node CREATED="1737515362910" ID="ID_1587990202" MODIFIED="1737693815237" TEXT="offene Rekursion">