Created
July 11, 2019 00:13
-
-
Save wtholliday/ec617cb55c0c439f3ea4d162af164ddc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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