Skip to content

Instantly share code, notes, and snippets.

@wtholliday
Created July 11, 2019 00:13
Show Gist options
  • Save wtholliday/ec617cb55c0c439f3ea4d162af164ddc to your computer and use it in GitHub Desktop.
Save wtholliday/ec617cb55c0c439f3ea4d162af164ddc to your computer and use it in GitHub Desktop.
#pragma once
template<typename>
class func;
// Alternative to std::function for when compile time is
// more important than runtime performance. Doesn't pull in
// any headers.
template<typename Result, typename... Arguments>
class func<Result (Arguments...)> {
struct holder {
virtual ~holder() {}
virtual Result call(Arguments...) = 0;
virtual holder* clone() = 0;
};
template<typename Lambda>
struct lambda_holder : public holder {
virtual ~lambda_holder() {}
Lambda lambda;
lambda_holder(Lambda l) : lambda(l) { }
Result call(Arguments... args) override {
return lambda(args...);
}
holder* clone() override {
return new lambda_holder<Lambda>(lambda);
}
};
public:
func() { }
func(const func& f) {
holder = f.holder->clone();
}
func& operator=(const func& f) {
if(holder) { delete holder; }
holder = f.holder ? f.holder->clone() : nullptr;
return *this;
}
// Create from a lambda.
template<class F>
func(F f) {
holder = new lambda_holder<F>{f};
}
~func() {
if(holder) { delete holder; }
}
Result operator()(Arguments... args) const {
assert(holder);
return holder->call(args...);
}
operator bool() const {
return holder;
}
private:
holder *holder = nullptr;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment