gemini-code-assist[bot] commented on code in PR #382:
URL: https://github.com/apache/tvm-ffi/pull/382#discussion_r2671437147


##########
docs/concepts/any.rst:
##########
@@ -0,0 +1,441 @@
+..  Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+..    http://www.apache.org/licenses/LICENSE-2.0
+
+..  Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+Any and AnyView
+===============
+
+TVM-FFI has :cpp:class:`tvm::ffi::Any` and :cpp:class:`tvm::ffi::AnyView`,
+type-erased containers that hold any supported value and transport it across
+C, C++, Python, and Rust boundaries through a stable ABI.
+
+Similar to ``std::any``, :cpp:class:`~tvm::ffi::Any` is a tagged union that 
store
+values of wide variety of types, including primitive types, objects, strings, 
etc.
+Unlike ``std::any``, it is designed for RTTI-free zero-copy inter-language 
exchange,
+with a fixed 16-byte layout and built-in support for reference counting and 
ownership.
+
+This tutorial covers all about Any: its common usage patterns, ownership 
semantics,
+and memory layout.
+
+
+Common Usecases
+---------------
+
+Function inputs and outputs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Use :cpp:class:`~tvm::ffi::AnyView` for function parameters,
+which avoids reference count churn or unnecessary copies, and 
:cpp:class:`~tvm::ffi::Any` for return values,
+which transfers ownership to the caller.
+
+.. code-block:: cpp
+
+   ffi::Any func_cpp_signature(ffi::AnyView arg0, ffi::AnyView arg1) {
+    ffi::Any result = arg0.cast<int>() + arg1.cast<int>();
+    return result;
+   }
+
+   // Variant: variadic function
+   void func_cpp_variadic(PackedArgs args, Any* ret) {
+     int32_t num_args = args.size();
+     int x0 = args[0].cast<int>();
+     int x1 = args[1].cast<int>();
+     int y = x0 + x1;
+     *ret = y;
+   }
+
+   // Variant: variadic function with C ABI signature
+   int func_c_abi_variadic(void*, const TVMFFIAny* args, int32_t num_args, 
TVMFFIAny* ret) {
+     TVM_FFI_SAFE_CALL_BEGIN();
+     int x0 = reinterpret_cast<const AnyView*>(args)[0].cast<int>();
+     int x1 = reinterpret_cast<const AnyView*>(args)[1].cast<int>();
+     int y = x0 + x1;
+     reinterpret_cast<Any*>(ret)[0] = y;
+     TVM_FFI_SAFE_CALL_END();
+   }
+
+
+Container Storage
+~~~~~~~~~~~~~~~~~
+
+:cpp:class:`~tvm::ffi::Any` can be stored in containers like 
:cpp:class:`~tvm::ffi::Map` and :cpp:class:`~tvm::ffi::Array`:
+
+.. code-block:: cpp
+
+   ffi::Map<ffi::String, ffi::Any> config;
+   config.Set("learning_rate", 0.001);
+   config.Set("batch_size", 32);
+   config.Set("device", DLDevice{kDLCUDA, 0});
+
+Extracting Values
+~~~~~~~~~~~~~~~~~
+
+Three methods pull values out of :cpp:class:`~tvm::ffi::Any`
+and :cpp:class:`~tvm::ffi::AnyView`, each with different strictness:
+
+.. list-table::
+   :header-rows: 1
+   :widths: 20 45 30
+
+   * - Method
+     - Behavior
+     - Use When
+   * - :cpp:func:`cast\<T\>() <tvm::ffi::Any::cast>`
+     - Returns ``T`` or throws :cpp:class:`tvm::ffi::Error`
+     - You know the type and want to throw on type mismatch
+   * - :cpp:func:`try_cast\<T\>() <tvm::ffi::Any::try_cast>`
+     - Returns ``std::optional<T>``
+     - Returns None on type mismatch, allows type conversion
+   * - :cpp:func:`as\<T\>() <tvm::ffi::Any::as>`
+     - Returns ``std::optional<T>`` or ``const T*`` (for TVM-FFI object types)
+     - Returns None on type mismatch, but doesn't allow type conversion
+
+.. dropdown:: Example of :cpp:func:`cast\<T\>() <tvm::ffi::Any::cast>`
+
+  :cpp:func:`cast\<T\>() <tvm::ffi::Any::cast>` is the workhorse. It returns 
the value or throws:
+
+  .. code-block:: cpp
+
+    ffi::Any value = 42;
+    int x = value.cast<int>();       // OK: 42
+    double y = value.cast<double>(); // OK: 42.0 (int → double)
+
+    try {
+      ffi::String s = value.cast<ffi::String>();  // Throws TypeError
+    } catch (const ffi::Error& e) {
+      // "Cannot convert from type `int` to `ffi.Str`"
+    }
+
+.. dropdown:: Example of :cpp:func:`try_cast\<T\>() <tvm::ffi::Any::try_cast>`
+
+  :cpp:func:`try_cast\<T\>() <tvm::ffi::Any::try_cast>` allows type coercion:
+
+  .. code-block:: cpp
+
+    ffi::Any value = 42;
+
+    std::optional<double> opt_float = value.try_cast<double>();
+    // opt_float.has_value() == true, *opt_float == 42.0
+
+    std::optional<bool> opt_bool = value.try_cast<bool>();
+    // opt_bool.has_value() == true, *opt_bool == true
+
+
+.. dropdown:: Example of :cpp:func:`as\<T\>() <tvm::ffi::Any::as>`
+
+  :cpp:func:`as\<T\>() <tvm::ffi::Any::as>` is strict - it only succeeds if 
the stored type exactly matches:
+
+  .. code-block:: cpp
+
+    ffi::Any value = 42;
+
+    std::optional<int64_t> opt_int = value.as<int64_t>();
+    // opt_int.has_value() == true
+
+    std::optional<double> opt_float = value.as<double>();
+    // opt_float.has_value() == false (int stored, not float)
+
+    ffi::Any value = ffi::String("hello, world!");
+    if (const ffi::Object* obj = value.as<ffi::Object>()) {
+      // Use obj without copying
+    }
+
+
+Nullability Checks
+~~~~~~~~~~~~~~~~~~
+
+Compare with ``nullptr`` to check for ``None``:
+
+.. code-block:: cpp
+
+   ffi::Any value = std::nullopt;
+   if (value == nullptr) {
+     // Handle None case
+   } else {
+     // Process value
+   }
+
+
+Ownership
+---------
+
+The core distinction between :cpp:class:`tvm::ffi::Any` and
+:cpp:class:`tvm::ffi::AnyView` is **ownership**:
+
+.. list-table::
+   :header-rows: 1
+   :widths: 25 35 40
+
+   * - Aspect
+     - :cpp:class:`~tvm::ffi::AnyView`
+     - :cpp:class:`~tvm::ffi::Any`
+   * - Ownership
+     - Non-owning (like ``std::string_view``)
+     - Owning (like ``std::string``)
+   * - Reference counting
+     - No reference count changes on copy
+     - Increments reference count on copy; decrements on destroy
+   * - Lifetime
+     - Valid only while source lives
+     - Extends object lifetime
+   * - Primary use
+     - Function inputs
+     - Return values, storage
+
+Code Examples
+~~~~~~~~~~~~~~
+
+:cpp:class:`~tvm::ffi::AnyView` is a lightweight view. Copying it just copies 
16 bytes
+- no reference count updates. This makes it perfect for passing arguments 
without overhead:
+
+.. code-block:: cpp
+
+   void process(ffi::AnyView value) {}
+
+:cpp:class:`~tvm::ffi::Any` is a managed container. Copy an 
:cpp:class:`~tvm::ffi::Any` holding an object, and the reference
+count goes up. Destroy it, and the count goes down:
+
+.. code-block:: cpp
+
+   ffi::Any create_value() {
+     ffi::Any result;
+     {
+       ffi::String str = "hello"; // refcount = 1 (str created)
+       result = str;              // refcount 1 -> 2 (result owns str)
+     }                            // refcount 2 -> 1 (str is destroyed)
+     return result;               // refcount = 1 (result returns to caller)
+   }
+
+
+ABI Boundary
+~~~~~~~~~~~~
+
+TVM-FFI's function calling convention follows a simple rule:
+
+- **Inputs are non-owning**: Arguments are passed as 
:cpp:class:`~tvm::ffi::AnyView`. The caller
+  retains ownership; the callee borrows them for the duration of the call.
+- **Outputs are owning**: The return value is an :cpp:class:`~tvm::ffi::Any`. 
Ownership transfers
+  to the caller, who becomes responsible for the value's lifetime.
+
+.. code-block:: cpp
+
+   // TVM-FFI C ABI
+   int32_t tvm_ffi_c_abi(
+     void* handle,
+     const AnyView* args,   // (Non-owning) args: AnyView[num_args]
+     int32_t num_args,
+     Any* result,           // (Owning) result: Any (caller takes ownership)
+   );
+
+Destruction Semantics in C
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In C, which doesn't have RAII, you need to manually destroy the 
:cpp:class:`~tvm::ffi::Any` object
+by calling :cpp:func:`TVMFFIObjectDecRef` for heap-allocated objects.
+
+.. code-block:: cpp
+
+   void destroy_any(TVMFFIAny* any) {
+     if (any->type_index >= kTVMFFIStaticObjectBegin) {
+       // Decrement the reference count of the heap-allocated object
+       TVMFFIObjectDecRef(any->v_obj);
+     }
+     empty_any_just_to_be_safe(any);
+   }
+
+   void empty_any_just_to_be_safe(Any* any) {
+     any->type_index = kTVMFFINone;
+     any->zero_padding = 0;
+     any->v_int64 = 0;
+   }

