NexusForce 1.0.0
A rigorously engineered full-stack C++ backend library.
载入中...
搜索中...
未找到
functional/function.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_FUNCTIONAL_FUNCTION_HPP__
2#define NEFORCE_CORE_FUNCTIONAL_FUNCTION_HPP__
3
10
11#include <typeinfo>
12#include <new>
15NEFORCE_BEGIN_NAMESPACE__
16
22
29template <typename Sign>
31
33NEFORCE_BEGIN_INNER__
34
41enum class FUNCTION_OPERATE {
42 GET_TYPE_INFO,
43 GET_PTR,
44 COPY_PTR,
45 DESTROY_PTR
46};
47
48
55class __undefined_util;
56
63union __nocopy_type {
64 void* object_;
65 const void* const_object_;
66 void (*function_pointer_)();
67 void (__undefined_util::*member_pointer_)();
68};
69
76union storage_data {
77 storage_data() noexcept = default;
78
79 NEFORCE_NODISCARD void* access() noexcept { return &data_[0]; }
80 NEFORCE_NODISCARD const void* access() const noexcept { return &data_[0]; }
81
82 template <typename T>
83 NEFORCE_NODISCARD T& access() noexcept {
84 return *static_cast<T*>(access());
85 }
86
87 template <typename T>
88 NEFORCE_NODISCARD const T& access() const noexcept {
89 return *static_cast<const T*>(access());
90 }
91
92 __nocopy_type unused_;
93 byte_t data_[sizeof(__nocopy_type)];
94};
95
102class __function_base {
103public:
104 static constexpr size_t max_size_ = sizeof(__nocopy_type);
105 static constexpr size_t max_align_ = alignof(__nocopy_type);
106
114 template <typename F>
115 class __manager_base {
116 protected:
117 static constexpr bool stored_ = is_location_invariant_v<F> && sizeof(F) <= max_size_ &&
118 alignof(F) <= max_align_ && max_align_ % alignof(F) == 0;
119
120 private:
121 template <typename U, bool = stored_>
122 struct __get_pointer_impl;
123
124 template <typename U>
125 struct __get_pointer_impl<U, true> {
126 static U* get(const storage_data& src) noexcept {
127 const U& f = src.access<U>();
128 return const_cast<U*>(_NEFORCE addressof(f));
129 }
130 };
131
132 template <typename U>
133 struct __get_pointer_impl<U, false> {
134 static U* get(const storage_data& src) noexcept { return src.access<U*>(); }
135 };
136
137 protected:
138 using storage_ = bool_constant<stored_>;
139
140 static F* get_pointer(const storage_data& src) noexcept { return __get_pointer_impl<F>::get(src); }
141
142 private:
143 template <typename Fn>
144 static void create(storage_data& data, Fn&& f, true_type /*unused*/) {
145 ::new (data.access()) F(_NEFORCE forward<Fn>(f));
146 }
147 template <typename Fn>
148 static void create(storage_data& data, Fn&& f, false_type /*unused*/) {
149 data.access<F*>() = new F(_NEFORCE forward<Fn>(f));
150 }
151
152 static void destroy(storage_data& data, true_type /*unused*/) { data.access<F>().~F(); }
153 static void destroy(storage_data& data, false_type /*unused*/) { delete data.access<F*>(); }
154
155 public:
156 static bool manage(storage_data& dest, const storage_data& src, const FUNCTION_OPERATE oper) {
157 switch (oper) {
158 case FUNCTION_OPERATE::GET_TYPE_INFO:
159 dest.access<const std::type_info*>() = &typeid(F);
160 break;
161 case FUNCTION_OPERATE::GET_PTR:
162 dest.access<F*>() = __manager_base::get_pointer(src);
163 break;
164 case FUNCTION_OPERATE::COPY_PTR:
165 __manager_base::init_func(dest, *const_cast<const F*>(__manager_base::get_pointer(src)));
166 break;
167 case FUNCTION_OPERATE::DESTROY_PTR:
168 __manager_base::destroy(dest, storage_());
169 break;
170 }
171 return false;
172 }
173
174 template <typename Fn>
175 static void init_func(storage_data& func,
176 Fn&& f) noexcept(conjunction_v<storage_, is_nothrow_constructible<F, Fn>>) {
177 __manager_base::create(func, _NEFORCE forward<Fn>(f), storage_());
178 }
179
180 template <typename Sign>
181 static bool not_empty_function(const _NEFORCE function<Sign>& f) noexcept {
182 return static_cast<bool>(f);
183 }
184 template <typename T>
185 static bool not_empty_function(T* fptr) noexcept {
186 return fptr != nullptr;
187 }
188 template <typename Class, typename T>
189 static bool not_empty_function(T Class::* mptr) noexcept {
190 return mptr != nullptr;
191 }
192 template <typename T>
193 static bool not_empty_function(const T& /*unused*/) noexcept {
194 return true;
195 }
196 };
197
198 using manage_type = bool (*)(storage_data&, const storage_data&, FUNCTION_OPERATE);
199
200 storage_data func_{};
201 manage_type manager_ = nullptr;
202
203
204 __function_base() noexcept = default;
205 ~__function_base() {
206 if (manager_ != nullptr) {
207 manager_(func_, func_, FUNCTION_OPERATE::DESTROY_PTR);
208 }
209 }
210
211 NEFORCE_NODISCARD bool empty() const { return manager_ == nullptr; }
212};
213
222template <typename Sign, typename F>
223class __function_manage_handler;
224
225template <typename Res, typename F, typename... Args>
226class __function_manage_handler<Res(Args...), F> : public __function_base::__manager_base<F> {
227private:
228 using base_type = __function_base::__manager_base<F>;
229
230public:
231 static bool manage(storage_data& dest, const storage_data& src, FUNCTION_OPERATE oper) {
232 switch (oper) {
233 case FUNCTION_OPERATE::GET_TYPE_INFO:
234 dest.access<const std::type_info*>() = &typeid(F);
235 break;
236 case FUNCTION_OPERATE::GET_PTR:
237 dest.access<F*>() = base_type::get_pointer(src);
238 break;
239 default:
240 base_type::manage(dest, src, oper);
241 }
242 return false;
243 }
244
245 static Res invoke(const storage_data& f, Args... args) {
246 return _NEFORCE invoke_r<Res>(*base_type::get_pointer(f), _NEFORCE forward<Args>(args)...);
247 }
248
249 template <typename Fn>
250 static constexpr bool nothrow_init() noexcept {
251 return conjunction_v<typename base_type::storage_, is_nothrow_constructible<F, Fn>>;
252 }
253};
254
255template <>
256class __function_manage_handler<void, void> {
257public:
258 static bool manage(storage_data& /*unused*/, const storage_data& /*unused*/, FUNCTION_OPERATE /*unused*/) {
259 return false;
260 }
261};
262
263template <typename Sign, typename F, bool Valid = is_object_v<F>>
264struct __function_handler_dispatch : __function_manage_handler<Sign, remove_cv_t<F>> {};
265
266template <typename Sign, typename F>
267struct __function_handler_dispatch<Sign, F, false> : __function_manage_handler<void, void> {};
268
269NEFORCE_END_INNER__
271
279template <typename Res, typename... Args>
280class function<Res(Args...)> : inner::__function_base {
281private:
282 using invoker_type = Res (*)(const inner::storage_data&, Args...);
283
284private:
285 invoker_type invoker_ = nullptr;
286
287private:
288 template <typename F, bool IsSelf = is_same_v<remove_cvref_t<F>, function>>
289 using enable_decay_t = typename enable_if_t<!IsSelf, decay<F>>::type;
290
291 template <typename F, typename = void>
292 struct callable_t : false_type {};
293
294 template <typename F>
295 struct callable_t<
297 : true_type {};
298
299 template <typename F>
300 using handler_t = inner::__function_manage_handler<Res(Args...), decay_t<F>>;
301
302 template <typename F, enable_if_t<is_object_v<F>, int> = 0>
303 NEFORCE_ALWAYS_INLINE const F* __target_impl() const noexcept {
304 if (manager_ == &inner::__function_handler_dispatch<Res(Args...), F>::manage) {
305 inner::storage_data ptr{};
306 manager_(ptr, func_, inner::FUNCTION_OPERATE::GET_PTR);
307 return ptr.access<const F*>();
308 }
309 return nullptr;
310 }
311
312 template <typename F, enable_if_t<!is_object_v<F>, int> = 0>
313 NEFORCE_ALWAYS_INLINE const F* __target_impl() const noexcept {
314 return nullptr;
315 }
316
317public:
318 using result_type = Res;
319
324 function(nullptr_t np = nullptr) noexcept :
325 __function_base() {}
326
331 function(const function& other) :
332 __function_base() {
333 if (static_cast<bool>(other)) {
334 other.manager_(func_, other.func_, inner::FUNCTION_OPERATE::COPY_PTR);
335 invoker_ = other.invoker_;
336 manager_ = other.manager_;
337 }
338 }
339
344 function(function&& other) noexcept :
345 __function_base() {
346 func_ = other.func_;
347 manager_ = other.manager_;
348 invoker_ = other.invoker_;
349 other.manager_ = nullptr;
350 other.invoker_ = nullptr;
351 }
352
358 template <typename F, enable_if_t<callable_t<F>::value, int> = 0>
359 function(F&& callable) noexcept(handler_t<F>::template nothrow_init<F>()) :
360 __function_base() {
362 "target of function must be constructible");
363
364 using handler = handler_t<F>;
365 if (handler::not_empty_function(callable)) {
366 handler::init_func(func_, _NEFORCE forward<F>(callable));
367 invoker_ = &handler::invoke;
368 manager_ = &handler::manage;
369 }
370 }
371
377 function& operator=(const function& other) {
378 function(other).swap(*this);
379 return *this;
380 }
381
387 function& operator=(function&& other) noexcept {
388 function(_NEFORCE move(other)).swap(*this);
389 return *this;
390 }
391
398 if (manager_) {
399 manager_(func_, func_, inner::FUNCTION_OPERATE::DESTROY_PTR);
400 manager_ = nullptr;
401 invoker_ = nullptr;
402 }
403 return *this;
404 }
405
412 template <typename F, enable_if_t<callable_t<F>::value, int> = 0>
413 function& operator=(F&& callable) noexcept(handler_t<F>::template nothrow_init<F>()) {
414 function(_NEFORCE forward<F>(callable)).swap(*this);
415 return *this;
416 }
417
424 template <typename F>
426 function(wrapper).swap(*this);
427 return *this;
428 }
429
434 void swap(function& other) noexcept {
435 _NEFORCE swap(func_, other.func_);
436 _NEFORCE swap(manager_, other.manager_);
437 _NEFORCE swap(invoker_, other.invoker_);
438 }
439
444 explicit operator bool() const noexcept { return !empty(); }
445
452 Res operator()(Args... args) const {
453 if (empty()) {
454 NEFORCE_THROW_EXCEPTION(memory_exception("functional pointing to null."));
455 }
456 return invoker_(func_, _NEFORCE forward<Args>(args)...);
457 }
458
463 NEFORCE_NODISCARD const std::type_info& target_type() const noexcept {
464 if (manager_) {
465 inner::storage_data result{};
466 manager_(result, func_, inner::FUNCTION_OPERATE::GET_TYPE_INFO);
467 if (const auto* const info = result.access<const std::type_info*>()) {
468 return *info;
469 }
470 }
471 return typeid(void);
472 }
473
479 template <typename F>
480 const F* target() const noexcept {
481 return __target_impl<F>();
482 }
483
489 template <typename F>
490 F* target() noexcept {
491 const F* f = const_cast<const function*>(this)->target<F>();
492 return const_cast<F*>(f);
493 }
494};
495
496#ifdef NEFORCE_STANDARD_17
498NEFORCE_BEGIN_INNER__
499
500template <typename>
501struct __function_guide_helper;
502
503template <typename Result, typename Class, typename... Args>
504struct __function_guide_helper<Result (Class::*)(Args...)> {
505 using type = Result(Args...);
506};
507
508NEFORCE_END_INNER__
510
511template <typename Res, typename... Args>
512function(Res (*)(Args...)) -> function<Res(Args...)>;
513
514template <typename Func, typename Sign = typename inner::__function_guide_helper<
515 remove_function_qualifiers_t<decltype(&Func::operator())>>::type>
516function(Func) -> function<Sign>;
517
518#endif
519
520
529template <typename Res, typename... Args>
530bool operator==(const function<Res(Args...)>& f, nullptr_t np) noexcept {
531 return !static_cast<bool>(f);
532}
533
542template <typename Res, typename... Args>
543bool operator==(nullptr_t np, const function<Res(Args...)>& f) noexcept {
544 return !static_cast<bool>(f);
545}
546
555template <typename Res, typename... Args>
556bool operator!=(const function<Res(Args...)>& f, nullptr_t np) noexcept {
557 return static_cast<bool>(f);
558}
559
568template <typename Res, typename... Args>
569bool operator!=(nullptr_t np, const function<Res(Args...)>& f) noexcept {
570 return static_cast<bool>(f);
571}
572 // FunctionWrapper
574
575NEFORCE_END_NAMESPACE__
576#endif // NEFORCE_CORE_FUNCTIONAL_FUNCTION_HPP__
function(function &&other) noexcept
移动构造函数
function & operator=(const function &other)
复制赋值运算符
function & operator=(function &&other) noexcept
移动赋值运算符
function(nullptr_t np=nullptr) noexcept
默认构造函数
function & operator=(reference_wrapper< F > wrapper) noexcept
从引用包装器赋值
const std::type_info & target_type() const noexcept
获取目标类型信息
function(F &&callable) noexcept(handler_t< F >::template nothrow_init< F >())
从任意可调用对象构造
Res operator()(Args... args) const
函数调用运算符
F * target() noexcept
获取目标对象的指针
function & operator=(nullptr_t np) noexcept
空指针赋值运算符
void swap(function &other) noexcept
交换两个function对象
function(const function &other)
复制构造函数
const F * target() const noexcept
获取目标对象的常量指针
function & operator=(F &&callable) noexcept(handler_t< F >::template nothrow_init< F >())
从任意可调用对象赋值
函数包装器主模板声明
异常处理框架
constexpr T * addressof(T &x) noexcept
获取对象的地址
constexpr T && forward(remove_reference_t< 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 bool is_invocable_r_v
is_invocable_r的便捷变量模板
typename remove_cvref< T >::type remove_cvref_t
remove_cvref的便捷别名
typename remove_function_qualifiers< T >::type remove_function_qualifiers_t
remove_function_qualifiers的便捷别名
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
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_constructible_v
is_constructible的便捷变量模板
constexpr bool is_copy_constructible_v
is_copy_constructible的便捷变量模板
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
constexpr bool is_same_v
is_same的便捷变量模板
bool_constant< false > false_type
表示false的类型
bool_constant< true > true_type
表示true的类型
统一调用接口
function< float(float)> function
缓动函数类型:输入归一化时间 [0,1],输出进度 [0,1]