// examples/tuple_return_value // 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, "foo"); GLOBAL_STR(str1, "i = %d"); GLOBAL_STR(str2, "s = %s"); GLOBAL_STR(str3, "bar"); GLOBAL_STR(str4, "length = %d"); GLOBAL_STR(str5, "spam"); namespace tuple_return_value { // forward declare } // forward declare namespace tuple_return_value namespace tuple_return_value { // declare Tuple2 f(int x); void run_tests(); void run_benchmarks(); inline Str* fmt0(int a0) { gBuf.reset(); gBuf.write_const("i = ", 4); gBuf.format_d(a0); return gBuf.getvalue(); } inline Str* fmt1(Str* a0) { gBuf.reset(); gBuf.write_const("s = ", 4); gBuf.format_s(a0); return gBuf.getvalue(); } inline Str* fmt2(int a0) { gBuf.reset(); gBuf.write_const("length = ", 9); gBuf.format_d(a0); return gBuf.getvalue(); } } // declare namespace tuple_return_value namespace tuple_return_value { // define Tuple2 f(int x) { int i; Str* s = nullptr; StackRoots _roots({&s}); i = (x + 42); s = str0; return (Tuple2(i, s)); } void run_tests() { int i; Str* s = nullptr; List*>* items = nullptr; Tuple2* mytuple = nullptr; int myint; Str* mystr = nullptr; StackRoots _roots({&s, &items, &mytuple, &mystr}); Tuple2 tup0 = f(0); i = tup0.at0(); s = tup0.at1(); println_stderr(fmt0(i)); println_stderr(fmt1(s)); items = Alloc*>>(); items->append((Alloc>(43, str3))); println_stderr(fmt2(len(items))); mytuple = (Alloc>(44, str5)); Tuple2* tup1 = mytuple; myint = tup1->at0(); mystr = tup1->at1(); } void run_benchmarks() { int j; Str* s = nullptr; StackRoots _roots({&s}); for (int i = 0; i < 1000000; ++i) { Tuple2 tup2 = f(i); j = tup2.at0(); s = tup2.at1(); if (j == 100000) { print(str(i)); } } } } // define namespace tuple_return_value int main(int argc, char **argv) { // gc_heap::gHeap.Init(512); gc_heap::gHeap.Init(128 << 10); // 128 KiB; doubling in size // gc_heap::gHeap.Init(400 << 20); // 400 MiB to avoid garbage collection if (getenv("BENCHMARK")) { fprintf(stderr, "Benchmarking...\n"); tuple_return_value::run_benchmarks(); } else { tuple_return_value::run_tests(); } }