Lumiera 0.pre.04~rc.1
»edit your freedom«
Loading...
Searching...
No Matches
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)
5 2010, 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
42#ifndef LIB_ITER_SOURCE_H
43#define LIB_ITER_SOURCE_H
44
45
46#include "lib/meta/util.hpp"
47#include "lib/iter-adapter.hpp"
48#include "lib/itertools.hpp"
49#include "lib/nocopy.hpp"
50
51#include <type_traits>
52#include <utility>
53#include <string>
54#include <memory>
55
56
57
58
59namespace lib {
60
61 using std::string;
62 using std::shared_ptr;
63 using std::forward;
64
65
66
78 template<typename TY>
80 {
81
82 protected: /* == data source API to implement == */
83
84 using Pos = TY*;
85 using DataHandle = shared_ptr<IterSource>;
86
88
91 virtual Pos firstResult () =0;
92
97 virtual void nextResult(Pos& pos) =0;
98
105 virtual void disconnect () { }
106
107
108
109 public:
110 virtual ~IterSource() { };
111
112 virtual
113 operator string() const
114 {
115 return "IterSource<" + lib::meta::typeStr<TY>()+ ">";
116 }
117
118
119 /* == Iteration control API for IterAdapter frontend == */
120
121 friend bool
122 checkPoint (DataHandle const&, Pos const& pos)
123 {
124 return bool(pos);
125 }
126
127 friend void
128 iterNext (DataHandle& source, Pos& pos)
129 {
130 ASSERT (source);
131 source->nextResult(pos);
132 }
133
134
135 /* == public builder API to create instances == */
136
137 struct iterator
138 : IterAdapter<Pos, DataHandle>
139 {
141 using _I::IterAdapter;
142
143 operator string() const {return _I::source()? string(*_I::source()) : "⟂"; }
144 };
145
150 static iterator
151 build (IterSource& sourceImpl)
152 {
153 return startIteration (DataHandle{&sourceImpl, &detach_without_destroy});
154 }
155
162 static iterator
163 build (IterSource* sourceImplObject)
164 {
165 return startIteration (DataHandle{sourceImplObject, &destroy_managed_source});
166 }
167
169
170 using value_type = TY;
171 using reference = TY&;
172 using pointer = TY*;
173
174
175
176 private:
177 static iterator
179 {
180 REQUIRE (sourceHandle);
181 Pos first = sourceHandle->firstResult();
182 return {move(sourceHandle), first};
183 }
184
185
186 static void
188 {
189 WARN_IF (!source, library, "IterSource deleter called with NULL source pointer");
190 if (source)
191 source->disconnect();
192 }
193
194 static void
196 {
197 WARN_IF (!source, library, "IterSource deleter called with NULL source pointer");
198 if (source)
199 {
200 source->disconnect();
201 delete source;
202 }
203 }
204 };
205
206
208 template<typename TY>
209 IterSource<TY>::iterator IterSource<TY>::EMPTY_SOURCE = iterator();
210
211
212
213
214
221 template<class IT, class ISO = IterSource<typename meta::ValueTypeBinding<IT>::value_type>>
223 : public ISO
225 {
227
228 protected:
229 using Pos = ISO::Pos;
230
231 Pos
233 {
234 if (!src_)
235 return 0;
236 else
237 return & *src_;
238 }
239
240 void
242 {
243 if (!pos) return;
244 if (src_) ++src_;
245 if (src_)
246 pos = & *src_;
247 else
248 pos = 0;
249 }
250
251
252
253 public:
254 WrappedLumieraIter (IT const& orig)
255 : src_(orig)
256 { }
257
259 : src_(forward<IT>(orig))
260 { }
261
262
263 protected:
264 IT& wrappedIter() { return src_; }
265 IT const& wrappedIter() const { return src_; }
266 };
267
268
269
270
271 /* === pre-defined Adapters for frequently used Containers === */
272
273 namespace iter_source {
274 namespace { // traits and helpers...
275
276 template<class CON>
277 struct _SeqT
278 {
279 using Val = CON::iterator::value_type;
281 };
282
283 template<class IT>
284 struct _RangeT
285 {
286 using Val = IT::value_type;
288 };
289
290 template<class MAP>
291 struct _MapT
292 {
293 using Key = MAP::key_type;
294 using Val = MAP::value_type::second_type;
297 };
298
299
300 template<class IT>
301 struct _IterT
302 {
303 using Src = std::remove_reference<IT>::type;
304 using Val = Src::value_type;
306 };
307
308 template<class IT, class FUN>
310 {
311 using Src = std::remove_reference<IT>::type;
315 };
316
317 template<class IT>
319 {
320 using Src = std::remove_reference<IT>::type;
321 using PairType = Src::value_type;
322 using ValType = PairType::second_type;
323 using ConstKeyType = PairType::first_type;
324
325 // since we're returning the keys always by value,
326 // we can strip the const added by the STL map types
327 using KeyType = std::remove_const<ConstKeyType>::type;
328
331
332 static KeyType takeFirst (PairType const& pair) { return pair.first; }
333 static ValType takeSecond(PairType const& pair) { return pair.second;}
334 };
335
336
337 template<class IT>
338 _PairIterT<IT>::KeyIter
339 takePairFirst (IT&& source)
340 {
341 return transformIterator(forward<IT>(source), _PairIterT<IT>::takeFirst );
342 }
343
344 template<class IT>
345 _PairIterT<IT>::ValIter
346 takePairSecond (IT&& source)
347 {
348 return transformIterator(forward<IT>(source), _PairIterT<IT>::takeSecond );
349 }
350
351 } //(END) type helpers...
352
353
354
358 template<class IT>
359 _IterT<IT>::Iter
360 wrapIter (IT&& source)
361 {
362 using Src = _IterT<IT>::Src;
363 using Val = _IterT<IT>::Val;
364
365 return IterSource<Val>::build (new WrappedLumieraIter<Src> (forward<IT>(source)));
366 }
367
368
374 template<typename VAL>
375 auto
376 singleVal (VAL&& something)
377 {
378 using Src = decltype(singleValIterator (forward<VAL>(something)));
379 using Val = _IterT<Src>::Val;
380
381 return IterSource<Val>::build (new WrappedLumieraIter<Src>{singleValIterator (forward<VAL>(something))});
382 }
383
384
394 template<class IT, class FUN>
395 _TransformIterT<IT,FUN>::Iter
396 transform (IT&& source, FUN processingFunc)
397 {
398 using ValType = _TransformIterT<IT,FUN>::ResVal;
399 using TransIT = _TransformIterT<IT,FUN>::TransIter;
400
403 transformIterator (forward<IT>(source), processingFunc)));
404 }
405
406
410 template<class MAP>
411 _MapT<MAP>::KeyIter
412 eachMapKey (MAP& map)
413 {
415
416 Range contents (map.begin(), map.end());
417 return wrapIter (takePairFirst (contents));
418 }
419
420
424 template<class MAP>
425 _MapT<MAP>::ValIter
426 eachMapVal (MAP& map)
427 {
429
430 Range contents (map.begin(), map.end());
431 return wrapIter (takePairSecond(contents));
432 }
433
434
440 template<class MAP>
441 _MapT<MAP>::KeyIter
442 eachDistinctKey (MAP& map)
443 {
445
446 Range contents (map.begin(), map.end());
447 return wrapIter (filterRepetitions (takePairFirst(contents)));
448 }
449
450
455 template<class MAP>
456 _MapT<MAP>::ValIter
457 eachValForKey (MAP& map, typename _MapT<MAP>::Key key)
458 {
459 using Pos = MAP::iterator;
460 using Range = RangeIter<Pos>;
461
462 std::pair<Pos,Pos> valuesForKey = map.equal_range(key);
463 Range contents (valuesForKey.first, valuesForKey.second);
464 return wrapIter (takePairSecond(contents));
465 }
466
467
474 template<class CON>
475 _SeqT<CON>::Iter
476 eachEntry (CON& container)
477 {
478 using ValType = _SeqT<CON>::Val;
480
481 Range contents (container.begin(), container.end());
483 }
484
485
489 template<class IT>
490 _RangeT<IT>::Iter
491 eachEntry (IT const& begin, IT const& end)
492 {
493 using ValType = _RangeT<IT>::Val;
494 using Range = RangeIter<IT>;
495
496 Range contents (begin, end);
498 }
499
500
501}} // namespace lib::iter_source
502#endif
Adapter for building an implementation of the »Lumiera Forward Iterator« concept.
ConRef source()
allow derived classes to access backing container
Iteration source interface to abstract a data source, which then can be accessed through IterAdapter ...
shared_ptr< IterSource > DataHandle
static void detach_without_destroy(IterSource *source)
friend void iterNext(DataHandle &source, Pos &pos)
virtual Pos firstResult()=0
iteration start: prepare the first element.
static iterator build(IterSource *sourceImplObject)
build an iterator frontend, thereby managing the given heap allocated source object instance.
static iterator startIteration(DataHandle sourceHandle)
static iterator build(IterSource &sourceImpl)
build an iterator frontend for the given source,
friend bool checkPoint(DataHandle const &, Pos const &pos)
virtual void disconnect()
disconnect the data source / iteration frontend.
virtual ~IterSource()
virtual void nextResult(Pos &pos)=0
iteration step: switch on to the next element.
static void destroy_managed_source(IterSource *source)
static iterator EMPTY_SOURCE
storage for the empty data-source constant
Accessing a STL element range through a Lumiera forward iterator, An instance of this iterator adapte...
Iterator tool treating pulled data by a custom transformation (function)
Standard implementation of the IterSource interface: a wrapped "Lumiera Forward Iterator".
void nextResult(Pos &pos)
WrappedLumieraIter(IT const &orig)
Pos firstResult()
iteration start: prepare the first element.
IT const & wrappedIter() const
Any copy and copy construction prohibited.
Definition nocopy.hpp:38
Helper template(s) for creating Lumiera Forward Iterators.
Helpers for working with iterators based on the pipeline model.
Simple and lightweight helpers for metaprogramming and type detection.
_PairIterT< IT >::ValIter takePairSecond(IT &&source)
_PairIterT< IT >::KeyIter takePairFirst(IT &&source)
_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 singleVal(VAL &&something)
an IterSource frontend to return just a single value once.
_MapT< MAP >::KeyIter eachMapKey(MAP &map)
_IterT< IT >::Iter wrapIter(IT &&source)
wraps a given Lumiera Forward Iterator, exposing just a IterSource based frontend.
_MapT< MAP >::ValIter eachMapVal(MAP &map)
_SeqT< CON >::Iter eachEntry(CON &container)
enable_if_c< Cond::value, T >::type enable_if
SFINAE helper to control the visibility of specialisations and overloads.
Definition meta/util.hpp:87
Implementation namespace for support and library code.
auto filterRepetitions(IT const &source)
filters away repeated values emitted by source iterator
auto transformIterator(IT const &src, FUN processingFunc)
Build a TransformIter: convenience free function shortcut, picking up the involved types automaticall...
auto singleValIterator(VAL &&something)
Build a SingleValIter: convenience free function shortcut, to pick up just any value and wrap it as L...
Mix-Ins to allow or prohibit various degrees of copying and cloning.
Trait template for uniform access to function signature types.
Definition function.hpp:144