// BEGIN mycpp output #include "mycpp/runtime.h" GLOBAL_STR(str0, "ab"); GLOBAL_STR(str1, "--"); GLOBAL_STR(str2, "ab"); GLOBAL_STR(str3, "-|_"); GLOBAL_STR(str4, "ABC"); GLOBAL_STR(str5, "ab"); GLOBAL_STR(str6, "-|_"); GLOBAL_STR(str7, "ABC"); namespace cartesian { // forward declare } // forward declare namespace cartesian namespace cartesian { // declare void Cartesian(List* dims, List* out); void run_tests(); void run_benchmarks(); } // declare namespace cartesian namespace cartesian { // define void Cartesian(List* dims, List* out) { List* rest = nullptr; if (len(dims) == 1) { for (StrIter it(dims->at(0)); !it.Done(); it.Next()) { BigStr* ch = it.Value(); out->append(ch); } } else { rest = Alloc>(); Cartesian(dims->slice(1), rest); for (StrIter it(dims->at(0)); !it.Done(); it.Next()) { BigStr* ch = it.Value(); for (ListIter it(rest); !it.Done(); it.Next()) { BigStr* r = it.Value(); out->append(str_concat(ch, r)); } } } } void run_tests() { List* out = nullptr; List* tmp = nullptr; List* tmp2 = nullptr; out = Alloc>(); tmp = NewList(std::initializer_list{str0}); Cartesian(tmp, out); for (ListIter it(out); !it.Done(); it.Next()) { BigStr* s = it.Value(); print(s); } print(str1); out = Alloc>(); tmp2 = NewList(std::initializer_list{str2, str3, str4}); Cartesian(tmp2, out); for (ListIter it(out); !it.Done(); it.Next()) { BigStr* s = it.Value(); print(s); } } void run_benchmarks() { int i; int n; List* out = nullptr; i = 0; n = 100000; while (i < n) { out = Alloc>(); Cartesian(NewList(std::initializer_list{str5, str6, str7}), out); i = (i + 1); mylib::MaybeCollect(); } } } // define namespace cartesian