LeviLamina
Loading...
Searching...
No Matches
function_invoke.h
1#pragma once
2
3#include <functional>
4
5#include "ll/api/base/TypeTraits.h"
6#include "mc/platform/brstd/detail/DerivedType.h"
7#include "mc/platform/brstd/detail/function_invoke_base.h"
8
9namespace brstd::detail::function {
10
11template <DerivedType Type, class Signature>
12class function_invoke : public function_invoke_base<Type, Signature> {
14
15 template <class Fn>
16 static constexpr bool enable_one_arg_constructor =
17 !(std::is_same_v<std::remove_cvref_t<Fn>, function_invoke>
18 || std::is_base_of_v<function_invoke, std::remove_cvref_t<Fn>>)
19 && !ll::traits::is_specialization_of_v<std::remove_cvref_t<Fn>, std::in_place_type_t>
20 && base::template is_callable_from<std::decay_t<Fn>>;
21
22 template <class Fn, class... Xs>
23 static constexpr bool enable_in_place_constructor =
24 std::is_constructible_v<std::decay_t<Fn>, Xs...> && base::template is_callable_from<std::decay_t<Fn>>;
25
26 template <class Fn, class U, class... Xs>
27 static constexpr bool enable_in_place_list_constructor =
28 std::is_constructible_v<std::decay_t<Fn>, std::initializer_list<U>&, Xs...>
29 && base::template is_callable_from<std::decay_t<Fn>>;
30
31public:
32 function_invoke() = default;
33 function_invoke(std::nullptr_t) : function_invoke() {}
34 template <class F>
35 requires enable_one_arg_constructor<F>
36 function_invoke(F&& f) {
37 using Fn = std::decay_t<F>;
38 static_assert(std::is_constructible_v<Fn, F>);
39 if constexpr (std::is_member_pointer_v<Fn> || std::is_pointer_v<Fn> || requires(F e) {
40 { e == nullptr } -> std::same_as<bool>;
41 }) {
42 if (f == nullptr) {
43 this->construct_empty();
44 return;
45 }
46 }
47 using FnInvQuals = base::template FnInvQuals<Fn>;
48 this->template construct_target<Fn, FnInvQuals>(std::forward<F>(f));
49 }
50
51 template <class F, class... Xs>
52 requires enable_in_place_constructor<F, Xs...>
53 explicit function_invoke(std::in_place_type_t<F>, Xs&&... args) {
54 using Fn = std::decay_t<F>;
55 static_assert(std::is_same_v<Fn, F>);
56 using FnInvQuals = base::template FnInvQuals<Fn>;
57 this->template construct_target<Fn, FnInvQuals>(std::forward<Xs>(args)...);
58 }
59
60 template <class F, class U, class... Xs>
61 requires enable_in_place_list_constructor<F, U, Xs...>
62 explicit function_invoke(std::in_place_type_t<F>, std::initializer_list<U> l, Xs&&... args) {
63 using Fn = std::decay_t<F>;
64 static_assert(std::is_same_v<Fn, F>);
65 using FnInvQuals = base::template FnInvQuals<Fn>;
66 this->template construct_target<Fn, FnInvQuals>(l, std::forward<Xs>(args)...);
67 }
68
69public:
70 void swap(function_invoke& other) {
71 function_invoke tmp = std::move(other);
72 other = std::move(*this);
73 *this = std::move(tmp);
74 }
75};
76
77} // namespace brstd::detail::function
Definition function_invoke_base.h:12
Definition function_invoke.h:12