Skip to content

Instantly share code, notes, and snippets.

@remyroez
Last active November 17, 2016 04:11
Show Gist options
  • Save remyroez/64ef33d03a453d357b0313fa13873008 to your computer and use it in GitHub Desktop.
Save remyroez/64ef33d03a453d357b0313fa13873008 to your computer and use it in GitHub Desktop.
invoke test
#include <iostream>
#include <functional>
#include <type_traits>
// impl ----------
template <typename T, typename F = decltype(+std::declval<T>())>
class fn {
public:
using type = std::remove_pointer_t<F>;
using function = std::function<type>;
fn() : _f([](){}) {}
fn(T f) : _f(+f) {}
fn(function f) : _f(f) {}
fn(const fn &rhs) = default;
fn &operator =(const fn &) = default;
fn &operator =(F f) { _f = f; return *this; }
fn &operator =(function f) { _f = f; return *this; }
fn &operator =(auto f) { _f = f; return *this; }
template <typename... Args>
decltype(auto) operator()(Args&&... args) { return std::invoke(_f, std::forward<Args>(args)...); }
void reset(function f) { _f = f; }
private:
function _f;
};
// usage ----------
constexpr auto foo() { return "hoge"; }
constexpr auto bar() { return "fuga"; }
constexpr auto baz = []() constexpr { return "moge"; };
int main()
{
fn a(foo);
std::cout << a() << std::endl;
fn b(foo);
b = bar;
std::cout << b() << std::endl;
fn c([]() constexpr { return "lambda"; });
c = baz;
std::cout << c() << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment