pointerPointerArray<T, RInner extends RType> static method
StructLiveList<StructLiveList<T, RInner> , RPointer<RInner> >
pointerPointerArray<T, RInner extends RType>(
- MemoryPointer<
RType> ? ptrOf(), - StructPointerArrayField<
T, RPointer< field,RInner> > - List<
List< initialT> >
Pointer to an array of pointers: T** -> T* -> T[].
The outer list represents the array of T* pointers; every element
is itself a live list over the T[] that particular T* points to,
built lazily and cached in nestedCache as indices are accessed.
Implementation
static StructLiveList<StructLiveList<T, RInner>, RPointer<RInner>> pointerPointerArray<
T,
RInner extends RType
>(
MemoryPointer? Function() ptrOf,
StructPointerArrayField<T, RPointer<RInner>> field,
List<List<T>> initial,
) {
final outerCodec = field.codec;
final innerCodec = outerCodec.inner as PointerCodec<T, RInner>;
final innerAccess = _ResolvedPointerAccess<T, RInner>(innerCodec);
final nestedCache = <StructLiveList<T, RInner>>[];
StructLiveList<T, RInner> build(int index) {
while (nestedCache.length <= index) {
final i = nestedCache.length;
final initialInner = i < initial.length ? initial[i] : const <Never>[];
nestedCache.add(._(
() {
final outerFieldPtr = ptrOf()?.offsetBy(field.offset);
if (outerFieldPtr == null) return null;
final arrayBase = outerCodec.deref(outerFieldPtr);
if (arrayBase.isNull) return null;
final resolved = outerCodec.pointerElementPtr(arrayBase, i);
return resolved.isNull ? null : resolved;
},
0,
null,
innerAccess,
initialInner,
));
}
return nestedCache[index];
}
return ._(ptrOf, field.offset, null, _LazyBuiltAccess<StructLiveList<T, RInner>>(build), nestedCache);
}