• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_