80 using lumiera::error::LERR_(ITER_EXHAUST);
109 return util::unConst (checkPoint()? p : e);
115 if (not checkPoint())
return;
162 return 'A' + rand() % 26;
167 : lim_{len>=0? len : std::numeric_limits<size_t>::max()}
169 , letter_{rndLetter()}
181 return unConst(
this)->letter_;
187 ASSERT (checkPoint());
189 letter_ = rndLetter();
199 return util::join (std::forward<II> (ii),
"-");
210 if (++ii) cout <<
"-";
275 verify_wrappedState();
276 verify_wrappedIterator();
278 verify_expandOperation();
279 verify_expand_rootCurrent();
280 verify_transformOperation();
281 verify_combinedExpandTransform();
282 verify_customProcessingLayer();
283 verify_scheduledExpansion();
284 verify_untilStopTrigger();
285 verify_FilterIterator();
286 verify_FilterChanges();
287 verify_asIterSource();
292 verify_depthFirstExploration();
293 demonstrate_LayeredEvaluation();
304 auto ii =
explore (CountDown{5,0});
330 vector<int> numz{1,-2,3,-5,8,-13};
331 auto ii = eachElm(numz);
397 verify_treeExpandingIterator(
399 .expand([](uint j){
return CountDown{j-1}; })
402 verify_treeExpandingIterator(
404 .expand([](uint j){
return NumberSequence{j-1}; })
408 vector<vector<uint>> childBuffer;
409 auto expandIntoChildBuffer = [&](uint j) -> vector<uint>&
411 childBuffer.emplace_back();
412 vector<uint>& childNumbz = childBuffer.back();
413 for (
size_t i=0; i<j-1; ++i)
414 childNumbz.push_back(j-1 - i);
418 verify_treeExpandingIterator(
420 .expand(expandIntoChildBuffer)
424 CHECK (5 == childBuffer.size());
430 verify_treeExpandingIterator(
432 .expand([](CountDown
const& core){
return CountDown{ core.yield() - 1}; })
435 verify_treeExpandingIterator(
437 .expand([](CountDown core){
return NumberSequence{ core.yield() - 1}; })
440 verify_treeExpandingIterator(
442 .expand([](
auto & it){
return CountDown{ *it - 1}; })
445 verify_treeExpandingIterator(
447 .expand([](
auto it){
return decltype(it){ *it - 1}; })
454 verify_treeExpandingIterator (EXP ii)
461 CHECK (0 == ii.depth());
464 CHECK (1 == ii.depth());
467 CHECK (1 == ii.depth());
470 CHECK (2 == ii.depth());
473 CHECK (1 == ii.depth());
476 CHECK (0 == ii.depth());
479 CHECK (1 == ii.depth());
482 CHECK (0 == ii.depth());
485 CHECK (1 == ii.depth());
488 CHECK (0 == ii.depth());
508 auto tree =
explore(CountDown{25})
509 .expand([](uint j){
return CountDown{j-1}; });
511 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");
513 CHECK (0 == tree.depth());
520 tree.expandChildren();
521 CHECK (1 == tree.depth());
528 tree.expandChildren();
531 CHECK (2 == tree.depth());
532 CHECK (
materialise(tree) ==
"12-11-10-9-8-7-6-5-4-3-2-1-" 533 "14-13-12-11-10-9-8-7-6-5-4-3-2-1-" 534 "20-19-18-17-16-15-14-13-12-11-10-9-8-7-6-5-4-3-2-1");
539 CHECK (
materialise(tree) ==
"12-11-10-9-8-7-6-5-4-3-2-1");
540 CHECK (0 == tree.depth());
563 auto multiply = [](
int v){
return 2*v; };
565 _Fmt embrace{
"≺%s≻"};
566 auto formatify = [&](
auto it){
return string{embrace % *it}; };
569 auto ii =
explore(CountDown{7,4})
587 vector<int64_t> numz{1,-2,3,-5,8,-13};
590 .transform(formatify)) );
594 .transform(formatify)) );
599 .transform(formatify)
600 .transform(formatify)) );
606 auto jj =
explore (CountDown{4})
607 .transform([&](
int v)
614 CHECK (fact == -2*3);
620 CHECK (fact == -2*3);
621 CHECK (-2*3*3 == *jj);
622 CHECK (fact == 2*2*3);
623 CHECK (-2*3*3 == *jj);
624 CHECK (-2*3*3 == *jj);
625 CHECK (fact == 2*2*3);
628 CHECK (2*2*3*2 == *jj);
629 CHECK (fact == -2*2*2*3);
632 CHECK (2*2*3*2 == *jj);
636 CHECK (-23*1 == *jj);
637 CHECK (fact == 2*23);
641 CHECK (fact == 2*23);
644 CHECK (fact == 2*23);
650 auto kk =
explore (CountDown{9,4})
651 .transform([](CountDown& core)
653 uint delta = core.p - core.e;
695 auto ii =
explore(CountDown{5})
696 .expand([](uint j){
return CountDown{j-1}; })
697 .transform([](
int v){
return 2*v; })
700 CHECK (
"int" == meta::typeStr(*ii));
713 .expand([](uint j){
return CountDown{j-1}; })
714 .transform([](
int v){
return 2*v; })
715 .transform([](
auto& it)
725 .transform([](
float f){
return 0.055 + f/2; })
727 ==
"5.055-4.055-20.055-1.055-2.055-1.055" );
761 .processingLayer<MagicTestRubbish>()
767 .transform([](uint v){
return 2*v; })
768 .processingLayer<MagicTestRubbish>()
769 .
filter([](
int v){
return v % 3; })
788 auto ii =
explore(CountDown{6})
789 .expand([](uint j){
return CountDown{j-2}; })
790 .expandOnIteration();
796 CHECK (ii.depth() == 0);
800 CHECK (ii.depth() == 0);
803 CHECK (ii.depth() == 1);
807 CHECK (ii.depth() == 1);
811 CHECK (ii.depth() == 2);
814 CHECK (ii.depth() == 1);
819 CHECK (ii.depth() == 1);
822 CHECK (ii.depth() == 0);
846 .iterUntil([](uint j){
return j < 5; })
848 ==
"10-9-8-7-6-5"_expect);
852 .iterWhile([](uint j){
return j > 5; })
854 ==
"10-9-8-7-6"_expect);
858 .iterWhile([](
int j){
return j > -5; })
860 ==
"10-9-8-7-6-5-4-3-2-1"_expect);
864 .iterWhile([](uint j){
return j > 25; })
883 .
filter([](uint j){
return j % 2; })
885 ==
"9-7-5-3-1"_expect);
889 auto ii =
explore(CountDown{10})
890 .
filter([](
int j){
return j > 9; });
892 CHECK (not isnil (ii));
900 auto jj =
explore(CountDown{5})
901 .
filter([](
int j){
return j > 9; });
914 .transform([](
float f){
return 0.55 + 2*f; })
915 .
filter([](CountDown& core){
return core.p % 2; })
917 ==
"18.55-14.55-10.55"_expect);
925 .expand([](uint i){
return CountDown{i%4==0? i-1 : 0}; })
926 .
filter([](uint i){
return i%2 == 0; })
929 ==
"10-8-6-4-2-2-6-4-2-2"_expect);
939 auto kk =
explore(CountDown{10,5})
940 .expand([](uint j){
return CountDown{j-1}; })
941 .transform([](
int v){
return 2*v; })
953 ==
"14-12-10-8-6-4-2-14-12"_expect);
964 CHECK (
materialise(kk.filter([](
long i){ return i % 7; }))
965 ==
"12-10-8-6-4-2-12"_expect);
989 auto seq =
explore(CountDown{20})
992 auto takeEve = [](uint i){
return i%2 == 0; };
993 auto takeTrd = [](uint i){
return i%3 == 0; };
1000 seq.andFilter (takeEve);
1005 seq.andFilter (takeTrd);
1013 seq.setNewFilter (takeTrd);
1018 seq.orNotFilter (takeEve);
1030 seq.andNotFilter ([&](CountDown& core)
1032 buff += util::toString(core.p) +
".";
1038 CHECK (
".3." == buff);
1041 CHECK (
".3.1." == buff);
1043 CHECK (isnil (seq));
1049 .mutableFilter(takeTrd);
1052 seq.disableFilter();
1056 seq.andNotFilter (takeEve);
1060 seq.disableFilter();
1067 CHECK (isnil (seq));
1078 auto accumulated =
explore(CountDown{30})
1079 .transform([](
int i){
return i-1; })
1082 using Res = decltype(accumulated);
1083 CHECK (lib::test::showType<Res>() ==
"int"_expect);
1085 auto expectedSum = [](
auto N){
return N*(N+1) / 2; };
1086 CHECK (accumulated == expectedSum(29));
1090 .
reduce([](
int i){
return i - 0.5; }
1091 ,[](
string accu,
float val)
1093 return accu+
">"+util::toString(val);
1097 ==
">->9.5>8.5>7.5>6.5>5.5>4.5>3.5>2.5>1.5>0.5"_expect);
1101 .
reduce([](
auto it) ->
string 1103 return _Fmt{
"○%s●"} % *it;
1105 ==
"○9●○8●○7●○6●○5●○4●○3●○2●○1●"_expect);
1115 auto solidified =
explore(CountDown{20})
1116 .
filter ([](uint i){
return i % 2; })
1117 .transform([](uint i){
return 0.5*i; })
1120 using Res = decltype(solidified);
1121 CHECK (lib::test::showType<Res>() ==
"vector<double>"_expect);
1122 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);
1153 CHECK (isnil (sequence));
1155 sequence =
explore(CountDown{20,10})
1156 .
filter([](uint i){
return i % 2; })
1159 CHECK (not isnil (sequence));
1160 CHECK (19 == *sequence);
1165 .transform([](uint i){
return i*2; })
1168 CHECK (38 == *sequence);
1169 CHECK (
"38-34-30-26-22" ==
materialise(sequence));
1175 CHECK (22 == *sequence);
1177 CHECK (isnil (sequence));
1182 CHECK (isnil (exploreIter));
1184 exploreIter =
explore(CountDown{20,10})
1185 .
filter([](uint i){
return i % 2; })
1186 .transform([](uint i){
return i*2; })
1187 .
filter([](
int i){
return i>25; })
1188 .expand([](uint i){
return CountDown{i-10, 20}; })
1189 .transform([](uint u) ->
char {
return '@'+u-20; })
1193 CHECK (
'R' == *exploreIter);
1195 CHECK (
'N' == *exploreIter);
1197 exploreIter.expandChildren();
1199 CHECK (
'D' == *exploreIter);
1201 CHECK (
"D-C-B-A-J-F" ==
materialise(exploreIter));
1225 virtual PrivateSource* expandChildren()
const =0;
1228 class VerySpecificIter
1233 VerySpecificIter(uint start)
1237 virtual PrivateSource*
1238 expandChildren()
const override 1240 return new VerySpecificIter{*wrappedIter() - 2};
1246 return *wrappedIter();
1254 explore (
new VerySpecificIter{7})));
1258 PrivateSource* niente =
nullptr;
1259 CHECK (isnil (
explore (niente)));
1263 VerySpecificIter vsit{5};
1269 .expand ([](PrivateSource& source){
return source.expandChildren(); });
1271 CHECK (not isnil (ii));
1273 CHECK (5 == vsit.currentVal());
1276 CHECK (4 == vsit.currentVal());
1278 CHECK (0 == ii.depth());
1279 ii.expandChildren();
1280 CHECK (1 == ii.depth());
1286 CHECK (4 == vsit.currentVal());
1287 CHECK (1 == ii.depth());
1289 CHECK (0 == ii.depth());
1291 CHECK (3 == vsit.currentVal());
1294 CHECK (2 == vsit.currentVal());
1297 CHECK (1 == vsit.currentVal());
1326 .expand([](uint j){
return CountDown{j-1}; })
1328 .transform([](
int i){
return i*10; })
1330 ==
"40-30-20-10-10-20-10-10-30-20-10-10-20-10-10");
1334 using Tu2 = std::tuple<uint, uint>;
1335 auto summingExpander = [](Tu2
const& tup)
1337 uint val = get<0>(tup);
1338 uint sum = get<1>(tup);
1345 .transform([](uint i){
return Tu2{i,0}; })
1346 .expand(summingExpander)
1348 .transform([](Tu2 res){
return get<1>(res); })
1350 ==
"0-4-7-9-10-0-3-5-6-0-2-3-0-1");
1383 DataSrc searchSpace =
explore(RandomSeq{-1})
1384 .expand([](
char){
return RandomSeq{15}; })
1394 State(DataSrc& s,
string& t)
1409 return *unConst(
this);
1416 protocol.resize (1+src.depth());
1423 src.expandChildren();
1424 protocol.resize (1+src.depth());
1430 ASSERT (src.depth() < toFind.size());
1431 return *src == toFind[src.depth()];
1437 string toFind = util::join (
explore (RandomSeq{5}),
"");
1438 cout <<
"Search in random tree: toFind = "<<toFind<<endl;
1440 auto theSearch =
explore (State{searchSpace, toFind})
1443 while (it->src.depth() < it->toFind.size() - 1
1445 it->expandChildren();
1447 return it->isMatch();
1452 CHECK (not isnil(theSearch));
1453 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 a statement indeed raises an exception.
A straight descending number sequence as basic test iterator.
void verify_combinedExpandTransform()
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".
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.