Maipa's Standard Library Extension 1.5.6
mstd
Loading...
Searching...
No Matches
function_view.hpp
1/*
2 * mstd - Maipa's Standard Library
3 *
4 * Licensed under the BSD 3-Clause License with Attribution Requirement.
5 * See the LICENSE file for details: https://github.com/MAIPA01/mstd/blob/main/LICENSE
6 *
7 * Copyright (c) 2025, Patryk Antosik (MAIPA01)
8 */
9
10#pragma once
11#ifndef _MSTD_FUNCTION_VIEW_HPP_
12 #define _MSTD_FUNCTION_VIEW_HPP_
13
14 #include "fmt/chrono.h"
15
16
17 #include <mstd/config.hpp>
18
20_MSTD_WARNING("this is only available for c++17 and greater!");
21 #else
22
23 #include <mstd/functions_types.hpp>
24 #include <mstd/is_same_function.hpp>
25
26namespace mstd {
27 namespace utils {
28 #pragma region VALIDITY_CHECKS
29 template<class FreeFunc, class F, class Ret, class... Args>
33
34 template<class MemberFunc, class F, class Ret, class... Args>
39
40 template<class Functor, bool IsConst, class F, class Ret, class... Args>
45
47 template<class FreeFunc, class F, class Ret, class... Args>
49
50 template<class MemberFunc, class F, class Ret, class... Args>
52
53 template<class Functor, bool IsConst, class F, class Ret, class... Args>
55 #endif
56 #pragma endregion
57
59 union {
60 void* functor_ptr = nullptr;
61 void (*func_ptr)();
62 std::byte mem_func_buffer[sizeof(void*) * 3];
63 };
64 };
65
66 template<class F, class Ret, class ArgsTuple>
68
69 template<class F, class Ret, class... Args>
70 struct base_function_view<F, Ret, std::tuple<Args...> > {
71 private:
72 template<class FreeFunc>
74
75 template<class MemberFunc>
77 utils::is_valid_member_function_v<mstd::remove_cvref_t<MemberFunc>, F, Ret, Args...>;
78
79 template<class Functor, bool IsConst>
81
82 template<class FreeFunc>
84 Args&&... args) noexcept(is_noexcept_function_v<FreeFunc>) {
86
87 func_ptr freeFunc = reinterpret_cast<func_ptr>(storage.func_ptr);
88 return std::invoke(freeFunc, std::forward<Args>(args)...);
89 }
90
91 template<class MemberFunc>
104
105 template<class Functor>
107 Args&&... args) noexcept(is_noexcept_function_v<Functor>) {
108 return std::invoke(*static_cast<Functor*>(storage.functor_ptr), std::forward<Args>(args)...);
109 }
110
111 using _invoker_type = Ret (*)(const function_storage&, void*, Args&&...) noexcept(is_noexcept_function_v<F>);
112
114 void* _parent = nullptr;
116
117 public:
119
120 base_function_view(std::nullptr_t) noexcept : base_function_view() {}
121
124
130
131 virtual ~base_function_view() noexcept = default;
132
133 base_function_view& operator=(std::nullptr_t) noexcept {
134 reset();
135 return *this;
136 }
137
142 return *this;
143 }
144
148 _parent = std::exchange(other._parent, nullptr);
149 _invoker = std::exchange(other._invoker, nullptr);
150 return *this;
151 }
152
153 #pragma region FREE_FUNCTIONS
155 template<class FreeFunc>
157 #else
158 template<class FreeFunc, std::enable_if_t<is_valid_free_function_v<FreeFunc>, bool> = true>
159 #endif
160 base_function_view(FreeFunc&& freeFunc) noexcept : _invoker(&_free_func_invoker<FreeFunc>) {
161 std::memset(&_storage, 0, sizeof(function_storage));
163 _storage.func_ptr = reinterpret_cast<void (*)()>(freeFunc);
164 }
165 else { _storage.func_ptr = reinterpret_cast<void (*)()>(&freeFunc); }
166 }
167
169 template<class FreeFunc>
171 #else
172 template<class FreeFunc, std::enable_if_t<is_valid_free_function_v<FreeFunc>, bool> = true>
173 #endif
174 base_function_view& operator=(FreeFunc&& freeFunc) noexcept {
176 std::memset(&_storage, 0, sizeof(function_storage));
178 _storage.func_ptr = reinterpret_cast<void (*)()>(freeFunc);
179 }
180 else { _storage.func_ptr = reinterpret_cast<void (*)()>(&freeFunc); }
181 return *this;
182 }
183
184 #pragma endregion
185
186 #pragma region MEMBER_FUNCTIONS
188 template<class MemberFunc>
190 #else
191 template<class MemberFunc, std::enable_if_t<is_valid_member_function_v<MemberFunc>, bool> = true>
192 #endif
198
200 template<class MemberFunc>
202 #else
203 template<class MemberFunc, std::enable_if_t<is_valid_member_function_v<MemberFunc>, bool> = true>
204 #endif
210
212 template<class MemberFunc>
214 #else
215 template<class MemberFunc, std::enable_if_t<is_valid_member_function_v<MemberFunc>, bool> = true>
216 #endif
222
224 template<class MemberFunc>
226 #else
227 template<class MemberFunc, std::enable_if_t<is_valid_member_function_v<MemberFunc>, bool> = true>
228 #endif
234
236 template<class MemberFunc>
238 #else
239 template<class MemberFunc, std::enable_if_t<is_valid_member_function_v<MemberFunc>, bool> = true>
240 #endif
250
252 template<class MemberFunc>
254 #else
255 template<class MemberFunc, std::enable_if_t<is_valid_member_function_v<MemberFunc>, bool> = true>
256 #endif
266
267 #pragma endregion
268
269 #pragma region FUNCTORS
271 template<class Functor>
273 #else
274 template<class Functor, std::enable_if_t<is_valid_functor_v<Functor, false>, bool> = true>
275 #endif
280
282 template<class Functor>
284 #else
285 template<class Functor, std::enable_if_t<is_valid_functor_v<Functor, true>, bool> = true>
286 #endif
291
293 template<class Functor>
295 #else
296 template<class Functor, std::enable_if_t<is_valid_functor_v<Functor, true>, bool> = true>
297 #endif
298 base_function_view(Functor&& functor) noexcept = delete;
299
301 template<class Functor>
303 #else
304 template<class Functor, std::enable_if_t<is_valid_functor_v<Functor, false>, bool> = true>
305 #endif
306 base_function_view& operator=(Functor& functor) noexcept {
307 std::memset(&_storage, 0, sizeof(function_storage));
310 return *this;
311 }
312
314 template<class Functor>
316 #else
317 template<class Functor, std::enable_if_t<is_valid_functor_v<Functor, true>, bool> = true>
318 #endif
319 base_function_view& operator=(const Functor& functor) noexcept {
320 std::memset(&_storage, 0, sizeof(function_storage));
323 return *this;
324 }
325
327 template<class Functor>
329 #else
330 template<class Functor, std::enable_if_t<is_valid_functor_v<Functor, true>, bool> = true>
331 #endif
332 base_function_view& operator=(Functor&& functor) noexcept = delete;
333 #pragma endregion
334
335 void reset() noexcept {
336 std::memset(&_storage, 0, sizeof(function_storage));
337 _parent = nullptr;
338 _invoker = nullptr;
339 }
340
342 template<class... InvokeArgs>
344 #else
345 template<class... InvokeArgs, std::enable_if_t<std::is_invocable_v<F, InvokeArgs...>, bool> = true>
346 #endif
349 }
350
352 template<class... InvokeArgs>
354 #else
355 template<class... InvokeArgs, std::enable_if_t<std::is_invocable_v<F, InvokeArgs...>, bool> = true>
356 #endif
358 return invoke(std::forward<InvokeArgs>(args)...);
359 }
360
361 [[nodiscard]] operator bool() const noexcept { return operator!=(nullptr); }
362
363 [[nodiscard]] bool operator!() const noexcept { return !static_cast<bool>(*this); }
364
365 [[nodiscard]] bool operator==(const base_function_view& other) const noexcept {
366 if (_parent != other._parent) { return false; }
367 if (_invoker != other._invoker) { return false; }
368
369 if (_invoker == nullptr) { return true; }
370
371 return std::memcmp(&_storage, &other._storage, sizeof(function_storage)) == 0;
372 }
373
374 [[nodiscard]] bool operator!=(const base_function_view& other) const noexcept
376 = default;
377 #else
378 {
379 return !operator==(other);
380 }
381 #endif
382
383 [[nodiscard]] bool operator==(std::nullptr_t) const noexcept { return _invoker == nullptr; }
384
385 [[nodiscard]] bool operator!=(std::nullptr_t) const noexcept { return !operator==(nullptr); }
386 };
387
388 template<class F>
390
391 template<class F>
395
398 #endif
399 } // namespace utils
400
403 #else
404 template<class F, std::enable_if_t<utils::is_valid_function_view_function_v<F>, bool> = true>
405 #endif
407 private:
409
410 template<class Func>
413
414 public:
415 function_view() noexcept = default;
416
417 function_view(nullptr_t) noexcept : _base(nullptr) {}
418
419 function_view(const function_view&) noexcept = default;
420 function_view(function_view&&) noexcept = default;
421 ~function_view() noexcept override = default;
422
424 template<class Func>
426 #else
427 template<class Func,
429 #endif
431 }
432
434 template<class MemberFunc>
436 #else
437 template<class MemberFunc, std::enable_if_t<can_be_noexcept_v<MemberFunc>, bool> = true>
438 #endif
441
443 template<class MemberFunc>
445 #else
446 template<class MemberFunc, std::enable_if_t<can_be_noexcept_v<MemberFunc>, bool> = true>
447 #endif
451
453 template<class MemberFunc>
455 #else
456 template<class MemberFunc, std::enable_if_t<can_be_noexcept_v<MemberFunc>, bool> = true>
457 #endif
460
462 template<class MemberFunc>
464 #else
465 template<class MemberFunc, std::enable_if_t<can_be_noexcept_v<MemberFunc>, bool> = true>
466 #endif
469
470 function_view& operator=(const function_view&) noexcept = default;
471 function_view& operator=(function_view&&) noexcept = default;
472
473 using _base::operator=;
474 };
475} // namespace mstd
476
477 #endif
478#endif
Definition function_view.hpp:406
function_view & operator=(function_view &&) noexcept=default
function_view(function_view &&) noexcept=default
function_view(const function_view &) noexcept=default
~function_view() noexcept override=default
static _MSTD_CONSTEXPR17 bool can_be_noexcept_v
Definition function_view.hpp:411
function_view() noexcept=default
function_view(nullptr_t) noexcept
Definition function_view.hpp:417
#define _MSTD_HAS_CXX17
Definition config.hpp:45
#define _MSTD_CONSTEXPR17
Definition config.hpp:76
#define _MSTD_HAS_CXX20
Definition config.hpp:52
Definition function_traits.hpp:23
static _MSTD_CONSTEXPR17 bool is_valid_function_view_function_v
Definition function_view.hpp:392
static _MSTD_CONSTEXPR17 bool is_valid_member_function_v
Definition function_view.hpp:35
static _MSTD_CONSTEXPR17 bool is_valid_free_function_v
Definition function_view.hpp:30
static _MSTD_CONSTEXPR17 bool is_valid_functor_v
Definition function_view.hpp:41
Definition arithmetic_types.hpp:23
base_function_view() noexcept
Definition function_view.hpp:118
static Ret _free_func_invoker(const function_storage &storage, void *, Args &&... args) noexcept(is_noexcept_function_v< FreeFunc >)
Definition function_view.hpp:83
static _MSTD_CONSTEXPR17 bool is_valid_member_function_v
Definition function_view.hpp:76
static _MSTD_CONSTEXPR17 bool is_valid_free_function_v
Definition function_view.hpp:73
base_function_view(FreeFunc &&freeFunc) noexcept
Definition function_view.hpp:160
base_function_view(base_function_view &&other) noexcept
Definition function_view.hpp:125
base_function_view & operator=(const Functor &functor) noexcept
Definition function_view.hpp:319
static Ret _functor_invoker(const function_storage &storage, void *, Args &&... args) noexcept(is_noexcept_function_v< Functor >)
Definition function_view.hpp:106
base_function_view & operator=(const base_function_view &other) noexcept
Definition function_view.hpp:138
void reset() noexcept
Definition function_view.hpp:335
static _MSTD_CONSTEXPR17 bool is_valid_functor_v
Definition function_view.hpp:80
base_function_view & operator=(FreeFunc &&freeFunc) noexcept
Definition function_view.hpp:174
base_function_view & operator=(Functor &functor) noexcept
Definition function_view.hpp:306
static Ret _member_func_invoker(const function_storage &storage, void *parent, Args &&... args) noexcept(is_noexcept_function_v< MemberFunc >)
Definition function_view.hpp:92
base_function_view(std::nullptr_t) noexcept
Definition function_view.hpp:120
base_function_view & operator=(base_function_view &&other) noexcept
Definition function_view.hpp:145
base_function_view & operator=(std::nullptr_t) noexcept
Definition function_view.hpp:133
base_function_view(const base_function_view &other) noexcept
Definition function_view.hpp:122
function_storage _storage
Definition function_view.hpp:113
_invoker_type _invoker
Definition function_view.hpp:115
Definition function_view.hpp:67
Definition function_view.hpp:58
void * functor_ptr
Definition function_view.hpp:60
void(* func_ptr)()
Definition function_view.hpp:61
std::byte mem_func_buffer[sizeof(void *) *3]
Definition function_view.hpp:62