1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #ifndef RUNTIME_INCLUDE_TAIHE_CALLBACK_HPP_
16 #define RUNTIME_INCLUDE_TAIHE_CALLBACK_HPP_
17 // NOLINTBEGIN
18
19 #include <taihe/callback.abi.h>
20 #include <taihe/common.hpp>
21 #include <taihe/object.hpp>
22
23 #include <type_traits>
24
25 namespace taihe {
26 template <typename Signature>
27 struct callback_view;
28
29 template <typename Signature>
30 struct callback;
31
32 template <typename Return, typename... Params>
33 struct callback_view<Return(Params...)> {
34 static constexpr bool is_holder = false;
35
36 using vtable_type = as_abi_t<Return>(DataBlockHead *, as_abi_t<Params>...);
37 using view_type = callback_view<Return(Params...)>;
38 using holder_type = callback<Return(Params...)>;
39
40 struct abi_type {
41 vtable_type *vtbl_ptr;
42 DataBlockHead *data_ptr;
43 } m_handle;
44
callback_viewtaihe::callback_view45 explicit callback_view(abi_type handle) : m_handle(handle) {}
46
operator data_viewtaihe::callback_view47 operator data_view() const &
48 {
49 return data_view(this->m_handle.data_ptr);
50 }
51
operator data_holdertaihe::callback_view52 operator data_holder() const &
53 {
54 return data_holder(tobj_dup(this->m_handle.data_ptr));
55 }
56
57 public:
is_errortaihe::callback_view58 bool is_error() const &
59 {
60 return m_handle.vtbl_ptr == nullptr;
61 }
62
operator ()taihe::callback_view63 Return operator()(Params... params) const &
64 {
65 if constexpr (std::is_void_v<Return>) {
66 return m_handle.vtbl_ptr(m_handle.data_ptr, into_abi<Params>(params)...);
67 } else {
68 return from_abi<Return>(m_handle.vtbl_ptr(m_handle.data_ptr, into_abi<Params>(params)...));
69 }
70 }
71
72 public:
73 template <typename Impl>
vtbl_impltaihe::callback_view74 static as_abi_t<Return> vtbl_impl(DataBlockHead *data_ptr, as_abi_t<Params>... params)
75 {
76 if constexpr (std::is_void_v<Return>) {
77 return cast_data_ptr<Impl>(data_ptr)->operator()(from_abi<Params>(params)...);
78 } else {
79 return into_abi<Return>(cast_data_ptr<Impl>(data_ptr)->operator()(from_abi<Params>(params)...));
80 }
81 };
82
83 template <typename Impl>
84 static constexpr struct IdMapItem idmap_impl[0] = {};
85 };
86
87 template <typename Return, typename... Params>
88 struct callback<Return(Params...)> : callback_view<Return(Params...)> {
89 static constexpr bool is_holder = true;
90
91 using typename callback_view<Return(Params...)>::abi_type;
92
callbacktaihe::callback93 explicit callback(abi_type handle) : callback_view<Return(Params...)>(handle) {}
94
~callbacktaihe::callback95 ~callback()
96 {
97 tobj_drop(this->m_handle.data_ptr);
98 }
99
operator =taihe::callback100 callback &operator=(callback other)
101 {
102 std::swap(this->m_handle, other.m_handle);
103 return *this;
104 }
105
callbacktaihe::callback106 callback(callback<Return(Params...)> &&other)
107 : callback({
108 other.m_handle.vtbl_ptr,
109 std::exchange(other.m_handle.data_ptr, nullptr),
110 })
111 {
112 }
113
callbacktaihe::callback114 callback(callback<Return(Params...)> const &other)
115 : callback({
116 other.m_handle.vtbl_ptr,
117 tobj_dup(other.m_handle.data_ptr),
118 })
119 {
120 }
121
callbacktaihe::callback122 callback(callback_view<Return(Params...)> const &other)
123 : callback({
124 other.m_handle.vtbl_ptr,
125 tobj_dup(other.m_handle.data_ptr),
126 })
127 {
128 }
129
operator data_viewtaihe::callback130 operator data_view() const &
131 {
132 return data_view(this->m_handle.data_ptr);
133 }
134
operator data_holdertaihe::callback135 operator data_holder() const &
136 {
137 return data_holder(tobj_dup(this->m_handle.data_ptr));
138 }
139
operator data_holdertaihe::callback140 operator data_holder() &&
141 {
142 return data_holder(std::exchange(this->m_handle.data_ptr, nullptr));
143 }
144 };
145
146 template <typename Return, typename... Params>
147 struct as_abi<callback_view<Return(Params...)>> {
148 using type = TCallback;
149 };
150
151 template <typename Return, typename... Params>
152 struct as_abi<callback<Return(Params...)>> {
153 using type = TCallback;
154 };
155
156 template <typename Return, typename... Params>
157 struct as_param<callback<Return(Params...)>> {
158 using type = callback_view<Return(Params...)>;
159 };
160
161 template <typename Return, typename... Params>
operator ==(callback_view<Return (Params...)> lhs,callback_view<Return (Params...)> rhs)162 inline bool operator==(callback_view<Return(Params...)> lhs, callback_view<Return(Params...)> rhs)
163 {
164 return data_view(lhs) == data_view(rhs);
165 }
166 } // namespace taihe
167
168 template <typename Return, typename... Params>
169 struct std::hash<taihe::callback<Return(Params...)>> {
operator ()std::hash170 std::size_t operator()(taihe::callback_view<Return(Params...)> val) const noexcept
171 {
172 return std::hash<taihe::data_holder>()(val);
173 }
174 };
175 // NOLINTEND
176 #endif // RUNTIME_INCLUDE_TAIHE_CALLBACK_HPP_