Lumiera  0.pre.03
»edit your freedom«
iter-source.hpp
Go to the documentation of this file.
1 /*
2  ITER-SOURCE.hpp - an interface to build an opaque iterator-based data source
3 
4  Copyright (C) Lumiera.org
5  2010, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
51 #ifndef LIB_ITER_SOURCE_H
52 #define LIB_ITER_SOURCE_H
53 
54 
55 #include "lib/meta/util.hpp"
56 #include "lib/iter-adapter.hpp"
57 #include "lib/itertools.hpp"
58 #include "lib/nocopy.hpp"
59 
60 #include <type_traits>
61 #include <utility>
62 #include <string>
63 #include <memory>
64 
65 
66 
67 
68 namespace lib {
69 
70  using std::string;
71  using std::shared_ptr;
72  using std::forward;
73 
74 
75 
87  template<typename TY>
88  class IterSource
89  {
90 
91  protected: /* == data source API to implement == */
92 
93  typedef TY* Pos;
95 
97 
100  virtual Pos firstResult () =0;
101 
106  virtual void nextResult(Pos& pos) =0;
107 
114  virtual void disconnect () { }
115 
116 
117 
118  public:
119  virtual ~IterSource() { };
120 
121  virtual
122  operator string() const
123  {
124  return "IterSource<" + lib::meta::typeStr<TY>()+ ">";
125  }
126 
127 
128  /* == Iteration control API for IterAdapter frontend == */
129 
130  friend bool
131  checkPoint (DataHandle const&, Pos const& pos)
132  {
133  return bool(pos);
134  }
135 
136  friend void
137  iterNext (DataHandle& source, Pos& pos)
138  {
139  ASSERT (source);
140  source->nextResult(pos);
141  }
142 
143 
144  /* == public builder API to create instances == */
145 
146  struct iterator
147  : IterAdapter<Pos, DataHandle>
148  {
150  using _I::IterAdapter;
151 
152  operator string() const {return _I::source()? string(*_I::source()) : "⟂"; }
153  };
154 
159  static iterator
160  build (IterSource& sourceImpl)
161  {
162  return std::move(
163  startIteration (DataHandle{&sourceImpl, &detach_without_destroy}));
164  }
165 
172  static iterator
173  build (IterSource* sourceImplObject)
174  {
175  return std::move(
176  startIteration (DataHandle{sourceImplObject, &destroy_managed_source}));
177  }
178 
179  static iterator EMPTY_SOURCE;
180 
181  using value_type = TY;
182  using reference = TY&;
183  using pointer = TY*;
184 
185 
186 
187  private:
188  static iterator
189  startIteration (DataHandle sourceHandle)
190  {
191  REQUIRE (sourceHandle);
192  Pos first = sourceHandle->firstResult();
193  return {move(sourceHandle), first};
194  }
195 
196 
197  static void
198  detach_without_destroy (IterSource * source)
199  {
200  WARN_IF (!source, library, "IterSource deleter called with NULL source pointer");
201  if (source)
202  source->disconnect();
203  }
204 
205  static void
206  destroy_managed_source (IterSource * source)
207  {
208  WARN_IF (!source, library, "IterSource deleter called with NULL source pointer");
209  if (source)
210  {
211  source->disconnect();
212  delete source;
213  }
214  }
215  };
216 
217 
219  template<typename TY>
221 
222 
223 
224 
225 
232  template<class IT, class ISO = IterSource<typename meta::ValueTypeBinding<IT>::value_type>>
234  : public ISO
236  {
237  IT src_;
238 
239  protected:
240  using Pos = typename ISO::Pos;
241 
242  Pos
243  firstResult ()
244  {
245  if (!src_)
246  return 0;
247  else
248  return & *src_;
249  }
250 
251  void
252  nextResult (Pos& pos)
253  {
254  if (!pos) return;
255  if (src_) ++src_;
256  if (src_)
257  pos = & *src_;
258  else
259  pos = 0;
260  }
261 
262 
263 
264  public:
265  WrappedLumieraIter (IT const& orig)
266  : src_(orig)
267  { }
268 
269  WrappedLumieraIter (IT&& orig)
270  : src_(forward<IT>(orig))
271  { }
272 
273 
274  protected:
275  IT& wrappedIter() { return src_; }
276  IT const& wrappedIter() const { return src_; }
277  };
278 
279 
280 
281 
282  /* === pre-defined Adapters for frequently used Containers === */
283 
284  namespace iter_source {
285  namespace { // traits and helpers...
286 
287  template<class CON>
288  struct _SeqT
289  {
290  using Val = typename CON::iterator::value_type;
291  using Iter = typename IterSource<Val>::iterator;
292  };
293 
294  template<class IT>
295  struct _RangeT
296  {
297  using Val = typename IT::value_type;
298  using Iter = typename IterSource<Val>::iterator;
299  };
300 
301  template<class MAP>
302  struct _MapT
303  {
304  using Key = typename MAP::key_type;
305  using Val = typename MAP::value_type::second_type;
306  using KeyIter = typename IterSource<Key>::iterator;
307  using ValIter = typename IterSource<Val>::iterator;
308  };
309 
310 
311  template<class IT>
312  struct _IterT
313  {
314  using Src = typename std::remove_reference<IT>::type;
315  using Val = typename Src::value_type;
316  using Iter = typename IterSource<Val>::iterator;
317  };
318 
319  template<class IT, class FUN>
321  {
322  using Src = typename std::remove_reference<IT>::type;
323  using ResVal = typename lib::meta::_Fun<FUN>::Ret;
325  using Iter = typename IterSource<ResVal>::iterator;
326  };
327 
328  template<class IT>
329  struct _PairIterT
330  {
331  using Src = typename std::remove_reference<IT>::type;
332  using PairType = typename Src::value_type;
333  using ValType = typename PairType::second_type;
334  using ConstKeyType = typename PairType::first_type;
335 
336  // since we're returning the keys always by value,
337  // we can strip the const added by the STL map types
338  using KeyType = typename std::remove_const<ConstKeyType>::type;
339 
342 
343  static KeyType takeFirst (PairType const& pair) { return pair.first; }
344  static ValType takeSecond(PairType const& pair) { return pair.second;}
345  };
346 
347 
348  template<class IT>
349  typename _PairIterT<IT>::KeyIter
350  takePairFirst (IT&& source)
351  {
352  return transformIterator(forward<IT>(source), _PairIterT<IT>::takeFirst );
353  }
354 
355  template<class IT>
356  typename _PairIterT<IT>::ValIter
357  takePairSecond (IT&& source)
358  {
359  return transformIterator(forward<IT>(source), _PairIterT<IT>::takeSecond );
360  }
361 
362  } //(END) type helpers...
363 
364 
365 
369  template<class IT>
370  typename _IterT<IT>::Iter
372  {
373  using Src = typename _IterT<IT>::Src;
374  using Val = typename _IterT<IT>::Val;
375 
376  return IterSource<Val>::build (new WrappedLumieraIter<Src> (forward<IT>(source)));
377  }
378 
379 
385  template<typename VAL>
386  auto
387  singleVal (VAL&& something)
388  {
389  using Src = decltype(singleValIterator (forward<VAL>(something)));
390  using Val = typename _IterT<Src>::Val;
391 
392  return IterSource<Val>::build (new WrappedLumieraIter<Src>{singleValIterator (forward<VAL>(something))});
393  }
394 
395 
405  template<class IT, class FUN>
406  typename _TransformIterT<IT,FUN>::Iter
407  transform (IT&& source, FUN processingFunc)
408  {
409  typedef typename _TransformIterT<IT,FUN>::ResVal ValType;
410  typedef typename _TransformIterT<IT,FUN>::TransIter TransIT;
411 
414  transformIterator (forward<IT>(source), processingFunc)));
415  }
416 
417 
421  template<class MAP>
422  typename _MapT<MAP>::KeyIter
423  eachMapKey (MAP& map)
424  {
425  using Range = RangeIter<typename MAP::iterator>;
426 
427  Range contents (map.begin(), map.end());
428  return wrapIter (takePairFirst (contents));
429  }
430 
431 
435  template<class MAP>
436  typename _MapT<MAP>::ValIter
437  eachMapVal (MAP& map)
438  {
439  using Range = RangeIter<typename MAP::iterator>;
440 
441  Range contents (map.begin(), map.end());
442  return wrapIter (takePairSecond(contents));
443  }
444 
445 
451  template<class MAP>
452  typename _MapT<MAP>::KeyIter
453  eachDistinctKey (MAP& map)
454  {
455  using Range = RangeIter<typename MAP::iterator>;
456 
457  Range contents (map.begin(), map.end());
458  return wrapIter (filterRepetitions (takePairFirst(contents)));
459  }
460 
461 
466  template<class MAP>
467  typename _MapT<MAP>::ValIter
468  eachValForKey (MAP& map, typename _MapT<MAP>::Key key)
469  {
470  using Pos = typename MAP::iterator;
471  using Range = RangeIter<Pos>;
472 
473  std::pair<Pos,Pos> valuesForKey = map.equal_range(key);
474  Range contents (valuesForKey.first, valuesForKey.second);
475  return wrapIter (takePairSecond(contents));
476  }
477 
478 
485  template<class CON>
486  typename _SeqT<CON>::Iter
487  eachEntry (CON& container)
488  {
489  using ValType = typename _SeqT<CON>::Val;
490  using Range = RangeIter<typename CON::iterator>;
491 
492  Range contents (container.begin(), container.end());
494  }
495 
496 
500  template<class IT>
501  typename _RangeT<IT>::Iter
502  eachEntry (IT const& begin, IT const& end)
503  {
504  using ValType = typename _RangeT<IT>::Val;
505  using Range = RangeIter<IT>;
506 
507  Range contents (begin, end);
509  }
510 
511 
512 }} // namespace lib::iter_source
513 #endif
_IterT< IT >::Iter wrapIter(IT &&source)
wraps a given Lumiera Forward Iterator, exposing just a IterSource based frontend.
static iterator EMPTY_SOURCE
storage for the empty data-source constant
Helper template(s) for creating Lumiera Forward Iterators.
Simple and lightweight helpers for metaprogramming and type detection.
Any copy and copy construction prohibited.
Definition: nocopy.hpp:46
Helper for uniform access to function signature types.
Definition: function.hpp:108
ConRef source()
allow derived classes to access backing container
Implementation namespace for support and library code.
virtual void nextResult(Pos &pos)=0
iteration step: switch on to the next element.
Iteration source interface to abstract a data source, which then can be accessed through IterAdapter ...
Definition: iter-source.hpp:88
Mix-Ins to allow or prohibit various degrees of copying and cloning.
Iterator tool treating pulled data by a custom transformation (function)
Definition: itertools.hpp:763
auto singleVal(VAL &&something)
an IterSource frontend to return just a single value once.
_MapT< MAP >::KeyIter eachMapKey(MAP &map)
_TransformIterT< IT, FUN >::Iter transform(IT &&source, FUN processingFunc)
pipes a given Lumiera Forward Iterator through a transformation function and wraps the resulting tran...
auto singleValIterator(VAL &&something)
Build a SingleValIter: convenience free function shortcut, to pick up just any value and wrap it as L...
Definition: itertools.hpp:664
_MapT< MAP >::ValIter eachMapVal(MAP &map)
static iterator build(IterSource &sourceImpl)
build an iterator frontend for the given source,
virtual Pos firstResult()=0
iteration start: prepare the first element.
Helpers for working with iterators based on the pipeline model.
Accessing a STL element range through a Lumiera forward iterator, An instance of this iterator adapte...
auto transformIterator(IT const &src, FUN processingFunc)
Build a TransformIter: convenience free function shortcut, picking up the involved types automaticall...
Definition: itertools.hpp:797
Standard implementation of the IterSource interface: a wrapped "Lumiera Forward Iterator".
string contents(Rec const &object)
render the child elements as string data for test/verification
Adapter for building an implementation of the »Lumiera Forward Iterator« concept. ...
virtual void disconnect()
disconnect the data source / iteration frontend.
_SeqT< CON >::Iter eachEntry(CON &container)
auto filterRepetitions(IT const &source)
filters away repeated values emitted by source iterator
Definition: itertools.hpp:855
static iterator build(IterSource *sourceImplObject)
build an iterator frontend, thereby managing the given heap allocated source object instance...