Request
range-for adapters over IVector<T> / IVectorView<T> and IIterable<T> (including map IKeyValuePair<K,V>) that prefetch a block per GetMany call instead of crossing the ABI once per element.
Why
Stock range-for is one ABI round-trip per element: GetAt(i) on an indexed collection, or Current + MoveNext on an iterator. GetMany fills a caller buffer in one call, so a block prefetch cuts the crossings to roughly one per block. On a cross-proc or heavily-marshaled collection that's the dominant cost.
Semantics
Single-pass buffering. A buffered element outlives the MoveNext that would otherwise have destroyed it — same observable behavior as wil::to_vector(coll) today, which callers already use for exactly this reason. On the indexed path, random access and E_BOUNDS at/after the end are preserved (an out-of-window index re-anchors the block; an at/after-end index defers to GetAt).
Where
wil/cppwinrt.h. Prototyped in microsoft/cppwinrt#1608 and pulled back out — cppwinrt stays projection-only, adapters live in WIL (sylveon on #1608).
Implementation
Prototype: microsoft/cppwinrt@390e118 (non-GetAt collections — IIterable and map IKeyValuePair — via IIterator::GetMany per block) and microsoft/cppwinrt@ab1f299 (indexed IVector/IVectorView via GetMany block prefetch). Both gate on the element type being default-constructible and the collection actually exposing GetMany, and fall back to per-element GetAt/Current otherwise.
(via Copilot)
Request
range-for adapters over
IVector<T>/IVectorView<T>andIIterable<T>(including mapIKeyValuePair<K,V>) that prefetch a block perGetManycall instead of crossing the ABI once per element.Why
Stock range-for is one ABI round-trip per element:
GetAt(i)on an indexed collection, orCurrent+MoveNexton an iterator.GetManyfills a caller buffer in one call, so a block prefetch cuts the crossings to roughly one per block. On a cross-proc or heavily-marshaled collection that's the dominant cost.Semantics
Single-pass buffering. A buffered element outlives the
MoveNextthat would otherwise have destroyed it — same observable behavior aswil::to_vector(coll)today, which callers already use for exactly this reason. On the indexed path, random access andE_BOUNDSat/after the end are preserved (an out-of-window index re-anchors the block; an at/after-end index defers toGetAt).Where
wil/cppwinrt.h. Prototyped in microsoft/cppwinrt#1608 and pulled back out — cppwinrt stays projection-only, adapters live in WIL (sylveon on #1608).Implementation
Prototype: microsoft/cppwinrt@390e118 (non-
GetAtcollections —IIterableand mapIKeyValuePair— viaIIterator::GetManyper block) and microsoft/cppwinrt@ab1f299 (indexedIVector/IVectorViewviaGetManyblock prefetch). Both gate on the element type being default-constructible and the collection actually exposingGetMany, and fall back to per-elementGetAt/Currentotherwise.(via Copilot)