19
19
#include < mlc/c_api.h>
20
20
#include < sstream>
21
21
#include < type_traits>
22
+ #include < vector>
22
23
#if MLC_DEBUG_MODE == 1
23
24
#include < iostream>
24
25
#endif
@@ -159,6 +160,7 @@ template <typename T> constexpr bool IsPOD = IsPODImpl<T>::value;
159
160
template <typename , typename = void > struct IsObjImpl : std::false_type {};
160
161
template <typename T> struct IsObjImpl <T, std::void_t <decltype (T::_type_info)>> : std::true_type {};
161
162
template <typename T> constexpr static bool IsObj = IsObjImpl<T>::value;
163
+ template <typename T> constexpr static bool IsRawObjPtr = std::is_pointer_v<T> && IsObj<std::remove_pointer_t <T>>;
162
164
template <typename ObjectType, typename = std::enable_if_t <IsObj<ObjectType>>> struct DefaultObjectAllocator ;
163
165
template <typename T, typename = void > struct AllocatorOfImplImpl { using Type = DefaultObjectAllocator<T>; };
164
166
template <typename T> struct AllocatorOfImplImpl <T, std::void_t <typename T::Allocator>> { using Type = typename T::Allocator; };
@@ -243,39 +245,6 @@ template <typename, typename = void> struct PODTraits {};
243
245
template <typename T, typename = void > struct ObjPtrTraits ;
244
246
template <typename T> struct ObjPtrTraits <ListObj<T>, void >;
245
247
246
- template <typename _T> struct Type2Str {
247
- static std::string Run () {
248
- using T = RemoveCR<_T>;
249
- if constexpr (std::is_same_v<T, Any>) {
250
- return " Any" ;
251
- } else if constexpr (std::is_same_v<T, AnyView>) {
252
- return " AnyView" ;
253
- } else if constexpr (std::is_same_v<T, void >) {
254
- return " void" ;
255
- } else if constexpr (IsPOD<T>) {
256
- return PODTraits<T>::Type2Str ();
257
- } else if constexpr (std::is_pointer_v<T> && IsObj<std::remove_pointer_t <T>>) {
258
- return std::string (std::remove_pointer_t <T>::_type_key) + " *" ;
259
- } else if constexpr (std::is_same_v<T, UList>) {
260
- return " list[Any]" ;
261
- } else if constexpr (std::is_same_v<T, UDict>) {
262
- return " dict[Any, Any]" ;
263
- } else if constexpr (std::is_base_of_v<UList, T>) {
264
- return " list[" + Type2Str<typename T::TElem>::Run () + " ]" ;
265
- } else if constexpr (std::is_base_of_v<UDict, T>) {
266
- return " dict[" + Type2Str<typename T::TKey>::Run () + " , " + Type2Str<typename T::TValue>::Run () + " ]" ;
267
- } else if constexpr (IsRef<T>) {
268
- return " Ref<" + std::string (T::TObj::_type_key) + " >" ;
269
- } else if constexpr (IsObjRef<T>) {
270
- return std::string (T::TObj::_type_key);
271
- } else if constexpr (IsObj<T>) {
272
- return std::string (T::_type_key);
273
- } else {
274
- static_assert (std::is_void_v<T>, " Unsupported type" );
275
- }
276
- }
277
- };
278
-
279
248
/* ********* Section 3. Errors *********/
280
249
281
250
struct TemporaryTypeError : public std ::exception {};
@@ -306,14 +275,27 @@ StrObj *StrCopyFromCharArray(const char *source, size_t length);
306
275
void FuncCall (const void *func, int32_t num_args, const MLCAny *args, MLCAny *ret);
307
276
template <typename DerivedType, typename SelfType = Object> bool IsInstanceOf (const MLCAny *self);
308
277
309
- MLC_INLINE const char * TypeIndex2TypeKey (int32_t type_index) {
278
+ MLC_INLINE MLCTypeInfo * TypeIndex2TypeInfo (int32_t type_index) {
310
279
MLCTypeInfo *type_info;
311
280
MLCTypeIndex2Info (nullptr , type_index, &type_info);
312
- return type_info ? type_info->type_key : " (undefined)" ;
281
+ return type_info;
282
+ }
283
+
284
+ MLC_INLINE const char *TypeIndex2TypeKey (int32_t type_index) {
285
+ if (MLCTypeInfo *type_info = TypeIndex2TypeInfo (type_index)) {
286
+ return type_info->type_key ;
287
+ }
288
+ return " (undefined)" ;
313
289
}
314
290
315
291
MLC_INLINE const char *TypeIndex2TypeKey (const MLCAny *self) {
316
- return self == nullptr ? " None" : TypeIndex2TypeKey (self->type_index );
292
+ if (self == nullptr ) {
293
+ return " None" ;
294
+ }
295
+ if (MLCTypeInfo *type_info = TypeIndex2TypeInfo (self->type_index )) {
296
+ return type_info->type_key ;
297
+ }
298
+ return " (undefined)" ;
317
299
}
318
300
319
301
MLC_INLINE MLCTypeInfo *TypeRegister (int32_t parent_type_index, int32_t type_index, const char *type_key,
@@ -331,6 +313,77 @@ MLC_INLINE bool IsTypeIndexPOD(int32_t type_index) {
331
313
return type_index < static_cast <int32_t >(MLCTypeIndex::kMLCStaticObjectBegin );
332
314
}
333
315
316
+ template <typename _T> struct Type2Str {
317
+ using T = RemoveCR<_T>;
318
+ static std::string Run () {
319
+ if constexpr (std::is_same_v<T, Any>) {
320
+ return " Any" ;
321
+ } else if constexpr (std::is_same_v<T, AnyView>) {
322
+ return " AnyView" ;
323
+ } else if constexpr (std::is_same_v<T, void >) {
324
+ return " void" ;
325
+ } else if constexpr (std::is_same_v<T, Object>) {
326
+ return " object.Object" ;
327
+ } else if constexpr (std::is_same_v<T, ObjectRef>) {
328
+ return " object.ObjectRef" ;
329
+ } else if constexpr (IsPOD<T>) {
330
+ return PODTraits<T>::Type2Str ();
331
+ } else if constexpr (IsRawObjPtr<T>) {
332
+ using U = std::remove_pointer_t <T>;
333
+ return Type2Str<U>::Run () + " *" ;
334
+ } else if constexpr (std::is_base_of_v<UListObj, T>) {
335
+ using E = typename T::TElem;
336
+ return " object.ListObj[" + Type2Str<E>::Run () + " ]" ;
337
+ } else if constexpr (std::is_base_of_v<UDictObj, T>) {
338
+ using K = typename T::TKey;
339
+ using V = typename T::TValue;
340
+ return " object.DictObj[" + Type2Str<K>::Run () + " , " + Type2Str<V>::Run () + " ]" ;
341
+ } else if constexpr (std::is_base_of_v<UList, T>) {
342
+ using E = typename T::TElem;
343
+ return " list[" + Type2Str<E>::Run () + " ]" ;
344
+ } else if constexpr (std::is_base_of_v<UDict, T>) {
345
+ using K = typename T::TKey;
346
+ using V = typename T::TValue;
347
+ return " dict[" + Type2Str<K>::Run () + " , " + Type2Str<V>::Run () + " ]" ;
348
+ } else if constexpr (IsRef<T>) {
349
+ return " Ref<" + Type2Str<typename T::TObj>::Run () + " >" ;
350
+ } else if constexpr (IsObjRef<T>) {
351
+ return std::string (T::TObj::_type_key);
352
+ } else if constexpr (IsObj<T>) {
353
+ return std::string (T::_type_key) + " Obj" ;
354
+ } else {
355
+ static_assert (std::is_void_v<T>, " Unsupported type" );
356
+ }
357
+ }
358
+
359
+ static void CollectTypeInfo (std::vector<MLCTypeInfo *> *info) {
360
+ if constexpr (std::is_same_v<T, Any> || std::is_same_v<T, AnyView>) {
361
+ info->push_back (TypeIndex2TypeInfo (static_cast <int32_t >(MLCTypeIndex::kMLCNone )));
362
+ } else if constexpr (std::is_same_v<T, void >) {
363
+ MLC_THROW (TypeError) << " `void` is not allowed in type annotation" ;
364
+ } else if constexpr (std::is_same_v<T, char *>) {
365
+ info->push_back (TypeIndex2TypeInfo (PODTraits<_T>::default_type_index));
366
+ } else if constexpr (IsPOD<T>) {
367
+ info->push_back (TypeIndex2TypeInfo (PODTraits<T>::default_type_index));
368
+ } else if constexpr (IsRawObjPtr<T>) {
369
+ using U = std::remove_pointer_t <T>;
370
+ Type2Str<Ref<U>>::CollectTypeInfo (info);
371
+ } else if constexpr (std::is_base_of_v<UList, T>) {
372
+ info->push_back (TypeIndex2TypeInfo (static_cast <int32_t >(MLCTypeIndex::kMLCList )));
373
+ Type2Str<typename T::TElem>::CollectTypeInfo (info);
374
+ } else if constexpr (std::is_base_of_v<UDict, T>) {
375
+ info->push_back (TypeIndex2TypeInfo (static_cast <int32_t >(MLCTypeIndex::kMLCDict )));
376
+ Type2Str<typename T::TKey>::CollectTypeInfo (info);
377
+ Type2Str<typename T::TValue>::CollectTypeInfo (info);
378
+ } else if constexpr (IsRef<T> || IsObjRef<T>) {
379
+ using U = typename T::TObj;
380
+ info->push_back (TypeIndex2TypeInfo (U::_type_index));
381
+ } else {
382
+ static_assert (std::is_void_v<T>, " Unsupported type" );
383
+ }
384
+ }
385
+ };
386
+
334
387
MLC_INLINE void IncRef (MLCObject *obj) {
335
388
if (obj != nullptr ) {
336
389
#ifdef _MSC_VER
0 commit comments