81 using LERR_(ITER_EXHAUST);
110 return util::unConst (checkPoint()? p : e);
116 if (not checkPoint())
return;
163 return 'A' + rand() % 26;
168 : lim_{len>=0? len : std::numeric_limits<size_t>::max()}
170 , letter_{rndLetter()}
182 return unConst(
this)->letter_;
188 ASSERT (checkPoint());
190 letter_ = rndLetter();
200 return util::join (std::forward<II> (ii),
"-");
211 if (++ii) cout <<
"-";
276 verify_wrappedState();
277 verify_wrappedIterator();
279 verify_expandOperation();
280 verify_expand_rootCurrent();
281 verify_transformOperation();
282 verify_elementGroupingOperation();
283 verify_aggregatingGroupItration();
284 verify_combinedExpandTransform();
285 verify_customProcessingLayer();
286 verify_scheduledExpansion();
287 verify_untilStopTrigger();
288 verify_FilterIterator();
289 verify_FilterChanges();
290 verify_asIterSource();
295 verify_depthFirstExploration();
296 demonstrate_LayeredEvaluation();
307 auto ii =
explore (CountDown{5,0});
333 vector<int> numz{1,-2,3,-5,8,-13};
334 auto ii = eachElm(numz);
400 verify_treeExpandingIterator(
402 .expand([](uint j){
return CountDown{j-1}; })
405 verify_treeExpandingIterator(
407 .expand([](uint j){
return NumberSequence{j-1}; })
411 vector<vector<uint>> childBuffer;
412 auto expandIntoChildBuffer = [&](uint j) -> vector<uint>&
414 childBuffer.emplace_back();
415 vector<uint>& childNumbz = childBuffer.back();
416 for (
size_t i=0; i<j-1; ++i)
417 childNumbz.push_back(j-1 - i);
421 verify_treeExpandingIterator(
423 .expand(expandIntoChildBuffer)
427 CHECK (5 == childBuffer.size());
433 verify_treeExpandingIterator(
435 .expand([](CountDown
const& core){
return CountDown{ core.yield() - 1}; })
438 verify_treeExpandingIterator(
440 .expand([](CountDown core){
return NumberSequence{ core.yield() - 1}; })
443 verify_treeExpandingIterator(
445 .expand([](
auto & it){
return CountDown{ *it - 1}; })
448 verify_treeExpandingIterator(
450 .expand([](
auto it){
return decltype(it){ *it - 1}; })
457 verify_treeExpandingIterator (EXP ii)
464 CHECK (0 == ii.depth());
467 CHECK (1 == ii.depth());
470 CHECK (1 == ii.depth());
473 CHECK (2 == ii.depth());
476 CHECK (1 == ii.depth());
479 CHECK (0 == ii.depth());
482 CHECK (1 == ii.depth());
485 CHECK (0 == ii.depth());
488 CHECK (1 == ii.depth());
491 CHECK (0 == ii.depth());
511 auto tree =
explore(CountDown{25})
512 .expand([](uint j){
return CountDown{j-1}; });
514 CHECK (
materialise(tree) ==
"25-24-23-22-21-20-19-18-17-16-15-14-13-12-11-10-9-8-7-6-5-4-3-2-1");
516 CHECK (0 == tree.depth());
523 tree.expandChildren();
524 CHECK (1 == tree.depth());
531 tree.expandChildren();
534 CHECK (2 == tree.depth());
535 CHECK (
materialise(tree) ==
"12-11-10-9-8-7-6-5-4-3-2-1-" 536 "14-13-12-11-10-9-8-7-6-5-4-3-2-1-" 537 "20-19-18-17-16-15-14-13-12-11-10-9-8-7-6-5-4-3-2-1");
542 CHECK (
materialise(tree) ==
"12-11-10-9-8-7-6-5-4-3-2-1");
543 CHECK (0 == tree.depth());
566 auto multiply = [](
int v){
return 2*v; };
568 _Fmt embrace{
"≺%s≻"};
569 auto formatify = [&](
auto it){
return string{embrace % *it}; };
572 auto ii =
explore(CountDown{7,4})
590 vector<int64_t> numz{1,-2,3,-5,8,-13};
593 .transform(formatify)) );
597 .transform(formatify)) );
602 .transform(formatify)
603 .transform(formatify)) );
609 auto jj =
explore (CountDown{4})
610 .transform([&](
int v)
617 CHECK (fact == -2*3);
623 CHECK (fact == -2*3);
624 CHECK (-2*3*3 == *jj);
625 CHECK (fact == 2*2*3);
626 CHECK (-2*3*3 == *jj);
627 CHECK (-2*3*3 == *jj);
628 CHECK (fact == 2*2*3);
631 CHECK (2*2*3*2 == *jj);
632 CHECK (fact == -2*2*2*3);
635 CHECK (2*2*3*2 == *jj);
639 CHECK (-23*1 == *jj);
640 CHECK (fact == 2*23);
644 CHECK (fact == 2*23);
647 CHECK (fact == 2*23);
653 auto kk =
explore (CountDown{9,4})
654 .transform([](CountDown& core)
656 uint delta = core.p - core.e;
686 auto showGroup = [](
auto it){
return "["+util::join(*it)+
"]"; };
690 .transform(showGroup)
692 ==
"[10, 9, 8]-[7, 6, 5]-[4, 3, 2]"_expect);
695 auto ii =
explore(CountDown{23})
698 CHECK(ii.getGroupedElms());
699 CHECK(not ii.getRestElms());
700 CHECK (
materialise(ii.getGroupedElms()) ==
"23-22-21-20-19"_expect);
702 CHECK ( test::showType<decltype(*ii)>()==
"array<unsigned int, 5ul>&"_expect);
704 uint s = *(ii.getGroupedElms());
708 CHECK (5 == grp.size());
709 auto& [a,b,c,d,e] = grp;
715 CHECK (not ii.getRestElms());
722 CHECK(ii.getGroupedElms());
723 CHECK(ii.getRestElms());
724 CHECK (
materialise(ii.getGroupedElms()) ==
"3-2-1"_expect);
725 CHECK (
materialise(ii.getRestElms()) ==
"3-2-1"_expect);
728 auto iii =
explore(CountDown{4})
731 CHECK (
materialise(iii.getRestElms()) ==
"4-3-2-1"_expect);
749 .groupedBy(std::ilogbf)
751 ==
"27-22-5-1"_expect);
755 .transform(util::toString<uint>)
756 .groupedBy([](
auto& it) {
return std::ilogbf (it.p); })
758 ==
"1098-7654-32-1"_expect);
761 auto showGroup = [](
auto it){
return "["+util::join(*it)+
"]"; };
765 .groupedBy(std::ilogbf
766 ,[](vector<uint>& accum, uint val)
768 accum.push_back (val);
770 .transform(showGroup)
772 ==
"[10, 9, 8]-[7, 6, 5, 4]-[3, 2]-[1]"_expect);
801 auto ii =
explore(CountDown{5})
802 .expand([](uint j){
return CountDown{j-1}; })
803 .transform([](
int v){
return 2*v; })
806 CHECK (
"int" == meta::typeStr(*ii));
819 .expand([](uint j){
return CountDown{j-1}; })
820 .transform([](
int v){
return 2*v; })
821 .transform([](
auto& it)
831 .transform([](
float f){
return 0.055 + f/2; })
833 ==
"5.055-4.055-20.055-1.055-2.055-1.055" );
867 .processingLayer<MagicTestRubbish>()
873 .transform([](uint v){
return 2*v; })
874 .processingLayer<MagicTestRubbish>()
875 .
filter([](
int v){
return v % 3; })
894 auto ii =
explore(CountDown{6})
895 .expand([](uint j){
return CountDown{j-2}; })
896 .expandOnIteration();
902 CHECK (ii.depth() == 0);
906 CHECK (ii.depth() == 0);
909 CHECK (ii.depth() == 1);
913 CHECK (ii.depth() == 1);
917 CHECK (ii.depth() == 2);
920 CHECK (ii.depth() == 1);
925 CHECK (ii.depth() == 1);
928 CHECK (ii.depth() == 0);
952 .iterUntil([](uint j){
return j < 5; })
954 ==
"10-9-8-7-6-5"_expect);
958 .iterWhile([](uint j){
return j > 5; })
960 ==
"10-9-8-7-6"_expect);
964 .iterWhile([](
int j){
return j > -5; })
966 ==
"10-9-8-7-6-5-4-3-2-1"_expect);
970 .iterWhile([](uint j){
return j > 25; })
989 .
filter([](uint j){
return j % 2; })
991 ==
"9-7-5-3-1"_expect);
995 auto ii =
explore(CountDown{10})
996 .
filter([](
int j){
return j > 9; });
998 CHECK (not isnil (ii));
1006 auto jj =
explore(CountDown{5})
1007 .
filter([](
int j){
return j > 9; });
1020 .transform([](
float f){
return 0.55 + 2*f; })
1021 .
filter([](CountDown& core){
return core.p % 2; })
1023 ==
"18.55-14.55-10.55"_expect);
1031 .expand([](uint i){
return CountDown{i%4==0? i-1 : 0}; })
1032 .
filter([](uint i){
return i%2 == 0; })
1035 ==
"10-8-6-4-2-2-6-4-2-2"_expect);
1044 bool toggle =
false;
1045 auto kk =
explore(CountDown{10,5})
1046 .expand([](uint j){
return CountDown{j-1}; })
1047 .transform([](
int v){
return 2*v; })
1052 it.expandChildren();
1059 ==
"14-12-10-8-6-4-2-14-12"_expect);
1070 CHECK (
materialise(kk.filter([](
long i){ return i % 7; }))
1071 ==
"12-10-8-6-4-2-12"_expect);
1095 auto seq =
explore(CountDown{20})
1098 auto takeEve = [](uint i){
return i%2 == 0; };
1099 auto takeTrd = [](uint i){
return i%3 == 0; };
1106 seq.andFilter (takeEve);
1111 seq.andFilter (takeTrd);
1119 seq.setNewFilter (takeTrd);
1124 seq.orNotFilter (takeEve);
1136 seq.andNotFilter ([&](CountDown& core)
1138 buff += util::toString(core.p) +
".";
1144 CHECK (
".3." == buff);
1147 CHECK (
".3.1." == buff);
1149 CHECK (isnil (seq));
1155 .mutableFilter(takeTrd);
1158 seq.disableFilter();
1162 seq.andNotFilter (takeEve);
1166 seq.disableFilter();
1173 CHECK (isnil (seq));
1184 auto accumulated =
explore(CountDown{30})
1185 .transform([](
int i){
return i-1; })
1188 using Res = decltype(accumulated);
1189 CHECK (lib::test::showType<Res>() ==
"int"_expect);
1191 auto expectedSum = [](
auto N){
return N*(N+1) / 2; };
1192 CHECK (accumulated == expectedSum(29));
1196 .
reduce([](
int i){
return i - 0.5; }
1197 ,[](
string accu,
float val)
1199 return accu+
">"+util::toString(val);
1203 ==
">->9.5>8.5>7.5>6.5>5.5>4.5>3.5>2.5>1.5>0.5"_expect);
1207 .
reduce([](
auto it) ->
string 1209 return _Fmt{
"○%s●"} % *it;
1211 ==
"○9●○8●○7●○6●○5●○4●○3●○2●○1●"_expect);
1215 .
reduce(iter_explorer::IDENTITY, std::minus<int>(), expectedSum(9))
1226 auto solidified =
explore(CountDown{20})
1227 .
filter ([](uint i){
return i % 2; })
1228 .transform([](uint i){
return 0.5*i; })
1231 using Res = decltype(solidified);
1232 CHECK (lib::test::showType<Res>() ==
"vector<double>"_expect);
1233 CHECK (util::join(solidified,
"|") ==
"9.5|8.5|7.5|6.5|5.5|4.5|3.5|2.5|1.5|0.5"_expect);
1264 CHECK (isnil (sequence));
1266 sequence =
explore(CountDown{20,10})
1267 .
filter([](uint i){
return i % 2; })
1270 CHECK (not isnil (sequence));
1271 CHECK (19 == *sequence);
1276 .transform([](uint i){
return i*2; })
1279 CHECK (38 == *sequence);
1280 CHECK (
"38-34-30-26-22" ==
materialise(sequence));
1286 CHECK (22 == *sequence);
1288 CHECK (isnil (sequence));
1293 CHECK (isnil (exploreIter));
1295 exploreIter =
explore(CountDown{20,10})
1296 .
filter([](uint i){
return i % 2; })
1297 .transform([](uint i){
return i*2; })
1298 .
filter([](
int i){
return i>25; })
1299 .expand([](uint i){
return CountDown{i-10, 20}; })
1300 .transform([](uint u) ->
char {
return '@'+u-20; })
1304 CHECK (
'R' == *exploreIter);
1306 CHECK (
'N' == *exploreIter);
1308 exploreIter.expandChildren();
1310 CHECK (
'D' == *exploreIter);
1312 CHECK (
"D-C-B-A-J-F" ==
materialise(exploreIter));
1336 virtual PrivateSource* expandChildren()
const =0;
1339 class VerySpecificIter
1344 VerySpecificIter(uint start)
1348 virtual PrivateSource*
1349 expandChildren()
const override 1351 return new VerySpecificIter{*wrappedIter() - 2};
1357 return *wrappedIter();
1365 explore (
new VerySpecificIter{7})));
1369 PrivateSource* niente =
nullptr;
1370 CHECK (isnil (
explore (niente)));
1374 VerySpecificIter vsit{5};
1380 .expand ([](PrivateSource& source){
return source.expandChildren(); });
1382 CHECK (not isnil (ii));
1384 CHECK (5 == vsit.currentVal());
1387 CHECK (4 == vsit.currentVal());
1389 CHECK (0 == ii.depth());
1390 ii.expandChildren();
1391 CHECK (1 == ii.depth());
1397 CHECK (4 == vsit.currentVal());
1398 CHECK (1 == ii.depth());
1400 CHECK (0 == ii.depth());
1402 CHECK (3 == vsit.currentVal());
1405 CHECK (2 == vsit.currentVal());
1408 CHECK (1 == vsit.currentVal());
1437 .expand([](uint j){
return CountDown{j-1}; })
1439 .transform([](
int i){
return i*10; })
1441 ==
"40-30-20-10-10-20-10-10-30-20-10-10-20-10-10");
1445 using Tu2 = std::tuple<uint, uint>;
1446 auto summingExpander = [](Tu2
const& tup)
1448 uint val = get<0>(tup);
1449 uint sum = get<1>(tup);
1456 .transform([](uint i){
return Tu2{i,0}; })
1457 .expand(summingExpander)
1459 .transform([](Tu2 res){
return get<1>(res); })
1461 ==
"0-4-7-9-10-0-3-5-6-0-2-3-0-1");
1494 DataSrc searchSpace =
explore(RandomSeq{-1})
1495 .expand([](
char){
return RandomSeq{15}; })
1505 State(DataSrc& s,
string& t)
1520 return *unConst(
this);
1527 protocol.resize (1+src.depth());
1534 src.expandChildren();
1535 protocol.resize (1+src.depth());
1541 ASSERT (src.depth() < toFind.size());
1542 return *src == toFind[src.depth()];
1548 string toFind = util::join (
explore (RandomSeq{5}),
"");
1549 cout <<
"Search in random tree: toFind = "<<toFind<<endl;
1551 auto theSearch =
explore (State{searchSpace, toFind})
1554 while (it->src.depth() < it->toFind.size() - 1
1556 it->expandChildren();
1558 return it->isMatch();
1563 CHECK (not isnil(theSearch));
1564 cout <<
"Protocol of the search: " <<
materialise(theSearch->protocol) <<endl;
void verify_asIterSource()
This iteration _"state core" type_ describes a descending sequence of numbers yet to be delivered...
string materialise(II &&ii)
Diagnostic helper: join all the elements from a copy of the iterator.
void verify_customProcessingLayer()
void verify_FilterChanges()
auto explore(IT &&srcSeq)
start building a IterExplorer by suitably wrapping the given iterable source.
void demonstrate_LayeredEvaluation()
void verify_scheduledExpansion()
void verify_expand_rootCurrent()
void verify_untilStopTrigger()
void verify_expandOperation()
bool filter(Placement< DummyMO > const &candidate)
a filter predicate to pick some objects from a resultset.
void verify_depthFirstExploration()
void verify_wrappedIterator()
void verify_transformOperation()
demo of a custom processing layer interacting directly with the iteration mechanism.
ostringstream protocol
used to verify the test function calls
bool operator==(PtrDerefIter< I1 > const &il, PtrDerefIter< I2 > const &ir)
Supporting equality comparisons...
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT)
Macro to verify that a statement indeed raises an exception.
A straight descending number sequence as basic test iterator.
void verify_combinedExpandTransform()
void verify_elementGroupingOperation()
Iterator front-end to manage and operate a IterExplorer pipeline opaquely.
A front-end for using printf-style formatting.
Implementation namespace for support and library code.
void verify_wrappedState()
Iteration source interface to abstract a data source, which then can be accessed through IterAdapter ...
Simple test class runner.
Another Lumiera Forward Iterator building block, based on incorporating a state type right into the i...
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
A collection of frequently used helper functions to support unit testing.
_SeqT< CON >::Range eachElm(CON &coll)
auto singleValIterator(VAL &&something)
Build a SingleValIter: convenience free function shortcut, to pick up just any value and wrap it as L...
Helpers for type detection, type rewriting and metaprogramming.
void pullOut(II &ii)
Diagnostic helper: "squeeze out" the given iterator until exhaustion.
Pseudo-Iterator to yield just a single value.
Building tree expanding and backtracking evaluations within hierarchical scopes.
Preconfigured adapters for some STL container standard usage situations.
Standard implementation of the IterSource interface: a wrapped "Lumiera Forward Iterator".
void verify_aggregatingGroupItration()
Another iteration _"state core"_ to produce a sequence of random numbers.
void verify_FilterIterator()
bool isSameObject(A const &a, B const &b)
compare plain object identity, bypassing any custom comparison operators.