Lumiera  0.pre.03
»edit your freedom«
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 
80 namespace lib {
81 namespace iter {
82 
83  using std::move;
84  using std::forward;
85  using std::string;
86 
87  using lib::meta::disable_if;
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 = typename _Trait::Pipeline;
154 
155  using Value = typename _Base::value_type;
156  using Filter = typename _Trait::Filter;
157  using Step = typename _Trait::StepFunctor;
158 
160  std::vector<Step> stepChain_;
161 
162 
163  bool
164  needsExpansion() const
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
190  iterNext()
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 
206  operator++()
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>,
255  IterChainSearch&& >
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*/
auto chainSearch(SRC &&srcData)
setup a chain search configuration by suitably wrapping the given container.
std::function< void(Filter &)> StepFunctor
each step in the chain is a functor to reconfigure the underlying filter
auto explore(IT &&srcSeq)
start building a IterExplorer by suitably wrapping the given iterable source.
bool filter(Placement< DummyMO > const &candidate)
a filter predicate to pick some objects from a resultset.
Simple and lightweight helpers for metaprogramming and type detection.
IterChainSearch(SEQ &&srcData)
Build a chain-search mechanism based on the given source data sequence.
std::vector< Step > stepChain_
Storage for a sequence of filter configuration functors.
Implementation namespace for support and library code.
IterChainSearch && search(Value target)
attach additional direct search for a given value.
IterChainSearch && addStep(FUN &&configureSearchStep)
configure additional chained search condition.
Iterator based linear search mechanism, with the ability to perform consecutive search with backtrack...
Lumiera error handling (C++ interface).
disable_if< is_convertible< FUN, Value >, IterChainSearch &&> search(FUN &&filterPredicate)
attach additional search with the given filter predicate.
Building tree expanding and backtracking evaluations within hierarchical scopes.
IterChainSearch && clearFilter()
drop all search condition frames.
auto buildChainExplorer(SRC &&dataSource)
define the chained-search mechanism: invoking filter.expandChildren() adds a new layer with the copy ...