diff --git a/xpcom/ds/nsTArray.h b/xpcom/ds/nsTArray.h index 48a20d504214..240ae54ede1d 100644 --- a/xpcom/ds/nsTArray.h +++ b/xpcom/ds/nsTArray.h @@ -116,11 +116,19 @@ class JSStructuredCloneData; // The public classes defined in this header are // // nsTArray, +// CopyableTArray, // FallibleTArray, -// AutoTArray, and +// AutoTArray, +// CopyableAutoTArray // -// nsTArray and AutoTArray are infallible by default. To opt-in to fallible -// behaviour, use the `mozilla::fallible` parameter and check the return value. +// nsTArray, CopyableTArray, AutoTArray and CopyableAutoTArray are infallible by +// default. To opt-in to fallible behaviour, use the `mozilla::fallible` +// parameter and check the return value. +// +// CopyableTArray and CopyableAutoTArray< are copy-constructible and +// copy-assignable. Use these only when syntactically necessary to avoid implcit +// unintentional copies. nsTArray/AutoTArray can be conveniently copied using +// the Clone() member function. Consider using std::move where possible. // // If you just want to declare the nsTArray types (e.g., if you're in a header // file and don't need the full nsTArray definitions) consider including @@ -2662,6 +2670,16 @@ class nsTArray : public nsTArray_Impl { AppendElements(aIL.begin(), aIL.size()); } + template + nsTArray(const Item* aArray, size_type aArrayLen) { + AppendElements(aArray, aArrayLen); + } + + template + explicit nsTArray(mozilla::Span aSpan) { + AppendElements(aSpan); + } + template explicit nsTArray(const nsTArray_Impl& aOther) : base_type(aOther) {} @@ -2739,6 +2757,12 @@ class nsTArray : public nsTArray_Impl { this->template AppendElementsInternal(1)); } + self_type Clone() const { + self_type result; + result.Assign(*this); + return result; + } + mozilla::NotNull InsertElementsAt(index_type aIndex, size_type aCount) { return mozilla::WrapNotNullUnchecked( @@ -2848,6 +2872,47 @@ class nsTArray : public nsTArray_Impl { } }; +template +class CopyableTArray : public nsTArray { + public: + using nsTArray::nsTArray; + + CopyableTArray(const CopyableTArray& aOther) : nsTArray() { + this->Assign(aOther); + } + CopyableTArray& operator=(const CopyableTArray& aOther) { + if (this != &aOther) { + this->Assign(aOther); + } + return *this; + } + template + MOZ_IMPLICIT CopyableTArray(const nsTArray_Impl& aOther) { + this->Assign(aOther); + } + template + CopyableTArray& operator=(const nsTArray_Impl& aOther) { + if constexpr (std::is_same_v) { + if (this == &aOther) { + return *this; + } + } + this->Assign(aOther); + return *this; + } + template + MOZ_IMPLICIT CopyableTArray(nsTArray_Impl&& aOther) + : nsTArray{std::move(aOther)} {} + template + CopyableTArray& operator=(nsTArray_Impl&& aOther) { + static_cast&>(*this) = std::move(aOther); + return *this; + } + + CopyableTArray(CopyableTArray&&) = default; + CopyableTArray& operator=(CopyableTArray&&) = default; +}; + // // FallibleTArray is a fallible vector class. // @@ -2949,6 +3014,14 @@ class MOZ_NON_MEMMOVABLE AutoTArray : public nsTArray { return *this; } + // Intentionally hides nsTArray_Impl::Clone to make clones usually be + // AutoTArray as well. + self_type Clone() const { + self_type result; + result.Assign(*this); + return result; + } + private: // nsTArray_base casts itself as an nsAutoArrayBase in order to get a pointer // to mAutoBuf. @@ -3000,7 +3073,9 @@ class MOZ_NON_MEMMOVABLE AutoTArray : public nsTArray { // inline header overhead. // template -class AutoTArray : public nsTArray {}; +class AutoTArray : public nsTArray { + using nsTArray::nsTArray; +}; template struct nsTArray_RelocationStrategy> { diff --git a/xpcom/ds/nsTArrayForwardDeclare.h b/xpcom/ds/nsTArrayForwardDeclare.h index 167ecef79b8c..f88855080305 100644 --- a/xpcom/ds/nsTArrayForwardDeclare.h +++ b/xpcom/ds/nsTArrayForwardDeclare.h @@ -27,7 +27,13 @@ class nsTArray; template class FallibleTArray; +template +class CopyableTArray; + template class AutoTArray; +template +class CopyableAutoTArray; + #endif