Expand description
Mutable List container sharing the ffi.List object layout with C++.
ListObj mirrors C++ ListObj (Object followed by TVMFFISeqCell), so
Rust reads and edits the element cells in place: reads, List::set,
List::insert, List::remove, List::remove_range,
List::truncate, List::reverse, List::clear and iteration touch
the buffer directly, with no FFI call. The object and its element buffer
are allocated by the C++ runtime (ffi.List), because the buffer is a
separate allocation that data_deleter has to free with the allocator that
produced it. For the same reason, growing a full buffer is left to C++
(ffi.ListReserve), which the mutators call only when there is no spare
capacity; the elements themselves are then written in place.
A List is a shared handle, as in C++ and Python: cloning it bumps the
refcount, and a mutation through one handle is seen through all of them.
That is why the mutating methods take &self, and why elements are
returned by value rather than by reference. Like its C++ counterpart it is
not synchronized; the raw buffer pointer keeps it !Send and !Sync.
Any conversions follow C++ SeqTypeTraitsBase (seq_base.h): an ffi.List
whose elements all match T is shared; an ffi.Array, or a list whose
elements need converting, is copied into a new list.
Structsยง
- Mutable, reference-counted sequence of
T, sharing its underlyingListObjwith C++. Cloning is cheap (it bumps the refcount) and yields a handle to the same list. - Iterator over a
List, created byList::iter. Each step yieldsOk(T), or theTYPE_ERRORList::getwould give when the element at that position is not aT(another handle to the same list may have put it there), and then moves on to the next element. It re-reads the length on every step, so it stays in bounds if the list is mutated meanwhile; iterating from the back (rev) pins the end at the first back step. - Container object for
List, laid out as C++ListObj. Unlikeffi.Array, the element bufferdatais a separate allocation that the C++ runtime replaces when the list grows.