Review Comment:
   ![high](https://www.gstatic.com/codereviewagent/high-priority.svg)
   
   The function `empty_any_just_to_be_safe` is defined to take `Any*`, but it's 
called with a `TVMFFIAny*` in `destroy_any`. This is a type mismatch. The 
function should take `TVMFFIAny*` to be compatible with its usage. `Any` is a 
C++ class wrapper, while `TVMFFIAny` is the underlying C struct, which seems to 
be the intended type here given the C-style memory manipulation.
   
   ```suggestion
      void empty_any_just_to_be_safe(TVMFFIAny* any) {
        any->type_index = kTVMFFINone;
        any->zero_padding = 0;
        any->v_int64 = 0;
      }
   ```



##########
docs/concepts/any.rst:
##########
@@ -0,0 +1,441 @@
+..  Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+..    http://www.apache.org/licenses/LICENSE-2.0
+
+..  Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+Any and AnyView
+===============
+
+TVM-FFI has :cpp:class:`tvm::ffi::Any` and :cpp:class:`tvm::ffi::AnyView`,
+type-erased containers that hold any supported value and transport it across
+C, C++, Python, and Rust boundaries through a stable ABI.
+
+Similar to ``std::any``, :cpp:class:`~tvm::ffi::Any` is a tagged union that 
store
+values of wide variety of types, including primitive types, objects, strings, 
etc.
+Unlike ``std::any``, it is designed for RTTI-free zero-copy inter-language 
exchange,
+with a fixed 16-byte layout and built-in support for reference counting and 
ownership.
+
+This tutorial covers all about Any: its common usage patterns, ownership 
semantics,
+and memory layout.
+
+
+Common Usecases
+---------------
+
+Function inputs and outputs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Use :cpp:class:`~tvm::ffi::AnyView` for function parameters,
+which avoids reference count churn or unnecessary copies, and 
:cpp:class:`~tvm::ffi::Any` for return values,
+which transfers ownership to the caller.
+
+.. code-block:: cpp
+
+   ffi::Any func_cpp_signature(ffi::AnyView arg0, ffi::AnyView arg1) {
+    ffi::Any result = arg0.cast<int>() + arg1.cast<int>();
+    return result;
+   }
+
+   // Variant: variadic function
+   void func_cpp_variadic(PackedArgs args, Any* ret) {
+     int32_t num_args = args.size();

Review Comment:
   ![medium](https://www.gstatic.com/codereviewagent/medium-priority.svg)
   
   The variable `num_args` is declared but never used in this function. It's 
best to remove it to avoid confusion and keep the example clean.



##########
docs/concepts/any.rst:
##########
@@ -0,0 +1,441 @@
+..  Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+..    http://www.apache.org/licenses/LICENSE-2.0
+
+..  Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+Any and AnyView
+===============
+
+TVM-FFI has :cpp:class:`tvm::ffi::Any` and :cpp:class:`tvm::ffi::AnyView`,
+type-erased containers that hold any supported value and transport it across
+C, C++, Python, and Rust boundaries through a stable ABI.
+
+Similar to ``std::any``, :cpp:class:`~tvm::ffi::Any` is a tagged union that 
store
+values of wide variety of types, including primitive types, objects, strings, 
etc.
+Unlike ``std::any``, it is designed for RTTI-free zero-copy inter-language 
exchange,
+with a fixed 16-byte layout and built-in support for reference counting and 
ownership.
+
+This tutorial covers all about Any: its common usage patterns, ownership 
semantics,
+and memory layout.
+
+
+Common Usecases
+---------------
+
+Function inputs and outputs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Use :cpp:class:`~tvm::ffi::AnyView` for function parameters,
+which avoids reference count churn or unnecessary copies, and 
:cpp:class:`~tvm::ffi::Any` for return values,
+which transfers ownership to the caller.
+
+.. code-block:: cpp
+
+   ffi::Any func_cpp_signature(ffi::AnyView arg0, ffi::AnyView arg1) {
+    ffi::Any result = arg0.cast<int>() + arg1.cast<int>();
+    return result;
+   }
+
+   // Variant: variadic function
+   void func_cpp_variadic(PackedArgs args, Any* ret) {
+     int32_t num_args = args.size();
+     int x0 = args[0].cast<int>();
+     int x1 = args[1].cast<int>();
+     int y = x0 + x1;
+     *ret = y;
+   }
+
+   // Variant: variadic function with C ABI signature
+   int func_c_abi_variadic(void*, const TVMFFIAny* args, int32_t num_args, 
TVMFFIAny* ret) {
+     TVM_FFI_SAFE_CALL_BEGIN();
+     int x0 = reinterpret_cast<const AnyView*>(args)[0].cast<int>();
+     int x1 = reinterpret_cast<const AnyView*>(args)[1].cast<int>();
+     int y = x0 + x1;
+     reinterpret_cast<Any*>(ret)[0] = y;
+     TVM_FFI_SAFE_CALL_END();
+   }
+
+
+Container Storage
+~~~~~~~~~~~~~~~~~
+
+:cpp:class:`~tvm::ffi::Any` can be stored in containers like 
:cpp:class:`~tvm::ffi::Map` and :cpp:class:`~tvm::ffi::Array`:
+
+.. code-block:: cpp
+
+   ffi::Map<ffi::String, ffi::Any> config;
+   config.Set("learning_rate", 0.001);
+   config.Set("batch_size", 32);
+   config.Set("device", DLDevice{kDLCUDA, 0});
+
+Extracting Values
+~~~~~~~~~~~~~~~~~
+
+Three methods pull values out of :cpp:class:`~tvm::ffi::Any`
+and :cpp:class:`~tvm::ffi::AnyView`, each with different strictness:
+
+.. list-table::
+   :header-rows: 1
+   :widths: 20 45 30
+
+   * - Method
+     - Behavior
+     - Use When
+   * - :cpp:func:`cast\<T\>() <tvm::ffi::Any::cast>`
+     - Returns ``T`` or throws :cpp:class:`tvm::ffi::Error`
+     - You know the type and want to throw on type mismatch
+   * - :cpp:func:`try_cast\<T\>() <tvm::ffi::Any::try_cast>`
+     - Returns ``std::optional<T>``
+     - Returns None on type mismatch, allows type conversion
+   * - :cpp:func:`as\<T\>() <tvm::ffi::Any::as>`
+     - Returns ``std::optional<T>`` or ``const T*`` (for TVM-FFI object types)
+     - Returns None on type mismatch, but doesn't allow type conversion
+
+.. dropdown:: Example of :cpp:func:`cast\<T\>() <tvm::ffi::Any::cast>`
+
+  :cpp:func:`cast\<T\>() <tvm::ffi::Any::cast>` is the workhorse. It returns 
the value or throws:
+
+  .. code-block:: cpp
+
+    ffi::Any value = 42;
+    int x = value.cast<int>();       // OK: 42
+    double y = value.cast<double>(); // OK: 42.0 (int → double)
+
+    try {
+      ffi::String s = value.cast<ffi::String>();  // Throws TypeError
+    } catch (const ffi::Error& e) {
+      // "Cannot convert from type `int` to `ffi.Str`"
+    }
+
+.. dropdown:: Example of :cpp:func:`try_cast\<T\>() <tvm::ffi::Any::try_cast>`
+
+  :cpp:func:`try_cast\<T\>() <tvm::ffi::Any::try_cast>` allows type coercion:
+
+  .. code-block:: cpp
+
+    ffi::Any value = 42;
+
+    std::optional<double> opt_float = value.try_cast<double>();
+    // opt_float.has_value() == true, *opt_float == 42.0
+
+    std::optional<bool> opt_bool = value.try_cast<bool>();
+    // opt_bool.has_value() == true, *opt_bool == true
+
+
+.. dropdown:: Example of :cpp:func:`as\<T\>() <tvm::ffi::Any::as>`
+
+  :cpp:func:`as\<T\>() <tvm::ffi::Any::as>` is strict - it only succeeds if 
the stored type exactly matches:
+
+  .. code-block:: cpp
+
+    ffi::Any value = 42;
+
+    std::optional<int64_t> opt_int = value.as<int64_t>();
+    // opt_int.has_value() == true
+
+    std::optional<double> opt_float = value.as<double>();
+    // opt_float.has_value() == false (int stored, not float)
+
+    ffi::Any value = ffi::String("hello, world!");
+    if (const ffi::Object* obj = value.as<ffi::Object>()) {
+      // Use obj without copying
+    }
+
+
+Nullability Checks
+~~~~~~~~~~~~~~~~~~
+
+Compare with ``nullptr`` to check for ``None``:
+
+.. code-block:: cpp
+
+   ffi::Any value = std::nullopt;
+   if (value == nullptr) {
+     // Handle None case
+   } else {
+     // Process value
+   }
+
+
+Ownership
+---------
+
+The core distinction between :cpp:class:`tvm::ffi::Any` and
+:cpp:class:`tvm::ffi::AnyView` is **ownership**:
+
+.. list-table::
+   :header-rows: 1
+   :widths: 25 35 40
+
+   * - Aspect
+     - :cpp:class:`~tvm::ffi::AnyView`
+     - :cpp:class:`~tvm::ffi::Any`
+   * - Ownership
+     - Non-owning (like ``std::string_view``)
+     - Owning (like ``std::string``)
+   * - Reference counting
+     - No reference count changes on copy
+     - Increments reference count on copy; decrements on destroy
+   * - Lifetime
+     - Valid only while source lives
+     - Extends object lifetime
+   * - Primary use
+     - Function inputs
+     - Return values, storage
+
+Code Examples
+~~~~~~~~~~~~~~
+
+:cpp:class:`~tvm::ffi::AnyView` is a lightweight view. Copying it just copies 
16 bytes
+- no reference count updates. This makes it perfect for passing arguments 
without overhead:
+
+.. code-block:: cpp
+
+   void process(ffi::AnyView value) {}
+
+:cpp:class:`~tvm::ffi::Any` is a managed container. Copy an 
:cpp:class:`~tvm::ffi::Any` holding an object, and the reference
+count goes up. Destroy it, and the count goes down:
+
+.. code-block:: cpp
+
+   ffi::Any create_value() {
+     ffi::Any result;
+     {
+       ffi::String str = "hello"; // refcount = 1 (str created)
+       result = str;              // refcount 1 -> 2 (result owns str)
+     }                            // refcount 2 -> 1 (str is destroyed)
+     return result;               // refcount = 1 (result returns to caller)
+   }
+
+
+ABI Boundary
+~~~~~~~~~~~~
+
+TVM-FFI's function calling convention follows a simple rule:
+
+- **Inputs are non-owning**: Arguments are passed as 
:cpp:class:`~tvm::ffi::AnyView`. The caller
+  retains ownership; the callee borrows them for the duration of the call.
+- **Outputs are owning**: The return value is an :cpp:class:`~tvm::ffi::Any`. 
Ownership transfers
+  to the caller, who becomes responsible for the value's lifetime.
+
+.. code-block:: cpp
+
+   // TVM-FFI C ABI
+   int32_t tvm_ffi_c_abi(
+     void* handle,
+     const AnyView* args,   // (Non-owning) args: AnyView[num_args]
+     int32_t num_args,
+     Any* result,           // (Owning) result: Any (caller takes ownership)
+   );
+
+Destruction Semantics in C
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In C, which doesn't have RAII, you need to manually destroy the 
:cpp:class:`~tvm::ffi::Any` object
+by calling :cpp:func:`TVMFFIObjectDecRef` for heap-allocated objects.
+
+.. code-block:: cpp
+
+   void destroy_any(TVMFFIAny* any) {
+     if (any->type_index >= kTVMFFIStaticObjectBegin) {
+       // Decrement the reference count of the heap-allocated object
+       TVMFFIObjectDecRef(any->v_obj);
+     }
+     empty_any_just_to_be_safe(any);
+   }
+
+   void empty_any_just_to_be_safe(Any* any) {
+     any->type_index = kTVMFFINone;
+     any->zero_padding = 0;
+     any->v_int64 = 0;
+   }
+
+On the contrary, destroying :cpp:class:`~tvm::ffi::AnyView` is effectively a 
no-op besides emptying its content.
+
+.. code-block:: cpp
+
+   void destroy_any_view(AnyView* any_view) {
+     empty_any_view_just_to_be_safe(any_view);
+   }
+
+
+Layout
+------
+
+Tagged Union
+~~~~~~~~~~~~
+
+At C ABI level, every value lives in a :cpp:class:`TVMFFIAny`:
+
+.. code-block:: cpp
+
+   typedef struct TVMFFIAny {
+     int32_t type_index;      // Bytes 0-3: identifies the stored type
+     union {
+       uint32_t zero_padding; // Bytes 4-7: must be zero (or small_str_len)
+       uint32_t small_str_len;
+     };
+     union {                  // Bytes 8-15: the actual value
+       int64_t v_int64;
+       double v_float64;
+       void* v_ptr;
+       TVMFFIObject* v_obj;
+       DLDevice v_device;
+       char v_bytes[8];
+       // ... other union members
+     };

Review Comment:
   ![medium](https://www.gstatic.com/codereviewagent/medium-priority.svg)
   
   The `TVMFFIAny` struct definition in this example is incomplete compared to 
the `c_api.h` header and the table of atomic types that follows. It's missing 
`v_c_str`, `v_dtype`, and `v_uint64`. This can be confusing for readers. Please 
update the struct definition to be more complete and consistent.
   
   ```suggestion
        union {                  // Bytes 8-15: the actual value
          int64_t v_int64;
          double v_float64;
          void* v_ptr;
          const char* v_c_str;
          TVMFFIObject* v_obj;
          DLDataType v_dtype;
          DLDevice v_device;
          char v_bytes[8];
          uint64_t v_uint64;
          // ... other union members
        };
   ```



##########
docs/concepts/any.rst:
##########
@@ -0,0 +1,441 @@
+..  Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+..    http://www.apache.org/licenses/LICENSE-2.0
+
+..  Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+Any and AnyView
+===============
+
+TVM-FFI has :cpp:class:`tvm::ffi::Any` and :cpp:class:`tvm::ffi::AnyView`,
+type-erased containers that hold any supported value and transport it across
+C, C++, Python, and Rust boundaries through a stable ABI.
+
+Similar to ``std::any``, :cpp:class:`~tvm::ffi::Any` is a tagged union that 
store
+values of wide variety of types, including primitive types, objects, strings, 
etc.
+Unlike ``std::any``, it is designed for RTTI-free zero-copy inter-language 
exchange,
+with a fixed 16-byte layout and built-in support for reference counting and 
ownership.
+
+This tutorial covers all about Any: its common usage patterns, ownership 
semantics,
+and memory layout.
+
+
+Common Usecases
+---------------
+
+Function inputs and outputs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Use :cpp:class:`~tvm::ffi::AnyView` for function parameters,
+which avoids reference count churn or unnecessary copies, and 
:cpp:class:`~tvm::ffi::Any` for return values,
+which transfers ownership to the caller.
+
+.. code-block:: cpp
+
+   ffi::Any func_cpp_signature(ffi::AnyView arg0, ffi::AnyView arg1) {
+    ffi::Any result = arg0.cast<int>() + arg1.cast<int>();
+    return result;
+   }
+
+   // Variant: variadic function
+   void func_cpp_variadic(PackedArgs args, Any* ret) {
+     int32_t num_args = args.size();
+     int x0 = args[0].cast<int>();
+     int x1 = args[1].cast<int>();
+     int y = x0 + x1;
+     *ret = y;
+   }
+
+   // Variant: variadic function with C ABI signature
+   int func_c_abi_variadic(void*, const TVMFFIAny* args, int32_t num_args, 
TVMFFIAny* ret) {
+     TVM_FFI_SAFE_CALL_BEGIN();
+     int x0 = reinterpret_cast<const AnyView*>(args)[0].cast<int>();
+     int x1 = reinterpret_cast<const AnyView*>(args)[1].cast<int>();
+     int y = x0 + x1;
+     reinterpret_cast<Any*>(ret)[0] = y;
+     TVM_FFI_SAFE_CALL_END();
+   }
+
+
+Container Storage
+~~~~~~~~~~~~~~~~~
+
+:cpp:class:`~tvm::ffi::Any` can be stored in containers like 
:cpp:class:`~tvm::ffi::Map` and :cpp:class:`~tvm::ffi::Array`:
+
+.. code-block:: cpp
+
+   ffi::Map<ffi::String, ffi::Any> config;
+   config.Set("learning_rate", 0.001);
+   config.Set("batch_size", 32);
+   config.Set("device", DLDevice{kDLCUDA, 0});
+
+Extracting Values
+~~~~~~~~~~~~~~~~~
+
+Three methods pull values out of :cpp:class:`~tvm::ffi::Any`
+and :cpp:class:`~tvm::ffi::AnyView`, each with different strictness:
+
+.. list-table::
+   :header-rows: 1
+   :widths: 20 45 30
+
+   * - Method
+     - Behavior
+     - Use When
+   * - :cpp:func:`cast\<T\>() <tvm::ffi::Any::cast>`
+     - Returns ``T`` or throws :cpp:class:`tvm::ffi::Error`
+     - You know the type and want to throw on type mismatch
+   * - :cpp:func:`try_cast\<T\>() <tvm::ffi::Any::try_cast>`
+     - Returns ``std::optional<T>``
+     - Returns None on type mismatch, allows type conversion
+   * - :cpp:func:`as\<T\>() <tvm::ffi::Any::as>`
+     - Returns ``std::optional<T>`` or ``const T*`` (for TVM-FFI object types)
+     - Returns None on type mismatch, but doesn't allow type conversion
+
+.. dropdown:: Example of :cpp:func:`cast\<T\>() <tvm::ffi::Any::cast>`
+
+  :cpp:func:`cast\<T\>() <tvm::ffi::Any::cast>` is the workhorse. It returns 
the value or throws:
+
+  .. code-block:: cpp
+
+    ffi::Any value = 42;
+    int x = value.cast<int>();       // OK: 42
+    double y = value.cast<double>(); // OK: 42.0 (int → double)
+
+    try {
+      ffi::String s = value.cast<ffi::String>();  // Throws TypeError
+    } catch (const ffi::Error& e) {
+      // "Cannot convert from type `int` to `ffi.Str`"
+    }
+
+.. dropdown:: Example of :cpp:func:`try_cast\<T\>() <tvm::ffi::Any::try_cast>`
+
+  :cpp:func:`try_cast\<T\>() <tvm::ffi::Any::try_cast>` allows type coercion:
+
+  .. code-block:: cpp
+
+    ffi::Any value = 42;
+
+    std::optional<double> opt_float = value.try_cast<double>();
+    // opt_float.has_value() == true, *opt_float == 42.0
+
+    std::optional<bool> opt_bool = value.try_cast<bool>();
+    // opt_bool.has_value() == true, *opt_bool == true
+
+
+.. dropdown:: Example of :cpp:func:`as\<T\>() <tvm::ffi::Any::as>`
+
+  :cpp:func:`as\<T\>() <tvm::ffi::Any::as>` is strict - it only succeeds if 
the stored type exactly matches:
+
+  .. code-block:: cpp
+
+    ffi::Any value = 42;
+
+    std::optional<int64_t> opt_int = value.as<int64_t>();
+    // opt_int.has_value() == true
+
+    std::optional<double> opt_float = value.as<double>();
+    // opt_float.has_value() == false (int stored, not float)
+
+    ffi::Any value = ffi::String("hello, world!");
+    if (const ffi::Object* obj = value.as<ffi::Object>()) {
+      // Use obj without copying
+    }
+
+
+Nullability Checks
+~~~~~~~~~~~~~~~~~~
+
+Compare with ``nullptr`` to check for ``None``:
+
+.. code-block:: cpp
+
+   ffi::Any value = std::nullopt;
+   if (value == nullptr) {
+     // Handle None case
+   } else {
+     // Process value
+   }
+
+
+Ownership
+---------
+
+The core distinction between :cpp:class:`tvm::ffi::Any` and
+:cpp:class:`tvm::ffi::AnyView` is **ownership**:
+
+.. list-table::
+   :header-rows: 1
+   :widths: 25 35 40
+
+   * - Aspect
+     - :cpp:class:`~tvm::ffi::AnyView`
+     - :cpp:class:`~tvm::ffi::Any`
+   * - Ownership
+     - Non-owning (like ``std::string_view``)
+     - Owning (like ``std::string``)
+   * - Reference counting
+     - No reference count changes on copy
+     - Increments reference count on copy; decrements on destroy
+   * - Lifetime
+     - Valid only while source lives
+     - Extends object lifetime
+   * - Primary use
+     - Function inputs
+     - Return values, storage
+
+Code Examples
+~~~~~~~~~~~~~~
+
+:cpp:class:`~tvm::ffi::AnyView` is a lightweight view. Copying it just copies 
16 bytes
+- no reference count updates. This makes it perfect for passing arguments 
without overhead:
+
+.. code-block:: cpp
+
+   void process(ffi::AnyView value) {}
+
+:cpp:class:`~tvm::ffi::Any` is a managed container. Copy an 
:cpp:class:`~tvm::ffi::Any` holding an object, and the reference
+count goes up. Destroy it, and the count goes down:
+
+.. code-block:: cpp
+
+   ffi::Any create_value() {
+     ffi::Any result;
+     {
+       ffi::String str = "hello"; // refcount = 1 (str created)
+       result = str;              // refcount 1 -> 2 (result owns str)
+     }                            // refcount 2 -> 1 (str is destroyed)
+     return result;               // refcount = 1 (result returns to caller)
+   }
+
+
+ABI Boundary
+~~~~~~~~~~~~
+
+TVM-FFI's function calling convention follows a simple rule:
+
+- **Inputs are non-owning**: Arguments are passed as 
:cpp:class:`~tvm::ffi::AnyView`. The caller
+  retains ownership; the callee borrows them for the duration of the call.
+- **Outputs are owning**: The return value is an :cpp:class:`~tvm::ffi::Any`. 
Ownership transfers
+  to the caller, who becomes responsible for the value's lifetime.
+
+.. code-block:: cpp
+
+   // TVM-FFI C ABI
+   int32_t tvm_ffi_c_abi(
+     void* handle,
+     const AnyView* args,   // (Non-owning) args: AnyView[num_args]
+     int32_t num_args,
+     Any* result,           // (Owning) result: Any (caller takes ownership)
+   );
+
+Destruction Semantics in C
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In C, which doesn't have RAII, you need to manually destroy the 
:cpp:class:`~tvm::ffi::Any` object
+by calling :cpp:func:`TVMFFIObjectDecRef` for heap-allocated objects.
+
+.. code-block:: cpp
+
+   void destroy_any(TVMFFIAny* any) {
+     if (any->type_index >= kTVMFFIStaticObjectBegin) {
+       // Decrement the reference count of the heap-allocated object
+       TVMFFIObjectDecRef(any->v_obj);
+     }
+     empty_any_just_to_be_safe(any);
+   }
+
+   void empty_any_just_to_be_safe(Any* any) {
+     any->type_index = kTVMFFINone;
+     any->zero_padding = 0;
+     any->v_int64 = 0;
+   }
+
+On the contrary, destroying :cpp:class:`~tvm::ffi::AnyView` is effectively a 
no-op besides emptying its content.
+
+.. code-block:: cpp
+
+   void destroy_any_view(AnyView* any_view) {
+     empty_any_view_just_to_be_safe(any_view);
+   }

Review Comment:
   ![high](https://www.gstatic.com/codereviewagent/high-priority.svg)
   
   The function `empty_any_view_just_to_be_safe` is not defined; this seems to 
be a typo for `empty_any_just_to_be_safe`. Additionally, assuming 
`empty_any_just_to_be_safe` is corrected to take a `TVMFFIAny*` as suggested in 
another comment, `any_view` (which is `AnyView*`) needs to be cast to 
`TVMFFIAny*`.
   
   The `reinterpret_cast` is appropriate here because `AnyView` is designed to 
have the same memory layout as `TVMFFIAny`.
   
   ```suggestion
      void destroy_any_view(AnyView* any_view) {
        empty_any_just_to_be_safe(reinterpret_cast<TVMFFIAny*>(any_view));
      }
   ```



##########
docs/concepts/any.rst:
##########
@@ -0,0 +1,441 @@
+..  Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+..    http://www.apache.org/licenses/LICENSE-2.0
+
+..  Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+Any and AnyView
+===============
+
+TVM-FFI has :cpp:class:`tvm::ffi::Any` and :cpp:class:`tvm::ffi::AnyView`,
+type-erased containers that hold any supported value and transport it across
+C, C++, Python, and Rust boundaries through a stable ABI.
+
+Similar to ``std::any``, :cpp:class:`~tvm::ffi::Any` is a tagged union that 
store
+values of wide variety of types, including primitive types, objects, strings, 
etc.
+Unlike ``std::any``, it is designed for RTTI-free zero-copy inter-language 
exchange,
+with a fixed 16-byte layout and built-in support for reference counting and 
ownership.
+
+This tutorial covers all about Any: its common usage patterns, ownership 
semantics,
+and memory layout.

Review Comment:
   ![medium](https://www.gstatic.com/codereviewagent/medium-priority.svg)
   
   Some minor grammatical and wording improvements for better clarity and 
formality in the introduction.
   
   ```suggestion
   Similar to ``std::any``, :cpp:class:`~tvm::ffi::Any` is a tagged union that 
stores
   values of a wide variety of types, including primitive types, objects, 
strings, etc.
   Unlike ``std::any``, it is designed for RTTI-free zero-copy inter-language 
exchange,
   with a fixed 16-byte layout and built-in support for reference counting and 
ownership.
   
   This tutorial covers `Any` in detail: its common usage patterns, ownership 
semantics,
   and memory layout.
   ```



##########
docs/concepts/any.rst:
##########
@@ -0,0 +1,441 @@
+..  Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+..    http://www.apache.org/licenses/LICENSE-2.0
+
+..  Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+Any and AnyView
+===============
+
+TVM-FFI has :cpp:class:`tvm::ffi::Any` and :cpp:class:`tvm::ffi::AnyView`,
+type-erased containers that hold any supported value and transport it across
+C, C++, Python, and Rust boundaries through a stable ABI.
+
+Similar to ``std::any``, :cpp:class:`~tvm::ffi::Any` is a tagged union that 
store
+values of wide variety of types, including primitive types, objects, strings, 
etc.
+Unlike ``std::any``, it is designed for RTTI-free zero-copy inter-language 
exchange,
+with a fixed 16-byte layout and built-in support for reference counting and 
ownership.
+
+This tutorial covers all about Any: its common usage patterns, ownership 
semantics,
+and memory layout.
+
+
+Common Usecases
+---------------
+
+Function inputs and outputs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Use :cpp:class:`~tvm::ffi::AnyView` for function parameters,
+which avoids reference count churn or unnecessary copies, and 
:cpp:class:`~tvm::ffi::Any` for return values,
+which transfers ownership to the caller.
+
+.. code-block:: cpp
+
+   ffi::Any func_cpp_signature(ffi::AnyView arg0, ffi::AnyView arg1) {
+    ffi::Any result = arg0.cast<int>() + arg1.cast<int>();
+    return result;
+   }
+
+   // Variant: variadic function
+   void func_cpp_variadic(PackedArgs args, Any* ret) {
+     int32_t num_args = args.size();
+     int x0 = args[0].cast<int>();
+     int x1 = args[1].cast<int>();
+     int y = x0 + x1;
+     *ret = y;
+   }
+
+   // Variant: variadic function with C ABI signature
+   int func_c_abi_variadic(void*, const TVMFFIAny* args, int32_t num_args, 
TVMFFIAny* ret) {
+     TVM_FFI_SAFE_CALL_BEGIN();
+     int x0 = reinterpret_cast<const AnyView*>(args)[0].cast<int>();
+     int x1 = reinterpret_cast<const AnyView*>(args)[1].cast<int>();
+     int y = x0 + x1;
+     reinterpret_cast<Any*>(ret)[0] = y;
+     TVM_FFI_SAFE_CALL_END();
+   }
+
+
+Container Storage
+~~~~~~~~~~~~~~~~~
+
+:cpp:class:`~tvm::ffi::Any` can be stored in containers like 
:cpp:class:`~tvm::ffi::Map` and :cpp:class:`~tvm::ffi::Array`:
+
+.. code-block:: cpp
+
+   ffi::Map<ffi::String, ffi::Any> config;
+   config.Set("learning_rate", 0.001);
+   config.Set("batch_size", 32);
+   config.Set("device", DLDevice{kDLCUDA, 0});
+
+Extracting Values
+~~~~~~~~~~~~~~~~~
+
+Three methods pull values out of :cpp:class:`~tvm::ffi::Any`
+and :cpp:class:`~tvm::ffi::AnyView`, each with different strictness:
+
+.. list-table::
+   :header-rows: 1
+   :widths: 20 45 30
+
+   * - Method
+     - Behavior
+     - Use When
+   * - :cpp:func:`cast\<T\>() <tvm::ffi::Any::cast>`
+     - Returns ``T`` or throws :cpp:class:`tvm::ffi::Error`
+     - You know the type and want to throw on type mismatch
+   * - :cpp:func:`try_cast\<T\>() <tvm::ffi::Any::try_cast>`
+     - Returns ``std::optional<T>``
+     - Returns None on type mismatch, allows type conversion
+   * - :cpp:func:`as\<T\>() <tvm::ffi::Any::as>`
+     - Returns ``std::optional<T>`` or ``const T*`` (for TVM-FFI object types)
+     - Returns None on type mismatch, but doesn't allow type conversion

Review Comment:
   ![medium](https://www.gstatic.com/codereviewagent/medium-priority.svg)
   
   In a C++ context, "None" is ambiguous. It's clearer to state that `try_cast` 
and `as` return `std::nullopt` on type mismatch.
   
   ```suggestion
      * - :cpp:func:`try_cast\<T\>() <tvm::ffi::Any::try_cast>`
        - Returns ``std::optional<T>``
        - Returns ``std::nullopt`` on type mismatch, allows type conversion
      * - :cpp:func:`as\<T\>() <tvm::ffi::Any::as>`
        - Returns ``std::optional<T>`` or ``const T*`` (for TVM-FFI object 
types)
        - Returns ``std::nullopt`` on type mismatch, but doesn't allow type 
conversion
   ```



##########
docs/concepts/any.rst:
##########
@@ -0,0 +1,441 @@
+..  Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+..    http://www.apache.org/licenses/LICENSE-2.0
+
+..  Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+Any and AnyView
+===============
+
+TVM-FFI has :cpp:class:`tvm::ffi::Any` and :cpp:class:`tvm::ffi::AnyView`,
+type-erased containers that hold any supported value and transport it across
+C, C++, Python, and Rust boundaries through a stable ABI.
+
+Similar to ``std::any``, :cpp:class:`~tvm::ffi::Any` is a tagged union that 
store
+values of wide variety of types, including primitive types, objects, strings, 
etc.
+Unlike ``std::any``, it is designed for RTTI-free zero-copy inter-language 
exchange,
+with a fixed 16-byte layout and built-in support for reference counting and 
ownership.
+
+This tutorial covers all about Any: its common usage patterns, ownership 
semantics,
+and memory layout.
+
+
+Common Usecases
+---------------
+
+Function inputs and outputs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Use :cpp:class:`~tvm::ffi::AnyView` for function parameters,
+which avoids reference count churn or unnecessary copies, and 
:cpp:class:`~tvm::ffi::Any` for return values,
+which transfers ownership to the caller.
+
+.. code-block:: cpp
+
+   ffi::Any func_cpp_signature(ffi::AnyView arg0, ffi::AnyView arg1) {
+    ffi::Any result = arg0.cast<int>() + arg1.cast<int>();
+    return result;
+   }
+
+   // Variant: variadic function
+   void func_cpp_variadic(PackedArgs args, Any* ret) {
+     int32_t num_args = args.size();
+     int x0 = args[0].cast<int>();
+     int x1 = args[1].cast<int>();
+     int y = x0 + x1;
+     *ret = y;
+   }
+
+   // Variant: variadic function with C ABI signature
+   int func_c_abi_variadic(void*, const TVMFFIAny* args, int32_t num_args, 
TVMFFIAny* ret) {
+     TVM_FFI_SAFE_CALL_BEGIN();
+     int x0 = reinterpret_cast<const AnyView*>(args)[0].cast<int>();
+     int x1 = reinterpret_cast<const AnyView*>(args)[1].cast<int>();
+     int y = x0 + x1;
+     reinterpret_cast<Any*>(ret)[0] = y;
+     TVM_FFI_SAFE_CALL_END();
+   }
+
+
+Container Storage
+~~~~~~~~~~~~~~~~~
+
+:cpp:class:`~tvm::ffi::Any` can be stored in containers like 
:cpp:class:`~tvm::ffi::Map` and :cpp:class:`~tvm::ffi::Array`:
+
+.. code-block:: cpp
+
+   ffi::Map<ffi::String, ffi::Any> config;
+   config.Set("learning_rate", 0.001);
+   config.Set("batch_size", 32);
+   config.Set("device", DLDevice{kDLCUDA, 0});
+
+Extracting Values
+~~~~~~~~~~~~~~~~~
+
+Three methods pull values out of :cpp:class:`~tvm::ffi::Any`
+and :cpp:class:`~tvm::ffi::AnyView`, each with different strictness:
+
+.. list-table::
+   :header-rows: 1
+   :widths: 20 45 30
+
+   * - Method
+     - Behavior
+     - Use When
+   * - :cpp:func:`cast\<T\>() <tvm::ffi::Any::cast>`
+     - Returns ``T`` or throws :cpp:class:`tvm::ffi::Error`
+     - You know the type and want to throw on type mismatch
+   * - :cpp:func:`try_cast\<T\>() <tvm::ffi::Any::try_cast>`
+     - Returns ``std::optional<T>``
+     - Returns None on type mismatch, allows type conversion
+   * - :cpp:func:`as\<T\>() <tvm::ffi::Any::as>`
+     - Returns ``std::optional<T>`` or ``const T*`` (for TVM-FFI object types)
+     - Returns None on type mismatch, but doesn't allow type conversion
+
+.. dropdown:: Example of :cpp:func:`cast\<T\>() <tvm::ffi::Any::cast>`
+
+  :cpp:func:`cast\<T\>() <tvm::ffi::Any::cast>` is the workhorse. It returns 
the value or throws:
+
+  .. code-block:: cpp
+
+    ffi::Any value = 42;
+    int x = value.cast<int>();       // OK: 42
+    double y = value.cast<double>(); // OK: 42.0 (int → double)
+
+    try {
+      ffi::String s = value.cast<ffi::String>();  // Throws TypeError
+    } catch (const ffi::Error& e) {
+      // "Cannot convert from type `int` to `ffi.Str`"
+    }
+
+.. dropdown:: Example of :cpp:func:`try_cast\<T\>() <tvm::ffi::Any::try_cast>`
+
+  :cpp:func:`try_cast\<T\>() <tvm::ffi::Any::try_cast>` allows type coercion:
+
+  .. code-block:: cpp
+
+    ffi::Any value = 42;
+
+    std::optional<double> opt_float = value.try_cast<double>();
+    // opt_float.has_value() == true, *opt_float == 42.0
+
+    std::optional<bool> opt_bool = value.try_cast<bool>();
+    // opt_bool.has_value() == true, *opt_bool == true
+
+
+.. dropdown:: Example of :cpp:func:`as\<T\>() <tvm::ffi::Any::as>`
+
+  :cpp:func:`as\<T\>() <tvm::ffi::Any::as>` is strict - it only succeeds if 
the stored type exactly matches:
+
+  .. code-block:: cpp
+
+    ffi::Any value = 42;
+
+    std::optional<int64_t> opt_int = value.as<int64_t>();
+    // opt_int.has_value() == true
+
+    std::optional<double> opt_float = value.as<double>();
+    // opt_float.has_value() == false (int stored, not float)
+
+    ffi::Any value = ffi::String("hello, world!");
+    if (const ffi::Object* obj = value.as<ffi::Object>()) {
+      // Use obj without copying
+    }

Review Comment:
   ![medium](https://www.gstatic.com/codereviewagent/medium-priority.svg)
   
   The variable `value` is redeclared in the same scope, which is a C++ 
compilation error. Please use a different variable name for the string example 
to avoid confusion.
   
   ```suggestion
       ffi::Any str_value = ffi::String("hello, world!");
       if (const ffi::Object* obj = str_value.as<ffi::Object>()) {
         // Use obj without copying
       }
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to