Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
iter-chain-search.hpp
Go to the documentation of this file.
1/*
2 ITER-CHAIN-SEARCH.hpp - chained search with backtracking based on (bidirectional) iterator
3
4 Copyright (C)
5 2018, Hermann Vosseler <Ichthyostega@web.de>
6
7  **Lumiera** is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version. See the file COPYING for further details.
11
12*/
13
14
67#ifndef SRC_LIB_ITER_CHAIN_SEARCH_H
68#define SRC_LIB_ITER_CHAIN_SEARCH_H
69
70
71#include "lib/error.hpp"
72#include "lib/iter-explorer.hpp"
73#include "lib/meta/util.hpp"
74
75#include <utility>
76#include <vector>
77#include <string>
78
79
80namespace lib {
81namespace iter {
82
83 using std::move;
84 using std::forward;
85 using std::string;
86
88
89
90 namespace { // type construction helpers...
91
92 template<class SRC>
93 auto
94 buildSearchFilter (SRC&& dataSource)
95 {
96 return explore (forward<SRC> (dataSource))
97 .mutableFilter();
98 }
99
107 template<class SRC>
108 auto
109 buildChainExplorer (SRC&& dataSource)
110 {
111 return buildSearchFilter (forward<SRC> (dataSource))
112 .expand ([](auto it){ return it; }); // child iterator starts as copy of current level iterator
113 }
114
124 template<class SRC>
126 {
127 using Filter = decltype( buildSearchFilter(std::declval<SRC>()).asIterator() );
128 using Pipeline = decltype( buildChainExplorer (std::declval<SRC>()) );
129
131 using StepFunctor = std::function<void(Filter&)>;
132 };
133
134 }//(End)type construction helpers
135
136
137
138
139
140 /*********************************************************************************************************/
148 template<class SRC>
150 : public _IterChainSetup<SRC>::Pipeline
151 {
152 using _Trait = _IterChainSetup<SRC>;
153 using _Base = _Trait::Pipeline;
154
155 using Value = _Base::value_type;
156 using Filter = _Trait::Filter;
157 using Step = _Trait::StepFunctor;
158
160 std::vector<Step> stepChain_;
161
162
163 bool
165 {
166 return _Base::depth() < stepChain_.size();
167 }
168
169 public:
176 template<class SEQ>
177 explicit
178 IterChainSearch (SEQ&& srcData)
179 : _Base{buildChainExplorer (forward<SEQ> (srcData))}
180 { // mark initial pristine state
181 _Base::disableFilter();
182 }
183
184 // inherited default ctor and standard copy operations
185 using _Base::_Base;
186
187
188 /* === adapted iteration control API === */
189 void
191 {
192 _Base::__throw_if_empty();
193 if (not needsExpansion())
194 _Base::iterNext();
195 while (needsExpansion() // Backtracking loop: attempt to establish all conditions
196 and _Base::checkPoint()) // possibly trying further combinations until success:
197 {
198 uint depth =_Base::depth();
199 _Base::expandChildren(); // create copy of current filter embedded into child level
200 stepChain_[depth] (_Base::accessCurrentChildIter()); // invoke step functor to reconfigure this filter...
201 _Base::dropExhaustedChildren(); // which thereby might become empty
202 }
203 }
204
207 {
208 iterNext();
209 return *this;
210 }
211
212
213
228 template<typename FUN>
230 addStep (FUN&& configureSearchStep)
231 {
232 if (not this->empty())
233 {
234 Step nextStep{forward<FUN> (configureSearchStep)};
235
236 if (_Base::isDisabled())
237 nextStep (*this); // apply first step immediately
238 else // (implicitly enables the base filter)
239 {
240 stepChain_.emplace_back (move (nextStep)); // append all further steps into the chain...
241 this->iterNext(); // then establish invariant:
242 } // expand to leaf and forward to first match
243 }
244 return move(*this);
245 }
246
253 template<typename FUN>
254 disable_if<is_convertible<FUN, Value>,
256 search (FUN&& filterPredicate)
257 {
258 addStep ([predicate{forward<FUN> (filterPredicate)}]
259 (Filter& filter)
260 { // manipulate current filter configuration
261 filter.setNewFilter (predicate);
262 });
263 return move(*this);
264 }
265
271 search (Value target)
272 {
273 search ([target](Value const& currVal) { return currVal == target; });
274 return move(*this);
275 }
276
284 {
285 stepChain_.clear();
286 _Base::rootCurrent();
287 _Base::disableFilter();
288 return move(*this);
289 }
290 };
291
292
293
294
295 /* ==== convenient builder free function ==== */
296
308 template<class SRC>
309 inline auto
310 chainSearch (SRC&& srcData)
311 {
312 return IterChainSearch<SRC>{forward<SRC> (srcData)};
313 }
314
315
316
317}} // namespace lib::iter
318#endif /*SRC_LIB_ITER_CHAIN_SEARCH_H*/
Iterator based linear search mechanism, with the ability to perform consecutive search with backtrack...
IterChainSearch && search(Value target)
attach additional direct search for a given value.
_IterChainSetup< SRC > _Trait
IterChainSearch && addStep(FUN &&configureSearchStep)
configure additional chained search condition.
std::vector< Step > stepChain_
Storage for a sequence of filter configuration functors.
disable_if< is_convertible< FUN, Value >, IterChainSearch && > search(FUN &&filterPredicate)
attach additional search with the given filter predicate.
IterChainSearch && clearFilter()
drop all search condition frames.
IterChainSearch(SEQ &&srcData)
Build a chain-search mechanism based on the given source data sequence.
Lumiera error handling (C++ interface).
unsigned int uint
Definition integral.hpp:29
Building tree expanding and backtracking evaluations within hierarchical scopes.
Simple and lightweight helpers for metaprogramming and type detection.
auto buildChainExplorer(SRC &&dataSource)
define the chained-search mechanism: invoking filter.expandChildren() adds a new layer with the copy ...
decltype(buildChainExplorer(std::declval< SRC >())) Pipeline
decltype(buildSearchFilter(std::declval< SRC >()).asIterator()) Filter
std::function< void(Filter &)> StepFunctor
each step in the chain is a functor to reconfigure the underlying filter
auto chainSearch(SRC &&srcData)
setup a chain search configuration by suitably wrapping the given container.
enable_if_c< not Cond::value, T >::type disable_if
Definition meta/util.hpp:90
Implementation namespace for support and library code.
auto explore(IT &&srcSeq)
start building a IterExplorer by suitably wrapping the given iterable source.