ChainSearch: ensure to pass current state without spurious copy

It is essential that we pass the current state of the filter
into the expand functor, where it needs to be copied (once!)
to create a child state, which can then be augmented.

This augmented state is then pushed onto a stack, to enable backtracking.


Due to the flexible adapters and the wrapping into the TreeExplorer builder,
we ended up performing several spurious copies on the current state
This commit is contained in:
Fischlurch 2018-09-07 20:44:25 +02:00
parent d923138d1c
commit c0b8b63df0
3 changed files with 118 additions and 6 deletions

View file

@ -92,11 +92,19 @@ namespace iter {
template<class SRC>
struct _IterChainSetup
{
using Filter = decltype( buildSearchFilter (std::declval<SRC>()) );
using StepFunctor = typename iter_explorer::_BoundFunctor<Filter(Filter const&), Filter const&>::Functor;
using Filter = decltype( buildSearchFilter(std::declval<SRC>()).asIterator() );
using StepFunctor = std::function<Filter(Filter const&)>;
using StepWrapper = typename iter_explorer::_BoundFunctor<Filter(Filter const&), Filter const&>::Functor;
// ^^^^^^^^^^^^^ used as argument on generic lambda
using Pipeline = decltype( buildExplorer (std::declval<SRC>(), std::declval<StepFunctor>()) );
static Pipeline
configurePipeline (SRC&& dataSource, StepFunctor step)
{
return buildExplorer(forward<SRC> (dataSource), move (step));
}
};
}//(End)type construction helpers
@ -122,7 +130,7 @@ namespace iter {
using Value = typename _Base::value_type;
using Filter = typename _Trait::Filter;
using Step = typename _Trait::StepFunctor;
using Step = typename _Trait::StepWrapper;
std::vector<Step> stepChain_;
@ -136,8 +144,8 @@ namespace iter {
template<class SEQ>
explicit
IterChainSearch (SEQ&& srcData)
: _Base{move (buildExplorer (forward<SEQ> (srcData)
,Step{[this](Filter const& curr){ return configureFilterChain(curr); }}))}
: _Base{_Trait::configurePipeline (forward<SEQ> (srcData)
,[this](Filter const& curr){ return configureFilterChain(curr); })}
{ }
// inherited default ctor and standard copy operations
@ -165,6 +173,7 @@ namespace iter {
search (FUN&& configureSearchStep)
{
stepChain_.emplace_back (Step{forward<FUN> (configureSearchStep)});
this->iterNext(); // establish invariant: expand to leaf and forward to first match
return move(*this);
}

View file

@ -1474,6 +1474,16 @@ namespace lib {
{
return IterExploreSource<value_type> {move(*this)};
}
/** _terminal builder_ to strip the TreeExplorer and expose the built Pipeline.
* @return a »Lumiera Forward iterator« incorporating the complete pipeline logic.
*/
SRC
asIterator()
{
return SRC {move(*this)};
}
};

View file

@ -31215,6 +31215,99 @@
<icon BUILTIN="flag-yellow"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1536340043113" ID="ID_1162927294" MODIFIED="1536340232698" TEXT="aktuellen Zustand als Argument">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1536340051461" ID="ID_1232898317" MODIFIED="1536345629500" TEXT="Wichtig: Referenz">
<linktarget COLOR="#a9b4c1" DESTINATION="ID_1232898317" ENDARROW="Default" ENDINCLINATION="550;0;" ID="Arrow_ID_1329838760" SOURCE="ID_1977741990" STARTARROW="None" STARTINCLINATION="109;0;"/>
<icon BUILTIN="button_ok"/>
<node CREATED="1536340255596" ID="ID_1394539187" MODIFIED="1536340348029" TEXT="&#xfc;berfl&#xfc;ssige Kopie erstellt">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1536340275802" ID="ID_1689368781" MODIFIED="1536340292559" TEXT="im Aufruf des inneren (grwrappten) Funktors">
<icon BUILTIN="info"/>
</node>
<node CREATED="1536340301958" ID="ID_932937045" MODIFIED="1536340319264" TEXT="das reingegebene Argument zeigt noch (korrekt) auf die aktuelle Pipeline"/>
<node CREATED="1536340325843" ID="ID_1834736142" MODIFIED="1536340342005" TEXT="aber das eingwickelte Lambda sieht eine const&amp; auf eine Kopie"/>
</node>
<node COLOR="#338800" CREATED="1536342792784" ID="ID_363834044" MODIFIED="1536342806527" TEXT="doppeltes Wrappen unn&#xf6;tig">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1536342807526" ID="ID_1490056918" MODIFIED="1536342900054" TEXT="stattdessen im vector&lt;Step&gt; wrappen">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...d.h. die <i>einzelnen</i>&#160;Steps in der Pipeline direkt wrappen.
</p>
<p>
Dann ist au&#223;en herum keine Anpassung der Argumente mehr notwendig,
</p>
<p>
und man kann die Expand-Funktion direkt als std::function-Objekt durchgeben
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="idea"/>
</node>
</node>
<node CREATED="1536340063062" ID="ID_1554385479" MODIFIED="1536340152896" TEXT="und zwar const&amp;">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...um den Expand-Funktor zu zwingen, eine Kopie zu machen;
</p>
<p>
es sollte die Filter-Konfiguration auf der Kopie manipuliert werden,
</p>
<p>
w&#228;hrend das Original auf dem Auswertungs-Stack liegen bleibt,
</p>
<p>
f&#252;r sp&#228;teres Backtracking...
</p>
</body>
</html>
</richcontent>
</node>
<node COLOR="#338800" CREATED="1536345349807" ID="ID_219089137" MODIFIED="1536345462776" TEXT="TreeExplorer strippen">
<icon BUILTIN="button_ok"/>
<node CREATED="1536345360133" ID="ID_23274093" MODIFIED="1536345384449" TEXT="wird immer noch au&#xdf;ern herumgewickelt">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...damit man stets weitere Builder-Funktionen auf der Pipeline aufrufen kann
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1536345386770" ID="ID_1554908631" MODIFIED="1536345421597" TEXT="wir brauchen aber den Filter-Iterator selber">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
weil wir <i>diesen</i>&#160;manipulieren
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1536345422997" ID="ID_1977741990" MODIFIED="1536345460034" TEXT="nur so kann man eine Referenz auf den Zustand in den Expand-Funktor geben">
<arrowlink DESTINATION="ID_1232898317" ENDARROW="Default" ENDINCLINATION="550;0;" ID="Arrow_ID_1329838760" STARTARROW="None" STARTINCLINATION="109;0;"/>
<icon BUILTIN="idea"/>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1536018862802" ID="ID_1044555993" MODIFIED="1536329736419" TEXT="abgeleiteten Frame konstruieren">
<linktarget COLOR="#65a7b1" DESTINATION="ID_1044555993" ENDARROW="Default" ENDINCLINATION="70;92;" ID="Arrow_ID_575633930" SOURCE="ID_1532889609" STARTARROW="None" STARTINCLINATION="149;-3;"/>
<icon BUILTIN="button_ok"/>