#include <iostream>
#include <utility>
#include <memory>
template<class Sig>class func;
namespace details{
template<class Sig>struct inner;
template<class R,class...Args>
struct inner<R(Args...)>{
virtual ~inner() {};
virtual R invoke(Args&&...args) =0;
};
template<class F,class Sig>struct impl;
template<class F,class R,class...Args>
struct impl<F,R(Args...)>:inner<R(Args...)>{
F f;
template<class... Ts>
impl(Ts&&...ts):f(std::forward<Ts>(ts)...){}
R invoke(Args&&...args)override{
return f(std::forward<Args>(args)...);
}
};
}
template<class T>struct emplace_as{};
template<class R,class...Args>
class func<R(Args...)>{
std::unique_ptr<details::inner<R(Args...)>> pImpl;
public:
R operator()(Args...args){
return pImpl->invoke(std::forward<Args>(args)...);
}
explicit operator bool()const{return pImpl;}
func(func&&)=default;
template<class F,class...Ts,class=typename std::enable_if<
std::is_convertible<decltype(std::declval<F>()(std::declval<Args>()...)),R>::value
>::type>
func(emplace_as<F>,Ts&&...ts):
pImpl( new details::impl<F, R(Args...)>{std::forward<Ts>(ts)...} )
{}
template<class F,class=typename std::enable_if<
std::is_convertible<decltype(std::declval<F>()(std::declval<Args>()...)),R>::value
>::type>
func(F&&f):
func(
emplace_as<typename std::decay<F>::type>(),
std::forward<F>(f)
)
{}
};
int main() {
func<void()> test = [](){ std::cout << "hello world\n"; };
test();
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dXRpbGl0eT4KI2luY2x1ZGUgPG1lbW9yeT4KCnRlbXBsYXRlPGNsYXNzIFNpZz5jbGFzcyBmdW5jOwpuYW1lc3BhY2UgZGV0YWlsc3sKICB0ZW1wbGF0ZTxjbGFzcyBTaWc+c3RydWN0IGlubmVyOwogIHRlbXBsYXRlPGNsYXNzIFIsY2xhc3MuLi5BcmdzPgogIHN0cnVjdCBpbm5lcjxSKEFyZ3MuLi4pPnsKICAgIHZpcnR1YWwgfmlubmVyKCkge307CiAgICB2aXJ0dWFsIFIgaW52b2tlKEFyZ3MmJi4uLmFyZ3MpID0wOwogIH07CiAgdGVtcGxhdGU8Y2xhc3MgRixjbGFzcyBTaWc+c3RydWN0IGltcGw7CiAgdGVtcGxhdGU8Y2xhc3MgRixjbGFzcyBSLGNsYXNzLi4uQXJncz4KICBzdHJ1Y3QgaW1wbDxGLFIoQXJncy4uLik+OmlubmVyPFIoQXJncy4uLik+ewogICAgRiBmOwogICAgdGVtcGxhdGU8Y2xhc3MuLi4gVHM+CiAgICBpbXBsKFRzJiYuLi50cyk6ZihzdGQ6OmZvcndhcmQ8VHM+KHRzKS4uLil7fQogICAgUiBpbnZva2UoQXJncyYmLi4uYXJncylvdmVycmlkZXsKICAgICAgcmV0dXJuIGYoc3RkOjpmb3J3YXJkPEFyZ3M+KGFyZ3MpLi4uKTsKICAgIH0KICB9Owp9CnRlbXBsYXRlPGNsYXNzIFQ+c3RydWN0IGVtcGxhY2VfYXN7fTsKdGVtcGxhdGU8Y2xhc3MgUixjbGFzcy4uLkFyZ3M+CmNsYXNzIGZ1bmM8UihBcmdzLi4uKT57CiAgc3RkOjp1bmlxdWVfcHRyPGRldGFpbHM6OmlubmVyPFIoQXJncy4uLik+PiBwSW1wbDsKcHVibGljOgogIFIgb3BlcmF0b3IoKShBcmdzLi4uYXJncyl7CiAgICByZXR1cm4gcEltcGwtPmludm9rZShzdGQ6OmZvcndhcmQ8QXJncz4oYXJncykuLi4pOwogIH0KICBleHBsaWNpdCBvcGVyYXRvciBib29sKCljb25zdHtyZXR1cm4gcEltcGw7fQogIGZ1bmMoZnVuYyYmKT1kZWZhdWx0OwogIHRlbXBsYXRlPGNsYXNzIEYsY2xhc3MuLi5UcyxjbGFzcz10eXBlbmFtZSBzdGQ6OmVuYWJsZV9pZjwKICAgIHN0ZDo6aXNfY29udmVydGlibGU8ZGVjbHR5cGUoc3RkOjpkZWNsdmFsPEY+KCkoc3RkOjpkZWNsdmFsPEFyZ3M+KCkuLi4pKSxSPjo6dmFsdWUKICA+Ojp0eXBlPgogIGZ1bmMoZW1wbGFjZV9hczxGPixUcyYmLi4udHMpOgogICAgcEltcGwoIG5ldyBkZXRhaWxzOjppbXBsPEYsIFIoQXJncy4uLik+e3N0ZDo6Zm9yd2FyZDxUcz4odHMpLi4ufSApCiAge30KCiAgdGVtcGxhdGU8Y2xhc3MgRixjbGFzcz10eXBlbmFtZSBzdGQ6OmVuYWJsZV9pZjwKICAgIHN0ZDo6aXNfY29udmVydGlibGU8ZGVjbHR5cGUoc3RkOjpkZWNsdmFsPEY+KCkoc3RkOjpkZWNsdmFsPEFyZ3M+KCkuLi4pKSxSPjo6dmFsdWUKICA+Ojp0eXBlPgogIGZ1bmMoRiYmZik6CiAgICBmdW5jKAogICAgICBlbXBsYWNlX2FzPHR5cGVuYW1lIHN0ZDo6ZGVjYXk8Rj46OnR5cGU+KCksCiAgICAgIHN0ZDo6Zm9yd2FyZDxGPihmKQogICAgKQogIHt9Cn07CgppbnQgbWFpbigpIHsKICAgIGZ1bmM8dm9pZCgpPiB0ZXN0ID0gW10oKXsgc3RkOjpjb3V0IDw8ICJoZWxsbyB3b3JsZFxuIjsgfTsKCXRlc3QoKTsKfQ==