97#ifndef LIB_ITER_EXPLORER_H
98#define LIB_ITER_EXPLORER_H
119 template<
typename T,
class A>
class vector;
120 template<
typename K,
typename CMP,
class A>
class set;
133 namespace iter_explorer {
191 :
public ISO::iterator
201 :
Iterator{ISO::build (externalSource)}
206 :
Iterator{heapObject? ISO::build (heapObject)
215 REQUIRE (ISO::iterator::isValid());
216 return static_cast<ISO&
> (*ISO::iterator::source());
234 using std::is_const_v;
235 using std::is_base_of;
236 using std::common_type;
237 using std::common_type_t;
238 using std::conditional_t;
239 using std::is_convertible;
240 using std::remove_reference_t;
250 : __and_<can_STL_ForEach<SRC>
251 ,__not_<can_IterForEach<SRC>>
257 : __and_<can_IterForEach<SRC>
258 ,__not_<is_StateCore<SRC>>
267 template<
class SRC,
typename SEL=
void>
270 static_assert (!
sizeof(SRC),
"Can not build IterExplorer: Unable to figure out how to iterate the given SRC type.");
291 static_assert (not std::is_rvalue_reference<SRC>::value,
292 "container needs to exist elsewhere during the lifetime of the iteration");
298 struct _DecoratorTraits<ISO*, enable_if<is_base_of<IterSource<typename ISO::value_type>, ISO>>>
305 struct _DecoratorTraits<ISO*&, enable_if<is_base_of<IterSource<typename ISO::value_type>, ISO>>>
310 struct _DecoratorTraits<ISO&, enable_if<is_base_of<IterSource<typename ISO::value_type>, ISO>>>
324 template<
class SRC,
class RES>
331 static constexpr bool can_reconcile = _CommonT::value;
332 static constexpr bool isRefResult = _CommonT::isRef;
334 static_assert (can_reconcile,
335 "source iterator and result from the expansion must yield compatible values");
336 static_assert (is_const_v<SrcYield> == is_const_v<ResYield>,
337 "source and expanded types differ in const-ness");
351 namespace iter_explorer {
354 constexpr auto IDENTITY = [](
auto it){
return *it;};
385 template<
class FUN,
typename SRC>
389 template<
typename F,
typename SEL =
void>
399 using Arg = std::add_lvalue_reference<SRC>::type;
400 using Ret =
decltype(std::declval<F>() (std::declval<Arg>()));
413 template<
class ARG,
class SEL =
void>
417 static_assert (std::is_convertible<ARG, FunArgType>::value,
418 "the bound functor must accept the source iterator or state core as parameter");
420 static decltype(
auto)
423 return forward<FUN> (rawFunctor);
430 ,__not_<is_convertible<IT, Arg>>>>>
435 return [rawFun](IT& srcIter) ->
Res {
return rawFun(*srcIter); };
442 , is_base_of<IterSource<typename IT::value_type>, remove_reference_t<Arg>>
450 return [rawFun](IT&
iter) ->
Res {
return rawFun(
iter.source()); };
465 template<
typename FUN,
typename SRC>
470 static_assert(std::is_constructible<bool, Res>::value,
"Functor must be a predicate");
477 template<
class SRC,
class FUN>
553 template<
class SRC,
class RES>
557 static_assert(can_IterForEach<SRC>::value,
"Lumiera Iterator required as source");
573 template<
typename FUN>
574 Expander (SRC&& parentExplorer, FUN&& expandFunctor)
575 : SRC{move (parentExplorer)}
587 REQUIRE (this->
checkPoint(),
"attempt to expand an empty explorer");
592 if (not isnil(expanded))
712 static_assert(is_StateCore<SRC>::value,
"need wrapped state core as predecessor in pipeline");
721 SRC::__throw_if_empty();
722 SRC::expandChildren();
735 static_assert(is_StateCore<SRC>::value,
"need wrapped state core as predecessor in pipeline");
754 SRC::__throw_if_empty();
755 SRC::expandChildren();
781 template<
class SRC,
class RES>
785 static_assert(can_IterForEach<SRC>::value,
"Lumiera Iterator required as source");
799 template<
typename FUN>
801 : SRC{move (dataSrc)}
802 ,
trafo_{
_FunTraits<FUN,SRC>::adaptFunctor (forward<FUN> (transformFunctor))}
819 swap (*
this,changed);
841 SRC::expandChildren();
855 return unConst(
this)->invokeTransformation();
869 return unConst(*
this);
891 template<
class SRC,
class RES, u
int grp>
895 static_assert(can_IterForEach<SRC>::value,
"Lumiera Iterator required as source");
920 : SRC{move (dataSrc)}
956 SRC::expandChildren();
971 return unConst(
buff_).group();
985 return unConst(*
this);
1024 template<
class SRC,
typename AGG,
class GRP>
1028 static_assert(can_IterForEach<SRC>::value,
"Lumiera Iterator required as source");
1048 template<
class FGRP,
class FAGG>
1050 : SRC{move (dataSrc)}
1068 return *unConst(
this)->agg_;
1077 agg_ = std::nullopt;
1085 return unConst(*
this);
1117 static_assert(can_IterForEach<SRC>::value,
"Lumiera Iterator required as source");
1129 template<
typename FUN>
1131 : SRC{move (dataSrc)}
1143 SRC::expandChildren();
1173 return unConst(*
this);
1218 static_assert(can_IterForEach<SRC>::value,
"Lumiera Iterator required as source");
1224 template<
typename FUN>
1226 :
_Filter{move (dataSrc), forward<FUN> (filterFun)}
1233 template<
typename COND>
1238 ,[](
auto first,
auto chain)
1240 return [=](
auto& val)
1249 template<
typename COND>
1254 ,[](
auto first,
auto chain)
1256 return [=](
auto& val)
1265 template<
typename COND>
1270 ,[](
auto first,
auto chain)
1272 return [=](
auto& val)
1281 template<
typename COND>
1286 ,[](
auto first,
auto chain)
1288 return [=](
auto& val)
1300 auto dummy = [](
auto){
return false; };
1302 ,[](
auto currentFilter,
auto)
1304 return [=](
auto& val)
1306 return not currentFilter(val);
1312 template<
typename COND>
1317 ,[](
auto,
auto chain)
1319 return [=](
auto& val)
1330 _Filter::predicate_ =
nullptr;
1350 template<
typename COND,
class COMB>
1354 static_assert_isPredicate<COND,SRC>();
1356 if (_Filter::isDisabled())
1359 _Filter::predicate_ = buildCombinedClause (_Filter::predicate_
1362 _Filter::pullFilter();
1382 static_assert(can_IterForEach<SRC>::value,
"Lumiera Iterator required as source");
1394 template<
typename FUN>
1396 :
Core{move (dataSrc)}
1425 template<
typename VAL>
1453 using Parent::Parent;
1493 template<
typename VAL>
1526 new iter_explorer::PackagedIterExplorerSource<IT> {
1527 move (opaqueSrcPipeline)})}
1533 if (not this->source())
1534 throw error::State (
"operating on a disabled default constructed IterExplorer"
1535 ,error::LUMIERA_ERROR_BOTTOM_VALUE);
1537 auto source = unConst(
this)->source().get();
1582 static_assert(can_IterForEach<SRC>::value,
"Lumiera Iterator required as source");
1646 using ResIter = _DecoratorTraits<ResCore>::SrcIter;
1667 using ResIter = _DecoratorTraits<ResCore>::SrcIter;
1677 return this->expand (forward<FUN> (expandFunctor))
1695 using ResIter = _DecoratorTraits<ResCore>::SrcIter;
1718 using ResIter = _DecoratorTraits<ResCore>::SrcIter;
1738 using ResIter = _DecoratorTraits<ResCore>::SrcIter;
1755 template<
class FGRP,
class FAGG>
1766 using ResIter = _DecoratorTraits<ResCore>::SrcIter;
1769 ,forward<FGRP> (groupFun)
1770 ,forward<FAGG> (aggFun)});
1774 template<
class FGRP>
1779 return groupedBy (forward<FGRP> (groupFun)
1780 ,[](Value& agg, Value
const& val){ agg += val; }
1792 iter_explorer::static_assert_isPredicate<FUN,SRC>();
1795 using ResIter = _DecoratorTraits<ResCore>::SrcIter;
1808 iter_explorer::static_assert_isPredicate<FUN,SRC>();
1811 using ResIter = _DecoratorTraits<ResCore>::SrcIter;
1815 ,[whileCond = forward<FUN>(untilCond)](ArgType val)
1817 return not whileCond(val);
1833 iter_explorer::static_assert_isPredicate<FUN,SRC>();
1836 using ResIter = _DecoratorTraits<ResCore>::SrcIter;
1863 iter_explorer::static_assert_isPredicate<FUN,SRC>();
1866 using ResIter = _DecoratorTraits<ResCore>::SrcIter;
1875 return mutableFilter (iter_explorer::ACCEPT_ALL);
1891 template<
template<
class>
class LAY>
1895 using ResCore = LAY<SRC>;
1896 using ResIter = _DecoratorTraits<ResCore>::SrcIter;
1908 static_assert (not std::is_pointer_v<Val>);
1909 return IterExplorer::transform ([](Val& ref){
return &ref; });
1917 return IterExplorer::transform ([](Ptr ptr){
return *ptr; });
1924 template<
template<
typename>
class SET =std::set>
1930 using ResIter = _DecoratorTraits<ResCore>::SrcIter;
1932 for (
auto& val : *
this)
1933 buffer.emplace (val);
1961 return SRC {move(*
this)};
1970 foreach (FUN&& consumer)
1973 SRC& pipeline = *
this;
1974 for ( ; pipeline; ++pipeline)
1975 consumeFun (pipeline);
1989 ,
typename COMB =
decltype(std::plus<>())
1992 reduce (FUN&& accessor
1993 ,COMB junctor =COMB()
1994 ,VAL seedVal =VAL())
1998 VAL sum{move(seedVal)};
1999 IterExplorer::foreach ([&](SRC& srcIter){ sum = junctor (sum, accessVal(srcIter)); });
2007 return IterExplorer::reduce ([](
const reference val){
return val; });
2014 return IterExplorer::reduce ([](
auto){
return size_t(1); });
2021 static_assert (std::is_constructible<bool,value_type>());
2022 SRC& pipeline = *
this;
2023 for ( ; pipeline; ++pipeline)
2033 static_assert (std::is_constructible<bool,value_type>());
2034 SRC& pipeline = *
this;
2035 for ( ; pipeline; ++pipeline)
2047 template<
template<
typename>
class CON =std::vector>
2051 CON<value_type> con{};
2060 CON con{move(sink)};
2070 for (
auto& val : *
this)
2071 con.push_back (val);
2086 template<
class SRC,
class SEL =
void>
2100 template<
class SRC,
class SEL =
void>
2118 template<
class SRC,
class SEL =
void>
2191 using RawIter = _PipelineDetector<IT>::RawIter;
2192 using SrcIter = _DecoratorTraits<RawIter>::SrcIter;
2193 using Base = _BaseDetector<SrcIter>::BaseAdapter;
Adapter to »piggy-back« a STL iterable container inline and expose it as »state core«.
void resetPos(Pos otherPos)
Adapter to build a demand-driven tree expanding and exploring computation based on a custom opaque st...
auto mutableFilter(FUN &&filterPredicate)
attach a special filter adapter, allowing to change the filter predicate while iterating.
auto expandAll(FUN &&expandFunctor)
shortcut notation to invoke expand(expandFunctor) followed by expandAll()
auto derefPtr()
preconfigured transformer to dereference pointers into references
void effuse(CON &con)
_terminal builder to fill an existing container with all results from this Pipeline
auto iterWhile(FUN &&whileCond)
adapt this IterExplorer to iterate only as long as a condition holds true.
auto expand(FUN &&expandFunctor)
preconfigure this IterExplorer to allow for »expansion of children«.
auto expandOnIteration()
extension functionality to be used on top of expand(), to perform expansion on next iteration.
auto groupedBy(FGRP &&groupFun, FAGG &&aggFun)
adapt this IterExplorer to group elements by a custom criterium and aggregate the group members.
meta::ValueTypeBinding< SRC >::pointer pointer
auto grouped()
adapt this IterExplorer to group result elements into fixed size chunks, packaged as std::array.
auto effuse(CON &&sink) -> CON
auto resultSum()
simplified terminal builder to reduce by numeric sum.
bool and_all()
simplified terminal builder to check if all results yields true (short-circuit)
auto processingLayer()
builder function to attach a custom extension layer.
meta::ValueTypeBinding< SRC >::value_type value_type
auto transform(FUN &&transformFunctor)
adapt this IterExplorer to pipe each result value through a transformation function.
auto deduplicate()
preconfigured decorator to materialise, sort and deduplicate all source elements.
auto iterUntil(FUN &&untilCond)
adapt this IterExplorer to iterate until a condition becomes first true.
IterExploreSource< value_type > asIterSource()
terminal builder to package the processing pipeline as IterSource.
SRC asIterator()
terminal builder to strip the IterExplorer and expose the built Pipeline.
auto asPtr()
preconfigured transformer to pass pointers down the pipeline
auto filter(FUN &&filterPredicate)
adapt this IterExplorer to filter results, by invoking the given functor to approve them.
auto groupedBy(FGRP &&groupFun)
simplified grouping to sum / combine all values in a group
auto expandAll()
extension functionality to be used on top of expand(), to perform expansion automatically.
size_t count()
simplified terminal builder to count number of elements from this sequence.
bool has_any()
simplified terminal builder to check if any result yields true (short-circuit)
meta::ValueTypeBinding< SRC >::reference reference
auto effuse()
terminal builder to pour and materialise all results from this Pipeline.
Iteration source interface to abstract a data source, which then can be accessed through IterAdapter ...
Adapter to dress up an existing »Lumiera Forward Iterator« as »state core«.
Decorator-Adapter to make a »*State Core*« iterable as Lumiera Forward Iterator.
Accessing a STL element range through a Lumiera forward iterator, An instance of this iterator adapte...
std::remove_reference< reference >::type value_type
Block of raw uninitialised storage with array like access.
Standard implementation of the IterSource interface: a wrapped "Lumiera Forward Iterator".
Interface to indicate and expose the ability for child expansion.
virtual size_t depth() const =0
virtual VAL * expandChildren()=0
void rootCurrent()
lock into the current child sequence.
void expandChildren()
core operation: expand current head element
RootExpandFunctor expandRoot_
void dropExhaustedChildren()
IterStack< ResIter > expansions_
ResIter & accessCurrentChildIter()
size_t depth() const
diagnostics: current level of nested child expansion
_Trait::YieldRes YieldRes
function< RES(SRC &)> RootExpandFunctor
_Trait::value_type value_type
_ExpanderTraits< SRC, RES > _Trait
ChldExpandFunctor expandChild_
function< RES(ResIter &)> ChldExpandFunctor
Expander(SRC &&parentExplorer, FUN &&expandFunctor)
_Trait::reference reference
void expandChildren()
refresh state when other layers manipulate the source sequence.
SRC::reference yield() const
Filter(SRC &&dataSrc, FUN &&filterFun)
function< bool(SRC &)> FilterPredicate
FilterPredicate predicate_
meta::ValueTypeBinding< SRC >::value_type SrcValue
GroupAggregator()=default
function< GRP(SRC &)> Grouping
GroupAggregator(SRC &&dataSrc, FGRP &&groupFun, FAGG &&aggFun)
meta::RefTraits< AGG >::Reference reference
function< void(AGG &, SrcValue &)> Aggregator
meta::RefTraits< AGG >::Value value_type
meta::RefTraits< AGG >::Pointer pointer
std::optional< AGG > agg_
void expandChildren()
refresh state when other layers manipulate the source sequence.
auto getRestElms()
Retrieve the tail elements produced by the source, which did not suffice to fill a full group.
std::array< RES, grp > Group
auto getGroupedElms()
Iterate over the Elements in the current group.
Adapt an IterSource to make it iterable.
IterSourceIter(ISO *heapObject)
own and manage a heap allocated IterSource
IterSourceIter(ISO &externalSource)
link to existing IterSource (without memory management)
void setNewFilter(COND &&entirelyDifferentPredicate)
replace the existing predicate with the given, entirely different predicate
void andFilter(COND &&conjunctiveClause)
remould existing predicate to require in addition the given clause to hold
void andNotFilter(COND &&conjunctiveClause)
remould existing predicate to require in addition the negation of the given clause to hold
void remouldFilter(COND &&additionalClause, COMB buildCombinedClause)
void orNotFilter(COND &&disjunctiveClause)
remould existing predicate to require either the old OR the negation of a new clause to hold
void orFilter(COND &&disjunctiveClause)
remould existing predicate to require either the old OR the given new clause to hold
void flipFilter()
remould existing predicate to negate the meaning of the existing clause
void disableFilter()
discard filter predicates and disable any filtering
MutableFilter(SRC &&dataSrc, FUN &&filterFun)
~PackagedIterExplorerSource()
virtual Val * expandChildren() override
virtual size_t depth() const override
function< bool(SRC &)> Cond
StopTrigger(SRC &&dataSrc, FUN &&condition)
bool checkPoint() const
adapt the iteration control API for IterableDecorator: check the stop condition first and block event...
Metaprogramming helpers to check for specific properties of a type in question.
Lumiera error handling (C++ interface).
Metaprogramming tools for detecting and transforming function types.
Adapter to store and hold an element of arbitrary type in local storage.
Helper template(s) for creating Lumiera Forward Iterators.
Extension module to build an opaque data source, accessible as Lumiera Forward Iterator.
Conveniently iterable stack and queue containers.
SrcIter::value_type SrcVal
_UnstripAdapter< _SrcIT >::RawIter RawIter
SRC::TAG_IterExplorer_Src _SrcIT
meta::RefTraits< iter::CoreYield< SrcRaw > >::Value SrcVal
COR::TAG_CheckedCore_Raw RawIter
lib::meta::Strip< SRC >::Type SrcRaw
remove_reference_t< SRC > SrcIter
Detect or otherwise add BaseAdapter.
Detect if given source was already built by IterExplorer;.
Detect and remove typical adapter layers added by a preceding IterExplorer usage.
void static_assert_isPredicate()
lib::meta::RefTraits< Result >::Value ResVal
meta::Strip< CON >::TypeReferred::iterator iterator
meta::Strip< CON >::TypeReferred::const_iterator const_iterator
iter_explorer::_FunTraits< FUN, SRC >::Res Result
constexpr auto ACCEPT_ALL
Implementation namespace for support and library code.
auto explore(IT &&srcSeq)
start building a IterExplorer by suitably wrapping the given iterable source.
LumieraError< LERR_(STATE)> State
bool isnil(lib::time::Duration const &dur)
Iterator front-end to manage and operate a IterExplorer pipeline opaquely.
Expandable & expandableSource() const
IterExploreSource()=default
IterExploreSource(IT &&opaqueSrcPipeline)
A Stack which can be popped by iterating.
IterStack & push(TY const &elm)
helper to derive a suitable common type when expanding children
_CommonT::ResType YieldRes
iter::Yield< ResIter > ResYield
_CommonT::value_type value_type
meta::CommonResultYield< SrcYield, ResYield > _CommonT
_CommonT::reference reference
_CommonT::pointer pointer
iter::Yield< SRC > SrcYield
_DecoratorTraits< RES >::SrcIter ResIter
void expandChildren()
collaboration: recurse into nested scope
size_t depth() const
collaboration: number of nested scopes
BaseAdapter(SRC const &src)
SRC TAG_IterExplorer_BaseAdapter
StlRange(CON const &container)
Adapt STL compliant container.
static auto wrap(function< Sig > rawFun)
static auto wrap(function< Sig > rawFun)
adapt to a functor, which accesses the source iterator or embedded "state core"
remove_reference_t< Arg > FunArgType
static decltype(auto) wrap(FUN &&rawFunctor)
decltype(std::declval< F >()(std::declval< Arg >())) Ret
std::add_lvalue_reference< SRC >::type Arg
_Fun< Sig >::Args::List::Head Arg
static auto adaptFunctor(FUN &&rawFunctor)
builder to create a nested/wrapping functor, suitably adapting the arguments
FunDetector< FUN >::Sig Sig
handle all regular "function-like" entities
Helpers for type detection, type rewriting and metaprogramming.
A raw memory block with proper alignment and array access.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...