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_OBJECT_HPP_
16 #define RUNTIME_INCLUDE_TAIHE_OBJECT_HPP_
17 // NOLINTBEGIN
18
19 #include <taihe/object.abi.h>
20 #include <taihe/common.hpp>
21
22 #include <cstddef>
23 #include <type_traits>
24
25 // Raw Data Handler //
26
27 namespace taihe {
28 struct data_view;
29 struct data_holder;
30
31 struct data_view {
32 DataBlockHead *data_ptr;
33
data_viewtaihe::data_view34 explicit data_view(DataBlockHead *other_data_ptr) : data_ptr(other_data_ptr) {}
35 };
36
37 struct data_holder : public data_view {
data_holdertaihe::data_holder38 explicit data_holder(DataBlockHead *other_data_ptr) : data_view(other_data_ptr) {}
39
operator =taihe::data_holder40 data_holder &operator=(data_holder other)
41 {
42 std::swap(this->data_ptr, other.data_ptr);
43 return *this;
44 }
45
~data_holdertaihe::data_holder46 ~data_holder()
47 {
48 tobj_drop(this->data_ptr);
49 }
50
data_holdertaihe::data_holder51 data_holder(data_view const &other) : data_holder(tobj_dup(other.data_ptr)) {}
52
data_holdertaihe::data_holder53 data_holder(data_holder const &other) : data_holder(tobj_dup(other.data_ptr)) {}
54
data_holdertaihe::data_holder55 data_holder(data_holder &&other) : data_holder(other.data_ptr)
56 {
57 other.data_ptr = nullptr;
58 }
59 };
60
operator ==(data_view lhs,data_view rhs)61 inline bool operator==(data_view lhs, data_view rhs)
62 {
63 return lhs.data_ptr->rtti_ptr->same_fptr(lhs.data_ptr, rhs.data_ptr);
64 }
65 } // namespace taihe
66
67 template <>
68 struct std::hash<taihe::data_holder> {
operator ()std::hash69 std::size_t operator()(taihe::data_view val) const
70 {
71 return val.data_ptr->rtti_ptr->hash_fptr(val.data_ptr);
72 }
73 };
74
75 // Specific Impl Type Object Handler //
76
77 namespace taihe {
78 template <typename Impl>
79 struct data_block_full : DataBlockHead {
80 Impl impl;
81
82 template <typename... Args>
data_block_fulltaihe::data_block_full83 data_block_full(Args &&...args) : impl(std::forward<Args>(args)...)
84 {
85 }
86 };
87
88 template <typename Impl, typename Enabled = void>
89 struct hash_impl_t {
operator ()taihe::hash_impl_t90 std::size_t operator()(data_view val) const
91 {
92 return reinterpret_cast<std::size_t>(val.data_ptr);
93 }
94 };
95
96 template <typename Impl, typename Enabled = void>
97 struct same_impl_t {
operator ()taihe::same_impl_t98 bool operator()(data_view lhs, data_view rhs) const
99 {
100 return lhs.data_ptr == rhs.data_ptr;
101 }
102 };
103
104 template <typename Impl>
105 constexpr inline hash_impl_t<Impl> hash_impl;
106
107 template <typename Impl>
108 constexpr inline same_impl_t<Impl> same_impl;
109
110 template <typename Impl>
cast_data_ptr(struct DataBlockHead * data_ptr)111 inline Impl *cast_data_ptr(struct DataBlockHead *data_ptr)
112 {
113 return &static_cast<data_block_full<Impl> *>(data_ptr)->impl;
114 }
115
116 template <typename Impl, typename... Args>
make_data_ptr(Args &&...args)117 inline DataBlockHead *make_data_ptr(Args &&...args)
118 {
119 return new data_block_full<Impl>(std::forward<Args>(args)...);
120 }
121
122 template <typename Impl>
free_data_ptr(struct DataBlockHead * data_ptr)123 inline void free_data_ptr(struct DataBlockHead *data_ptr)
124 {
125 delete static_cast<data_block_full<Impl> *>(data_ptr);
126 }
127
128 template <typename Impl>
hash_data_ptr(struct DataBlockHead * val_data_ptr)129 inline std::size_t hash_data_ptr(struct DataBlockHead *val_data_ptr)
130 {
131 return hash_impl<Impl>(data_view(val_data_ptr));
132 }
133
134 template <typename Impl>
same_data_ptr(struct DataBlockHead * lhs_data_ptr,struct DataBlockHead * rhs_data_ptr)135 inline bool same_data_ptr(struct DataBlockHead *lhs_data_ptr, struct DataBlockHead *rhs_data_ptr)
136 {
137 return same_impl<Impl>(data_view(lhs_data_ptr), data_view(rhs_data_ptr));
138 }
139
140 template <typename Impl, typename... InterfaceTypes>
141 struct impl_view;
142
143 template <typename Impl, typename... InterfaceTypes>
144 struct impl_holder;
145
146 template <typename Impl, typename... InterfaceTypes>
147 struct impl_view {
148 DataBlockHead *data_ptr;
149
impl_viewtaihe::impl_view150 explicit impl_view(DataBlockHead *other_data_ptr) : data_ptr(other_data_ptr) {}
151
152 template <typename InterfaceView, std::enable_if_t<!InterfaceView::is_holder, int> = 0>
operator InterfaceViewtaihe::impl_view153 operator InterfaceView() const &
154 {
155 return InterfaceView({
156 this->template get_vtbl_ptr<InterfaceView>(),
157 this->data_ptr,
158 });
159 }
160
161 template <typename InterfaceHolder, std::enable_if_t<InterfaceHolder::is_holder, int> = 0>
operator InterfaceHoldertaihe::impl_view162 operator InterfaceHolder() const &
163 {
164 return InterfaceHolder({
165 this->template get_vtbl_ptr<InterfaceHolder>(),
166 tobj_dup(this->data_ptr),
167 });
168 }
169
operator data_viewtaihe::impl_view170 operator data_view() const &
171 {
172 return data_view(this->data_ptr);
173 }
174
operator data_holdertaihe::impl_view175 operator data_holder() const &
176 {
177 return data_holder(tobj_dup(this->data_ptr));
178 }
179
180 public:
operator ->taihe::impl_view181 Impl *operator->() const
182 {
183 return cast_data_ptr<Impl>(this->data_ptr);
184 }
185
operator *taihe::impl_view186 Impl &operator*() const
187 {
188 return *cast_data_ptr<Impl>(this->data_ptr);
189 }
190
191 public:
192 static constexpr struct typeinfo_t {
193 uint64_t version;
194 void (*free_fptr)(struct DataBlockHead *);
195 std::size_t (*hash_fptr)(struct DataBlockHead *);
196 bool (*same_fptr)(struct DataBlockHead *, struct DataBlockHead *);
197 uint64_t len = 0;
198 struct IdMapItem idmap[((sizeof(InterfaceTypes::template idmap_impl<Impl>) / sizeof(IdMapItem)) + ...)] = {};
__anon738bdf550102taihe::impl_view199 } rtti = [] {
200 struct typeinfo_t info = {
201 .version = 0,
202 .free_fptr = &free_data_ptr<Impl>,
203 .hash_fptr = &hash_data_ptr<Impl>,
204 .same_fptr = &same_data_ptr<Impl>,
205 };
206 (
207 [&] {
208 using InterfaceType = InterfaceTypes;
209 for (std::size_t j = 0; j < sizeof(InterfaceType::template idmap_impl<Impl>) / sizeof(IdMapItem);
210 info.len++, j++) {
211 info.idmap[info.len] = InterfaceType::template idmap_impl<Impl>[j];
212 }
213 }(),
214 ...);
215 return info;
216 }();
217
218 template <typename InterfaceDest,
219 std::enable_if_t<
220 (std::is_convertible_v<typename InterfaceTypes::view_type, typename InterfaceDest::view_type> || ...),
221 int> = 0>
get_vtbl_ptrtaihe::impl_view222 static inline typename InterfaceDest::vtable_type const *get_vtbl_ptr()
223 {
224 typename InterfaceDest::vtable_type const *vtbl_ptr;
225 (
226 [&] {
227 using InterfaceType = InterfaceTypes;
228 if constexpr (std::is_convertible_v<typename InterfaceType::view_type,
229 typename InterfaceDest::view_type>) {
230 vtbl_ptr = typename InterfaceDest::view_type(typename InterfaceType::view_type({
231 &InterfaceType::template vtbl_impl<Impl>,
232 nullptr,
233 }))
234 .m_handle.vtbl_ptr;
235 }
236 }(),
237 ...);
238 return vtbl_ptr;
239 }
240 };
241
242 template <typename Impl, typename... InterfaceTypes>
243 struct impl_holder : public impl_view<Impl, InterfaceTypes...> {
244 using impl_view<Impl, InterfaceTypes...>::rtti;
245
impl_holdertaihe::impl_holder246 explicit impl_holder(DataBlockHead *other_data_ptr) : impl_view<Impl, InterfaceTypes...>(other_data_ptr) {}
247
248 template <typename... Args>
maketaihe::impl_holder249 static impl_holder make(Args &&...args)
250 {
251 DataBlockHead *data_ptr = make_data_ptr<Impl>(std::forward<Args>(args)...);
252 tobj_init(data_ptr, reinterpret_cast<TypeInfo const *>(&rtti));
253 return impl_holder(data_ptr);
254 }
255
operator =taihe::impl_holder256 impl_holder &operator=(impl_holder other)
257 {
258 std::swap(this->data_ptr, other.data_ptr);
259 return *this;
260 }
261
~impl_holdertaihe::impl_holder262 ~impl_holder()
263 {
264 tobj_drop(this->data_ptr);
265 }
266
impl_holdertaihe::impl_holder267 impl_holder(impl_view<Impl, InterfaceTypes...> const &other) : impl_holder(tobj_dup(other.data_ptr)) {}
268
impl_holdertaihe::impl_holder269 impl_holder(impl_holder<Impl, InterfaceTypes...> const &other) : impl_holder(tobj_dup(other.data_ptr)) {}
270
impl_holdertaihe::impl_holder271 impl_holder(impl_holder<Impl, InterfaceTypes...> &&other) : impl_holder(std::exchange(other.data_ptr, nullptr)) {}
272
273 template <typename InterfaceView, std::enable_if_t<!InterfaceView::is_holder, int> = 0>
operator InterfaceViewtaihe::impl_holder274 operator InterfaceView() const &
275 {
276 return InterfaceView({
277 this->template get_vtbl_ptr<InterfaceView>(),
278 this->data_ptr,
279 });
280 }
281
282 template <typename InterfaceHolder, std::enable_if_t<InterfaceHolder::is_holder, int> = 0>
operator InterfaceHoldertaihe::impl_holder283 operator InterfaceHolder() const &
284 {
285 return InterfaceHolder({
286 this->template get_vtbl_ptr<InterfaceHolder>(),
287 tobj_dup(this->data_ptr),
288 });
289 }
290
291 template <typename InterfaceHolder, std::enable_if_t<InterfaceHolder::is_holder, int> = 0>
operator InterfaceHoldertaihe::impl_holder292 operator InterfaceHolder() &&
293 {
294 return InterfaceHolder({
295 this->template get_vtbl_ptr<InterfaceHolder>(),
296 std::exchange(this->data_ptr, nullptr),
297 });
298 }
299
operator data_viewtaihe::impl_holder300 operator data_view() const &
301 {
302 return data_view(this->data_ptr);
303 }
304
operator data_holdertaihe::impl_holder305 operator data_holder() const &
306 {
307 return data_holder(tobj_dup(this->data_ptr));
308 }
309
operator data_holdertaihe::impl_holder310 operator data_holder() &&
311 {
312 return data_holder(std::exchange(this->data_ptr, nullptr));
313 }
314 };
315
316 template <typename Impl, typename... InterfaceTypes, typename... Args>
make_holder(Args &&...args)317 inline auto make_holder(Args &&...args)
318 {
319 return impl_holder<Impl, InterfaceTypes...>::make(std::forward<Args>(args)...);
320 }
321
322 template <typename Impl, typename... InterfaceTypes>
operator ==(impl_view<Impl,InterfaceTypes...> lhs,impl_view<Impl,InterfaceTypes...> rhs)323 inline bool operator==(impl_view<Impl, InterfaceTypes...> lhs, impl_view<Impl, InterfaceTypes...> rhs)
324 {
325 return data_view(lhs) == data_view(rhs);
326 }
327 } // namespace taihe
328
329 template <typename Impl, typename... InterfaceTypes>
330 struct std::hash<taihe::impl_holder<Impl, InterfaceTypes...>> {
operator ()std::hash331 std::size_t operator()(taihe::data_view val) const noexcept
332 {
333 return std::hash<taihe::data_holder>()(val);
334 }
335 };
336 // NOLINTEND
337 #endif // RUNTIME_INCLUDE_TAIHE_OBJECT_HPP_