@@ -99,14 +99,41 @@ class AnyView {
99
99
return *this ;
100
100
}
101
101
102
+ /* !
103
+ * \brief Try to see if we can reinterpret the AnyView to as T object.
104
+ *
105
+ * \tparam T The type to cast to.
106
+ * \return The casted value, or std::nullopt if the cast is not possible.
107
+ * \note This function won't try run type conversion (use try_cast for that purpose).
108
+ */
102
109
template <typename T, typename = std::enable_if_t <TypeTraits<T>::convert_enabled>>
103
110
TVM_FFI_INLINE std::optional<T> as () const {
104
- return TypeTraits<T>::TryConvertFromAnyView (&data_);
111
+ if (TypeTraits<T>::CheckAnyStrict (&data_)) {
112
+ return TypeTraits<T>::CopyFromAnyViewAfterCheck (&data_);
113
+ } else {
114
+ return std::optional<T>(std::nullopt );
115
+ }
116
+ }
117
+ /*
118
+ * \brief Shortcut of as Object to cast to a const pointer when T is an Object.
119
+ *
120
+ * \tparam T The object type.
121
+ * \return The requested pointer, returns nullptr if type mismatches.
122
+ */
123
+ template <typename T, typename = std::enable_if_t <std::is_base_of_v<Object, T>>>
124
+ TVM_FFI_INLINE const T* as () const {
125
+ return this ->as <const T*>().value_or (nullptr );
105
126
}
106
127
128
+ /* *
129
+ * \brief Cast to a type T.
130
+ *
131
+ * \tparam T The type to cast to.
132
+ * \return The casted value, or throws an exception if the cast is not possible.
133
+ */
107
134
template <typename T, typename = std::enable_if_t <TypeTraits<T>::convert_enabled>>
108
135
TVM_FFI_INLINE T cast () const {
109
- std::optional<T> opt = TypeTraits<T>::TryConvertFromAnyView (&data_);
136
+ std::optional<T> opt = TypeTraits<T>::TryCastFromAnyView (&data_);
110
137
if (!opt.has_value ()) {
111
138
TVM_FFI_THROW (TypeError) << " Cannot convert from type `"
112
139
<< TypeTraits<T>::GetMismatchTypeInfo (&data_) << " ` to `"
@@ -115,16 +142,17 @@ class AnyView {
115
142
return *std::move (opt);
116
143
}
117
144
118
- /*
119
- * \brief Shortcut of as Object to cast to a const pointer when T is an Object .
145
+ /* !
146
+ * \brief Try to cast to a type T, return std::nullopt if the cast is not possible .
120
147
*
121
- * \tparam T The object type.
122
- * \return The requested pointer, returns nullptr if type mismatches .
148
+ * \tparam T The type to cast to .
149
+ * \return The casted value, or std::nullopt if the cast is not possible .
123
150
*/
124
- template <typename T, typename = std::enable_if_t <std::is_base_of_v<Object, T> >>
125
- TVM_FFI_INLINE const T* as () const {
126
- return this -> as < const T*>(). value_or ( nullptr );
151
+ template <typename T, typename = std::enable_if_t <TypeTraits<T>::convert_enabled >>
152
+ TVM_FFI_INLINE std::optional<T> try_cast () const {
153
+ return TypeTraits<T>:: TryCastFromAnyView (&data_ );
127
154
}
155
+
128
156
// comparison with nullptr
129
157
TVM_FFI_INLINE bool operator ==(std::nullptr_t ) const noexcept {
130
158
return data_.type_index == TypeIndex::kTVMFFINone ;
@@ -269,13 +297,45 @@ class Any {
269
297
return *this ;
270
298
}
271
299
300
+ /* *
301
+ * \brief Try to reinterpret the Any as a type T, return std::nullopt if it is not possible.
302
+ *
303
+ * \tparam T The type to cast to.
304
+ * \return The casted value, or std::nullopt if the cast is not possible.
305
+ * \note This function won't try to run type conversion (use try_cast for that purpose).
306
+ */
307
+ template <typename T,
308
+ typename = std::enable_if_t <TypeTraits<T>::storage_enabled || std::is_same_v<T, Any>>>
309
+ TVM_FFI_INLINE std::optional<T> as () && {
310
+ if constexpr (std::is_same_v<T, Any>) {
311
+ return std::move (*this );
312
+ } else {
313
+ if (TypeTraits<T>::CheckAnyStrict (&data_)) {
314
+ return TypeTraits<T>::MoveFromAnyAfterCheck (&data_);
315
+ } else {
316
+ return std::optional<T>(std::nullopt );
317
+ }
318
+ }
319
+ }
320
+
321
+ /* *
322
+ * \brief Try to reinterpret the Any as a type T, return std::nullopt if it is not possible.
323
+ *
324
+ * \tparam T The type to cast to.
325
+ * \return The casted value, or std::nullopt if the cast is not possible.
326
+ * \note This function won't try to run type conversion (use try_cast for that purpose).
327
+ */
272
328
template <typename T,
273
329
typename = std::enable_if_t <TypeTraits<T>::convert_enabled || std::is_same_v<T, Any>>>
274
- TVM_FFI_INLINE std::optional<T> as () const {
330
+ TVM_FFI_INLINE std::optional<T> as () const & {
275
331
if constexpr (std::is_same_v<T, Any>) {
276
332
return *this ;
277
333
} else {
278
- return TypeTraits<T>::TryConvertFromAnyView (&data_);
334
+ if (TypeTraits<T>::CheckAnyStrict (&data_)) {
335
+ return TypeTraits<T>::CopyFromAnyViewAfterCheck (&data_);
336
+ } else {
337
+ return std::optional<T>(std::nullopt );
338
+ }
279
339
}
280
340
}
281
341
@@ -286,13 +346,18 @@ class Any {
286
346
* \return The requested pointer, returns nullptr if type mismatches.
287
347
*/
288
348
template <typename T, typename = std::enable_if_t <std::is_base_of_v<Object, T>>>
289
- TVM_FFI_INLINE const T* as () const {
349
+ TVM_FFI_INLINE const T* as () const & {
290
350
return this ->as <const T*>().value_or (nullptr );
291
351
}
292
352
353
+ /* *
354
+ * \brief Cast to a type T, throw an exception if the cast is not possible.
355
+ *
356
+ * \tparam T The type to cast to.
357
+ */
293
358
template <typename T, typename = std::enable_if_t <TypeTraits<T>::convert_enabled>>
294
359
TVM_FFI_INLINE T cast () const & {
295
- std::optional<T> opt = TypeTraits<T>::TryConvertFromAnyView (&data_);
360
+ std::optional<T> opt = TypeTraits<T>::TryCastFromAnyView (&data_);
296
361
if (!opt.has_value ()) {
297
362
TVM_FFI_THROW (TypeError) << " Cannot convert from type `"
298
363
<< TypeTraits<T>::GetMismatchTypeInfo (&data_) << " ` to `"
@@ -301,13 +366,18 @@ class Any {
301
366
return *std::move (opt);
302
367
}
303
368
369
+ /* *
370
+ * \brief Cast to a type T, throw an exception if the cast is not possible.
371
+ *
372
+ * \tparam T The type to cast to.
373
+ */
304
374
template <typename T, typename = std::enable_if_t <TypeTraits<T>::storage_enabled>>
305
375
TVM_FFI_INLINE T cast () && {
306
- if (TypeTraits<T>::CheckAnyStorage (&data_)) {
307
- return TypeTraits<T>::MoveFromAnyStorageAfterCheck (&data_);
376
+ if (TypeTraits<T>::CheckAnyStrict (&data_)) {
377
+ return TypeTraits<T>::MoveFromAnyAfterCheck (&data_);
308
378
}
309
379
// slow path, try to do fallback convert
310
- std::optional<T> opt = TypeTraits<T>::TryConvertFromAnyView (&data_);
380
+ std::optional<T> opt = TypeTraits<T>::TryCastFromAnyView (&data_);
311
381
if (!opt.has_value ()) {
312
382
TVM_FFI_THROW (TypeError) << " Cannot convert from type `"
313
383
<< TypeTraits<T>::GetMismatchTypeInfo (&data_) << " ` to `"
@@ -316,6 +386,22 @@ class Any {
316
386
return *std::move (opt);
317
387
}
318
388
389
+ /* *
390
+ * \brief Try to cast to a type T.
391
+ *
392
+ * \tparam T The type to cast to.
393
+ * \return The casted value, or std::nullopt if the cast is not possible.
394
+ * \note use STL name since it to be more consistent with cast API.
395
+ */
396
+ template <typename T,
397
+ typename = std::enable_if_t <TypeTraits<T>::convert_enabled || std::is_same_v<T, Any>>>
398
+ TVM_FFI_INLINE std::optional<T> try_cast () const {
399
+ if constexpr (std::is_same_v<T, Any>) {
400
+ return *this ;
401
+ } else {
402
+ return TypeTraits<T>::TryCastFromAnyView (&data_);
403
+ }
404
+ }
319
405
/*
320
406
* \brief Check if the two Any are same type and value in shallow comparison.
321
407
* \param other The other Any
@@ -412,23 +498,23 @@ struct AnyUnsafe : public ObjectUnsafe {
412
498
}
413
499
414
500
template <typename T>
415
- static TVM_FFI_INLINE bool CheckAnyStorage (const Any& ref) {
416
- return TypeTraits<T>::CheckAnyStorage (&(ref.data_ ));
501
+ static TVM_FFI_INLINE bool CheckAnyStrict (const Any& ref) {
502
+ return TypeTraits<T>::CheckAnyStrict (&(ref.data_ ));
417
503
}
418
504
419
505
template <typename T>
420
- static TVM_FFI_INLINE T CopyFromAnyStorageAfterCheck (const Any& ref) {
506
+ static TVM_FFI_INLINE T CopyFromAnyViewAfterCheck (const Any& ref) {
421
507
if constexpr (!std::is_same_v<T, Any>) {
422
- return TypeTraits<T>::CopyFromAnyStorageAfterCheck (&(ref.data_ ));
508
+ return TypeTraits<T>::CopyFromAnyViewAfterCheck (&(ref.data_ ));
423
509
} else {
424
510
return ref;
425
511
}
426
512
}
427
513
428
514
template <typename T>
429
- static TVM_FFI_INLINE T MoveFromAnyStorageAfterCheck (Any&& ref) {
515
+ static TVM_FFI_INLINE T MoveFromAnyAfterCheck (Any&& ref) {
430
516
if constexpr (!std::is_same_v<T, Any>) {
431
- return TypeTraits<T>::MoveFromAnyStorageAfterCheck (&(ref.data_ ));
517
+ return TypeTraits<T>::MoveFromAnyAfterCheck (&(ref.data_ ));
432
518
} else {
433
519
return std::move (ref);
434
520
}
@@ -461,7 +547,7 @@ struct AnyHash {
461
547
if (src.data_ .type_index == TypeIndex::kTVMFFIStr ||
462
548
src.data_ .type_index == TypeIndex::kTVMFFIBytes ) {
463
549
const BytesObjBase* src_str =
464
- details::AnyUnsafe::CopyFromAnyStorageAfterCheck <const BytesObjBase*>(src);
550
+ details::AnyUnsafe::CopyFromAnyViewAfterCheck <const BytesObjBase*>(src);
465
551
return details::StableHashBytes (src_str->data , src_str->size );
466
552
} else {
467
553
return src.data_ .v_uint64 ;
@@ -487,9 +573,9 @@ struct AnyEqual {
487
573
if (lhs.data_ .type_index == TypeIndex::kTVMFFIStr ||
488
574
lhs.data_ .type_index == TypeIndex::kTVMFFIBytes ) {
489
575
const BytesObjBase* lhs_str =
490
- details::AnyUnsafe::CopyFromAnyStorageAfterCheck <const BytesObjBase*>(lhs);
576
+ details::AnyUnsafe::CopyFromAnyViewAfterCheck <const BytesObjBase*>(lhs);
491
577
const BytesObjBase* rhs_str =
492
- details::AnyUnsafe::CopyFromAnyStorageAfterCheck <const BytesObjBase*>(rhs);
578
+ details::AnyUnsafe::CopyFromAnyViewAfterCheck <const BytesObjBase*>(rhs);
493
579
return Bytes::memncmp (lhs_str->data , rhs_str->data , lhs_str->size , rhs_str->size ) == 0 ;
494
580
}
495
581
return false ;
0 commit comments