https://bugzilla.mozilla.org/show_bug.cgi?id=1295611 has landed and added mozilla::Span (#include "mozilla/Span.h"; code in mfbt/Span.h). Going forward, please consider using mozilla::Span as a method argument where you'd previously have used a pointer argument and a length argument.
Span implements Rust's slice concept for C++. It's called "Span" instead of "Slice" to follow the naming used in C++ Core Guidelines. A Span wraps a pointer and a length that identify a non-owning view to a contiguous block of memory of objects of the same type. Various types, including (pre-decay) C arrays, XPCOM strings, nsTArray, mozilla::Array, mozilla::Range and contiguous standard-library containers, auto-convert into Spans when attempting to pass them as arguments to methods that take Spans. MakeSpan() functions can be used for explicit conversion in other contexts. MakeSpan() works conveniently with local variables declared as auto, so you don't need to write the type parameter of the Span. (Span itself autoconverts into mozilla::Range.) Like Rust's slices, Span provides safety against out-of-bounds access by performing run-time bound checks. However, unlike Rust's slices, Span cannot provide safety against use-after-free. (Note: Span is like Rust's slice only conceptually. Due to the lack of ABI guarantees, you should still decompose spans/slices to raw pointer and length parts when crossing the FFI.) In addition to having constructors and MakeSpan() functions that take various well-known types, a Span for an arbitrary type can be constructed (via constructor or MakeSpan()) from a pointer and a length or a pointer and another pointer pointing just past the last element. A Span<const char> can be obtained for const char* pointing to a zero-terminated C string using the MakeCStringSpan() function. A corresponding implicit constructor does not exist in order to avoid accidental construction in cases where const char* does not point to a zero-terminated C string. Span has methods that follow the Mozilla naming style and methods that don't. The methods that follow the Mozilla naming style are meant to be used directly from Mozilla code. The methods that don't are meant for integration with C++11 range-based loops and with meta-programming that expects the same methods that are found on the standard-library containers. For example, to decompose a Span into its parts in Mozilla code, use Elements() and Length() (as with nsTArray) instead of data() and size() (as with std::vector). The pointer and length wrapped by a Span cannot be changed after a Span has been created. When new values are required, simply create a new Span. Span has a method called Subspan() that works analogously to the Substring() method of XPCOM strings taking a start index and an optional length. As a Mozilla extension (relative to Microsoft's gsl::span that mozilla::Span is based on), Span has methods From(start), To(end) and FromTo(start, end) that correspond to Rust's &slice[start..], &slice[..end] and &slice[start..end], respectively. (That is, the end index is the index of the first element not to be included in the new subspan.) When indicating a Span that's only read from, const goes inside the type parameter. Don't put const in front of Span. That is: size_t ReadsFromOneSpanAndWritesToAnother(Span<const uint8_t> aReadFrom, Span<uint8_t> aWrittenTo); Any Span<const T> can be viewed as Span<const uint8_t> using the function AsBytes(). Any Span<T> can be viewed as Span<uint8_t> using the function AsWritableBytes(). FAQ: Why introduce mozilla::Span when mozilla::Range already exits? 1) Span's storage (pointer and length as opposed to pointer and pointer) matches Rust's slices without arithmetic, so they decompose and recompose as the other on the other side of the FFI without arithmetic. 2) An earlier dev-platform thread seemed to OK Span on the grounds of it having enough of a pedigree from C++ Core Guidelines. -- Henri Sivonen hsivo...@hsivonen.fi https://hsivonen.fi/ _______________________________________________ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform