aboutsummaryrefslogtreecommitdiff
path: root/y_combinator.h
blob: 9016b99631c248717714da5c9c44430788650b56 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#pragma once

#include <functional>

namespace y_combinator_details {

template <class Fun> struct y_combinator_result {
  template <class T>
  explicit y_combinator_result(T &&fun_) : fun(std::forward<T>(fun_)) {}

  template <class... Args> decltype(auto) operator()(Args &&...args) {
    return fun(std::ref(*this), std::forward<Args>(args)...);
  }

private:
  Fun fun;
};

} // namespace y_combinator_details

template <class Fun> static inline decltype(auto) y_combinator(Fun &&fun) {
  return y_combinator_details::y_combinator_result<std::decay_t<Fun>>(
      std::forward<Fun>(fun));
}