MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
function.hpp
浏览该文件的文档.
1#ifndef MSTL_CORE_FUNCTIONAL_FUNCTION_HPP__
2#define MSTL_CORE_FUNCTIONAL_FUNCTION_HPP__
3
10
13#include <typeinfo>
15
21
28template <typename Sign>
30
33
40enum class FUNCTION_OPERATE {
41 GET_TYPE_INFO,
42 GET_PTR,
43 COPY_PTR,
44 DESTROY_PTR
45};
46
47
54class __undefined_util;
55
62union __nocopy_type {
63 void* object_;
64 const void* const_object_;
65 void (* function_pointer_)();
66 void (__undefined_util::* member_pointer_)();
67};
68
75union storage_data {
76 MSTL_NODISCARD void* access() noexcept { return &data_[0]; }
77 MSTL_NODISCARD const void* access() const noexcept { return &data_[0]; }
78
79 template <typename T>
80 MSTL_NODISCARD T& access() noexcept { return *static_cast<T*>(access()); }
81
82 template <typename T>
83 MSTL_NODISCARD const T& access() const noexcept { return *static_cast<const T*>(access()); }
84
85 __nocopy_type unused_;
86 byte_t data_[sizeof(__nocopy_type)];
87};
88
95class __function_base {
96public:
97 static constexpr size_t max_size_ = sizeof(__nocopy_type);
98 static constexpr size_t max_align_ = alignof(__nocopy_type);
99
107 template <typename F>
108 class __manager_base {
109 protected:
110 static constexpr bool stored_ = is_location_invariant_v<F> && sizeof(F) <= max_size_
111 && alignof(F) <= max_align_ && max_align_ % alignof(F) == 0;
112
113 private:
114 template <typename U, bool = stored_>
115 struct __get_pointer_impl;
116
117 template <typename U>
118 struct __get_pointer_impl<U, true> {
119 static U* get(const storage_data& src) noexcept {
120 const U& f = src.access<U>();
121 return const_cast<U*>(_MSTL addressof(f));
122 }
123 };
124
125 template <typename U>
126 struct __get_pointer_impl<U, false> {
127 static U* get(const storage_data& src) noexcept {
128 return src.access<U*>();
129 }
130 };
131
132 protected:
133 using storage_ = bool_constant<stored_>;
134
135 static F* get_pointer(const storage_data& src) noexcept {
136 return __get_pointer_impl<F>::get(src);
137 }
138
139 private:
140 template <typename Fn>
141 static void create(storage_data& data, Fn&& f, true_type) {
142 ::new(data.access()) F(_MSTL forward<Fn>(f));
143 }
144 template <typename Fn>
145 static void create(storage_data& data, Fn&& f, false_type) {
146 data.access<F*>() = new F(_MSTL forward<Fn>(f));
147 }
148
149 static void destroy(storage_data& data, true_type) {
150 data.access<F>().~F();
151 }
152 static void destroy(storage_data& data, false_type) {
153 delete data.access<F*>();
154 }
155
156 public:
157 static bool manage(storage_data& dest, const storage_data& src, const FUNCTION_OPERATE oper) {
158 switch (oper) {
159 case FUNCTION_OPERATE::GET_TYPE_INFO:
160 dest.access<const std::type_info*>() = &typeid(F);
161 break;
162 case FUNCTION_OPERATE::GET_PTR:
163 dest.access<F*>() = __manager_base::get_pointer(src);
164 break;
165 case FUNCTION_OPERATE::COPY_PTR:
166 __manager_base::init_func(dest, *const_cast<const F*>(__manager_base::get_pointer(src)));
167 break;
168 case FUNCTION_OPERATE::DESTROY_PTR:
169 __manager_base::destroy(dest, storage_());
170 break;
171 }
172 return false;
173 }
174
175 template <typename Fn>
176 static void init_func(storage_data& func, Fn&& f)
177 noexcept(conjunction_v<storage_, is_nothrow_constructible<F, Fn>>) {
178 __manager_base::create(func, _MSTL forward<Fn>(f), storage_());
179 }
180
181 template <typename Sign>
182 static bool not_empty_function(const _MSTL function<Sign>& f) noexcept {
183 return static_cast<bool>(f);
184 }
185 template <typename T>
186 static bool not_empty_function(T* fptr) noexcept {
187 return fptr != nullptr;
188 }
189 template <typename Class, typename T>
190 static bool not_empty_function(T Class::* mptr) noexcept {
191 return mptr != nullptr;
192 }
193 template <typename T>
194 static bool not_empty_function(const T&) noexcept {
195 return true;
196 }
197 };
198
199 using manage_type = bool (*)(storage_data&, const storage_data&, FUNCTION_OPERATE);
200
201 storage_data func_{};
202 manage_type manager_ = nullptr;
203
204
205 __function_base() = default;
206 ~__function_base() {
207 if (manager_)
208 manager_(func_, func_, FUNCTION_OPERATE::DESTROY_PTR);
209 }
210
211 MSTL_NODISCARD bool empty() const { return !manager_; }
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>
227 : public __function_base::__manager_base<F> {
228private:
229 using base_type = __function_base::__manager_base<F>;
230public:
231 static bool manage(storage_data& dest, const storage_data& src,
232 FUNCTION_OPERATE oper) {
233 switch (oper) {
234 case FUNCTION_OPERATE::GET_TYPE_INFO:
235 dest.access<const std::type_info*>() = &typeid(F);
236 break;
237 case FUNCTION_OPERATE::GET_PTR:
238 dest.access<F*>() = base_type::get_pointer(src);
239 break;
240 default:
241 base_type::manage(dest, src, oper);
242 }
243 return false;
244 }
245
246 static Res invoke(const storage_data& f, Args&&... args) {
247 return _MSTL invoke_r<Res>(*base_type::get_pointer(f), _MSTL forward<Args>(args)...);
248 }
249
250 template <typename Fn>
251 static constexpr bool nothrow_init() noexcept {
252 return conjunction_v<typename base_type::storage_, is_nothrow_constructible<F, Fn>>;
253 }
254};
255
256template <>
257class __function_manage_handler<void, void> {
258public:
259 static bool manage(storage_data&, const storage_data&, FUNCTION_OPERATE) {
260 return false;
261 }
262};
263
264template <typename Sign, typename F, bool Valid = is_object_v<F>>
265struct __function_handler_dispatch : __function_manage_handler<Sign, remove_cv_t<F>> {};
266
267template <typename Sign, typename F>
268struct __function_handler_dispatch<Sign, F, false> : __function_manage_handler<void, void> {};
269
272
280template <typename Res, typename... Args>
281class function<Res(Args...)> : _INNER __function_base {
282private:
283 using invoker_type = Res (*)(const _INNER storage_data&, Args&&...);
284
285private:
286 invoker_type invoker_ = nullptr;
287
288private:
289 template <typename F, bool IsSelf = is_same_v<remove_cvref_t<F>, function>>
290 using enable_decay_t = typename enable_if_t<!IsSelf, decay<F>>::type;
291
292 template <typename F, typename = void>
293 struct callable_t : false_type {};
294
295 template <typename F>
296 struct callable_t<F, enable_if_t<
297 !is_same_v<remove_cvref_t<F>, function> &&
298 is_invocable_r_v<Res, decay_t<F>&, Args...>
299 >> : true_type {};
300
301 template <typename F>
302 using handler_t = _INNER __function_manage_handler<Res(Args...), decay_t<F>>;
303
304 template <typename F, enable_if_t<is_object_v<F>, int> = 0>
305 MSTL_ALWAYS_INLINE const F* __target_impl() const noexcept {
306 if (manager_ == &_INNER __function_handler_dispatch<Res(Args...), F>::manage
307 || (manager_ && typeid(F) == target_type())) {
308 _INNER storage_data ptr{};
309 manager_(ptr, func_, _INNER FUNCTION_OPERATE::GET_PTR);
310 return ptr.access<const F*>();
311 }
312 return nullptr;
313 }
314
315 template <typename F, enable_if_t<!is_object_v<F>, int> = 0>
316 MSTL_ALWAYS_INLINE const F* __target_impl() const noexcept {
317 return nullptr;
318 }
319
320public:
321 using result_type = Res;
322
327 function(nullptr_t null = nullptr) noexcept
328 : __function_base() {}
329
334 function(const function& x) : __function_base() {
335 if (static_cast<bool>(x)) {
336 x.manager_(func_, x.func_, _INNER FUNCTION_OPERATE::COPY_PTR);
337 invoker_ = x.invoker_;
338 manager_ = x.manager_;
339 }
340 }
341
346 function(function&& x) noexcept
347 : __function_base(), invoker_(x.invoker_) {
348 if (static_cast<bool>(x)) {
349 func_ = x.func_;
350 manager_ = x.manager_;
351 x.manager_ = nullptr;
352 x.invoker_ = nullptr;
353 }
354 }
355
361 template <typename F, enable_if_t<callable_t<F>::value, int> = 0>
362 function(F&& f) noexcept(handler_t<F>::template nothrow_init<F>())
363 : __function_base() {
364 static_assert(
365 is_copy_constructible_v<decay_t<F>> &&
366 is_constructible_v<decay_t<F>, F>,
367 "target of function must be constructible");
368
369 using handler = handler_t<F>;
370 if (handler::not_empty_function(f)) {
371 handler::init_func(func_, _MSTL forward<F>(f));
372 invoker_ = &handler::invoke;
373 manager_ = &handler::manage;
374 }
375 }
376
382 function& operator =(const function& x) {
383 function(x).swap(*this);
384 return *this;
385 }
386
392 function& operator =(function&& x) noexcept {
393 function(_MSTL move(x)).swap(*this);
394 return *this;
395 }
396
402 function& operator =(nullptr_t null) noexcept {
403 if (manager_) {
404 manager_(func_, func_, _INNER FUNCTION_OPERATE::DESTROY_PTR);
405 manager_ = nullptr;
406 invoker_ = nullptr;
407 }
408 return *this;
409 }
410
417 template <typename F, enable_if_t<callable_t<F>::value, int> = 0>
418 function& operator =(F&& f) noexcept(handler_t<F>::template nothrow_init<F>()) {
419 function(_MSTL forward<F>(f)).swap(*this);
420 return *this;
421 }
422
429 template <typename F>
430 function& operator =(reference_wrapper<F> f) noexcept {
431 function(f).swap(*this);
432 return *this;
433 }
434
439 void swap(function& x) noexcept {
440 _MSTL swap(func_, x.func_);
441 _MSTL swap(manager_, x.manager_);
442 _MSTL swap(invoker_, x.invoker_);
443 }
444
449 explicit operator bool() const noexcept { return !empty(); }
450
457 Res operator ()(Args&&... args) const
458 noexcept(noexcept(invoker_(func_, _MSTL forward<Args>(args)...))) {
459 if (empty()) {
460 throw_exception(memory_exception("functional pointing to null."));
461 }
462 return invoker_(func_, _MSTL forward<Args>(args)...);
463 }
464
469 MSTL_NODISCARD const std::type_info& target_type() const noexcept {
470 if (manager_) {
471 _INNER storage_data result{};
472 manager_(result, func_, _INNER FUNCTION_OPERATE::GET_TYPE_INFO);
473 if (const auto info = result.access<const std::type_info*>()) {
474 return *info;
475 }
476 }
477 return typeid(void);
478 }
479
485 template <typename F>
486 const F* target() const noexcept {
487 return __target_impl<F>();
488 }
489
495 template <typename F>
496 F* target() noexcept {
497 const F* f = const_cast<const function*>(this)->target<F>();
498 return *const_cast<F**>(&f);
499 }
500};
501
502#ifdef MSTL_SUPPORT_DEDUCTION_GUIDES__
505
506template <typename>
507struct __function_guide_helper;
508
509template <typename Result, typename Class, typename... Args>
510struct __function_guide_helper<Result (Class::*)(Args...)> {
511 using type = Result(Args...);
512};
513
516
517template <typename Res, typename... Args>
518function(Res(*)(Args...)) -> function<Res(Args...)>;
519
520template <typename Func, typename Sign = typename _INNER __function_guide_helper<
521 remove_function_qualifiers_t<decltype(&Func::operator ())>>::type>
522function(Func) -> function<Sign>;
523
524#endif
525
526
535template <typename Res, typename... Args>
536bool operator ==(const function<Res(Args...)>& f, nullptr_t null) noexcept {
537 return !static_cast<bool>(f);
538}
539
548template <typename Res, typename... Args>
549bool operator ==(nullptr_t null, const function<Res(Args...)>& f) noexcept {
550 return !static_cast<bool>(f);
551}
552
561template <typename Res, typename... Args>
562bool operator !=(const function<Res(Args...)>& f, nullptr_t null) noexcept {
563 return static_cast<bool>(f);
564}
565
574template <typename Res, typename... Args>
575bool operator !=(nullptr_t null, const function<Res(Args...)>& f) noexcept {
576 return static_cast<bool>(f);
577}
578 // FunctionWrapper
580
582#endif // MSTL_CORE_FUNCTIONAL_FUNCTION_HPP__
function(F &&f) noexcept(handler_t< F >::template nothrow_init< F >())
从任意可调用对象构造
void swap(function &x) noexcept
交换两个function对象
MSTL_NODISCARD const std::type_info & target_type() const noexcept
获取目标类型信息
Res result_type
返回类型别名
function(const function &x)
复制构造函数
function(function &&x) noexcept
移动构造函数
const F * target() const noexcept
获取目标对象的常量指针
F * target() noexcept
获取目标对象的指针
function(nullptr_t null=nullptr) noexcept
默认构造函数
函数包装器主模板声明
引用包装器类模板
MSTL异常处理框架
MSTL_NODISCARD constexpr T * addressof(T &x) noexcept
获取对象的地址
MSTL_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
MSTL_ALWAYS_INLINE 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 null) noexcept
不等于空指针比较
bool operator==(const function< Res(Args...)> &f, nullptr_t null) noexcept
等于空指针比较
MSTL_CONSTEXPR20 void destroy(T *pointer) noexcept(is_nothrow_destructible_v< T >)
销毁单个对象
MSTL_CONSTEXPR14 _INNER __invoke_result_aux< Callable, Args... >::type invoke(Callable &&f, Args &&... args) noexcept(is_nothrow_invocable< Callable, Args... >::value)
统一调用接口
MSTL_CONSTEXPR14 enable_if_t< is_invocable_r< Res, Callable, Args... >::value, Res > invoke_r(Callable &&f, Args &&... args) noexcept(is_nothrow_invocable< Callable, Args... >::value)
带返回类型检查的统一调用接口
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_INNER__
结束inner命名空间
#define _INNER
inner命名空间前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
#define MSTL_BEGIN_INNER__
开始inner命名空间
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)
移动范围元素
void swap()=delete
删除无参数的swap重载
typename decay< T >::type decay_t
decay的便捷别名
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr bool empty(const Container &cont) noexcept(noexcept(cont.empty()))
检查容器是否为空
MSTL_NODISCARD MSTL_ALWAYS_INLINE constexpr decltype(auto) data(Container &cont) noexcept(noexcept(cont.data()))
获取容器的底层数据指针
bool_constant< true > true_type
表示true的类型
bool_constant< false > false_type
表示false的类型
integral_constant< bool, Value > bool_constant
布尔常量包装器
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
MSTL统一调用接口
内存操作异常