Lumiera  0.pre.03
»edit your freedom«
iter-adapter.hpp File Reference

Go to the source code of this file.

Description

Helper template(s) for creating Lumiera Forward Iterators.

These are the foundation to build up iterator like types from scratch. Usually, these templates will be created and provided by a custom container type and accessed by the client through a typedef name "`iterator`" (similar to the usage within the STL). For more advanced usage, the providing container might want to subclass these iterators, e.g. to provide an additional, specialised API.

Depending on the concrete situation, several flavours are provided:

  • the IterAdapter retains an active callback connection to the controlling container, thus allowing arbitrary complex behaviour.
  • the IterStateWrapper uses a variation of that approach, where the representation of the current state is embedded as a State Core value element right into the iterator instance.
  • very similar is IterableDecorator, but this time directly as decorator to inherit from the »state core«, and without checks.
  • the RangeIter allows just to expose a range of elements defined by a STL-like pair of "start" and "end" iterators

Some more specific use cases are provided in the extension header iter-adapter-ptr-deref.hpp

  • often, objects are managed internally by pointers, while allowing the clients to use direct references; to support this usage scenario, PtrDerefIter wraps an existing iterator, while dereferencing any value automatically on access.
  • for some (very specific) usage situations we intend to explore the contents of a stable and unmodifiable data structure through pointers. The AddressExposingIter wraps another Lumiera Forward Iterator and exposes addresses – assuming the used source iterator is exposing references to pre-existing storage locations (not temporaries).

There are many further ways of building a Lumiera Forward Iterator. For example, lib::IterSource exposes an "iterable" source of data elements, while hiding the actual container or generator implementation behind a VTable call. Furthermore, complex processing chains with recursive expansion can be built with the IterExporer builder function. Besides, there are adapters for the most common usages with STL containers, and such iterators can also be combined and extended with the help of itertools.hpp

Basically every class in compliance with our specific iterator concept can be used as a building block within this framework.

Lumiera Forward Iterator concept

Similar to the STL, instead of using a common "Iterator" base class, we rather define a common set of functions and behaviour which can be expected from any such iterator. These rules are similar to STL's "forward iterator", with the addition of an bool check to detect iteration end. The latter is inspired by the hasNext() function found in many current languages supporting iterators. However, by inspiration from functional programming, we deliberately do not support the various extended iterator concepts from STL and boost (random access iterators, output iterators, arithmetics, difference between iterators and the like). According to this concept, an iterator is a promise for pulling values once, and nothing beyond that.

Notably,

  • any Lumiera forward iterator can be in a "exhausted" (invalid) state, which can be checked by the bool conversion. Especially, an instance created by the default ctor is always fixed to that state. This state is final and can not be reset, meaning that any iterator is a disposable one-way-off object.
  • iterators are copyable and equality comparable
  • when an iterator is not in the exhausted state, it may be dereferenced to yield the current value.
  • usually, the current value is exposed by-ref (but by-val is possible)
  • moreover, iterators may be incremented until exhaustion.

Conceptually, a Lumiera Iterator represents a lazy stream of calculations rather than a target value considered to be »within« a container. And while the result is in may cases deliberately exposed as a reference, in order to keep the door open for special-case manipulations, for the typical usage it is discouraged to assume anything about the source, beyond the limited access to some transient state as exposed during active iteration. Together, these rules enable a loose coupling to the source of data.

See also
iter-adapter-test.cpp
itertools.hpp
IterSource (completely opaque iterator)
value-type-binding.hpp

Definition in file iter-adapter.hpp.

#include "lib/error.hpp"
#include "lib/meta/value-type-binding.hpp"
#include <iterator>

Classes

class  CheckedCore< COR >
 Adapter to add sanity checks to a »state core«. More...
 
class  ConstIter< IT >
 wrapper to expose values as const More...
 
class  ContainerCore< CON >
 Adapter to »piggy-back« a STL iterable container inline and expose it as »state core«. More...
 
class  IterableDecorator< COR >
 Decorator-Adapter to make a »*State Core*« iterable as Lumiera Forward Iterator. More...
 
class  IterAdapter< POS, CON >
 Adapter for building an implementation of the »Lumiera Forward Iterator« concept. More...
 
class  IterStateCore< IT >
 Adapter to dress up an existing »Lumiera Forward Iterator« as »state core«. More...
 
class  IterStateWrapper< ST, T >
 Another Lumiera Forward Iterator building block, based on incorporating a state type as »*State Core*«, right into the iterator. More...
 
struct  IterType< TY >
 Helper for type rewritings: get the element type for an iterator like entity. More...
 
struct  IterType< Iter< TY, CON > >
 
struct  IterType< RangeIter< IT > >
 
class  NumIter< INT >
 Enumerate all "numbers" within a range. More...
 
class  RangeIter< IT >
 Accessing a STL element range through a Lumiera forward iterator, An instance of this iterator adapter is completely self-contained and allows to iterate once over the range of elements, until pos==end. More...
 
struct  IterType< RangeIter< IT > >::SimilarIter< T2 >
 < rebind to rewritten Iterator wrapped into RangeIter More...
 
struct  IterType< Iter< TY, CON > >::SimilarIter< T2 >
 < rebind to a similarly structured Iterator with value type T2 More...
 

Typedefs

template<class COR >
using CoreYield = decltype(std::declval< COR >().yield())
 the result type yielded by a »state core«
 
template<class IT >
using Yield = decltype(std::declval< IT >().operator*())
 type binding helper: an iterato's actual result type
 

Macros

#define ENABLE_USE_IN_STD_RANGE_FOR_LOOPS(ITER)
 use a given Lumiera Forward Iterator in standard "range for loops" More...
 
#define LIFT_PARENT_INCREMENT_OPERATOR(_BASECLASS_)
 define increment operator forwarding to baseclass but returning current More...
 

Functions

void _throwIterExhausted ()
 
template<typename INT >
NumIter< INT > eachNum (INT start=std::numeric_limits< INT >::min(), INT end=std::numeric_limits< INT >::max())
 convenience function to iterate "each number"
 
template<class P1 , class P2 , class CON >
bool operator!= (IterAdapter< P1, CON > const &il, IterAdapter< P2, CON > const &ir)
 
template<class ST , class T1 , class T2 >
bool operator!= (IterStateWrapper< ST, T1 > const &il, IterStateWrapper< ST, T2 > const &ir)
 
template<class I1 , class I2 >
bool operator!= (RangeIter< I1 > const &il, RangeIter< I2 > const &ir)
 
template<class I1 , class I2 >
bool operator!= (ConstIter< I1 > const &il, ConstIter< I2 > const &ir)
 
template<class P1 , class P2 , class CON >
bool operator== (IterAdapter< P1, CON > const &il, IterAdapter< P2, CON > const &ir)
 Supporting equality comparisons...
 
template<class ST , class T1 , class T2 >
bool operator== (IterStateWrapper< ST, T1 > const &il, IterStateWrapper< ST, T2 > const &ir)
 Supporting equality comparisons of equivalent iterators (same state type)...
 
template<class I1 , class I2 >
bool operator== (RangeIter< I1 > const &il, RangeIter< I2 > const &ir)
 Supporting equality comparisons...
 
template<class I1 , class I2 >
bool operator== (ConstIter< I1 > const &il, ConstIter< I2 > const &ir)
 Supporting equality comparisons...
 
template<class OBJ >
OBJ * unConst (const OBJ *o)
 shortcut to save some typing when having to define const and non-const variants of member functions More...
 
template<class OBJ >
OBJ & unConst (OBJ const &)
 

Namespaces

 lib
 Implementation namespace for support and library code.
 

Macro Definition Documentation

◆ ENABLE_USE_IN_STD_RANGE_FOR_LOOPS

#define ENABLE_USE_IN_STD_RANGE_FOR_LOOPS (   ITER)
Value:
friend ITER begin (ITER const& it){ return it; } \
friend ITER&& begin (ITER&& it) { return static_cast<ITER&&> (it); } \
friend ITER end (ITER const&) { return ITER(); } \
using iterator_category = std::input_iterator_tag; \
using difference_type = size_t;

use a given Lumiera Forward Iterator in standard "range for loops"

Definition at line 133 of file iter-adapter.hpp.

Referenced by ConstIter< IT >::getBase(), RangeIter< StlIter >::getPos(), NumIter< INT >::getPos(), and IterSnapshot< VAL >::IterSnapshot().

◆ LIFT_PARENT_INCREMENT_OPERATOR

#define LIFT_PARENT_INCREMENT_OPERATOR (   _BASECLASS_)
Value:
auto& \
operator++() \
{ \
_BASECLASS_::operator++(); \
return *this; \
}

define increment operator forwarding to baseclass but returning current

Definition at line 141 of file iter-adapter.hpp.


Class Documentation

◆ lib::IterType

struct lib::IterType
+ Inheritance diagram for IterType< TY >:
+ Collaboration diagram for IterType< TY >:

◆ lib::IterType< Iter< TY, CON > >

struct lib::IterType< Iter< TY, CON > >
Class Members
typedef CON Container
typedef TY ElemType
+ Collaboration diagram for IterType< Iter< TY, CON > >:

◆ lib::IterType< RangeIter< IT > >::SimilarIter

struct lib::IterType< RangeIter< IT > >::SimilarIter
Class Members
typedef IterType< IT >
::template SimilarIter< T2 >
::Type
WrappedIter
typedef RangeIter< WrappedIter > Type
+ Collaboration diagram for IterType< RangeIter< IT > >::SimilarIter< T2 >:

◆ lib::IterType< Iter< TY, CON > >::SimilarIter

struct lib::IterType< Iter< TY, CON > >::SimilarIter
Class Members
typedef Iter< T2, CON > Type
+ Collaboration diagram for IterType< Iter< TY, CON > >::SimilarIter< T2 >:

Function Documentation

◆ unConst()

OBJ * unConst ( const OBJ *  o)
inline

shortcut to save some typing when having to define const and non-const variants of member functions

Remarks
the »social contract« when using this function is that the programmer has to ensure effective const correctness!

Definition at line 358 of file util.hpp.

References util::unConst().

Referenced by util::unConst().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: