This is an automated email from the ASF dual-hosted git repository.

tqchen pushed a commit to branch refactor-s1
in repository https://gitbox.apache.org/repos/asf/tvm.git

commit 8a52b682b40e548d9870f41cbf82a666eb6dd9d1
Author: tqchen <[email protected]>
AuthorDate: Sun Apr 13 19:26:10 2025 -0400

    [FFI] clarify enabled into two categories
---
 ffi/include/tvm/ffi/any.h                         | 18 +++++++++---------
 ffi/include/tvm/ffi/container/array.h             |  6 +++---
 ffi/include/tvm/ffi/container/container_details.h |  4 ++--
 ffi/include/tvm/ffi/container/map.h               |  9 +++++----
 ffi/include/tvm/ffi/container/tuple.h             |  9 ++++++---
 ffi/include/tvm/ffi/container/variant.h           |  7 ++++---
 ffi/include/tvm/ffi/dtype.h                       |  2 ++
 ffi/include/tvm/ffi/function_details.h            |  4 ++--
 ffi/include/tvm/ffi/optional.h                    |  6 +++---
 ffi/include/tvm/ffi/reflection.h                  |  2 +-
 ffi/include/tvm/ffi/rvalue_ref.h                  | 11 +++++++----
 ffi/include/tvm/ffi/string.h                      |  8 ++++----
 ffi/include/tvm/ffi/type_traits.h                 | 15 ++++++++-------
 ffi/src/ffi/object.cc                             |  4 +++-
 14 files changed, 59 insertions(+), 46 deletions(-)

diff --git a/ffi/include/tvm/ffi/any.h b/ffi/include/tvm/ffi/any.h
index bfb70df132..a9ae2293f3 100644
--- a/ffi/include/tvm/ffi/any.h
+++ b/ffi/include/tvm/ffi/any.h
@@ -88,23 +88,23 @@ class AnyView {
     return *this;
   }
   // constructor from general types
-  template <typename T, typename = std::enable_if_t<TypeTraits<T>::enabled>>
+  template <typename T, typename = 
std::enable_if_t<TypeTraits<T>::convert_enabled>>
   AnyView(const T& other) {  // NOLINT(*)
     TypeTraits<T>::CopyToAnyView(other, &data_);
   }
-  template <typename T, typename = std::enable_if_t<TypeTraits<T>::enabled>>
+  template <typename T, typename = 
std::enable_if_t<TypeTraits<T>::convert_enabled>>
   TVM_FFI_INLINE AnyView& operator=(const T& other) {  // NOLINT(*)
     // copy-and-swap idiom
     AnyView(other).swap(*this);  // NOLINT(*)
     return *this;
   }
 
-  template <typename T, typename = std::enable_if_t<TypeTraits<T>::enabled>>
+  template <typename T, typename = 
std::enable_if_t<TypeTraits<T>::convert_enabled>>
   TVM_FFI_INLINE std::optional<T> as() const {
     return TypeTraits<T>::TryConvertFromAnyView(&data_);
   }
 
-  template <typename T, typename = std::enable_if_t<TypeTraits<T>::enabled>>
+  template <typename T, typename = 
std::enable_if_t<TypeTraits<T>::convert_enabled>>
   TVM_FFI_INLINE operator T() const {
     std::optional<T> opt = TypeTraits<T>::TryConvertFromAnyView(&data_);
     if (!opt.has_value()) {
@@ -247,11 +247,11 @@ class Any {
   /*! \brief Any can be converted to AnyView in zero cost. */
   operator AnyView() const { return AnyView::CopyFromTVMFFIAny(data_); }
   // constructor from general types
-  template <typename T, typename = std::enable_if_t<TypeTraits<T>::enabled>>
+  template <typename T, typename = 
std::enable_if_t<TypeTraits<T>::convert_enabled>>
   Any(T other) {  // NOLINT(*)
     TypeTraits<T>::MoveToAny(std::move(other), &data_);
   }
-  template <typename T, typename = std::enable_if_t<TypeTraits<T>::enabled>>
+  template <typename T, typename = 
std::enable_if_t<TypeTraits<T>::convert_enabled>>
   TVM_FFI_INLINE Any& operator=(T other) {  // NOLINT(*)
     // copy-and-swap idiom
     Any(std::move(other)).swap(*this);  // NOLINT(*)
@@ -259,7 +259,7 @@ class Any {
   }
 
   template <typename T,
-            typename = std::enable_if_t<TypeTraits<T>::enabled || 
std::is_same_v<T, Any>>>
+            typename = std::enable_if_t<TypeTraits<T>::convert_enabled || 
std::is_same_v<T, Any>>>
   TVM_FFI_INLINE std::optional<T> as() const {
     if constexpr (std::is_same_v<T, Any>) {
       return *this;
@@ -279,7 +279,7 @@ class Any {
     return this->as<const T*>().value_or(nullptr);
   }
 
-  template <typename T, typename = std::enable_if_t<TypeTraits<T>::enabled>>
+  template <typename T, typename = 
std::enable_if_t<TypeTraits<T>::convert_enabled>>
   TVM_FFI_INLINE operator T() const& {
     std::optional<T> opt = TypeTraits<T>::TryConvertFromAnyView(&data_);
     if (!opt.has_value()) {
@@ -290,7 +290,7 @@ class Any {
     return *std::move(opt);
   }
 
-  template <typename T, typename = 
std::enable_if_t<TypeTraits<T>::container_enabled>>
+  template <typename T, typename = 
std::enable_if_t<TypeTraits<T>::storage_enabled>>
   TVM_FFI_INLINE operator T() && {
     if (TypeTraits<T>::CheckAnyStorage(&data_)) {
       return TypeTraits<T>::MoveFromAnyStorageAfterCheck(&data_);
diff --git a/ffi/include/tvm/ffi/container/array.h 
b/ffi/include/tvm/ffi/container/array.h
index 47d5c532db..66d71d2421 100644
--- a/ffi/include/tvm/ffi/container/array.h
+++ b/ffi/include/tvm/ffi/container/array.h
@@ -302,7 +302,7 @@ inline constexpr bool is_valid_iterator_v = 
is_valid_iterator<T, IterType>::valu
  * operator[] only provides const access, use Set to mutate the content.
  * \tparam T The content Value type, must be compatible with tvm::ffi::Any
  */
-template <typename T, typename = typename 
std::enable_if_t<details::container_enabled_v<T>>>
+template <typename T, typename = typename 
std::enable_if_t<details::storage_enabled_v<T>>>
 class Array : public ObjectRef {
  public:
   using value_type = T;
@@ -927,8 +927,8 @@ class Array : public ObjectRef {
  * \param rhs second Array to be concatenated.
  * \return The concatenated Array. Original Arrays are kept unchanged.
  */
-template <typename T,
-          typename = typename std::enable_if_t<std::is_same_v<T, Any> || 
TypeTraits<T>::enabled>>
+template <typename T, typename = typename std::enable_if_t<std::is_same_v<T, 
Any> ||
+                                                           
TypeTraits<T>::convert_enabled>>
 inline Array<T> Concat(Array<T> lhs, const Array<T>& rhs) {
   for (const auto& x : rhs) {
     lhs.push_back(x);
diff --git a/ffi/include/tvm/ffi/container/container_details.h 
b/ffi/include/tvm/ffi/container/container_details.h
index 693d6063ea..73cb34afda 100644
--- a/ffi/include/tvm/ffi/container/container_details.h
+++ b/ffi/include/tvm/ffi/container/container_details.h
@@ -28,6 +28,7 @@
 #include <tvm/ffi/object.h>
 
 #include <sstream>
+#include <string>
 #include <type_traits>
 #include <utility>
 
@@ -272,8 +273,7 @@ class ReverseIterAdapter {
  * \return True if T is compatible with Any, false otherwise.
  */
 template <typename T>
-inline constexpr bool container_enabled_v =
-    std::is_same_v<T, Any> || TypeTraits<T>::container_enabled;
+inline constexpr bool storage_enabled_v = std::is_same_v<T, Any> || 
TypeTraits<T>::storage_enabled;
 
 /**
  * \brief Check if Any storage of Derived can always be directly used as Base.
diff --git a/ffi/include/tvm/ffi/container/map.h 
b/ffi/include/tvm/ffi/container/map.h
index 34c560fcda..b9d59d89ae 100644
--- a/ffi/include/tvm/ffi/container/map.h
+++ b/ffi/include/tvm/ffi/container/map.h
@@ -31,6 +31,7 @@
 #include <tvm/ffi/optional.h>
 
 #include <algorithm>
+#include <string>
 #include <type_traits>
 #include <unordered_map>
 #include <utility>
@@ -1147,8 +1148,8 @@ inline ObjectPtr<MapNode> make_object<>() = delete;
  * \tparam V The value NodeRef type.
  */
 template <typename K, typename V,
-          typename = typename std::enable_if_t<details::container_enabled_v<K> 
&&
-                                               
details::container_enabled_v<V>>>
+          typename = typename std::enable_if_t<details::storage_enabled_v<K> &&
+                                               details::storage_enabled_v<V>>>
 class Map : public ObjectRef {
  public:
   using key_type = K;
@@ -1369,8 +1370,8 @@ class Map : public ObjectRef {
  * @return The merged Array. Original Maps are kept unchanged.
  */
 template <typename K, typename V,
-          typename = typename std::enable_if_t<details::container_enabled_v<K> 
&&
-                                               
details::container_enabled_v<V>>>
+          typename = typename std::enable_if_t<details::storage_enabled_v<K> &&
+                                               details::storage_enabled_v<V>>>
 inline Map<K, V> Merge(Map<K, V> lhs, const Map<K, V>& rhs) {
   for (const auto& p : rhs) {
     lhs.Set(p.first, p.second);
diff --git a/ffi/include/tvm/ffi/container/tuple.h 
b/ffi/include/tvm/ffi/container/tuple.h
index 6d41e3757a..085c193ad3 100644
--- a/ffi/include/tvm/ffi/container/tuple.h
+++ b/ffi/include/tvm/ffi/container/tuple.h
@@ -26,6 +26,10 @@
 
 #include <tvm/ffi/container/array.h>
 
+#include <string>
+#include <tuple>
+#include <utility>
+
 namespace tvm {
 namespace ffi {
 
@@ -39,9 +43,8 @@ namespace ffi {
 template <typename... Types>
 class Tuple : public ObjectRef {
  public:
-  static constexpr bool all_container_enabled_v = 
(details::container_enabled_v<Types> && ...);
-  static_assert(all_container_enabled_v,
-                "All types used in Tuple<...> must be compatible with Any");
+  static constexpr bool all_storage_enabled_v = 
(details::storage_enabled_v<Types> && ...);
+  static_assert(all_storage_enabled_v, "All types used in Tuple<...> must be 
compatible with Any");
 
   Tuple() : ObjectRef(MakeDefaultTupleNode()) {}
   Tuple(const Tuple<Types...>& other) : ObjectRef(other) {}
diff --git a/ffi/include/tvm/ffi/container/variant.h 
b/ffi/include/tvm/ffi/container/variant.h
index 44f4c43ea3..4ce044bcfa 100644
--- a/ffi/include/tvm/ffi/container/variant.h
+++ b/ffi/include/tvm/ffi/container/variant.h
@@ -28,8 +28,9 @@
 #include <tvm/ffi/container/container_details.h>
 #include <tvm/ffi/optional.h>
 
-#include <sstream>
+#include <string>
 #include <type_traits>
+#include <utility>
 
 namespace tvm {
 namespace ffi {
@@ -41,7 +42,7 @@ namespace ffi {
 template <typename... V>
 class Variant {
  public:
-  static constexpr bool all_compatible_with_any_v = 
(TypeTraits<V>::container_enabled && ...);
+  static constexpr bool all_compatible_with_any_v = 
(TypeTraits<V>::storage_enabled && ...);
   static_assert(all_compatible_with_any_v,
                 "All types used in Variant<...> must be compatible with Any");
 
@@ -68,7 +69,7 @@ class Variant {
   }
 
   template <typename T, typename = enable_if_variant_contains_t<T>>
-  Variant(T other) : data_(std::move(other)) {}
+  Variant(T other) : data_(std::move(other)) {}  // NOLINT(*)
 
   template <typename T, typename = enable_if_variant_contains_t<T>>
   TVM_FFI_INLINE Variant& operator=(T other) {
diff --git a/ffi/include/tvm/ffi/dtype.h b/ffi/include/tvm/ffi/dtype.h
index 650a86c897..804edacd46 100644
--- a/ffi/include/tvm/ffi/dtype.h
+++ b/ffi/include/tvm/ffi/dtype.h
@@ -32,6 +32,8 @@
 #include <tvm/ffi/string.h>
 #include <tvm/ffi/type_traits.h>
 
+#include <string>
+
 namespace tvm {
 namespace ffi {
 /*!
diff --git a/ffi/include/tvm/ffi/function_details.h 
b/ffi/include/tvm/ffi/function_details.h
index f4462c0f7f..4524d8af4c 100644
--- a/ffi/include/tvm/ffi/function_details.h
+++ b/ffi/include/tvm/ffi/function_details.h
@@ -57,12 +57,12 @@ template <typename T>
 static constexpr bool ArgSupported =
     (std::is_same_v<std::remove_const_t<std::remove_reference_t<T>>, Any> ||
      std::is_same_v<std::remove_const_t<std::remove_reference_t<T>>, AnyView> 
||
-     TypeTraitsNoCR<T>::enabled);
+     TypeTraitsNoCR<T>::convert_enabled);
 
 // NOTE: return type can only support non-reference managed returns
 template <typename T>
 static constexpr bool RetSupported =
-    (std::is_same_v<T, Any> || std::is_void_v<T> || TypeTraits<T>::enabled);
+    (std::is_same_v<T, Any> || std::is_void_v<T> || 
TypeTraits<T>::convert_enabled);
 
 template <typename R, typename... Args>
 struct FuncFunctorImpl {
diff --git a/ffi/include/tvm/ffi/optional.h b/ffi/include/tvm/ffi/optional.h
index 241f08f92c..57c0f5145c 100644
--- a/ffi/include/tvm/ffi/optional.h
+++ b/ffi/include/tvm/ffi/optional.h
@@ -55,8 +55,8 @@ class Optional<T, 
std::enable_if_t<!use_ptr_based_optional_v<T>>> {
   Optional() = default;
   Optional(const Optional<T>& other) : data_(other.data_) {}
   Optional(Optional<T>&& other) : data_(std::move(other.data_)) {}
-  Optional(std::optional<T> other) : data_(std::move(other)) {}
-  Optional(std::nullopt_t) {}
+  Optional(std::optional<T> other) : data_(std::move(other)) {}  // NOLINT(*)
+  Optional(std::nullopt_t) {}  // NOLINT(*)
   // normal value handling.
   Optional(T other)  // NOLINT(*)
       : data_(std::move(other)) {}
@@ -148,7 +148,7 @@ class Optional<T, 
std::enable_if_t<use_ptr_based_optional_v<T>>> : public Object
   Optional(std::nullopt_t) {}  // NOLINT(*)
 
   // handle conversion from std::optional<T>
-  Optional(std::optional<T> other) {
+  Optional(std::optional<T> other) {  // NOLINT(*)
     if (other.has_value()) {
       *this = *std::move(other);
     }
diff --git a/ffi/include/tvm/ffi/reflection.h b/ffi/include/tvm/ffi/reflection.h
index 0507665596..230fec9ac0 100644
--- a/ffi/include/tvm/ffi/reflection.h
+++ b/ffi/include/tvm/ffi/reflection.h
@@ -38,7 +38,7 @@ struct TypeToFieldStaticTypeIndex {
 };
 
 template <typename T>
-struct TypeToFieldStaticTypeIndex<T, std::enable_if_t<TypeTraits<T>::enabled>> 
{
+struct TypeToFieldStaticTypeIndex<T, 
std::enable_if_t<TypeTraits<T>::convert_enabled>> {
   static constexpr int32_t value = TypeTraits<T>::field_static_type_index;
 };
 
diff --git a/ffi/include/tvm/ffi/rvalue_ref.h b/ffi/include/tvm/ffi/rvalue_ref.h
index 1eb5c2343c..a4a363fa17 100644
--- a/ffi/include/tvm/ffi/rvalue_ref.h
+++ b/ffi/include/tvm/ffi/rvalue_ref.h
@@ -27,6 +27,9 @@
 #include <tvm/ffi/object.h>
 #include <tvm/ffi/type_traits.h>
 
+#include <string>
+#include <utility>
+
 namespace tvm {
 namespace ffi {
 
@@ -69,7 +72,7 @@ template <typename TObjRef, typename = 
std::enable_if_t<std::is_base_of_v<Object
 class RValueRef {
  public:
   /*! \brief only allow move constructor from rvalue of T */
-  RValueRef(TObjRef&& data)
+  explicit RValueRef(TObjRef&& data)
       : 
data_(details::ObjectUnsafe::ObjectPtrFromObjectRef<Object>(std::move(data))) {}
 
   /*! \brief return the data as rvalue */
@@ -87,7 +90,7 @@ inline constexpr bool 
use_default_type_traits_v<RValueRef<TObjRef>> = false;
 
 template <typename TObjRef>
 struct TypeTraits<RValueRef<TObjRef>> : public TypeTraitsBase {
-  static constexpr bool container_enabled = false;
+  static constexpr bool storage_enabled = false;
 
   static TVM_FFI_INLINE void CopyToAnyView(const RValueRef<TObjRef>& src, 
TVMFFIAny* result) {
     result->type_index = TypeIndex::kTVMFFIObjectRValueRef;
@@ -103,7 +106,7 @@ struct TypeTraits<RValueRef<TObjRef>> : public 
TypeTraitsBase {
       // in this case we do not move the original rvalue ref since conversion 
creates a copy
       TVMFFIAny tmp_any;
       tmp_any.type_index = rvalue_ref->get()->type_index();
-      ;
+
       tmp_any.v_obj = reinterpret_cast<TVMFFIObject*>(rvalue_ref->get());
       return "RValueRef<" + TypeTraits<TObjRef>::GetMismatchTypeInfo(&tmp_any) 
+ ">";
     } else {
@@ -121,7 +124,7 @@ struct TypeTraits<RValueRef<TObjRef>> : public 
TypeTraitsBase {
       tmp_any.v_obj = reinterpret_cast<TVMFFIObject*>(rvalue_ref->get());
       // fast path, storage type matches, direct move the rvalue ref
       if (TypeTraits<TObjRef>::CheckAnyStorage(&tmp_any)) {
-        return TObjRef(std::move(*rvalue_ref));
+        return RValueRef<TObjRef>(TObjRef(std::move(*rvalue_ref)));
       }
       if (std::optional<TObjRef> opt = 
TypeTraits<TObjRef>::TryConvertFromAnyView(&tmp_any)) {
         // object type does not match up, we need to try to convert the object
diff --git a/ffi/include/tvm/ffi/string.h b/ffi/include/tvm/ffi/string.h
index c41b41c92e..51a1ecc810 100644
--- a/ffi/include/tvm/ffi/string.h
+++ b/ffi/include/tvm/ffi/string.h
@@ -213,7 +213,7 @@ class Bytes : public ObjectRef {
  */
 class String : public ObjectRef {
  public:
-  String(nullptr_t) = delete;
+  String(nullptr_t) = delete;  // NOLINT(*)
 
   /*!
    * \brief constructor from char [N]
@@ -392,7 +392,7 @@ template <int N>
 struct TypeTraits<char[N]> : public TypeTraitsBase {
   // NOTE: only enable implicit conversion into AnyView
   static constexpr int32_t field_static_type_index = TypeIndex::kTVMFFIRawStr;
-  static constexpr bool container_enabled = false;
+  static constexpr bool storage_enabled = false;
 
   static TVM_FFI_INLINE void CopyToAnyView(const char src[N], TVMFFIAny* 
result) {
     result->type_index = TypeIndex::kTVMFFIRawStr;
@@ -408,7 +408,7 @@ struct TypeTraits<char[N]> : public TypeTraitsBase {
 template <>
 struct TypeTraits<const char*> : public TypeTraitsBase {
   static constexpr int32_t field_static_type_index = TypeIndex::kTVMFFIRawStr;
-  static constexpr bool container_enabled = false;
+  static constexpr bool storage_enabled = false;
 
   static TVM_FFI_INLINE void CopyToAnyView(const char* src, TVMFFIAny* result) 
{
     TVM_FFI_ICHECK_NOTNULL(src);
@@ -435,7 +435,7 @@ struct TypeTraits<const char*> : public TypeTraitsBase {
 template <>
 struct TypeTraits<TVMFFIByteArray*> : public TypeTraitsBase {
   static constexpr int32_t field_static_type_index = 
TypeIndex::kTVMFFIByteArrayPtr;
-  static constexpr bool container_enabled = false;
+  static constexpr bool storage_enabled = false;
 
   static TVM_FFI_INLINE void CopyToAnyView(TVMFFIByteArray* src, TVMFFIAny* 
result) {
     TVM_FFI_ICHECK_NOTNULL(src);
diff --git a/ffi/include/tvm/ffi/type_traits.h 
b/ffi/include/tvm/ffi/type_traits.h
index aceb04676c..5f0b94d078 100644
--- a/ffi/include/tvm/ffi/type_traits.h
+++ b/ffi/include/tvm/ffi/type_traits.h
@@ -31,6 +31,7 @@
 
 #include <string>
 #include <type_traits>
+#include <utility>
 
 namespace tvm {
 namespace ffi {
@@ -65,9 +66,9 @@ namespace ffi {
 template <typename, typename = void>
 struct TypeTraits {
   /*! \brief Whether the type is enabled in FFI. */
-  static constexpr bool enabled = false;
+  static constexpr bool convert_enabled = false;
   /*! \brief Whether the type can appear as a storage type in Container */
-  static constexpr bool container_enabled = false;
+  static constexpr bool storage_enabled = false;
 };
 
 /*!
@@ -81,8 +82,8 @@ template <typename T>
 inline constexpr bool use_default_type_traits_v = true;
 
 struct TypeTraitsBase {
-  static constexpr bool enabled = true;
-  static constexpr bool container_enabled = true;
+  static constexpr bool convert_enabled = true;
+  static constexpr bool storage_enabled = true;
   // get mismatched type when result mismatches the trait.
   // this function is called after TryConvertFromAnyView fails
   // to get more detailed type information in runtime
@@ -140,7 +141,7 @@ struct TypeTraits<std::nullptr_t> : public TypeTraitsBase {
  */
 class StrictBool {
  public:
-  StrictBool(bool value) : value_(value) {}
+  StrictBool(bool value) : value_(value) {}  // NOLINT(*)
   operator bool() const { return value_; }
 
  private:
@@ -375,7 +376,7 @@ struct TypeTraits<DLDevice> : public TypeTraitsBase {
 // DLTensor*, requirement: not nullable, do not retain ownership
 template <>
 struct TypeTraits<DLTensor*> : public TypeTraitsBase {
-  static constexpr bool container_enabled = false;
+  static constexpr bool storage_enabled = false;
   static constexpr int32_t field_static_type_index = 
TypeIndex::kTVMFFIDLTensorPtr;
 
   static TVM_FFI_INLINE void CopyToAnyView(DLTensor* src, TVMFFIAny* result) {
@@ -508,7 +509,7 @@ struct TypeTraits<TObjRef, 
std::enable_if_t<std::is_base_of_v<ObjectRef, TObjRef
 template <typename T, typename... FallbackTypes>
 struct FallbackOnlyTraitsBase : public TypeTraitsBase {
   // disable container for FallbackOnlyTraitsBase
-  static constexpr bool container_enabled = false;
+  static constexpr bool storage_enabled = false;
 
   static TVM_FFI_INLINE std::optional<T> TryConvertFromAnyView(const 
TVMFFIAny* src) {
     return TryFallbackTypes<FallbackTypes...>(src);
diff --git a/ffi/src/ffi/object.cc b/ffi/src/ffi/object.cc
index b1978ff6b1..0b5933ca60 100644
--- a/ffi/src/ffi/object.cc
+++ b/ffi/src/ffi/object.cc
@@ -249,7 +249,9 @@ class TypeTable {
     ReserveBuiltinTypeIndex(StaticTypeKey::kTVMFFIOpaquePtr, 
TypeIndex::kTVMFFIOpaquePtr);
     ReserveBuiltinTypeIndex(StaticTypeKey::kTVMFFIDataType, 
TypeIndex::kTVMFFIDataType);
     ReserveBuiltinTypeIndex(StaticTypeKey::kTVMFFIDevice, 
TypeIndex::kTVMFFIDevice);
-    ReserveBuiltinTypeIndex(StaticTypeKey::kTVMFFIObjectRValueRef, 
TypeIndex::kTVMFFIObjectRValueRef);
+    ReserveBuiltinTypeIndex(
+      StaticTypeKey::kTVMFFIObjectRValueRef,
+      TypeIndex::kTVMFFIObjectRValueRef);
   }
 
   void ReserveBuiltinTypeIndex(const char* type_key, int32_t 
static_type_index) {

Reply via email to