Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Turn recursion into loop

I have an unknown type T that might be non-copy- or move-assignable, a function T op(const T &foo, Other bar) that computes and returns a new T based on an existing one, and a recursive function:

template<typename Iter, typename T>
T foldLeft(Iter first, Iter last, const T &z, std::function<T(T, Other)> op)
{
    if (first == last) {
        return z;
    }
    return foldLeft(std::next(first), last, op(z, *first), op);
}

The compiler can't always optimize the tail call, because T might have a non-trivial destructor. I'm trying to manually rewrite it with a loop, but can't figure out how to reassign to z.

like image 282
Zizheng Tai Avatar asked Jul 25 '26 21:07

Zizheng Tai


1 Answers

You may do the following, but the restriction is strange, and using std::accumulate seems simpler

template<typename Iter, typename T, typename Fn>
T foldLeft(Iter first, Iter last, const T &z, Fn op)
{
    std::aligned_storage_t<sizeof (T), alignof (T)> buf;
    T* res = new (&buf) T(z);
    for (auto it = first; it != last; ++it) {
        auto&& res2 = op(res, it);
        res->~T();
        res = new (&buf) T(std::move(res2));
    }
    T final_res = *res;
    res->~T();
    return final_res;
}

Note that it is not exception safe.

like image 129
Jarod42 Avatar answered Jul 28 '26 10:07

Jarod42