// BEGIN mycpp output #include "gc_heap.h" using gc_heap::Alloc; using gc_heap::kZeroMask; using gc_heap::StackRoots; #include "my_runtime.h" #include "mylib2.h" using gc_heap::NewStr; using gc_heap::NewList; using gc_heap::NewDict; 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; StackRoots _roots({&dims, &out, &rest}); if (len(dims) == 1) { for (StrIter it(dims->index(0)); !it.Done(); it.Next()) { Str* ch = it.Value(); StackRoots _for({&ch }); out->append(ch); } } else { rest = Alloc>(); Cartesian(dims->slice(1), rest); for (StrIter it(dims->index(0)); !it.Done(); it.Next()) { Str* ch = it.Value(); StackRoots _for({&ch }); for (ListIter it(rest); !it.Done(); it.Next()) { Str* r = it.Value(); StackRoots _for({&r }); out->append(str_concat(ch, r)); } } } } void run_tests() { List* out = nullptr; List* tmp = nullptr; List* tmp2 = nullptr; StackRoots _roots({&out, &tmp, &tmp2}); out = Alloc>(); tmp = NewList(std::initializer_list{str0}); Cartesian(tmp, out); for (ListIter it(out); !it.Done(); it.Next()) { Str* s = it.Value(); StackRoots _for({&s }); 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()) { Str* s = it.Value(); StackRoots _for({&s }); print(s); } } void run_benchmarks() { int i; int n; List* out = nullptr; StackRoots _roots({&out}); i = 0; n = 200000; while (i < n) { out = Alloc>(); Cartesian(NewList(std::initializer_list{str5, str6, str7}), out); i = (i + 1); } } } // define namespace cartesian