73 using LERR_(ITER_EXHAUST);
102 return util::unConst (checkPoint()? p : e);
108 if (not checkPoint())
return;
155 return 'A' +
rani(26);
160 : lim_{len>=0? len : std::numeric_limits<size_t>::max()}
162 , letter_{rndLetter()}
174 return unConst(
this)->letter_;
180 ASSERT (checkPoint());
182 letter_ = rndLetter();
192 return util::join (std::forward<II> (ii),
"-");
203 if (++ii) cout <<
"-";
270 verify_wrappedState();
271 verify_wrappedIterator();
273 verify_expandOperation();
274 verify_expand_rootCurrent();
275 verify_transformOperation();
276 verify_elementGroupingOperation();
277 verify_aggregatingGroupItration();
278 verify_combinedExpandTransform();
279 verify_customProcessingLayer();
280 verify_scheduledExpansion();
281 verify_untilStopTrigger();
282 verify_FilterIterator();
283 verify_FilterChanges();
284 verify_asIterSource();
290 verify_depthFirstExploration();
291 demonstrate_LayeredEvaluation();
302 auto ii =
explore (CountDown{5,0});
328 vector<int> numz{1,-2,3,-5,8,-13};
329 auto ii = eachElm(numz);
395 verify_treeExpandingIterator(
397 .expand([](uint j){
return CountDown{j-1}; })
400 verify_treeExpandingIterator(
402 .expand([](uint j){
return NumberSequence{j-1}; })
406 vector<vector<uint>> childBuffer;
407 auto expandIntoChildBuffer = [&](uint j) -> vector<uint>&
409 childBuffer.emplace_back();
410 vector<uint>& childNumbz = childBuffer.back();
411 for (
size_t i=0; i<j-1; ++i)
412 childNumbz.push_back(j-1 - i);
416 verify_treeExpandingIterator(
418 .expand(expandIntoChildBuffer)
422 CHECK (5 == childBuffer.size());
428 verify_treeExpandingIterator(
430 .expand([](CountDown
const& core){
return CountDown{ core.yield() - 1}; })
433 verify_treeExpandingIterator(
435 .expand([](CountDown core){
return NumberSequence{ core.yield() - 1}; })
438 verify_treeExpandingIterator(
440 .expand([](
auto & it){
return CountDown{ *it - 1}; })
443 verify_treeExpandingIterator(
445 .expand([](
auto it){
return decltype(it){ *it - 1}; })
452 verify_treeExpandingIterator (EXP ii)
459 CHECK (0 == ii.depth());
462 CHECK (1 == ii.depth());
465 CHECK (1 == ii.depth());
468 CHECK (2 == ii.depth());
471 CHECK (1 == ii.depth());
474 CHECK (0 == ii.depth());
477 CHECK (1 == ii.depth());
480 CHECK (0 == ii.depth());
483 CHECK (1 == ii.depth());
486 CHECK (0 == ii.depth());
506 auto tree =
explore(CountDown{25})
507 .expand([](uint j){
return CountDown{j-1}; });
509 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");
511 CHECK (0 == tree.depth());
518 tree.expandChildren();
519 CHECK (1 == tree.depth());
526 tree.expandChildren();
529 CHECK (2 == tree.depth());
530 CHECK (
materialise(tree) ==
"12-11-10-9-8-7-6-5-4-3-2-1-" 531 "14-13-12-11-10-9-8-7-6-5-4-3-2-1-" 532 "20-19-18-17-16-15-14-13-12-11-10-9-8-7-6-5-4-3-2-1");
537 CHECK (
materialise(tree) ==
"12-11-10-9-8-7-6-5-4-3-2-1");
538 CHECK (0 == tree.depth());
561 auto multiply = [](
int v){
return 2*v; };
563 _Fmt embrace{
"≺%s≻"};
564 auto formatify = [&](
auto it){
return string{embrace % *it}; };
567 auto ii =
explore(CountDown{7,4})
585 vector<int64_t> numz{1,-2,3,-5,8,-13};
588 .transform(formatify)) );
592 .transform(formatify)) );
597 .transform(formatify)
598 .transform(formatify)) );
604 auto jj =
explore (CountDown{4})
605 .transform([&](
int v)
612 CHECK (fact == -2*3);
618 CHECK (fact == -2*3);
619 CHECK (-2*3*3 == *jj);
620 CHECK (fact == 2*2*3);
621 CHECK (-2*3*3 == *jj);
622 CHECK (-2*3*3 == *jj);
623 CHECK (fact == 2*2*3);
626 CHECK (2*2*3*2 == *jj);
627 CHECK (fact == -2*2*2*3);
630 CHECK (2*2*3*2 == *jj);
634 CHECK (-23*1 == *jj);
635 CHECK (fact == 2*23);
639 CHECK (fact == 2*23);
642 CHECK (fact == 2*23);
648 auto kk =
explore (CountDown{9,4})
649 .transform([](CountDown& core)
651 uint delta = core.p - core.e;
681 auto showGroup = [](
auto it){
return "["+util::join(*it)+
"]"; };
685 .transform(showGroup)
687 ==
"[10, 9, 8]-[7, 6, 5]-[4, 3, 2]"_expect);
690 auto ii =
explore(CountDown{23})
693 CHECK(ii.getGroupedElms());
694 CHECK(not ii.getRestElms());
695 CHECK (
materialise(ii.getGroupedElms()) ==
"23-22-21-20-19"_expect);
697 CHECK ( test::showType<decltype(*ii)>()==
"array<uint, 5ul>&"_expect);
699 uint s = *(ii.getGroupedElms());
703 CHECK (5 == grp.size());
704 auto& [a,b,c,d,e] = grp;
710 CHECK (not ii.getRestElms());
717 CHECK(ii.getGroupedElms());
718 CHECK(ii.getRestElms());
719 CHECK (
materialise(ii.getGroupedElms()) ==
"3-2-1"_expect);
720 CHECK (
materialise(ii.getRestElms()) ==
"3-2-1"_expect);
723 auto iii =
explore(CountDown{4})
726 CHECK (
materialise(iii.getRestElms()) ==
"4-3-2-1"_expect);
744 .groupedBy(std::ilogbf)
746 ==
"27-22-5-1"_expect);
750 .transform(util::toString<uint>)
751 .groupedBy([](
auto& it) {
return std::ilogbf (it.p); })
753 ==
"1098-7654-32-1"_expect);
756 auto showGroup = [](
auto it){
return "["+util::join(*it)+
"]"; };
760 .groupedBy(std::ilogbf
761 ,[](vector<uint>& accum, uint val)
763 accum.push_back (val);
765 .transform(showGroup)
767 ==
"[10, 9, 8]-[7, 6, 5, 4]-[3, 2]-[1]"_expect);
796 auto ii =
explore(CountDown{5})
797 .expand([](uint j){
return CountDown{j-1}; })
798 .transform([](
int v){
return 2*v; })
801 CHECK (
"int" == meta::typeStr(*ii));
814 .expand([](uint j){
return CountDown{j-1}; })
815 .transform([](
int v){
return 2*v; })
816 .transform([](
auto& it)
826 .transform([](
float f){
return 0.055 + f/2; })
828 ==
"5.055-4.055-20.055-1.055-2.055-1.055" );
862 .processingLayer<MagicTestRubbish>()
868 .transform([](uint v){
return 2*v; })
869 .processingLayer<MagicTestRubbish>()
870 .
filter([](
int v){
return v % 3; })
889 auto ii =
explore(CountDown{6})
890 .expand([](uint j){
return CountDown{j-2}; })
891 .expandOnIteration();
897 CHECK (ii.depth() == 0);
901 CHECK (ii.depth() == 0);
904 CHECK (ii.depth() == 1);
908 CHECK (ii.depth() == 1);
912 CHECK (ii.depth() == 2);
915 CHECK (ii.depth() == 1);
920 CHECK (ii.depth() == 1);
923 CHECK (ii.depth() == 0);
947 .iterUntil([](uint j){
return j < 5; })
949 ==
"10-9-8-7-6-5"_expect);
953 .iterWhile([](uint j){
return j > 5; })
955 ==
"10-9-8-7-6"_expect);
959 .iterWhile([](
int j){
return j > -5; })
961 ==
"10-9-8-7-6-5-4-3-2-1"_expect);
965 .iterWhile([](uint j){
return j > 25; })
984 .
filter([](uint j){
return j % 2; })
986 ==
"9-7-5-3-1"_expect);
990 auto ii =
explore(CountDown{10})
991 .
filter([](
int j){
return j > 9; });
993 CHECK (not isnil (ii));
1001 auto jj =
explore(CountDown{5})
1002 .
filter([](
int j){
return j > 9; });
1015 .transform([](
float f){
return 0.55 + 2*f; })
1016 .
filter([](CountDown& core){
return core.p % 2; })
1018 ==
"18.55-14.55-10.55"_expect);
1026 .expand([](uint i){
return CountDown{i%4==0? i-1 : 0}; })
1027 .
filter([](uint i){
return i%2 == 0; })
1030 ==
"10-8-6-4-2-2-6-4-2-2"_expect);
1039 bool toggle =
false;
1040 auto kk =
explore(CountDown{10,5})
1041 .expand([](uint j){
return CountDown{j-1}; })
1042 .transform([](
int v){
return 2*v; })
1047 it.expandChildren();
1054 ==
"14-12-10-8-6-4-2-14-12"_expect);
1065 CHECK (
materialise(kk.filter([](
long i){ return i % 7; }))
1066 ==
"12-10-8-6-4-2-12"_expect);
1090 auto seq =
explore(CountDown{20})
1093 auto takeEve = [](uint i){
return i%2 == 0; };
1094 auto takeTrd = [](uint i){
return i%3 == 0; };
1101 seq.andFilter (takeEve);
1106 seq.andFilter (takeTrd);
1114 seq.setNewFilter (takeTrd);
1119 seq.orNotFilter (takeEve);
1131 seq.andNotFilter ([&](CountDown& core)
1133 buff += util::toString(core.p) +
".";
1139 CHECK (
".3." == buff);
1142 CHECK (
".3.1." == buff);
1144 CHECK (isnil (seq));
1150 .mutableFilter(takeTrd);
1153 seq.disableFilter();
1157 seq.andNotFilter (takeEve);
1161 seq.disableFilter();
1168 CHECK (isnil (seq));
1179 auto accumulated =
explore(CountDown{30})
1180 .transform([](
int i){
return i-1; })
1183 using Res = decltype(accumulated);
1184 CHECK (lib::test::showType<Res>() ==
"int"_expect);
1186 auto expectedSum = [](
auto N){
return N*(N+1) / 2; };
1187 CHECK (accumulated == expectedSum(29));
1191 .
reduce([](
int i){
return i - 0.5; }
1192 ,[](
string accu,
float val)
1194 return accu+
">"+util::toString(val);
1198 ==
">->9.5>8.5>7.5>6.5>5.5>4.5>3.5>2.5>1.5>0.5"_expect);
1202 .
reduce([](
auto it) ->
string 1204 return _Fmt{
"○%s●"} % *it;
1206 ==
"○9●○8●○7●○6●○5●○4●○3●○2●○1●"_expect);
1210 .
reduce(iter_explorer::IDENTITY, std::minus<int>(), expectedSum(9))
1221 auto solidified =
explore(CountDown{20})
1222 .
filter ([](uint i){
return i % 2; })
1223 .transform([](uint i){
return 0.5*i; })
1226 using Res = decltype(solidified);
1227 CHECK (lib::test::showType<Res>() ==
"vector<double>"_expect);
1228 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);
1239 .transform([](uint j){
return j % 5; })
1242 ==
"0-1-2-3-4"_expect);
1273 CHECK (isnil (sequence));
1275 sequence =
explore(CountDown{20,10})
1276 .
filter([](uint i){
return i % 2; })
1279 CHECK (not isnil (sequence));
1280 CHECK (19 == *sequence);
1285 .transform([](uint i){
return i*2; })
1288 CHECK (38 == *sequence);
1289 CHECK (
"38-34-30-26-22" ==
materialise(sequence));
1295 CHECK (22 == *sequence);
1297 CHECK (isnil (sequence));
1302 CHECK (isnil (exploreIter));
1304 exploreIter =
explore(CountDown{20,10})
1305 .
filter([](uint i){
return i % 2; })
1306 .transform([](uint i){
return i*2; })
1307 .
filter([](
int i){
return i>25; })
1308 .expand([](uint i){
return CountDown{i-10, 20}; })
1309 .transform([](uint u) ->
char {
return '@'+u-20; })
1313 CHECK (
'R' == *exploreIter);
1315 CHECK (
'N' == *exploreIter);
1317 exploreIter.expandChildren();
1319 CHECK (
'D' == *exploreIter);
1321 CHECK (
"D-C-B-A-J-F" ==
materialise(exploreIter));
1345 virtual PrivateSource* expandChildren()
const =0;
1348 class VerySpecificIter
1353 VerySpecificIter(uint start)
1357 virtual PrivateSource*
1358 expandChildren()
const override 1360 return new VerySpecificIter{*wrappedIter() - 2};
1366 return *wrappedIter();
1374 explore (
new VerySpecificIter{7})));
1378 PrivateSource* niente =
nullptr;
1379 CHECK (isnil (
explore (niente)));
1383 VerySpecificIter vsit{5};
1389 .expand ([](PrivateSource& source){
return source.expandChildren(); });
1391 CHECK (not isnil (ii));
1393 CHECK (5 == vsit.currentVal());
1396 CHECK (4 == vsit.currentVal());
1398 CHECK (0 == ii.depth());
1399 ii.expandChildren();
1400 CHECK (1 == ii.depth());
1406 CHECK (4 == vsit.currentVal());
1407 CHECK (1 == ii.depth());
1409 CHECK (0 == ii.depth());
1411 CHECK (3 == vsit.currentVal());
1414 CHECK (2 == vsit.currentVal());
1417 CHECK (1 == vsit.currentVal());
1446 .expand([](uint j){
return CountDown{j-1}; })
1448 .transform([](
int i){
return i*10; })
1450 ==
"40-30-20-10-10-20-10-10-30-20-10-10-20-10-10");
1454 using Tu2 = std::tuple<uint, uint>;
1455 auto summingExpander = [](Tu2
const& tup)
1457 uint val = get<0>(tup);
1458 uint sum = get<1>(tup);
1465 .transform([](uint i){
return Tu2{i,0}; })
1466 .expand(summingExpander)
1468 .transform([](Tu2 res){
return get<1>(res); })
1470 ==
"0-4-7-9-10-0-3-5-6-0-2-3-0-1");
1503 DataSrc searchSpace =
explore(RandomSeq{-1})
1504 .expand([](
char){
return RandomSeq{15}; })
1514 State(DataSrc& s,
string& t)
1529 return *unConst(
this);
1536 protocol.resize (1+src.depth());
1543 src.expandChildren();
1544 protocol.resize (1+src.depth());
1550 ASSERT (src.depth() < toFind.size());
1551 return *src == toFind[src.depth()];
1557 string toFind = util::join (
explore (RandomSeq{5}),
"");
1558 cout <<
"Search in random tree: toFind = "<<toFind<<endl;
1560 auto theSearch =
explore (State{searchSpace, toFind})
1563 while (it->src.depth() < it->toFind.size() - 1
1565 it->expandChildren();
1567 return it->isMatch();
1572 CHECK (not isnil(theSearch));
1573 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 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
int rani(uint bound=_iBOUND())
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 ...
Simplistic test class runner.
Another Lumiera Forward Iterator building block, based on incorporating a state type as »*State Core*...
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, based directly on the referee's memory identities. ...