diff --git a/xpcom/ds/nsTArray.h b/xpcom/ds/nsTArray.h index f627eab9e180..d468ddfeb9cd 100644 --- a/xpcom/ds/nsTArray.h +++ b/xpcom/ds/nsTArray.h @@ -106,18 +106,19 @@ class Endpoint; class JSStructuredCloneData; // -// nsTArray is a resizable array class, like std::vector. +// nsTArray is a resizable array class, like std::vector. // // Unlike std::vector, which follows C++'s construction/destruction rules, -// nsTArray assumes that your "T" can be memmoved()'ed safely. +// By default, nsTArray assumes that instances of E can be relocated safely +// using memory utils (memcpy/memmove). // // The public classes defined in this header are // -// nsTArray, -// CopyableTArray, -// FallibleTArray, -// AutoTArray, -// CopyableAutoTArray +// nsTArray, +// CopyableTArray, +// FallibleTArray, +// AutoTArray, +// CopyableAutoTArray // // nsTArray, CopyableTArray, AutoTArray and CopyableAutoTArray are infallible by // default. To opt-in to fallible behaviour, use the `mozilla::fallible` @@ -132,32 +133,42 @@ class JSStructuredCloneData; // file and don't need the full nsTArray definitions) consider including // nsTArrayForwardDeclare.h instead of nsTArray.h. // -// The template parameter (i.e., T in nsTArray) specifies the type of the -// elements and has the following requirements: +// The template parameter E specifies the type of the elements and has the +// following requirements: // -// T MUST be safely memmove()'able. -// T MUST define a copy-constructor. -// T MAY define operator< for sorting. -// T MAY define operator== for searching. +// E MUST be safely memmove()'able. +// E MUST define a copy-constructor. +// E MAY define operator< for sorting. +// E MAY define operator== for searching. // // (Note that the memmove requirement may be relaxed for certain types - see // nsTArray_RelocationStrategy below.) // -// For methods taking a Comparator instance, the Comparator must be a class -// defining the following methods: +// There is a public type elem_type defined as E within each array class, and we +// reference the type under this name below. +// +// For member functions taking a Comparator instance, Comparator must be either +// a functor with a tri-state comparison function with a signature compatible to +// +// /** @return negative iff a < b, 0 iff a == b, positive iff a > b */ +// int (const elem_type& a, const elem_type& b); +// +// or a class defining member functions with signatures compatible to: // // class Comparator { // public: // /** @return True if the elements are equals; false otherwise. */ -// bool Equals(const elem_type& a, const Item& b) const; +// bool Equals(const elem_type& a, const elem_type& b) const; // // /** @return True if (a < b); false otherwise. */ -// bool LessThan(const elem_type& a, const Item& b) const; +// bool LessThan(const elem_type& a, const elem_type& b) const; // }; // -// The Equals method is used for searching, and the LessThan method is used for -// searching and sorting. The |Item| type above can be arbitrary, but must -// match the Item type passed to the sort or search function. +// The Equals member function is used for searching, and the LessThan member +// function is used for searching and sorting. Note that some member functions, +// e.g. Compare, are templates where a different type Item can be used for the +// element to compare to. In that case, the signatures must be compatible to +// allow those comparisons, but the details are not documented here. // // @@ -277,7 +288,7 @@ class nsTArray_CopyDisabler { } // namespace detail -// This class provides a SafeElementAt method to nsTArray which does +// This class provides a SafeElementAt method to nsTArray which does // not take a second default value parameter. template struct nsTArray_SafeElementAtHelper : public ::detail::nsTArray_CopyDisabler { @@ -762,10 +773,10 @@ struct MOZ_NEEDS_MEMMOVABLE_TYPE nsTArray_RelocationStrategy { // Some classes require constructors/destructors to be called, so they are // specialized here. // -#define MOZ_DECLARE_RELOCATE_USING_MOVE_CONSTRUCTOR(T) \ +#define MOZ_DECLARE_RELOCATE_USING_MOVE_CONSTRUCTOR(E) \ template <> \ - struct nsTArray_RelocationStrategy { \ - using Type = nsTArray_RelocateUsingMoveConstructor; \ + struct nsTArray_RelocationStrategy { \ + using Type = nsTArray_RelocateUsingMoveConstructor; \ }; #define MOZ_DECLARE_RELOCATE_USING_MOVE_CONSTRUCTOR_FOR_TEMPLATE(T) \ @@ -1565,10 +1576,10 @@ class nsTArray_Impl // InsertElementAt(), or no-arg AppendElement() does, but without changing the // length of the array. // - // array[idx] = T() + // array[idx] = elem_type() // - // would accomplish the same thing as long as T has the appropriate moving - // operator=, but some types don't for various reasons. + // would accomplish the same thing as long as elem_type has the appropriate + // moving operator=, but some types don't for various reasons. mozilla::NotNull ReconstructElementAt(index_type aIndex) { elem_type* elem = &ElementAt(aIndex); elem_traits::Destruct(elem); @@ -3073,7 +3084,7 @@ Span MakeSpan( return aTArray; } -template +template class nsTArrayBackInserter : public std::iterator { ArrayT* mArray; @@ -3081,12 +3092,12 @@ class nsTArrayBackInserter public: explicit nsTArrayBackInserter(ArrayT& aArray) : mArray{&aArray} {} - nsTArrayBackInserter& operator=(const T& aValue) { + nsTArrayBackInserter& operator=(const E& aValue) { mArray->AppendElement(aValue); return *this; } - nsTArrayBackInserter& operator=(T&& aValue) { + nsTArrayBackInserter& operator=(E&& aValue) { mArray->AppendElement(std::move(aValue)); return *this; } @@ -3097,9 +3108,9 @@ class nsTArrayBackInserter nsTArrayBackInserter& operator++(int) { return *this; } }; -template -auto MakeBackInserter(nsTArray& aArray) { - return nsTArrayBackInserter>{aArray}; +template +auto MakeBackInserter(nsTArray& aArray) { + return nsTArrayBackInserter>{aArray}; } template @@ -3111,21 +3122,23 @@ Span(const nsTArray_Impl&) -> Span; // Provides a view on a nsTArray through which the existing array elements can // be accessed in a non-const way, but the array itself cannot be modified, so // that references to elements are guaranteed to be stable. -template +template class nsTArrayView { public: - using element_type = T; + using element_type = E; using pointer = element_type*; using reference = element_type&; - using index_type = typename Span::index_type; - using size_type = typename Span::index_type; + using index_type = typename Span::index_type; + using size_type = typename Span::index_type; - explicit nsTArrayView(nsTArray aArray) + explicit nsTArrayView(nsTArray aArray) : mArray(std::move(aArray)), mSpan(mArray) {} - T& operator[](index_type aIndex) { return mSpan[aIndex]; } + element_type& operator[](index_type aIndex) { return mSpan[aIndex]; } - const T& operator[](index_type aIndex) const { return mSpan[aIndex]; } + const element_type& operator[](index_type aIndex) const { + return mSpan[aIndex]; + } size_type Length() const { return mSpan.Length(); } @@ -3136,12 +3149,12 @@ class nsTArrayView { auto cbegin() const { return mSpan.cbegin(); } auto cend() const { return mSpan.cend(); } - Span AsSpan() { return mSpan; } - Span AsSpan() const { return mSpan; } + Span AsSpan() { return mSpan; } + Span AsSpan() const { return mSpan; } private: - nsTArray mArray; - const Span mSpan; + nsTArray mArray; + const Span mSpan; }; } // namespace mozilla