3 Commits

Author SHA1 Message Date
Alessandro Di Federico cfb47157b9 clang-tidy: readability-identifier-naming
This commit fixes all the non-compliance with our preliminary clang-tidy
configuration, which will be merged soon.
2022-01-07 09:18:05 +01:00
Pietro Fezzardi 8ffcd49dd2 RecursiveCoroutine: fix reference arguments
Before this commit, recursive coroutines did not work properly if they
had out arguments with reference type.
The reason is that `rc_run` was inferring the type of its arguments from
the arguments themselves, not from the prototype of the recursive
coroutine.

Hence, code snippets like the following did not work properly, because
`rc_run` was taking x by value, not by reference.

```
RecursiveCoroutine<void> accumulate_on_i(int &i) {
  // ...
}

int f() {
  int x = 0;
  rc_run(accumulate_on_i, x);
  return x;
}
```

This commit fixes the problem. Now the arguments of `rc_run` are
properly forwarded to the recursive coroutine.
2021-02-17 11:37:00 +01:00
Pietro Fezzardi e1b283b0b6 Add RecursiveCoroutine headers and tests
RecursiveCoroutines are a facility intended to be used as-drop in
replacement of recursive functions.

They provide the following features.
- They can be written almost as regular recursive functions,
  with 4 caveats.
  1. A recursive coroutine that returns a type `T`, needs to be declared
     to return a `RecursiveCoroutine<T>`.
  2. Inside the body of a recursive coroutine, when recursively calling
     another recursive coroutine, the recursive call needs to be
     prepended by the new keyword `rc_recur`.
  3. Inside the body of a recursive coroutine, the `return` statement
     needs to be substituted with `rc_return`.
  4. When launching a recursive coroutine `A` from a function that is
     not a recursive coroutine, `A` needs to be called with the provided
     dedicated template wrapper `rc_run`.
     The syntax is the following `rc_run(A, arg0, arg1, ...)`.
     This is necessary to enable swapping off recursive coroutine and
     fall back to regular recursion for debug.
     See below for how to do it.
- Unlike regular recursive functions, they don't use the system stack
  for recursion. They use a custom heap-allocated stack to manage
  recursion. This makes them more robust for implementing recursive
  functions that manipulate user-defined input, because they are much
  less likely to trigger stack overflow.
- They can be turned off compiling with
  `-DDISABLE_RECURSIVE_COROUTINES`, falling back to regular recursion,
  for debug purposes.
- They support both direct and indirect recursion, i.e. a recursive
  coroutine A can recursively call itself, or it can recursively call
  another recursive coroutine B, which in turns recursively calls A.
2020-12-29 16:15:31 +01:00