1#ifndef NEFORCE_CORE_FUNCTIONAL_FUNCTION_HPP__
2#define NEFORCE_CORE_FUNCTIONAL_FUNCTION_HPP__
14NEFORCE_BEGIN_NAMESPACE__
28template <
typename Sign>
40enum class FUNCTION_OPERATE {
54class __undefined_util;
64 const void* const_object_;
65 void (*function_pointer_)();
66 void (__undefined_util::*member_pointer_)();
76 storage_data() noexcept = default;
78 NEFORCE_NODISCARD
void* access() noexcept {
return &data_[0]; }
79 NEFORCE_NODISCARD
const void* access() const noexcept {
return &data_[0]; }
82 NEFORCE_NODISCARD T& access() noexcept {
83 return *
static_cast<T*
>(access());
87 NEFORCE_NODISCARD
const T& access() const noexcept {
88 return *
static_cast<const T*
>(access());
91 __nocopy_type unused_;
92 byte_t data_[
sizeof(__nocopy_type)];
101class __function_base {
103 static constexpr size_t max_size_ =
sizeof(__nocopy_type);
104 static constexpr size_t max_align_ =
alignof(__nocopy_type);
113 template <
typename F>
114 class __manager_base {
117 alignof(F) <= max_align_ && max_align_ %
alignof(F) == 0;
120 template <
typename U,
bool = stored_>
121 struct __get_pointer_impl;
123 template <
typename U>
124 struct __get_pointer_impl<U, true> {
125 static U*
get(
const storage_data& src)
noexcept {
126 const U& f = src.access<U>();
127 return const_cast<U*
>(_NEFORCE
addressof(f));
131 template <
typename U>
132 struct __get_pointer_impl<U, false> {
133 static U*
get(
const storage_data& src)
noexcept {
return src.access<U*>(); }
139 static F* get_pointer(
const storage_data& src)
noexcept {
return __get_pointer_impl<F>::get(src); }
142 template <
typename Fn>
146 template <typename Fn>
155 static bool manage(storage_data& dest,
const storage_data& src,
const FUNCTION_OPERATE oper) {
157 case FUNCTION_OPERATE::GET_TYPE_INFO:
158 dest.access<
const std::type_info*>() = &
typeid(F);
160 case FUNCTION_OPERATE::GET_PTR:
161 dest.access<F*>() = __manager_base::get_pointer(src);
163 case FUNCTION_OPERATE::COPY_PTR:
164 __manager_base::init_func(dest, *
const_cast<const F*
>(__manager_base::get_pointer(src)));
166 case FUNCTION_OPERATE::DESTROY_PTR:
167 __manager_base::destroy(dest, storage_());
173 template <
typename Fn>
174 static void init_func(storage_data& func,
176 __manager_base::create(func, _NEFORCE
forward<Fn>(f), storage_());
179 template <
typename Sign>
180 static bool not_empty_function(
const _NEFORCE function<Sign>& f)
noexcept {
181 return static_cast<bool>(f);
183 template <
typename T>
184 static bool not_empty_function(T* fptr)
noexcept {
185 return fptr !=
nullptr;
187 template <
typename Class,
typename T>
188 static bool not_empty_function(T Class::* mptr)
noexcept {
189 return mptr !=
nullptr;
191 template <
typename T>
192 static bool not_empty_function(
const T& )
noexcept {
197 using manage_type = bool (*)(storage_data&,
const storage_data&, FUNCTION_OPERATE);
199 storage_data func_{};
200 manage_type manager_ =
nullptr;
203 __function_base() noexcept = default;
205 if (manager_ !=
nullptr) {
206 manager_(func_, func_, FUNCTION_OPERATE::DESTROY_PTR);
210 NEFORCE_NODISCARD
bool empty()
const {
return manager_ ==
nullptr; }
221template <
typename Sign,
typename F>
222class __function_manage_handler;
224template <
typename Res,
typename F,
typename... Args>
225class __function_manage_handler<Res(Args...), F> :
public __function_base::__manager_base<F> {
227 using base_type = __function_base::__manager_base<F>;
230 static bool manage(storage_data& dest,
const storage_data& src, FUNCTION_OPERATE oper) {
232 case FUNCTION_OPERATE::GET_TYPE_INFO:
233 dest.access<
const std::type_info*>() = &
typeid(F);
235 case FUNCTION_OPERATE::GET_PTR:
236 dest.access<F*>() = base_type::get_pointer(src);
239 base_type::manage(dest, src, oper);
244 static Res
invoke(
const storage_data& f, Args... args) {
248 template <
typename Fn>
249 static constexpr bool nothrow_init() noexcept {
255class __function_manage_handler<void, void> {
257 static bool manage(storage_data& ,
const storage_data& , FUNCTION_OPERATE ) {
262template <
typename Sign,
typename F,
bool Val
id = is_
object_v<F>>
263struct __function_handler_dispatch : __function_manage_handler<Sign, remove_cv_t<F>> {};
265template <
typename Sign,
typename F>
266struct __function_handler_dispatch<Sign, F, false> : __function_manage_handler<void, void> {};
278template <
typename Res,
typename... Args>
279class function<Res(Args...)> : inner::__function_base {
281 using invoker_type = Res (*)(
const inner::storage_data&, Args...);
284 invoker_type invoker_ =
nullptr;
287 template <
typename F,
bool IsSelf = is_same_v<remove_cvref_t<F>, function>>
290 template <
typename F,
typename =
void>
293 template <
typename F>
298 template <
typename F>
299 using handler_t = inner::__function_manage_handler<Res(Args...),
decay_t<F>>;
301 template <
typename F, enable_if_t<is_
object_v<F>,
int> = 0>
302 NEFORCE_ALWAYS_INLINE
const F* __target_impl()
const noexcept {
303 if (manager_ == &inner::__function_handler_dispatch<Res(Args...), F>::manage) {
304 inner::storage_data ptr{};
305 manager_(ptr, func_, inner::FUNCTION_OPERATE::GET_PTR);
306 return ptr.access<
const F*>();
311 template <
typename F, enable_if_t<!is_
object_v<F>,
int> = 0>
312 NEFORCE_ALWAYS_INLINE
const F* __target_impl()
const noexcept {
332 if (
static_cast<bool>(other)) {
333 other.manager_(func_, other.func_, inner::FUNCTION_OPERATE::COPY_PTR);
334 invoker_ = other.invoker_;
335 manager_ = other.manager_;
346 manager_ = other.manager_;
347 invoker_ = other.invoker_;
348 other.manager_ =
nullptr;
349 other.invoker_ =
nullptr;
357 template <typename F, enable_if_t<callable_t<F>::value,
int> = 0>
358 function(F&& callable)
noexcept(handler_t<F>::template nothrow_init<F>()) :
361 "target of function must be constructible");
363 using handler = handler_t<F>;
364 if (handler::not_empty_function(callable)) {
365 handler::init_func(func_, _NEFORCE
forward<F>(callable));
366 invoker_ = &handler::invoke;
367 manager_ = &handler::manage;
398 manager_(func_, func_, inner::FUNCTION_OPERATE::DESTROY_PTR);
411 template <typename F, enable_if_t<callable_t<F>::value,
int> = 0>
423 template <
typename F>
434 _NEFORCE
swap(func_, other.func_);
435 _NEFORCE
swap(manager_, other.manager_);
436 _NEFORCE
swap(invoker_, other.invoker_);
443 explicit operator bool() const noexcept {
return !
empty(); }
462 NEFORCE_NODISCARD
const std::type_info&
target_type() const noexcept {
464 inner::storage_data result{};
465 manager_(result, func_, inner::FUNCTION_OPERATE::GET_TYPE_INFO);
466 if (
const auto*
const info = result.access<
const std::type_info*>()) {
478 template <
typename F>
480 return __target_impl<F>();
488 template <
typename F>
491 return const_cast<F*
>(f);
495#ifdef NEFORCE_STANDARD_17
500struct __function_guide_helper;
502template <
typename Result,
typename Class,
typename... Args>
503struct __function_guide_helper<Result (Class::*)(Args...)> {
504 using type = Result(Args...);
510template <
typename Res,
typename... Args>
511function(Res (*)(Args...)) -> function<Res(Args...)>;
513template <
typename Func,
typename Sign =
typename inner::__function_guide_helper<
515function(Func) -> function<Sign>;
528template <
typename Res,
typename... Args>
530 return !
static_cast<bool>(f);
541template <
typename Res,
typename... Args>
543 return !
static_cast<bool>(f);
554template <
typename Res,
typename... Args>
556 return static_cast<bool>(f);
567template <
typename Res,
typename... Args>
569 return static_cast<bool>(f);
574NEFORCE_END_NAMESPACE__
const std::type_info & target_type() const noexcept
获取目标类型信息
function & operator=(F &&callable) noexcept(handler_t< F >::template nothrow_init< F >())
从任意可调用对象赋值
void swap(function &other) noexcept
交换两个function对象
function & operator=(reference_wrapper< F > wrapper) noexcept
从引用包装器赋值
function(F &&callable) noexcept(handler_t< F >::template nothrow_init< F >())
从任意可调用对象构造
function & operator=(nullptr_t np) noexcept
空指针赋值运算符
function & operator=(const function &other)
复制赋值运算符
Res operator()(Args... args) const
函数调用运算符
function(nullptr_t np=nullptr) noexcept
默认构造函数
function & operator=(function &&other) noexcept
移动赋值运算符
const F * target() const noexcept
获取目标对象的常量指针
F * target() noexcept
获取目标对象的指针
function(const function &other)
复制构造函数
function(function &&other) noexcept
移动构造函数
constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
constexpr T * addressof(T &x) noexcept
获取对象的地址
enable_if_t< is_void_v< T >, future_result_t< T > > get(future< T > &f)
通用future结果获取函数
unsigned char byte_t
字节类型,定义为无符号字符
decltype(nullptr) nullptr_t
空指针类型
bool operator!=(const function< Res(Args...)> &f, nullptr_t np) noexcept
不等于空指针比较
bool operator==(const function< Res(Args...)> &f, nullptr_t np) noexcept
等于空指针比较
constexpr void destroy(T *pointer) noexcept(is_nothrow_destructible_v< T >)
销毁单个对象
constexpr inner::__invoke_result_aux< Callable, Args... >::type invoke(Callable &&f, Args &&... args) noexcept(is_nothrow_invocable< Callable, Args... >::value)
统一调用接口
constexpr enable_if_t< is_invocable_r< Res, Callable, Args... >::value, Res > invoke_r(Callable &&f, Args &&... args) noexcept(is_nothrow_invocable< Callable, Args... >::value)
带返回类型检查的统一调用接口
constexpr bool is_invocable_r_v
is_invocable_r的便捷变量模板
typename remove_function_qualifiers< T >::type remove_function_qualifiers_t
remove_function_qualifiers的便捷别名
typename remove_cvref< T >::type remove_cvref_t
remove_cvref的便捷别名
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
void swap()=delete
删除无参数的swap重载
typename decay< T >::type decay_t
decay的便捷别名
constexpr bool empty(const Container &cont) noexcept(noexcept(cont.empty()))
检查容器是否为空
constexpr decltype(auto) data(Container &cont) noexcept(noexcept(cont.data()))
获取容器的底层数据指针
constexpr bool is_copy_constructible_v
is_copy_constructible的便捷变量模板
constexpr bool is_constructible_v
is_constructible的便捷变量模板
constexpr bool is_location_invariant_v
is_location_invariant的便捷变量模板
constexpr bool conjunction_v
conjunction的便捷变量模板
bool_constant< true > true_type
表示true的类型
constexpr bool is_same_v
is_same的便捷变量模板
bool_constant< false > false_type
表示false的类型
integral_constant< bool, Value > bool_constant
布尔常量包装器
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名