Implementation:LaurentMazare Tch rs FFI Traits
| Knowledge Sources | |
|---|---|
| Domains | FFI, Type Abstraction, Collections |
| Last Updated | 2026-02-08 00:00 GMT |
Overview
The FFI Traits module defines DoubleList, IntList, and IntListOption trait abstractions that allow diverse Rust collection types to be uniformly passed as pointer-and-length pairs to C FFI functions.
Description
This module in torch-sys uses a list_trait! macro to generate traits and blanket implementations for passing Rust numeric collections across the FFI boundary. The C LibTorch API expects data as a raw pointer and an i32 length, so each trait provides two methods: as_ptr (returning *const T) and len_i32 (returning i32).
The list_trait! macro generates a trait and implementations for the following types:
- Scalar (
f64ori64) - treated as a single-element list (pointer to self, length 1) - Slice (
&[T]) - direct pointer and length - Owned slice (
[T]) - direct pointer and length - Vec (
Vec<T>and&Vec<T>) - delegates to the underlying slice - Boxed slice (
&Box<[T]>) - delegates to the underlying slice - Fixed-size array (
[T; N]and&[T; N]) - const-generic implementations for any size
The macro is invoked twice to generate:
- DoubleList for
f64values - IntList for
i64values
Additionally, IntListOption extends the IntList concept to handle optional integer lists. When the value is None, it returns a null pointer and a length of -1, signaling to the C side that no list was provided.
Usage
Use these traits as bounds on functions that pass numeric data to generated FFI bindings. They allow callers to provide data in whichever form is most convenient (a single scalar, a slice, a Vec, or an array) without requiring explicit conversion. The IntListOption trait is used when the C API accepts an optional list parameter.
Code Reference
Source Location
- Repository: LaurentMazare_Tch_rs
- File: torch-sys/src/traits.rs
Signature
// Generated by list_trait! macro for DoubleList (f64) and IntList (i64)
pub trait DoubleList {
fn as_ptr(&self) -> *const f64;
fn len_i32(&self) -> i32;
}
pub trait IntList {
fn as_ptr(&self) -> *const i64;
fn len_i32(&self) -> i32;
}
pub trait IntListOption {
fn as_ptr(&self) -> *const i64;
fn len_i32(&self) -> i32;
}
// IntListOption for Option<T> where T: IntListOption_
impl<T: IntListOption_> IntListOption for Option<T> {
fn as_ptr(&self) -> *const i64; // None => null
fn len_i32(&self) -> i32; // None => -1
}
Import
use torch_sys::traits::{DoubleList, IntList, IntListOption};
I/O Contract
DoubleList / IntList Trait Methods
| Method | Return Type | Description |
|---|---|---|
as_ptr(&self) |
*const f64 / *const i64 |
Raw pointer to the first element of the data |
len_i32(&self) |
i32 |
Number of elements in the collection |
Implementations by Type
| Implementing Type | as_ptr Behavior |
len_i32 Behavior
|
|---|---|---|
Scalar (f64 / i64) |
Pointer to self |
Returns 1
|
&[T] |
Slice pointer | self.len() as i32
|
[T] |
Slice pointer | self.len() as i32
|
Vec<T> / &Vec<T> |
self.as_slice().as_ptr() |
self.len() as i32
|
&Box<[T]> |
Deref then slice pointer | self.len() as i32
|
[T; N] / &[T; N] |
self.as_slice().as_ptr() |
self.len() as i32
|
IntListOption for Option<T>
| Variant | as_ptr |
len_i32
|
|---|---|---|
Some(v) |
Delegates to v.as_ptr() |
Delegates to v.len_i32()
|
None |
std::ptr::null() |
-1
|
The -1 length convention signals to the C++ side that no list was provided, distinguishing it from an empty list (length 0).
Usage Examples
use torch_sys::traits::{IntList, DoubleList, IntListOption};
// Any of these can be passed where IntList is expected:
fn call_ffi(list: impl IntList) {
let ptr = list.as_ptr();
let len = list.len_i32();
// Pass ptr and len to C FFI function...
}
// Single scalar - treated as a one-element list
call_ffi(42_i64);
// Slice
call_ffi(&[1_i64, 2, 3][..]);
// Vec
call_ffi(vec![10_i64, 20, 30]);
// Fixed-size array
call_ffi([100_i64, 200]);
// Optional list (IntListOption)
fn call_ffi_optional(list: impl IntListOption) {
let ptr = list.as_ptr();
let len = list.len_i32();
// ptr is null and len is -1 when None
}
call_ffi_optional(Some(vec![1_i64, 2, 3])); // ptr valid, len = 3
call_ffi_optional(None::<Vec<i64>>); // ptr null, len = -1