#pragma once #if USE_STDFUNCTION #include namespace hr { using std::function; } // namespace hr #else #include #include namespace hr { template class hyper_function; template using function = hyper_function; template struct hyper_function_state_base { virtual R call(Args...) const = 0; virtual hyper_function_state_base *clone() const = 0; virtual ~hyper_function_state_base() = default; }; template struct hyper_function_state : hyper_function_state_base { using Self = hyper_function_state; T t_; explicit hyper_function_state(T t) : t_(std::move(t)) {} R call(Args... args) const override { return const_cast(t_)(static_cast(args)...); } hyper_function_state_base *clone() const override { return new Self(*this); } }; template class hyper_function { hyper_function_state_base *ptr_ = nullptr; public: hyper_function() = default; template::type>()(std::declval()...)))> hyper_function(Callable&& t) : ptr_(new hyper_function_state::type, R, Args...>(static_cast(t))) {} ~hyper_function() { delete ptr_; } hyper_function(hyper_function& rhs) : ptr_(rhs.ptr_ ? rhs.ptr_->clone() : nullptr) {} hyper_function(const hyper_function& rhs) : ptr_(rhs.ptr_ ? rhs.ptr_->clone() : nullptr) {} hyper_function(hyper_function&& rhs) noexcept : ptr_(rhs.ptr_) { rhs.ptr_ = nullptr; } hyper_function(const hyper_function&& rhs) = delete; void operator=(hyper_function rhs) noexcept { std::swap(ptr_, rhs.ptr_); } R operator()(Args... args) const { return ptr_->call(static_cast(args)...); } explicit operator bool() const noexcept { return ptr_ != nullptr; } }; } // namespace hr #endif