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:
parent
d923138d1c
commit
c0b8b63df0
3 changed files with 118 additions and 6 deletions
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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="überflü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& auf eine Kopie"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1536342792784" ID="ID_363834044" MODIFIED="1536342806527" TEXT="doppeltes Wrappen unnötig">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1536342807526" ID="ID_1490056918" MODIFIED="1536342900054" TEXT="stattdessen im vector<Step> wrappen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...d.h. die <i>einzelnen</i> Steps in der Pipeline direkt wrappen.
|
||||
</p>
|
||||
<p>
|
||||
Dann ist auß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&">
|
||||
<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ährend das Original auf dem Auswertungs-Stack liegen bleibt,
|
||||
</p>
|
||||
<p>
|
||||
für spä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ß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> 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"/>
|
||||
|
|
|
|||
Loading…
Reference in a new issue