Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/xpcom/ds/nsTArray.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#ifndef nsTArray_h__
8
#define nsTArray_h__
9
10
#include "nsTArrayForwardDeclare.h"
11
#include "mozilla/Alignment.h"
12
#include "mozilla/ArrayIterator.h"
13
#include "mozilla/Assertions.h"
14
#include "mozilla/Attributes.h"
15
#include "mozilla/BinarySearch.h"
16
#include "mozilla/CheckedInt.h"
17
#include "mozilla/fallible.h"
18
#include "mozilla/FunctionTypeTraits.h"
19
#include "mozilla/MathAlgorithms.h"
20
#include "mozilla/MemoryReporting.h"
21
#include "mozilla/Move.h"
22
#include "mozilla/mozalloc.h"
23
#include "mozilla/ReverseIterator.h"
24
#include "mozilla/TypeTraits.h"
25
#include "mozilla/Span.h"
26
27
#include <string.h>
28
29
#include "nsCycleCollectionNoteChild.h"
30
#include "nsAlgorithm.h"
31
#include "nscore.h"
32
#include "nsQuickSort.h"
33
#include "nsDebug.h"
34
#include "nsISupportsImpl.h"
35
#include "nsRegionFwd.h"
36
#include <functional>
37
#include <initializer_list>
38
#include <new>
39
40
namespace JS {
41
template<class T>
42
class Heap;
43
class ObjectPtr;
44
} /* namespace JS */
45
46
class nsRegion;
47
namespace mozilla {
48
namespace layers {
49
struct TileClient;
50
} // namespace layers
51
} // namespace mozilla
52
53
namespace mozilla {
54
struct SerializedStructuredCloneBuffer;
55
class SourceBufferTask;
56
} // namespace mozilla
57
58
namespace mozilla {
59
namespace dom {
60
namespace ipc {
61
class StructuredCloneData;
62
} // namespace ipc
63
} // namespace dom
64
} // namespace mozilla
65
66
namespace mozilla {
67
namespace dom {
68
class ClonedMessageData;
69
class MessagePortMessage;
70
namespace indexedDB {
71
struct StructuredCloneReadInfo;
72
class SerializedStructuredCloneReadInfo;
73
class ObjectStoreCursorResponse;
74
} // namespace indexedDB
75
} // namespace dom
76
} // namespace mozilla
77
78
class JSStructuredCloneData;
79
80
//
81
// nsTArray is a resizable array class, like std::vector.
82
//
83
// Unlike std::vector, which follows C++'s construction/destruction rules,
84
// nsTArray assumes that your "T" can be memmoved()'ed safely.
85
//
86
// The public classes defined in this header are
87
//
88
//   nsTArray<T>,
89
//   FallibleTArray<T>,
90
//   AutoTArray<T, N>, and
91
//
92
// nsTArray and AutoTArray are infallible by default. To opt-in to fallible
93
// behaviour, use the `mozilla::fallible` parameter and check the return value.
94
//
95
// If you just want to declare the nsTArray types (e.g., if you're in a header
96
// file and don't need the full nsTArray definitions) consider including
97
// nsTArrayForwardDeclare.h instead of nsTArray.h.
98
//
99
// The template parameter (i.e., T in nsTArray<T>) specifies the type of the
100
// elements and has the following requirements:
101
//
102
//   T MUST be safely memmove()'able.
103
//   T MUST define a copy-constructor.
104
//   T MAY define operator< for sorting.
105
//   T MAY define operator== for searching.
106
//
107
// (Note that the memmove requirement may be relaxed for certain types - see
108
// nsTArray_CopyChooser below.)
109
//
110
// For methods taking a Comparator instance, the Comparator must be a class
111
// defining the following methods:
112
//
113
//   class Comparator {
114
//     public:
115
//       /** @return True if the elements are equals; false otherwise. */
116
//       bool Equals(const elem_type& a, const Item& b) const;
117
//
118
//       /** @return True if (a < b); false otherwise. */
119
//       bool LessThan(const elem_type& a, const Item& b) const;
120
//   };
121
//
122
// The Equals method is used for searching, and the LessThan method is used for
123
// searching and sorting.  The |Item| type above can be arbitrary, but must
124
// match the Item type passed to the sort or search function.
125
//
126
127
128
//
129
// nsTArrayFallibleResult and nsTArrayInfallibleResult types are proxy types
130
// which are used because you cannot use a templated type which is bound to
131
// void as an argument to a void function.  In order to work around that, we
132
// encode either a void or a boolean inside these proxy objects, and pass them
133
// to the aforementioned function instead, and then use the type information to
134
// decide what to do in the function.
135
//
136
// Note that public nsTArray methods should never return a proxy type.  Such
137
// types are only meant to be used in the internal nsTArray helper methods.
138
// Public methods returning non-proxy types cannot be called from other
139
// nsTArray members.
140
//
141
struct nsTArrayFallibleResult
142
{
143
  // Note: allows implicit conversions from and to bool
144
  MOZ_IMPLICIT nsTArrayFallibleResult(bool aResult) : mResult(aResult) {}
145
146
  MOZ_IMPLICIT operator bool() { return mResult; }
147
148
private:
149
  bool mResult;
150
};
151
152
struct nsTArrayInfallibleResult
153
{
154
};
155
156
//
157
// nsTArray*Allocators must all use the same |free()|, to allow swap()'ing
158
// between fallible and infallible variants.
159
//
160
161
struct nsTArrayFallibleAllocatorBase
162
{
163
  typedef bool ResultType;
164
  typedef nsTArrayFallibleResult ResultTypeProxy;
165
166
  static ResultType Result(ResultTypeProxy aResult) { return aResult; }
167
  static bool Successful(ResultTypeProxy aResult) { return aResult; }
168
  static ResultTypeProxy SuccessResult() { return true; }
169
  static ResultTypeProxy FailureResult() { return false; }
170
  static ResultType ConvertBoolToResultType(bool aValue) { return aValue; }
171
};
172
173
struct nsTArrayInfallibleAllocatorBase
174
{
175
  typedef void ResultType;
176
  typedef nsTArrayInfallibleResult ResultTypeProxy;
177
178
  static ResultType Result(ResultTypeProxy aResult) {}
179
  static bool Successful(ResultTypeProxy) { return true; }
180
  static ResultTypeProxy SuccessResult() { return ResultTypeProxy(); }
181
182
  static ResultTypeProxy FailureResult()
183
  {
184
    MOZ_CRASH("Infallible nsTArray should never fail");
185
    return ResultTypeProxy();
186
  }
187
188
  static ResultType ConvertBoolToResultType(bool aValue)
189
  {
190
    if (!aValue) {
191
      MOZ_CRASH("infallible nsTArray should never convert false to ResultType");
192
    }
193
  }
194
};
195
196
struct nsTArrayFallibleAllocator : nsTArrayFallibleAllocatorBase
197
{
198
  static void* Malloc(size_t aSize) { return malloc(aSize); }
199
  static void* Realloc(void* aPtr, size_t aSize)
200
  {
201
    return realloc(aPtr, aSize);
202
  }
203
204
  static void Free(void* aPtr) { free(aPtr); }
205
  static void SizeTooBig(size_t) {}
206
};
207
208
struct nsTArrayInfallibleAllocator : nsTArrayInfallibleAllocatorBase
209
{
210
  static void* Malloc(size_t aSize) { return moz_xmalloc(aSize); }
211
  static void* Realloc(void* aPtr, size_t aSize)
212
  {
213
    return moz_xrealloc(aPtr, aSize);
214
  }
215
216
  static void Free(void* aPtr) { free(aPtr); }
217
  static void SizeTooBig(size_t aSize) { NS_ABORT_OOM(aSize); }
218
};
219
220
// nsTArray_base stores elements into the space allocated beyond
221
// sizeof(*this).  This is done to minimize the size of the nsTArray
222
// object when it is empty.
223
struct nsTArrayHeader
224
{
225
  uint32_t mLength;
226
  uint32_t mCapacity : 31;
227
  uint32_t mIsAutoArray : 1;
228
};
229
230
extern "C" {
231
  extern nsTArrayHeader sEmptyTArrayHeader;
232
}
233
234
// This class provides a SafeElementAt method to nsTArray<T*> which does
235
// not take a second default value parameter.
236
template<class E, class Derived>
237
struct nsTArray_SafeElementAtHelper
238
{
239
  typedef E*       elem_type;
240
  typedef size_t   index_type;
241
242
  // No implementation is provided for these two methods, and that is on
243
  // purpose, since we don't support these functions on non-pointer type
244
  // instantiations.
245
  elem_type& SafeElementAt(index_type aIndex);
246
  const elem_type& SafeElementAt(index_type aIndex) const;
247
};
248
249
template<class E, class Derived>
250
struct nsTArray_SafeElementAtHelper<E*, Derived>
251
{
252
  typedef E*       elem_type;
253
  //typedef const E* const_elem_type;   XXX: see below
254
  typedef size_t   index_type;
255
256
  elem_type SafeElementAt(index_type aIndex)
257
  {
258
    return static_cast<Derived*>(this)->SafeElementAt(aIndex, nullptr);
259
  }
260
261
  // XXX: Probably should return const_elem_type, but callsites must be fixed.
262
  // Also, the use of const_elem_type for nsTArray<xpcGCCallback> in
263
  // xpcprivate.h causes build failures on Windows because xpcGCCallback is a
264
  // function pointer and MSVC doesn't like qualifying it with |const|.
265
  elem_type SafeElementAt(index_type aIndex) const
266
  {
267
    return static_cast<const Derived*>(this)->SafeElementAt(aIndex, nullptr);
268
  }
269
};
270
271
// E is the base type that the smart pointer is templated over; the
272
// smart pointer can act as E*.
273
template<class E, class Derived>
274
struct nsTArray_SafeElementAtSmartPtrHelper
275
{
276
  typedef E*       elem_type;
277
  typedef const E* const_elem_type;
278
  typedef size_t   index_type;
279
280
  elem_type SafeElementAt(index_type aIndex)
281
  {
282
    return static_cast<Derived*>(this)->SafeElementAt(aIndex, nullptr);
283
  }
284
285
  // XXX: Probably should return const_elem_type, but callsites must be fixed.
286
  elem_type SafeElementAt(index_type aIndex) const
287
  {
288
    return static_cast<const Derived*>(this)->SafeElementAt(aIndex, nullptr);
289
  }
290
};
291
292
template<class T> class nsCOMPtr;
293
294
template<class E, class Derived>
295
struct nsTArray_SafeElementAtHelper<nsCOMPtr<E>, Derived>
296
  : public nsTArray_SafeElementAtSmartPtrHelper<E, Derived>
297
{
298
};
299
300
template<class E, class Derived>
301
struct nsTArray_SafeElementAtHelper<RefPtr<E>, Derived>
302
  : public nsTArray_SafeElementAtSmartPtrHelper<E, Derived>
303
{
304
};
305
306
namespace mozilla {
307
template<class T> class OwningNonNull;
308
} // namespace mozilla
309
310
template<class E, class Derived>
311
struct nsTArray_SafeElementAtHelper<mozilla::OwningNonNull<E>, Derived>
312
{
313
  typedef E*       elem_type;
314
  typedef const E* const_elem_type;
315
  typedef size_t   index_type;
316
317
  elem_type SafeElementAt(index_type aIndex)
318
  {
319
    if (aIndex < static_cast<Derived*>(this)->Length()) {
320
      return static_cast<Derived*>(this)->ElementAt(aIndex);
321
    }
322
    return nullptr;
323
  }
324
325
  // XXX: Probably should return const_elem_type, but callsites must be fixed.
326
  elem_type SafeElementAt(index_type aIndex) const
327
  {
328
    if (aIndex < static_cast<const Derived*>(this)->Length()) {
329
      return static_cast<const Derived*>(this)->ElementAt(aIndex);
330
    }
331
    return nullptr;
332
  }
333
};
334
335
// Servo bindings.
336
extern "C" void Gecko_EnsureTArrayCapacity(void* aArray,
337
                                           size_t aCapacity,
338
                                           size_t aElementSize);
339
extern "C" void Gecko_ClearPODTArray(void* aArray,
340
                                     size_t aElementSize,
341
                                     size_t aElementAlign);
342
343
MOZ_NORETURN MOZ_COLD void
344
InvalidArrayIndex_CRASH(size_t aIndex, size_t aLength);
345
346
//
347
// This class serves as a base class for nsTArray.  It shouldn't be used
348
// directly.  It holds common implementation code that does not depend on the
349
// element type of the nsTArray.
350
//
351
template<class Alloc, class Copy>
352
class nsTArray_base
353
{
354
  // Allow swapping elements with |nsTArray_base|s created using a
355
  // different allocator.  This is kosher because all allocators use
356
  // the same free().
357
  template<class Allocator, class Copier>
358
  friend class nsTArray_base;
359
  friend void Gecko_EnsureTArrayCapacity(void* aArray, size_t aCapacity,
360
                                         size_t aElemSize);
361
  friend void Gecko_ClearPODTArray(void* aTArray, size_t aElementSize,
362
                                   size_t aElementAlign);
363
364
protected:
365
  typedef nsTArrayHeader Header;
366
367
public:
368
  typedef size_t size_type;
369
  typedef size_t index_type;
370
371
  // @return The number of elements in the array.
372
  size_type Length() const { return mHdr->mLength; }
373
374
  // @return True if the array is empty or false otherwise.
375
  bool IsEmpty() const { return Length() == 0; }
376
377
  // @return The number of elements that can fit in the array without forcing
378
  // the array to be re-allocated.  The length of an array is always less
379
  // than or equal to its capacity.
380
  size_type Capacity() const {  return mHdr->mCapacity; }
381
382
#ifdef DEBUG
383
  void* DebugGetHeader() const { return mHdr; }
384
#endif
385
386
protected:
387
  nsTArray_base();
388
389
  ~nsTArray_base();
390
391
  // Resize the storage if necessary to achieve the requested capacity.
392
  // @param aCapacity The requested number of array elements.
393
  // @param aElemSize The size of an array element.
394
  // @return False if insufficient memory is available; true otherwise.
395
  template<typename ActualAlloc>
396
  typename ActualAlloc::ResultTypeProxy EnsureCapacity(size_type aCapacity,
397
                                                       size_type aElemSize);
398
399
  // Tries to resize the storage to the minimum required amount. If this fails,
400
  // the array is left as-is.
401
  // @param aElemSize  The size of an array element.
402
  // @param aElemAlign The alignment in bytes of an array element.
403
  void ShrinkCapacity(size_type aElemSize, size_t aElemAlign);
404
405
  // This method may be called to resize a "gap" in the array by shifting
406
  // elements around.  It updates mLength appropriately.  If the resulting
407
  // array has zero elements, then the array's memory is free'd.
408
  // @param aStart     The starting index of the gap.
409
  // @param aOldLen    The current length of the gap.
410
  // @param aNewLen    The desired length of the gap.
411
  // @param aElemSize  The size of an array element.
412
  // @param aElemAlign The alignment in bytes of an array element.
413
  template<typename ActualAlloc>
414
  void ShiftData(index_type aStart, size_type aOldLen, size_type aNewLen,
415
                 size_type aElemSize, size_t aElemAlign);
416
417
  // This method may be called to swap elements from the end of the array to
418
  // fill a "gap" in the array. If the resulting array has zero elements, then
419
  // the array's memory is free'd.
420
  // @param aStart     The starting index of the gap.
421
  // @param aCount     The length of the gap.
422
  // @param aElemSize  The size of an array element.
423
  // @param aElemAlign The alignment in bytes of an array element.
424
  template<typename ActualAlloc>
425
  void SwapFromEnd(index_type aStart, size_type aCount,
426
                   size_type aElemSize, size_t aElemAlign);
427
428
  // This method increments the length member of the array's header.
429
  // Note that mHdr may actually be sEmptyTArrayHeader in the case where a
430
  // zero-length array is inserted into our array. But then aNum should
431
  // always be 0.
432
  void IncrementLength(size_t aNum)
433
7.13M
  {
434
7.13M
    if (mHdr == EmptyHdr()) {
435
37
      if (MOZ_UNLIKELY(aNum != 0)) {
436
0
        // Writing a non-zero length to the empty header would be extremely bad.
437
0
        MOZ_CRASH();
438
0
      }
439
7.13M
    } else {
440
7.13M
      mHdr->mLength += aNum;
441
7.13M
    }
442
7.13M
  }
443
444
  // This method inserts blank slots into the array.
445
  // @param aIndex the place to insert the new elements. This must be no
446
  //               greater than the current length of the array.
447
  // @param aCount the number of slots to insert
448
  // @param aElementSize the size of an array element.
449
  // @param aElemAlign the alignment in bytes of an array element.
450
  template<typename ActualAlloc>
451
  bool InsertSlotsAt(index_type aIndex, size_type aCount,
452
                     size_type aElementSize, size_t aElemAlign);
453
454
  template<typename ActualAlloc, class Allocator>
455
  typename ActualAlloc::ResultTypeProxy
456
  SwapArrayElements(nsTArray_base<Allocator, Copy>& aOther,
457
                    size_type aElemSize,
458
                    size_t aElemAlign);
459
460
  // This is an RAII class used in SwapArrayElements.
461
  class IsAutoArrayRestorer
462
  {
463
  public:
464
    IsAutoArrayRestorer(nsTArray_base<Alloc, Copy>& aArray, size_t aElemAlign);
465
    ~IsAutoArrayRestorer();
466
467
  private:
468
    nsTArray_base<Alloc, Copy>& mArray;
469
    size_t mElemAlign;
470
    bool mIsAuto;
471
  };
472
473
  // Helper function for SwapArrayElements. Ensures that if the array
474
  // is an AutoTArray that it doesn't use the built-in buffer.
475
  template<typename ActualAlloc>
476
  bool EnsureNotUsingAutoArrayBuffer(size_type aElemSize);
477
478
  // Returns true if this nsTArray is an AutoTArray with a built-in buffer.
479
  bool IsAutoArray() const { return mHdr->mIsAutoArray; }
480
481
  // Returns a Header for the built-in buffer of this AutoTArray.
482
  Header* GetAutoArrayBuffer(size_t aElemAlign)
483
  {
484
    MOZ_ASSERT(IsAutoArray(), "Should be an auto array to call this");
485
    return GetAutoArrayBufferUnsafe(aElemAlign);
486
  }
487
  const Header* GetAutoArrayBuffer(size_t aElemAlign) const
488
  {
489
    MOZ_ASSERT(IsAutoArray(), "Should be an auto array to call this");
490
    return GetAutoArrayBufferUnsafe(aElemAlign);
491
  }
492
493
  // Returns a Header for the built-in buffer of this AutoTArray, but doesn't
494
  // assert that we are an AutoTArray.
495
  Header* GetAutoArrayBufferUnsafe(size_t aElemAlign)
496
  {
497
    return const_cast<Header*>(static_cast<const nsTArray_base<Alloc, Copy>*>(
498
      this)->GetAutoArrayBufferUnsafe(aElemAlign));
499
  }
500
  const Header* GetAutoArrayBufferUnsafe(size_t aElemAlign) const;
501
502
  // Returns true if this is an AutoTArray and it currently uses the
503
  // built-in buffer to store its elements.
504
  bool UsesAutoArrayBuffer() const;
505
506
  // The array's elements (prefixed with a Header).  This pointer is never
507
  // null.  If the array is empty, then this will point to sEmptyTArrayHeader.
508
  Header* mHdr;
509
510
  Header* Hdr() const { return mHdr; }
511
  Header** PtrToHdr() { return &mHdr; }
512
  static Header* EmptyHdr() { return &sEmptyTArrayHeader; }
513
};
514
515
//
516
// This class defines convenience functions for element specific operations.
517
// Specialize this template if necessary.
518
//
519
template<class E>
520
class nsTArrayElementTraits
521
{
522
public:
523
  // Invoke the default constructor in place.
524
  static inline void Construct(E* aE)
525
124
  {
526
124
    // Do NOT call "E()"! That triggers C++ "default initialization"
527
124
    // which zeroes out POD ("plain old data") types such as regular
528
124
    // ints.  We don't want that because it can be a performance issue
529
124
    // and people don't expect it; nsTArray should work like a regular
530
124
    // C/C++ array in this respect.
531
124
    new (static_cast<void*>(aE)) E;
532
124
  }
nsTArrayElementTraits<mozilla::DeferredFinalizeFunctionHolder>::Construct(mozilla::DeferredFinalizeFunctionHolder*)
Line
Count
Source
525
18
  {
526
18
    // Do NOT call "E()"! That triggers C++ "default initialization"
527
18
    // which zeroes out POD ("plain old data") types such as regular
528
18
    // ints.  We don't want that because it can be a performance issue
529
18
    // and people don't expect it; nsTArray should work like a regular
530
18
    // C/C++ array in this respect.
531
18
    new (static_cast<void*>(aE)) E;
532
18
  }
nsTArrayElementTraits<nsComponentManagerImpl::PendingServiceInfo>::Construct(nsComponentManagerImpl::PendingServiceInfo*)
Line
Count
Source
525
100
  {
526
100
    // Do NOT call "E()"! That triggers C++ "default initialization"
527
100
    // which zeroes out POD ("plain old data") types such as regular
528
100
    // ints.  We don't want that because it can be a performance issue
529
100
    // and people don't expect it; nsTArray should work like a regular
530
100
    // C/C++ array in this respect.
531
100
    new (static_cast<void*>(aE)) E;
532
100
  }
nsTArrayElementTraits<nsComponentManagerImpl::ComponentLocation>::Construct(nsComponentManagerImpl::ComponentLocation*)
Line
Count
Source
525
6
  {
526
6
    // Do NOT call "E()"! That triggers C++ "default initialization"
527
6
    // which zeroes out POD ("plain old data") types such as regular
528
6
    // ints.  We don't want that because it can be a performance issue
529
6
    // and people don't expect it; nsTArray should work like a regular
530
6
    // C/C++ array in this respect.
531
6
    new (static_cast<void*>(aE)) E;
532
6
  }
533
  // Invoke the copy-constructor in place.
534
  template<class A>
535
  static inline void Construct(E* aE, A&& aArg)
536
180
  {
537
180
    typedef typename mozilla::RemoveCV<E>::Type E_NoCV;
538
180
    typedef typename mozilla::RemoveCV<A>::Type A_NoCV;
539
180
    static_assert(!mozilla::IsSame<E_NoCV*, A_NoCV>::value,
540
180
                  "For safety, we disallow constructing nsTArray<E> elements "
541
180
                  "from E* pointers. See bug 960591.");
542
180
    new (static_cast<void*>(aE)) E(std::forward<A>(aArg));
543
180
  }
Unexecuted instantiation: void nsTArrayElementTraits<mozilla::CycleCollectedJSContext::PendingIDBTransactionData>::Construct<mozilla::CycleCollectedJSContext::PendingIDBTransactionData const&>(mozilla::CycleCollectedJSContext::PendingIDBTransactionData*, mozilla::CycleCollectedJSContext::PendingIDBTransactionData const&)
Unexecuted instantiation: void nsTArrayElementTraits<nsCOMPtr<nsIRunnable> >::Construct<already_AddRefed<nsIRunnable> >(nsCOMPtr<nsIRunnable>*, already_AddRefed<nsIRunnable>&&)
Unexecuted instantiation: void nsTArrayElementTraits<mozilla::CycleCollectedJSContext::PendingIDBTransactionData>::Construct<mozilla::CycleCollectedJSContext::PendingIDBTransactionData>(mozilla::CycleCollectedJSContext::PendingIDBTransactionData*, mozilla::CycleCollectedJSContext::PendingIDBTransactionData&&)
Unexecuted instantiation: void nsTArrayElementTraits<mozilla::MemoryMapping>::Construct<mozilla::MemoryMapping>(mozilla::MemoryMapping*, mozilla::MemoryMapping&&)
Unexecuted instantiation: void nsTArrayElementTraits<ThreadsReporter::CollectReports(nsIHandleReportCallback*, nsISupports*, bool)::ThreadData>::Construct<ThreadsReporter::CollectReports(nsIHandleReportCallback*, nsISupports*, bool)::ThreadData>(ThreadsReporter::CollectReports(nsIHandleReportCallback*, nsISupports*, bool)::ThreadData*, ThreadsReporter::CollectReports(nsIHandleReportCallback*, nsISupports*, bool)::ThreadData&&)
Unexecuted instantiation: void nsTArrayElementTraits<RefPtr<mozilla::MemoryReportingProcess> >::Construct<mozilla::dom::ContentParent*&>(RefPtr<mozilla::MemoryReportingProcess>*, mozilla::dom::ContentParent*&)
Unexecuted instantiation: void nsTArrayElementTraits<RefPtr<mozilla::MemoryReportingProcess> >::Construct<already_AddRefed<mozilla::MemoryReportingProcess> >(RefPtr<mozilla::MemoryReportingProcess>*, already_AddRefed<mozilla::MemoryReportingProcess>&&)
Unexecuted instantiation: void nsTArrayElementTraits<BloatEntry*>::Construct<nsAutoPtr<BloatEntry>&>(BloatEntry**, nsAutoPtr<BloatEntry>&)
void nsTArrayElementTraits<nsAutoPtr<nsComponentManagerImpl::KnownModule> >::Construct<nsComponentManagerImpl::KnownModule*&>(nsAutoPtr<nsComponentManagerImpl::KnownModule>*, nsComponentManagerImpl::KnownModule*&)
Line
Count
Source
536
180
  {
537
180
    typedef typename mozilla::RemoveCV<E>::Type E_NoCV;
538
180
    typedef typename mozilla::RemoveCV<A>::Type A_NoCV;
539
180
    static_assert(!mozilla::IsSame<E_NoCV*, A_NoCV>::value,
540
180
                  "For safety, we disallow constructing nsTArray<E> elements "
541
180
                  "from E* pointers. See bug 960591.");
542
180
    new (static_cast<void*>(aE)) E(std::forward<A>(aArg));
543
180
  }
Unexecuted instantiation: void nsTArrayElementTraits<nsTString<char> >::Construct<nsTSubstring<char> const&>(nsTString<char>*, nsTSubstring<char> const&)
Unexecuted instantiation: void nsTArrayElementTraits<mozilla::Module const*>::Construct<mozilla::Module const*&>(mozilla::Module const**, mozilla::Module const*&)
Unexecuted instantiation: void nsTArrayElementTraits<mozilla::dom::StringBundleDescriptor>::Construct<mozilla::dom::StringBundleDescriptor>(mozilla::dom::StringBundleDescriptor*, mozilla::dom::StringBundleDescriptor&&)
Unexecuted instantiation: void nsTArrayElementTraits<RefPtr<nsAtom> >::Construct<RefPtr<nsAtom> const&>(RefPtr<nsAtom>*, RefPtr<nsAtom> const&)
Unexecuted instantiation: void nsTArrayElementTraits<RefPtr<nsAtom> >::Construct<RefPtr<nsAtom> >(RefPtr<nsAtom>*, RefPtr<nsAtom>&&)
Unexecuted instantiation: void nsTArrayElementTraits<nsAttrValue::EnumTable const*>::Construct<nsAttrValue::EnumTable const*&>(nsAttrValue::EnumTable const**, nsAttrValue::EnumTable const*&)
544
  // Invoke the destructor in place.
545
118
  static inline void Destruct(E* aE) { aE->~E(); }
Unexecuted instantiation: nsTArrayElementTraits<mozilla::CycleCollectedJSContext::PendingIDBTransactionData>::Destruct(mozilla::CycleCollectedJSContext::PendingIDBTransactionData*)
Unexecuted instantiation: nsTArrayElementTraits<nsCOMPtr<nsIRunnable> >::Destruct(nsCOMPtr<nsIRunnable>*)
Unexecuted instantiation: nsTArrayElementTraits<nsCOMPtr<nsISupports> >::Destruct(nsCOMPtr<nsISupports>*)
nsTArrayElementTraits<mozilla::DeferredFinalizeFunctionHolder>::Destruct(mozilla::DeferredFinalizeFunctionHolder*)
Line
Count
Source
545
18
  static inline void Destruct(E* aE) { aE->~E(); }
Unexecuted instantiation: nsTArrayElementTraits<mozilla::UniquePtr<mozilla::TokenizerBase<char>::Token, mozilla::DefaultDelete<mozilla::TokenizerBase<char>::Token> > >::Destruct(mozilla::UniquePtr<mozilla::TokenizerBase<char>::Token, mozilla::DefaultDelete<mozilla::TokenizerBase<char>::Token> >*)
Unexecuted instantiation: nsTArrayElementTraits<mozilla::dom::ContentParent*>::Destruct(mozilla::dom::ContentParent**)
Unexecuted instantiation: nsTArrayElementTraits<RefPtr<mozilla::MemoryReportingProcess> >::Destruct(RefPtr<mozilla::MemoryReportingProcess>*)
Unexecuted instantiation: nsTArrayElementTraits<mozilla::MemoryMapping>::Destruct(mozilla::MemoryMapping*)
Unexecuted instantiation: nsTArrayElementTraits<BloatEntry*>::Destruct(BloatEntry**)
Unexecuted instantiation: nsTArrayElementTraits<ThreadsReporter::CollectReports(nsIHandleReportCallback*, nsISupports*, bool)::ThreadData>::Destruct(ThreadsReporter::CollectReports(nsIHandleReportCallback*, nsISupports*, bool)::ThreadData*)
Unexecuted instantiation: Unified_cpp_xpcom_components0.cpp:nsTArrayElementTraits<(anonymous namespace)::CachedDirective>::Destruct((anonymous namespace)::CachedDirective*)
Unexecuted instantiation: nsTArrayElementTraits<mozilla::Module const*>::Destruct(mozilla::Module const**)
Unexecuted instantiation: nsTArrayElementTraits<nsComponentManagerImpl::ComponentLocation>::Destruct(nsComponentManagerImpl::ComponentLocation*)
nsTArrayElementTraits<nsComponentManagerImpl::PendingServiceInfo>::Destruct(nsComponentManagerImpl::PendingServiceInfo*)
Line
Count
Source
545
100
  static inline void Destruct(E* aE) { aE->~E(); }
Unexecuted instantiation: nsTArrayElementTraits<nsAutoPtr<nsComponentManagerImpl::KnownModule> >::Destruct(nsAutoPtr<nsComponentManagerImpl::KnownModule>*)
Unexecuted instantiation: nsTArrayElementTraits<mozilla::dom::StringBundleDescriptor>::Destruct(mozilla::dom::StringBundleDescriptor*)
Unexecuted instantiation: nsTArrayElementTraits<nsAttrValue::EnumTable const*>::Destruct(nsAttrValue::EnumTable const**)
546
};
547
548
// The default comparator used by nsTArray
549
template<class A, class B>
550
class nsDefaultComparator
551
{
552
public:
553
0
  bool Equals(const A& aA, const B& aB) const { return aA == aB; }
Unexecuted instantiation: nsDefaultComparator<mozilla::MemoryMapping, void const*>::Equals(mozilla::MemoryMapping const&, void const* const&) const
Unexecuted instantiation: nsDefaultComparator<unsigned int, unsigned int>::Equals(unsigned int const&, unsigned int const&) const
Unexecuted instantiation: nsDefaultComparator<nsAttrValue::EnumTable const*, nsAttrValue::EnumTable const*>::Equals(nsAttrValue::EnumTable const* const&, nsAttrValue::EnumTable const* const&) const
554
0
  bool LessThan(const A& aA, const B& aB) const { return aA < aB; }
555
};
556
557
template<bool IsPod, bool IsSameType>
558
struct AssignRangeAlgorithm
559
{
560
  template<class Item, class ElemType, class IndexType, class SizeType>
561
  static void implementation(ElemType* aElements, IndexType aStart,
562
                             SizeType aCount, const Item* aValues)
563
0
  {
564
0
    ElemType* iter = aElements + aStart;
565
0
    ElemType* end = iter + aCount;
566
0
    for (; iter != end; ++iter, ++aValues) {
567
0
      nsTArrayElementTraits<ElemType>::Construct(iter, *aValues);
568
0
    }
569
0
  }
Unexecuted instantiation: void AssignRangeAlgorithm<false, true>::implementation<mozilla::CycleCollectedJSContext::PendingIDBTransactionData, mozilla::CycleCollectedJSContext::PendingIDBTransactionData, unsigned long, unsigned long>(mozilla::CycleCollectedJSContext::PendingIDBTransactionData*, unsigned long, unsigned long, mozilla::CycleCollectedJSContext::PendingIDBTransactionData const*)
Unexecuted instantiation: void AssignRangeAlgorithm<false, true>::implementation<RefPtr<nsAtom>, RefPtr<nsAtom>, unsigned long, unsigned long>(RefPtr<nsAtom>*, unsigned long, unsigned long, RefPtr<nsAtom> const*)
570
};
571
572
template<>
573
struct AssignRangeAlgorithm<true, true>
574
{
575
  template<class Item, class ElemType, class IndexType, class SizeType>
576
  static void implementation(ElemType* aElements, IndexType aStart,
577
                             SizeType aCount, const Item* aValues)
578
  {
579
    memcpy(aElements + aStart, aValues, aCount * sizeof(ElemType));
580
  }
581
};
582
583
//
584
// Normally elements are copied with memcpy and memmove, but for some element
585
// types that is problematic.  The nsTArray_CopyChooser template class can be
586
// specialized to ensure that copying calls constructors and destructors
587
// instead, as is done below for JS::Heap<E> elements.
588
//
589
590
//
591
// A class that defines how to copy elements using memcpy/memmove.
592
//
593
struct nsTArray_CopyWithMemutils
594
{
595
  const static bool allowRealloc = true;
596
597
  static void MoveNonOverlappingRegionWithHeader(void* aDest, const void* aSrc,
598
                                                 size_t aCount, size_t aElemSize)
599
  {
600
    memcpy(aDest, aSrc, sizeof(nsTArrayHeader) + aCount * aElemSize);
601
  }
602
603
  static void MoveOverlappingRegion(void* aDest, void* aSrc, size_t aCount,
604
                                    size_t aElemSize)
605
  {
606
    memmove(aDest, aSrc, aCount * aElemSize);
607
  }
608
609
  static void MoveNonOverlappingRegion(void* aDest, void* aSrc, size_t aCount,
610
                                       size_t aElemSize)
611
  {
612
    memcpy(aDest, aSrc, aCount * aElemSize);
613
  }
614
};
615
616
//
617
// A template class that defines how to copy elements calling their constructors
618
// and destructors appropriately.
619
//
620
template<class ElemType>
621
struct nsTArray_CopyWithConstructors
622
{
623
  typedef nsTArrayElementTraits<ElemType> traits;
624
625
  const static bool allowRealloc = false;
626
627
  static void MoveNonOverlappingRegionWithHeader(void* aDest, void* aSrc, size_t aCount,
628
                                                 size_t aElemSize)
629
  {
630
    nsTArrayHeader* destHeader = static_cast<nsTArrayHeader*>(aDest);
631
    nsTArrayHeader* srcHeader = static_cast<nsTArrayHeader*>(aSrc);
632
    *destHeader = *srcHeader;
633
    MoveNonOverlappingRegion(static_cast<uint8_t*>(aDest) + sizeof(nsTArrayHeader),
634
                             static_cast<uint8_t*>(aSrc) + sizeof(nsTArrayHeader),
635
                             aCount, aElemSize);
636
  }
637
638
  // These functions are defined by analogy with memmove and memcpy.
639
  // What they actually do is slightly different: MoveOverlappingRegion
640
  // checks to see which direction the movement needs to take place,
641
  // whether from back-to-front of the range to be moved or from
642
  // front-to-back.  MoveNonOverlappingRegion assumes that moving
643
  // front-to-back is always valid.  So they're really more like
644
  // std::move{_backward,} in that respect.  We keep these names because
645
  // we think they read slightly better, and MoveNonOverlappingRegion is
646
  // only ever called on overlapping regions from MoveOverlappingRegion.
647
  static void MoveOverlappingRegion(void* aDest, void* aSrc, size_t aCount,
648
                                    size_t aElemSize)
649
  {
650
    ElemType* destElem = static_cast<ElemType*>(aDest);
651
    ElemType* srcElem = static_cast<ElemType*>(aSrc);
652
    ElemType* destElemEnd = destElem + aCount;
653
    ElemType* srcElemEnd = srcElem + aCount;
654
    if (destElem == srcElem) {
655
      return;  // In practice, we don't do this.
656
    }
657
658
    // Figure out whether to copy back-to-front or front-to-back.
659
    if (srcElemEnd > destElem && srcElemEnd < destElemEnd) {
660
      while (destElemEnd != destElem) {
661
        --destElemEnd;
662
        --srcElemEnd;
663
        traits::Construct(destElemEnd, std::move(*srcElemEnd));
664
        traits::Destruct(srcElemEnd);
665
      }
666
    } else {
667
      MoveNonOverlappingRegion(aDest, aSrc, aCount, aElemSize);
668
    }
669
  }
670
671
  static void MoveNonOverlappingRegion(void* aDest, void* aSrc, size_t aCount,
672
                                       size_t aElemSize)
673
  {
674
    ElemType* destElem = static_cast<ElemType*>(aDest);
675
    ElemType* srcElem = static_cast<ElemType*>(aSrc);
676
    ElemType* destElemEnd = destElem + aCount;
677
#ifdef DEBUG
678
    ElemType* srcElemEnd = srcElem + aCount;
679
    MOZ_ASSERT(srcElemEnd <= destElem || srcElemEnd > destElemEnd);
680
#endif
681
    while (destElem != destElemEnd) {
682
      traits::Construct(destElem, std::move(*srcElem));
683
      traits::Destruct(srcElem);
684
      ++destElem;
685
      ++srcElem;
686
    }
687
  }
688
};
689
690
//
691
// The default behaviour is to use memcpy/memmove for everything.
692
//
693
template<class E>
694
struct MOZ_NEEDS_MEMMOVABLE_TYPE nsTArray_CopyChooser
695
{
696
  using Type = nsTArray_CopyWithMemutils;
697
};
698
699
//
700
// Some classes require constructors/destructors to be called, so they are
701
// specialized here.
702
//
703
#define DECLARE_USE_COPY_CONSTRUCTORS(T)                \
704
  template<>                                            \
705
  struct nsTArray_CopyChooser<T>                        \
706
  {                                                     \
707
    using Type = nsTArray_CopyWithConstructors<T>;      \
708
  };
709
710
#define DECLARE_USE_COPY_CONSTRUCTORS_FOR_TEMPLATE(T)   \
711
  template<typename S>                                  \
712
  struct nsTArray_CopyChooser<T<S>>                     \
713
  {                                                     \
714
    using Type = nsTArray_CopyWithConstructors<T<S>>;   \
715
  };
716
717
DECLARE_USE_COPY_CONSTRUCTORS_FOR_TEMPLATE(JS::Heap)
718
DECLARE_USE_COPY_CONSTRUCTORS_FOR_TEMPLATE(std::function)
719
720
DECLARE_USE_COPY_CONSTRUCTORS(nsRegion)
721
DECLARE_USE_COPY_CONSTRUCTORS(nsIntRegion)
722
DECLARE_USE_COPY_CONSTRUCTORS(mozilla::layers::TileClient)
723
DECLARE_USE_COPY_CONSTRUCTORS(mozilla::SerializedStructuredCloneBuffer)
724
DECLARE_USE_COPY_CONSTRUCTORS(mozilla::dom::ipc::StructuredCloneData)
725
DECLARE_USE_COPY_CONSTRUCTORS(mozilla::dom::ClonedMessageData)
726
DECLARE_USE_COPY_CONSTRUCTORS(mozilla::dom::indexedDB::StructuredCloneReadInfo);
727
DECLARE_USE_COPY_CONSTRUCTORS(mozilla::dom::indexedDB::ObjectStoreCursorResponse)
728
DECLARE_USE_COPY_CONSTRUCTORS(mozilla::dom::indexedDB::SerializedStructuredCloneReadInfo);
729
DECLARE_USE_COPY_CONSTRUCTORS(JSStructuredCloneData)
730
DECLARE_USE_COPY_CONSTRUCTORS(mozilla::dom::MessagePortMessage)
731
DECLARE_USE_COPY_CONSTRUCTORS(mozilla::SourceBufferTask)
732
DECLARE_USE_COPY_CONSTRUCTORS(JS::ObjectPtr)
733
734
//
735
// Base class for nsTArray_Impl that is templated on element type and derived
736
// nsTArray_Impl class, to allow extra conversions to be added for specific
737
// types.
738
//
739
template<class E, class Derived>
740
struct nsTArray_TypedBase : public nsTArray_SafeElementAtHelper<E, Derived>
741
{
742
};
743
744
//
745
// Specialization of nsTArray_TypedBase for arrays containing JS::Heap<E>
746
// elements.
747
//
748
// These conversions are safe because JS::Heap<E> and E share the same
749
// representation, and since the result of the conversions are const references
750
// we won't miss any barriers.
751
//
752
// The static_cast is necessary to obtain the correct address for the derived
753
// class since we are a base class used in multiple inheritance.
754
//
755
template<class E, class Derived>
756
struct nsTArray_TypedBase<JS::Heap<E>, Derived>
757
  : public nsTArray_SafeElementAtHelper<JS::Heap<E>, Derived>
758
{
759
  operator const nsTArray<E>&()
760
  {
761
    static_assert(sizeof(E) == sizeof(JS::Heap<E>),
762
                  "JS::Heap<E> must be binary compatible with E.");
763
    Derived* self = static_cast<Derived*>(this);
764
    return *reinterpret_cast<nsTArray<E> *>(self);
765
  }
766
767
  operator const FallibleTArray<E>&()
768
  {
769
    Derived* self = static_cast<Derived*>(this);
770
    return *reinterpret_cast<FallibleTArray<E> *>(self);
771
  }
772
};
773
774
namespace detail {
775
776
// These helpers allow us to differentiate between tri-state comparator
777
// functions and classes with LessThan() and Equal() methods. If an object, when
778
// called as a function with two instances of our element type, returns an int,
779
// we treat it as a tri-state comparator.
780
//
781
// T is the type of the comparator object we want to check. U is the array
782
// element type that we'll be comparing.
783
//
784
// V is never passed, and is only used to allow us to specialize on the return
785
// value of the comparator function.
786
template <typename T, typename U, typename V = int>
787
struct IsCompareMethod : mozilla::FalseType {};
788
789
template <typename T, typename U>
790
struct IsCompareMethod<T, U, decltype(mozilla::DeclVal<T>()(mozilla::DeclVal<U>(), mozilla::DeclVal<U>()))>
791
  : mozilla::TrueType {};
792
793
// These two wrappers allow us to use either a tri-state comparator, or an
794
// object with Equals() and LessThan() methods interchangeably. They provide a
795
// tri-state Compare() method, and Equals() method, and a LessThan() method.
796
//
797
// Depending on the type of the underlying comparator, they either pass these
798
// through directly, or synthesize them from the methods available on the
799
// comparator.
800
//
801
// Callers should always use the most-specific of these methods that match their
802
// purpose.
803
804
// Comparator wrapper for a tri-state comparator function
805
template <typename T, typename U, bool IsCompare = IsCompareMethod<T, U>::value>
806
struct CompareWrapper
807
{
808
#ifdef _MSC_VER
809
#pragma warning(push)
810
#pragma warning(disable:4180) /* Silence "qualifier applied to function type has no meaning" warning */
811
#endif
812
  MOZ_IMPLICIT CompareWrapper(const T& aComparator)
813
    : mComparator(aComparator)
814
  {}
815
816
  template <typename A, typename B>
817
  int Compare(A& aLeft, B& aRight) const
818
  {
819
    return mComparator(aLeft, aRight);
820
  }
821
822
  template <typename A, typename B>
823
  bool Equals(A& aLeft, B& aRight) const
824
  {
825
    return Compare(aLeft, aRight) == 0;
826
  }
827
828
  template <typename A, typename B>
829
  bool LessThan(A& aLeft, B& aRight) const
830
  {
831
    return Compare(aLeft, aRight) < 0;
832
  }
833
834
  const T& mComparator;
835
#ifdef _MSC_VER
836
#pragma warning(pop)
837
#endif
838
};
839
840
// Comparator wrapper for a class with Equals() and LessThan() methods.
841
template <typename T, typename U>
842
struct CompareWrapper<T, U, false>
843
{
844
  MOZ_IMPLICIT CompareWrapper(const T& aComparator)
845
    : mComparator(aComparator)
846
0
  {}
Unexecuted instantiation: detail::CompareWrapper<nsDefaultComparator<mozilla::MemoryMapping, void const*>, void const*, false>::CompareWrapper(nsDefaultComparator<mozilla::MemoryMapping, void const*> const&)
Unexecuted instantiation: detail::CompareWrapper<nsDefaultComparator<BloatEntry*, BloatEntry*>, BloatEntry*, false>::CompareWrapper(nsDefaultComparator<BloatEntry*, BloatEntry*> const&)
Unexecuted instantiation: detail::CompareWrapper<nsComponentManagerImpl::ComponentLocationComparator, nsComponentManagerImpl::ComponentLocation, false>::CompareWrapper(nsComponentManagerImpl::ComponentLocationComparator const&)
Unexecuted instantiation: detail::CompareWrapper<nsDefaultComparator<unsigned int, unsigned int>, unsigned int, false>::CompareWrapper(nsDefaultComparator<unsigned int, unsigned int> const&)
Unexecuted instantiation: detail::CompareWrapper<AtomArrayStringComparator, nsTSubstring<char16_t>, false>::CompareWrapper(AtomArrayStringComparator const&)
Unexecuted instantiation: detail::CompareWrapper<nsDefaultComparator<nsAttrValue::EnumTable const*, nsAttrValue::EnumTable const*>, nsAttrValue::EnumTable const*, false>::CompareWrapper(nsDefaultComparator<nsAttrValue::EnumTable const*, nsAttrValue::EnumTable const*> const&)
847
848
  template <typename A, typename B>
849
  int Compare(A& aLeft, B& aRight) const
850
0
  {
851
0
    if (Equals(aLeft, aRight)) {
852
0
      return 0;
853
0
    }
854
0
    return LessThan(aLeft, aRight) ? -1 : 1;
855
0
  }
Unexecuted instantiation: int detail::CompareWrapper<nsDefaultComparator<mozilla::MemoryMapping, void const*>, void const*, false>::Compare<mozilla::MemoryMapping const, void const* const>(mozilla::MemoryMapping const&, void const* const&) const
Unexecuted instantiation: int detail::CompareWrapper<nsDefaultComparator<BloatEntry*, BloatEntry*>, BloatEntry*, false>::Compare<BloatEntry* const, BloatEntry* const>(BloatEntry* const&, BloatEntry* const&) const
856
857
  template <typename A, typename B>
858
  bool Equals(A& aLeft, B& aRight) const
859
0
  {
860
0
    return mComparator.Equals(aLeft, aRight);
861
0
  }
Unexecuted instantiation: bool detail::CompareWrapper<nsDefaultComparator<mozilla::MemoryMapping, void const*>, void const*, false>::Equals<mozilla::MemoryMapping const, void const* const>(mozilla::MemoryMapping const&, void const* const&) const
Unexecuted instantiation: bool detail::CompareWrapper<nsDefaultComparator<BloatEntry*, BloatEntry*>, BloatEntry*, false>::Equals<BloatEntry* const, BloatEntry* const>(BloatEntry* const&, BloatEntry* const&) const
Unexecuted instantiation: bool detail::CompareWrapper<nsComponentManagerImpl::ComponentLocationComparator, nsComponentManagerImpl::ComponentLocation, false>::Equals<nsComponentManagerImpl::ComponentLocation const, nsComponentManagerImpl::ComponentLocation const>(nsComponentManagerImpl::ComponentLocation const&, nsComponentManagerImpl::ComponentLocation const&) const
Unexecuted instantiation: bool detail::CompareWrapper<nsDefaultComparator<unsigned int, unsigned int>, unsigned int, false>::Equals<unsigned int const, unsigned int const>(unsigned int const&, unsigned int const&) const
Unexecuted instantiation: bool detail::CompareWrapper<AtomArrayStringComparator, nsTSubstring<char16_t>, false>::Equals<RefPtr<nsAtom> const, nsTSubstring<char16_t> const>(RefPtr<nsAtom> const&, nsTSubstring<char16_t> const&) const
Unexecuted instantiation: bool detail::CompareWrapper<nsDefaultComparator<nsAttrValue::EnumTable const*, nsAttrValue::EnumTable const*>, nsAttrValue::EnumTable const*, false>::Equals<nsAttrValue::EnumTable const* const, nsAttrValue::EnumTable const* const>(nsAttrValue::EnumTable const* const&, nsAttrValue::EnumTable const* const&) const
862
863
  template <typename A, typename B>
864
  bool LessThan(A& aLeft, B& aRight) const
865
0
  {
866
0
    return mComparator.LessThan(aLeft, aRight);
867
0
  }
Unexecuted instantiation: bool detail::CompareWrapper<nsDefaultComparator<mozilla::MemoryMapping, void const*>, void const*, false>::LessThan<mozilla::MemoryMapping const, void const* const>(mozilla::MemoryMapping const&, void const* const&) const
Unexecuted instantiation: bool detail::CompareWrapper<nsDefaultComparator<BloatEntry*, BloatEntry*>, BloatEntry*, false>::LessThan<BloatEntry* const, BloatEntry* const>(BloatEntry* const&, BloatEntry* const&) const
868
869
  const T& mComparator;
870
};
871
872
} // namespace detail
873
874
//
875
// nsTArray_Impl contains most of the guts supporting nsTArray, FallibleTArray,
876
// AutoTArray.
877
//
878
// The only situation in which you might need to use nsTArray_Impl in your code
879
// is if you're writing code which mutates a TArray which may or may not be
880
// infallible.
881
//
882
// Code which merely reads from a TArray which may or may not be infallible can
883
// simply cast the TArray to |const nsTArray&|; both fallible and infallible
884
// TArrays can be cast to |const nsTArray&|.
885
//
886
template<class E, class Alloc>
887
class nsTArray_Impl
888
  : public nsTArray_base<Alloc, typename nsTArray_CopyChooser<E>::Type>
889
  , public nsTArray_TypedBase<E, nsTArray_Impl<E, Alloc>>
890
{
891
private:
892
  typedef nsTArrayFallibleAllocator FallibleAlloc;
893
  typedef nsTArrayInfallibleAllocator InfallibleAlloc;
894
895
public:
896
  typedef typename nsTArray_CopyChooser<E>::Type     copy_type;
897
  typedef nsTArray_base<Alloc, copy_type>            base_type;
898
  typedef typename base_type::size_type              size_type;
899
  typedef typename base_type::index_type             index_type;
900
  typedef E                                          elem_type;
901
  typedef nsTArray_Impl<E, Alloc>                    self_type;
902
  typedef nsTArrayElementTraits<E>                   elem_traits;
903
  typedef nsTArray_SafeElementAtHelper<E, self_type> safeelementat_helper_type;
904
  typedef mozilla::ArrayIterator<elem_type&, nsTArray<E>>       iterator;
905
  typedef mozilla::ArrayIterator<const elem_type&, nsTArray<E>> const_iterator;
906
  typedef mozilla::ReverseIterator<iterator>         reverse_iterator;
907
  typedef mozilla::ReverseIterator<const_iterator>   const_reverse_iterator;
908
909
  using safeelementat_helper_type::SafeElementAt;
910
  using base_type::EmptyHdr;
911
912
  // A special value that is used to indicate an invalid or unknown index
913
  // into the array.
914
  static const index_type NoIndex = index_type(-1);
915
916
  using base_type::Length;
917
918
  //
919
  // Finalization method
920
  //
921
922
  ~nsTArray_Impl()
923
6.09M
  {
924
6.09M
    if (!base_type::IsEmpty()) {
925
0
      ClearAndRetainStorage();
926
0
    }
927
6.09M
    // mHdr cleanup will be handled by base destructor
928
6.09M
  }
Unexecuted instantiation: nsTArray_Impl<mozilla::CycleCollectedJSContext::PendingIDBTransactionData, nsTArrayInfallibleAllocator>::~nsTArray_Impl()
Unexecuted instantiation: nsTArray_Impl<nsCOMPtr<nsIRunnable>, nsTArrayInfallibleAllocator>::~nsTArray_Impl()
Unexecuted instantiation: nsTArray_Impl<nsCOMPtr<nsISupports>, nsTArrayInfallibleAllocator>::~nsTArray_Impl()
nsTArray_Impl<mozilla::DeferredFinalizeFunctionHolder, nsTArrayInfallibleAllocator>::~nsTArray_Impl()
Line
Count
Source
923
18
  {
924
18
    if (!base_type::IsEmpty()) {
925
0
      ClearAndRetainStorage();
926
0
    }
927
18
    // mHdr cleanup will be handled by base destructor
928
18
  }
nsTArray_Impl<mozilla::UniquePtr<mozilla::TokenizerBase<char>::Token, mozilla::DefaultDelete<mozilla::TokenizerBase<char>::Token> >, nsTArrayInfallibleAllocator>::~nsTArray_Impl()
Line
Count
Source
923
6.09M
  {
924
6.09M
    if (!base_type::IsEmpty()) {
925
0
      ClearAndRetainStorage();
926
0
    }
927
6.09M
    // mHdr cleanup will be handled by base destructor
928
6.09M
  }
nsTArray_Impl<mozilla::dom::ContentParent*, nsTArrayInfallibleAllocator>::~nsTArray_Impl()
Line
Count
Source
923
129
  {
924
129
    if (!base_type::IsEmpty()) {
925
0
      ClearAndRetainStorage();
926
0
    }
927
129
    // mHdr cleanup will be handled by base destructor
928
129
  }
Unexecuted instantiation: nsTArray_Impl<RefPtr<mozilla::MemoryReportingProcess>, nsTArrayInfallibleAllocator>::~nsTArray_Impl()
Unexecuted instantiation: nsTArray_Impl<mozilla::MemoryMapping, nsTArrayInfallibleAllocator>::~nsTArray_Impl()
Unexecuted instantiation: nsTArray_Impl<BloatEntry*, nsTArrayInfallibleAllocator>::~nsTArray_Impl()
Unexecuted instantiation: nsTArray_Impl<ThreadsReporter::CollectReports(nsIHandleReportCallback*, nsISupports*, bool)::ThreadData, nsTArrayInfallibleAllocator>::~nsTArray_Impl()
Unified_cpp_xpcom_components0.cpp:nsTArray_Impl<(anonymous namespace)::CachedDirective, nsTArrayInfallibleAllocator>::~nsTArray_Impl()
Line
Count
Source
923
12
  {
924
12
    if (!base_type::IsEmpty()) {
925
0
      ClearAndRetainStorage();
926
0
    }
927
12
    // mHdr cleanup will be handled by base destructor
928
12
  }
Unexecuted instantiation: nsTArray_Impl<mozilla::Module const*, nsTArrayInfallibleAllocator>::~nsTArray_Impl()
Unexecuted instantiation: nsTArray_Impl<nsComponentManagerImpl::ComponentLocation, nsTArrayInfallibleAllocator>::~nsTArray_Impl()
Unexecuted instantiation: nsTArray_Impl<nsComponentManagerImpl::PendingServiceInfo, nsTArrayInfallibleAllocator>::~nsTArray_Impl()
Unexecuted instantiation: nsTArray_Impl<nsAutoPtr<nsComponentManagerImpl::KnownModule>, nsTArrayInfallibleAllocator>::~nsTArray_Impl()
Unexecuted instantiation: nsTArray_Impl<mozilla::dom::StringBundleDescriptor, nsTArrayInfallibleAllocator>::~nsTArray_Impl()
Unexecuted instantiation: nsTArray_Impl<nsAttrValue::EnumTable const*, nsTArrayInfallibleAllocator>::~nsTArray_Impl()
929
930
  //
931
  // Initialization methods
932
  //
933
934
186
  nsTArray_Impl() {}
nsTArray_Impl<nsCOMPtr<nsISupports>, nsTArrayInfallibleAllocator>::nsTArray_Impl()
Line
Count
Source
934
3
  nsTArray_Impl() {}
nsTArray_Impl<nsCOMPtr<nsIRunnable>, nsTArrayInfallibleAllocator>::nsTArray_Impl()
Line
Count
Source
934
6
  nsTArray_Impl() {}
nsTArray_Impl<mozilla::CycleCollectedJSContext::PendingIDBTransactionData, nsTArrayInfallibleAllocator>::nsTArray_Impl()
Line
Count
Source
934
3
  nsTArray_Impl() {}
nsTArray_Impl<mozilla::DeferredFinalizeFunctionHolder, nsTArrayInfallibleAllocator>::nsTArray_Impl()
Line
Count
Source
934
18
  nsTArray_Impl() {}
Unexecuted instantiation: nsTArray_Impl<ThreadsReporter::CollectReports(nsIHandleReportCallback*, nsISupports*, bool)::ThreadData, nsTArrayInfallibleAllocator>::nsTArray_Impl()
nsTArray_Impl<mozilla::dom::ContentParent*, nsTArrayInfallibleAllocator>::nsTArray_Impl()
Line
Count
Source
934
129
  nsTArray_Impl() {}
Unexecuted instantiation: nsTArray_Impl<RefPtr<mozilla::MemoryReportingProcess>, nsTArrayInfallibleAllocator>::nsTArray_Impl()
Unexecuted instantiation: nsTArray_Impl<BloatEntry*, nsTArrayInfallibleAllocator>::nsTArray_Impl()
Unified_cpp_xpcom_components0.cpp:nsTArray_Impl<(anonymous namespace)::CachedDirective, nsTArrayInfallibleAllocator>::nsTArray_Impl()
Line
Count
Source
934
12
  nsTArray_Impl() {}
nsTArray_Impl<nsAutoPtr<nsComponentManagerImpl::KnownModule>, nsTArrayInfallibleAllocator>::nsTArray_Impl()
Line
Count
Source
934
3
  nsTArray_Impl() {}
nsTArray_Impl<nsComponentManagerImpl::PendingServiceInfo, nsTArrayInfallibleAllocator>::nsTArray_Impl()
Line
Count
Source
934
3
  nsTArray_Impl() {}
nsTArray_Impl<mozilla::Module const*, nsTArrayInfallibleAllocator>::nsTArray_Impl()
Line
Count
Source
934
3
  nsTArray_Impl() {}
nsTArray_Impl<nsComponentManagerImpl::ComponentLocation, nsTArrayInfallibleAllocator>::nsTArray_Impl()
Line
Count
Source
934
3
  nsTArray_Impl() {}
Unexecuted instantiation: nsTArray_Impl<mozilla::dom::StringBundleDescriptor, nsTArrayInfallibleAllocator>::nsTArray_Impl()
nsTArray_Impl<nsAttrValue::EnumTable const*, nsTArrayInfallibleAllocator>::nsTArray_Impl()
Line
Count
Source
934
3
  nsTArray_Impl() {}
935
936
  // Initialize this array and pre-allocate some number of elements.
937
0
  explicit nsTArray_Impl(size_type aCapacity) { SetCapacity(aCapacity); }
938
939
  // Initialize this array with an r-value.
940
  // Allow different types of allocators, since the allocator doesn't matter.
941
  template<typename Allocator>
942
  explicit nsTArray_Impl(nsTArray_Impl<E, Allocator>&& aOther)
943
0
  {
944
0
    SwapElements(aOther);
945
0
  }
946
947
  // The array's copy-constructor performs a 'deep' copy of the given array.
948
  // @param aOther The array object to copy.
949
  //
950
  // It's very important that we declare this method as taking |const
951
  // self_type&| as opposed to taking |const nsTArray_Impl<E, OtherAlloc>| for
952
  // an arbitrary OtherAlloc.
953
  //
954
  // If we don't declare a constructor taking |const self_type&|, C++ generates
955
  // a copy-constructor for this class which merely copies the object's
956
  // members, which is obviously wrong.
957
  //
958
  // You can pass an nsTArray_Impl<E, OtherAlloc> to this method because
959
  // nsTArray_Impl<E, X> can be cast to const nsTArray_Impl<E, Y>&.  So the
960
  // effect on the API is the same as if we'd declared this method as taking
961
  // |const nsTArray_Impl<E, OtherAlloc>&|.
962
  explicit nsTArray_Impl(const self_type& aOther) { AppendElements(aOther); }
963
964
  explicit nsTArray_Impl(std::initializer_list<E> aIL) { AppendElements(aIL.begin(), aIL.size()); }
965
  // Allow converting to a const array with a different kind of allocator,
966
  // Since the allocator doesn't matter for const arrays
967
  template<typename Allocator>
968
  operator const nsTArray_Impl<E, Allocator>&() const
969
  {
970
    return *reinterpret_cast<const nsTArray_Impl<E, Allocator>*>(this);
971
  }
972
  // And we have to do this for our subclasses too
973
  operator const nsTArray<E>&() const
974
0
  {
975
0
    return *reinterpret_cast<const InfallibleTArray<E>*>(this);
976
0
  }
Unexecuted instantiation: nsTArray_Impl<mozilla::MemoryMapping, nsTArrayInfallibleAllocator>::operator nsTArray<mozilla::MemoryMapping> const&() const
Unexecuted instantiation: nsTArray_Impl<ThreadsReporter::CollectReports(nsIHandleReportCallback*, nsISupports*, bool)::ThreadData, nsTArrayInfallibleAllocator>::operator nsTArray<ThreadsReporter::CollectReports(nsIHandleReportCallback*, nsISupports*, bool)::ThreadData> const&() const
977
  operator const FallibleTArray<E>&() const
978
  {
979
    return *reinterpret_cast<const FallibleTArray<E>*>(this);
980
  }
981
982
  // The array's assignment operator performs a 'deep' copy of the given
983
  // array.  It is optimized to reuse existing storage if possible.
984
  // @param aOther The array object to copy.
985
  self_type& operator=(const self_type& aOther)
986
  {
987
    if (this != &aOther) {
988
      ReplaceElementsAt(0, Length(), aOther.Elements(), aOther.Length());
989
    }
990
    return *this;
991
  }
992
993
  // The array's move assignment operator steals the underlying data from
994
  // the other array.
995
  // @param other  The array object to move from.
996
  self_type& operator=(self_type&& aOther)
997
  {
998
    if (this != &aOther) {
999
      Clear();
1000
      SwapElements(aOther);
1001
    }
1002
    return *this;
1003
  }
1004
1005
  // Return true if this array has the same length and the same
1006
  // elements as |aOther|.
1007
  template<typename Allocator>
1008
  bool operator==(const nsTArray_Impl<E, Allocator>& aOther) const
1009
0
  {
1010
0
    size_type len = Length();
1011
0
    if (len != aOther.Length()) {
1012
0
      return false;
1013
0
    }
1014
0
1015
0
    // XXX std::equal would be as fast or faster here
1016
0
    for (index_type i = 0; i < len; ++i) {
1017
0
      if (!(operator[](i) == aOther[i])) {
1018
0
        return false;
1019
0
      }
1020
0
    }
1021
0
1022
0
    return true;
1023
0
  }
1024
1025
  // Return true if this array does not have the same length and the same
1026
  // elements as |aOther|.
1027
  bool operator!=(const self_type& aOther) const { return !operator==(aOther); }
1028
1029
  template<typename Allocator>
1030
  self_type& operator=(const nsTArray_Impl<E, Allocator>& aOther)
1031
  {
1032
    ReplaceElementsAt(0, Length(), aOther.Elements(), aOther.Length());
1033
    return *this;
1034
  }
1035
1036
  template<typename Allocator>
1037
  self_type& operator=(nsTArray_Impl<E, Allocator>&& aOther)
1038
  {
1039
    Clear();
1040
    SwapElements(aOther);
1041
    return *this;
1042
  }
1043
1044
  // @return The amount of memory used by this nsTArray_Impl, excluding
1045
  // sizeof(*this). If you want to measure anything hanging off the array, you
1046
  // must iterate over the elements and measure them individually; hence the
1047
  // "Shallow" prefix.
1048
  size_t ShallowSizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
1049
0
  {
1050
0
    if (this->UsesAutoArrayBuffer() || Hdr() == EmptyHdr()) {
1051
0
      return 0;
1052
0
    }
1053
0
    return aMallocSizeOf(this->Hdr());
1054
0
  }
Unexecuted instantiation: nsTArray_Impl<mozilla::Module const*, nsTArrayInfallibleAllocator>::ShallowSizeOfExcludingThis(unsigned long (*)(void const*)) const
Unexecuted instantiation: nsTArray_Impl<nsComponentManagerImpl::ComponentLocation, nsTArrayInfallibleAllocator>::ShallowSizeOfExcludingThis(unsigned long (*)(void const*)) const
Unexecuted instantiation: nsTArray_Impl<nsAutoPtr<nsComponentManagerImpl::KnownModule>, nsTArrayInfallibleAllocator>::ShallowSizeOfExcludingThis(unsigned long (*)(void const*)) const
Unexecuted instantiation: nsTArray_Impl<nsComponentManagerImpl::PendingServiceInfo, nsTArrayInfallibleAllocator>::ShallowSizeOfExcludingThis(unsigned long (*)(void const*)) const
Unexecuted instantiation: nsTArray_Impl<RefPtr<nsAtom>, nsTArrayInfallibleAllocator>::ShallowSizeOfExcludingThis(unsigned long (*)(void const*)) const
1055
1056
  // @return The amount of memory used by this nsTArray_Impl, including
1057
  // sizeof(*this). If you want to measure anything hanging off the array, you
1058
  // must iterate over the elements and measure them individually; hence the
1059
  // "Shallow" prefix.
1060
  size_t ShallowSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
1061
0
  {
1062
0
    return aMallocSizeOf(this) + ShallowSizeOfExcludingThis(aMallocSizeOf);
1063
0
  }
Unexecuted instantiation: nsTArray_Impl<mozilla::Module const*, nsTArrayInfallibleAllocator>::ShallowSizeOfIncludingThis(unsigned long (*)(void const*)) const
Unexecuted instantiation: nsTArray_Impl<nsComponentManagerImpl::ComponentLocation, nsTArrayInfallibleAllocator>::ShallowSizeOfIncludingThis(unsigned long (*)(void const*)) const
Unexecuted instantiation: nsTArray_Impl<RefPtr<nsAtom>, nsTArrayInfallibleAllocator>::ShallowSizeOfIncludingThis(unsigned long (*)(void const*)) const
1064
1065
  //
1066
  // Accessor methods
1067
  //
1068
1069
  // This method provides direct access to the array elements.
1070
  // @return A pointer to the first element of the array.  If the array is
1071
  // empty, then this pointer must not be dereferenced.
1072
609
  elem_type* Elements() { return reinterpret_cast<elem_type*>(Hdr() + 1); }
Unexecuted instantiation: nsTArray_Impl<mozilla::CycleCollectedJSContext::PendingIDBTransactionData, nsTArrayInfallibleAllocator>::Elements()
Unexecuted instantiation: nsTArray_Impl<nsCOMPtr<nsIRunnable>, nsTArrayInfallibleAllocator>::Elements()
Unexecuted instantiation: nsTArray_Impl<nsCOMPtr<nsISupports>, nsTArrayInfallibleAllocator>::Elements()
nsTArray_Impl<mozilla::DeferredFinalizeFunctionHolder, nsTArrayInfallibleAllocator>::Elements()
Line
Count
Source
1072
54
  elem_type* Elements() { return reinterpret_cast<elem_type*>(Hdr() + 1); }
Unexecuted instantiation: nsTArray_Impl<mozilla::UniquePtr<mozilla::TokenizerBase<char>::Token, mozilla::DefaultDelete<mozilla::TokenizerBase<char>::Token> >, nsTArrayInfallibleAllocator>::Elements()
Unexecuted instantiation: nsTArray_Impl<mozilla::MemoryMapping, nsTArrayInfallibleAllocator>::Elements()
Unexecuted instantiation: nsTArray_Impl<mozilla::dom::ContentParent*, nsTArrayInfallibleAllocator>::Elements()
Unexecuted instantiation: nsTArray_Impl<RefPtr<mozilla::MemoryReportingProcess>, nsTArrayInfallibleAllocator>::Elements()
Unexecuted instantiation: nsTArray_Impl<BloatEntry*, nsTArrayInfallibleAllocator>::Elements()
Unexecuted instantiation: nsTArray_Impl<ThreadsReporter::CollectReports(nsIHandleReportCallback*, nsISupports*, bool)::ThreadData, nsTArrayInfallibleAllocator>::Elements()
Unexecuted instantiation: Unified_cpp_xpcom_components0.cpp:nsTArray_Impl<(anonymous namespace)::CachedDirective, nsTArrayInfallibleAllocator>::Elements()
Unexecuted instantiation: nsTArray_Impl<mozilla::Module const*, nsTArrayInfallibleAllocator>::Elements()
nsTArray_Impl<nsComponentManagerImpl::ComponentLocation, nsTArrayInfallibleAllocator>::Elements()
Line
Count
Source
1072
12
  elem_type* Elements() { return reinterpret_cast<elem_type*>(Hdr() + 1); }
nsTArray_Impl<nsComponentManagerImpl::PendingServiceInfo, nsTArrayInfallibleAllocator>::Elements()
Line
Count
Source
1072
363
  elem_type* Elements() { return reinterpret_cast<elem_type*>(Hdr() + 1); }
nsTArray_Impl<nsAutoPtr<nsComponentManagerImpl::KnownModule>, nsTArrayInfallibleAllocator>::Elements()
Line
Count
Source
1072
180
  elem_type* Elements() { return reinterpret_cast<elem_type*>(Hdr() + 1); }
Unexecuted instantiation: nsTArray_Impl<mozilla::dom::StringBundleDescriptor, nsTArrayInfallibleAllocator>::Elements()
Unexecuted instantiation: nsTArray_Impl<nsAttrValue::EnumTable const*, nsTArrayInfallibleAllocator>::Elements()
1073
1074
  // This method provides direct, readonly access to the array elements.
1075
  // @return A pointer to the first element of the array.  If the array is
1076
  // empty, then this pointer must not be dereferenced.
1077
  const elem_type* Elements() const
1078
63
  {
1079
63
    return reinterpret_cast<const elem_type*>(Hdr() + 1);
1080
63
  }
Unexecuted instantiation: nsTArray_Impl<mozilla::CycleCollectedJSContext::PendingIDBTransactionData, nsTArrayInfallibleAllocator>::Elements() const
Unexecuted instantiation: nsTArray_Impl<mozilla::MemoryMapping, nsTArrayInfallibleAllocator>::Elements() const
Unexecuted instantiation: nsTArray_Impl<ThreadsReporter::CollectReports(nsIHandleReportCallback*, nsISupports*, bool)::ThreadData, nsTArrayInfallibleAllocator>::Elements() const
nsTArray_Impl<nsComponentManagerImpl::PendingServiceInfo, nsTArrayInfallibleAllocator>::Elements() const
Line
Count
Source
1078
63
  {
1079
63
    return reinterpret_cast<const elem_type*>(Hdr() + 1);
1080
63
  }
Unexecuted instantiation: nsTArray_Impl<nsComponentManagerImpl::ComponentLocation, nsTArrayInfallibleAllocator>::Elements() const
Unexecuted instantiation: nsTArray_Impl<nsAttrValue::EnumTable const*, nsTArrayInfallibleAllocator>::Elements() const
1081
1082
  // This method provides direct access to an element of the array. The given
1083
  // index must be within the array bounds.
1084
  // @param aIndex The index of an element in the array.
1085
  // @return A reference to the i'th element of the array.
1086
  elem_type& ElementAt(index_type aIndex)
1087
187
  {
1088
187
    if (MOZ_UNLIKELY(aIndex >= Length())) {
1089
0
      InvalidArrayIndex_CRASH(aIndex, Length());
1090
0
    }
1091
187
    return Elements()[aIndex];
1092
187
  }
Unexecuted instantiation: nsTArray_Impl<nsCOMPtr<nsIRunnable>, nsTArrayInfallibleAllocator>::ElementAt(unsigned long)
Unexecuted instantiation: nsTArray_Impl<mozilla::CycleCollectedJSContext::PendingIDBTransactionData, nsTArrayInfallibleAllocator>::ElementAt(unsigned long)
nsTArray_Impl<mozilla::DeferredFinalizeFunctionHolder, nsTArrayInfallibleAllocator>::ElementAt(unsigned long)
Line
Count
Source
1087
18
  {
1088
18
    if (MOZ_UNLIKELY(aIndex >= Length())) {
1089
0
      InvalidArrayIndex_CRASH(aIndex, Length());
1090
0
    }
1091
18
    return Elements()[aIndex];
1092
18
  }
Unexecuted instantiation: nsTArray_Impl<mozilla::MemoryMapping, nsTArrayInfallibleAllocator>::ElementAt(unsigned long)
Unexecuted instantiation: nsTArray_Impl<mozilla::dom::ContentParent*, nsTArrayInfallibleAllocator>::ElementAt(unsigned long)
Unexecuted instantiation: nsTArray_Impl<RefPtr<mozilla::MemoryReportingProcess>, nsTArrayInfallibleAllocator>::ElementAt(unsigned long)
Unexecuted instantiation: nsTArray_Impl<BloatEntry*, nsTArrayInfallibleAllocator>::ElementAt(unsigned long)
nsTArray_Impl<nsComponentManagerImpl::PendingServiceInfo, nsTArrayInfallibleAllocator>::ElementAt(unsigned long)
Line
Count
Source
1087
163
  {
1088
163
    if (MOZ_UNLIKELY(aIndex >= Length())) {
1089
0
      InvalidArrayIndex_CRASH(aIndex, Length());
1090
0
    }
1091
163
    return Elements()[aIndex];
1092
163
  }
Unexecuted instantiation: Unified_cpp_xpcom_components0.cpp:nsTArray_Impl<(anonymous namespace)::CachedDirective, nsTArrayInfallibleAllocator>::ElementAt(unsigned long)
Unexecuted instantiation: nsTArray_Impl<mozilla::Module const*, nsTArrayInfallibleAllocator>::ElementAt(unsigned long)
nsTArray_Impl<nsComponentManagerImpl::ComponentLocation, nsTArrayInfallibleAllocator>::ElementAt(unsigned long)
Line
Count
Source
1087
6
  {
1088
6
    if (MOZ_UNLIKELY(aIndex >= Length())) {
1089
0
      InvalidArrayIndex_CRASH(aIndex, Length());
1090
0
    }
1091
6
    return Elements()[aIndex];
1092
6
  }
Unexecuted instantiation: nsTArray_Impl<nsAttrValue::EnumTable const*, nsTArrayInfallibleAllocator>::ElementAt(unsigned long)
1093
1094
  // This method provides direct, readonly access to an element of the array
1095
  // The given index must be within the array bounds.
1096
  // @param aIndex The index of an element in the array.
1097
  // @return A const reference to the i'th element of the array.
1098
  const elem_type& ElementAt(index_type aIndex) const
1099
63
  {
1100
63
    if (MOZ_UNLIKELY(aIndex >= Length())) {
1101
0
      InvalidArrayIndex_CRASH(aIndex, Length());
1102
0
    }
1103
63
    return Elements()[aIndex];
1104
63
  }
Unexecuted instantiation: nsTArray_Impl<mozilla::MemoryMapping, nsTArrayInfallibleAllocator>::ElementAt(unsigned long) const
Unexecuted instantiation: nsTArray_Impl<ThreadsReporter::CollectReports(nsIHandleReportCallback*, nsISupports*, bool)::ThreadData, nsTArrayInfallibleAllocator>::ElementAt(unsigned long) const
nsTArray_Impl<nsComponentManagerImpl::PendingServiceInfo, nsTArrayInfallibleAllocator>::ElementAt(unsigned long) const
Line
Count
Source
1099
63
  {
1100
63
    if (MOZ_UNLIKELY(aIndex >= Length())) {
1101
0
      InvalidArrayIndex_CRASH(aIndex, Length());
1102
0
    }
1103
63
    return Elements()[aIndex];
1104
63
  }
1105
1106
  // This method provides direct access to an element of the array in a bounds
1107
  // safe manner. If the requested index is out of bounds the provided default
1108
  // value is returned.
1109
  // @param aIndex The index of an element in the array.
1110
  // @param aDef   The value to return if the index is out of bounds.
1111
  elem_type& SafeElementAt(index_type aIndex, elem_type& aDef)
1112
  {
1113
    return aIndex < Length() ? Elements()[aIndex] : aDef;
1114
  }
1115
1116
  // This method provides direct access to an element of the array in a bounds
1117
  // safe manner. If the requested index is out of bounds the provided default
1118
  // value is returned.
1119
  // @param aIndex The index of an element in the array.
1120
  // @param aDef   The value to return if the index is out of bounds.
1121
  const elem_type& SafeElementAt(index_type aIndex, const elem_type& aDef) const
1122
  {
1123
    return aIndex < Length() ? Elements()[aIndex] : aDef;
1124
  }
1125
1126
  // Shorthand for ElementAt(aIndex)
1127
18
  elem_type& operator[](index_type aIndex) { return ElementAt(aIndex); }
Unexecuted instantiation: nsTArray_Impl<nsCOMPtr<nsIRunnable>, nsTArrayInfallibleAllocator>::operator[](unsigned long)
Unexecuted instantiation: nsTArray_Impl<mozilla::CycleCollectedJSContext::PendingIDBTransactionData, nsTArrayInfallibleAllocator>::operator[](unsigned long)
nsTArray_Impl<mozilla::DeferredFinalizeFunctionHolder, nsTArrayInfallibleAllocator>::operator[](unsigned long)
Line
Count
Source
1127
18
  elem_type& operator[](index_type aIndex) { return ElementAt(aIndex); }
Unexecuted instantiation: nsTArray_Impl<mozilla::MemoryMapping, nsTArrayInfallibleAllocator>::operator[](unsigned long)
Unexecuted instantiation: nsTArray_Impl<mozilla::dom::ContentParent*, nsTArrayInfallibleAllocator>::operator[](unsigned long)
Unexecuted instantiation: nsTArray_Impl<BloatEntry*, nsTArrayInfallibleAllocator>::operator[](unsigned long)
Unexecuted instantiation: Unified_cpp_xpcom_components0.cpp:nsTArray_Impl<(anonymous namespace)::CachedDirective, nsTArrayInfallibleAllocator>::operator[](unsigned long)
Unexecuted instantiation: nsTArray_Impl<mozilla::Module const*, nsTArrayInfallibleAllocator>::operator[](unsigned long)
1128
1129
  // Shorthand for ElementAt(aIndex)
1130
0
  const elem_type& operator[](index_type aIndex) const { return ElementAt(aIndex); }
1131
1132
  // Shorthand for ElementAt(length - 1)
1133
0
  elem_type& LastElement() { return ElementAt(Length() - 1); }
Unexecuted instantiation: nsTArray_Impl<RefPtr<mozilla::MemoryReportingProcess>, nsTArrayInfallibleAllocator>::LastElement()
Unexecuted instantiation: nsTArray_Impl<unsigned int, nsTArrayInfallibleAllocator>::LastElement()
1134
1135
  // Shorthand for ElementAt(length - 1)
1136
0
  const elem_type& LastElement() const { return ElementAt(Length() - 1); }
1137
1138
  // Shorthand for SafeElementAt(length - 1, def)
1139
  elem_type& SafeLastElement(elem_type& aDef)
1140
  {
1141
    return SafeElementAt(Length() - 1, aDef);
1142
  }
1143
1144
  // Shorthand for SafeElementAt(length - 1, def)
1145
  const elem_type& SafeLastElement(const elem_type& aDef) const
1146
  {
1147
    return SafeElementAt(Length() - 1, aDef);
1148
  }
1149
1150
  // Methods for range-based for loops.
1151
0
  iterator begin() { return iterator(*this, 0); }
Unexecuted instantiation: nsTArray_Impl<mozilla::MemoryMapping, nsTArrayInfallibleAllocator>::begin()
Unexecuted instantiation: nsTArray_Impl<ThreadsReporter::CollectReports(nsIHandleReportCallback*, nsISupports*, bool)::ThreadData, nsTArrayInfallibleAllocator>::begin()
1152
  const_iterator begin() const { return const_iterator(*this, 0); }
1153
  const_iterator cbegin() const { return begin(); }
1154
0
  iterator end() { return iterator(*this, Length()); }
Unexecuted instantiation: nsTArray_Impl<mozilla::MemoryMapping, nsTArrayInfallibleAllocator>::end()
Unexecuted instantiation: nsTArray_Impl<ThreadsReporter::CollectReports(nsIHandleReportCallback*, nsISupports*, bool)::ThreadData, nsTArrayInfallibleAllocator>::end()
1155
  const_iterator end() const { return const_iterator(*this, Length()); }
1156
  const_iterator cend() const { return end(); }
1157
1158
  // Methods for reverse iterating.
1159
  reverse_iterator rbegin() { return reverse_iterator(end()); }
1160
  const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
1161
  const_reverse_iterator crbegin() const { return rbegin(); }
1162
  reverse_iterator rend() { return reverse_iterator(begin()); }
1163
  const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
1164
  const_reverse_iterator crend() const { return rend(); }
1165
1166
  // Span integration
1167
1168
  operator mozilla::Span<elem_type>()
1169
  {
1170
    return mozilla::Span<elem_type>(Elements(), Length());
1171
  }
1172
1173
  operator mozilla::Span<const elem_type>() const
1174
  {
1175
    return mozilla::Span<const elem_type>(Elements(), Length());
1176
  }
1177
1178
  //
1179
  // Search methods
1180
  //
1181
1182
  // This method searches for the first element in this array that is equal
1183
  // to the given element.
1184
  // @param aItem  The item to search for.
1185
  // @param aComp  The Comparator used to determine element equality.
1186
  // @return       true if the element was found.
1187
  template<class Item, class Comparator>
1188
  bool Contains(const Item& aItem, const Comparator& aComp) const
1189
0
  {
1190
0
    return ApplyIf(aItem, 0, aComp,
1191
0
                   []() { return true; },
Unexecuted instantiation: bool nsTArray_Impl<unsigned int, nsTArrayInfallibleAllocator>::Contains<unsigned int, nsDefaultComparator<unsigned int, unsigned int> >(unsigned int const&, nsDefaultComparator<unsigned int, unsigned int> const&) const::{lambda()#1}::operator()() const
Unexecuted instantiation: bool nsTArray_Impl<RefPtr<nsAtom>, nsTArrayInfallibleAllocator>::Contains<nsTSubstring<char16_t>, AtomArrayStringComparator>(nsTSubstring<char16_t> const&, AtomArrayStringComparator const&) const::{lambda()#1}::operator()() const
1192
0
                   []() { return false; });
Unexecuted instantiation: bool nsTArray_Impl<unsigned int, nsTArrayInfallibleAllocator>::Contains<unsigned int, nsDefaultComparator<unsigned int, unsigned int> >(unsigned int const&, nsDefaultComparator<unsigned int, unsigned int> const&) const::{lambda()#2}::operator()() const
Unexecuted instantiation: bool nsTArray_Impl<RefPtr<nsAtom>, nsTArrayInfallibleAllocator>::Contains<nsTSubstring<char16_t>, AtomArrayStringComparator>(nsTSubstring<char16_t> const&, AtomArrayStringComparator const&) const::{lambda()#2}::operator()() const
1193
0
  }
Unexecuted instantiation: bool nsTArray_Impl<unsigned int, nsTArrayInfallibleAllocator>::Contains<unsigned int, nsDefaultComparator<unsigned int, unsigned int> >(unsigned int const&, nsDefaultComparator<unsigned int, unsigned int> const&) const
Unexecuted instantiation: bool nsTArray_Impl<RefPtr<nsAtom>, nsTArrayInfallibleAllocator>::Contains<nsTSubstring<char16_t>, AtomArrayStringComparator>(nsTSubstring<char16_t> const&, AtomArrayStringComparator const&) const
1194
1195
  // Like Contains(), but assumes a sorted array.
1196
  template<class Item, class Comparator>
1197
  bool ContainsSorted(const Item& aItem, const Comparator& aComp) const
1198
  {
1199
    return BinaryIndexOf(aItem, aComp) != NoIndex;
1200
  }
1201
1202
  // This method searches for the first element in this array that is equal
1203
  // to the given element.  This method assumes that 'operator==' is defined
1204
  // for elem_type.
1205
  // @param aItem  The item to search for.
1206
  // @return       true if the element was found.
1207
  template<class Item>
1208
  bool Contains(const Item& aItem) const
1209
0
  {
1210
0
    return Contains(aItem, nsDefaultComparator<elem_type, Item>());
1211
0
  }
1212
1213
  // Like Contains(), but assumes a sorted array.
1214
  template<class Item>
1215
  bool ContainsSorted(const Item& aItem) const
1216
  {
1217
    return BinaryIndexOf(aItem) != NoIndex;
1218
  }
1219
1220
  // This method searches for the offset of the first element in this
1221
  // array that is equal to the given element.
1222
  // @param aItem  The item to search for.
1223
  // @param aStart The index to start from.
1224
  // @param aComp  The Comparator used to determine element equality.
1225
  // @return       The index of the found element or NoIndex if not found.
1226
  template<class Item, class Comparator>
1227
  index_type IndexOf(const Item& aItem, index_type aStart,
1228
                     const Comparator& aComp) const
1229
0
  {
1230
0
    ::detail::CompareWrapper<Comparator, Item> comp(aComp);
1231
0
1232
0
    const elem_type* iter = Elements() + aStart;
1233
0
    const elem_type* iend = Elements() + Length();
1234
0
    for (; iter != iend; ++iter) {
1235
0
      if (comp.Equals(*iter, aItem)) {
1236
0
        return index_type(iter - Elements());
1237
0
      }
1238
0
    }
1239
0
    return NoIndex;
1240
0
  }
Unexecuted instantiation: unsigned long nsTArray_Impl<nsComponentManagerImpl::ComponentLocation, nsTArrayInfallibleAllocator>::IndexOf<nsComponentManagerImpl::ComponentLocation, nsComponentManagerImpl::ComponentLocationComparator>(nsComponentManagerImpl::ComponentLocation const&, unsigned long, nsComponentManagerImpl::ComponentLocationComparator const&) const
Unexecuted instantiation: unsigned long nsTArray_Impl<nsAttrValue::EnumTable const*, nsTArrayInfallibleAllocator>::IndexOf<nsAttrValue::EnumTable const*, nsDefaultComparator<nsAttrValue::EnumTable const*, nsAttrValue::EnumTable const*> >(nsAttrValue::EnumTable const* const&, unsigned long, nsDefaultComparator<nsAttrValue::EnumTable const*, nsAttrValue::EnumTable const*> const&) const
1241
1242
  // This method searches for the offset of the first element in this
1243
  // array that is equal to the given element.  This method assumes
1244
  // that 'operator==' is defined for elem_type.
1245
  // @param aItem  The item to search for.
1246
  // @param aStart The index to start from.
1247
  // @return       The index of the found element or NoIndex if not found.
1248
  template<class Item>
1249
  index_type IndexOf(const Item& aItem, index_type aStart = 0) const
1250
0
  {
1251
0
    return IndexOf(aItem, aStart, nsDefaultComparator<elem_type, Item>());
1252
0
  }
1253
1254
  // This method searches for the offset of the last element in this
1255
  // array that is equal to the given element.
1256
  // @param aItem  The item to search for.
1257
  // @param aStart The index to start from.  If greater than or equal to the
1258
  //               length of the array, then the entire array is searched.
1259
  // @param aComp  The Comparator used to determine element equality.
1260
  // @return       The index of the found element or NoIndex if not found.
1261
  template<class Item, class Comparator>
1262
  index_type LastIndexOf(const Item& aItem, index_type aStart,
1263
                         const Comparator& aComp) const
1264
  {
1265
    ::detail::CompareWrapper<Comparator, Item> comp(aComp);
1266
1267
    size_type endOffset = aStart >= Length() ? Length() : aStart + 1;
1268
    const elem_type* iend = Elements() - 1;
1269
    const elem_type* iter = iend + endOffset;
1270
    for (; iter != iend; --iter) {
1271
      if (comp.Equals(*iter, aItem)) {
1272
        return index_type(iter - Elements());
1273
      }
1274
    }
1275
    return NoIndex;
1276
  }
1277
1278
  // This method searches for the offset of the last element in this
1279
  // array that is equal to the given element.  This method assumes
1280
  // that 'operator==' is defined for elem_type.
1281
  // @param aItem  The item to search for.
1282
  // @param aStart The index to start from.  If greater than or equal to the
1283
  //               length of the array, then the entire array is searched.
1284
  // @return       The index of the found element or NoIndex if not found.
1285
  template<class Item>
1286
  index_type LastIndexOf(const Item& aItem,
1287
                         index_type aStart = NoIndex) const
1288
  {
1289
    return LastIndexOf(aItem, aStart, nsDefaultComparator<elem_type, Item>());
1290
  }
1291
1292
  // This method searches for the offset for the element in this array
1293
  // that is equal to the given element. The array is assumed to be sorted.
1294
  // If there is more than one equivalent element, there is no guarantee
1295
  // on which one will be returned.
1296
  // @param aItem  The item to search for.
1297
  // @param aComp  The Comparator used.
1298
  // @return       The index of the found element or NoIndex if not found.
1299
  template<class Item, class Comparator>
1300
  index_type BinaryIndexOf(const Item& aItem, const Comparator& aComp) const
1301
0
  {
1302
0
    using mozilla::BinarySearchIf;
1303
0
    ::detail::CompareWrapper<Comparator, Item> comp(aComp);
1304
0
1305
0
    size_t index;
1306
0
    bool found = BinarySearchIf(
1307
0
      *this, 0, Length(),
1308
0
      // Note: We pass the Compare() args here in reverse order and negate the
1309
0
      // results for compatibility reasons. Some existing callers use Equals()
1310
0
      // functions with first arguments which match aElement but not aItem, or
1311
0
      // second arguments that match aItem but not aElement. To accommodate
1312
0
      // those callers, we preserve the argument order of the older version of
1313
0
      // this API. These callers, however, should be fixed, and this special
1314
0
      // case removed.
1315
0
      [&] (const elem_type& aElement) { return -comp.Compare(aElement, aItem); },
1316
0
      &index);
1317
0
    return found ? index : NoIndex;
1318
0
  }
1319
1320
  // This method searches for the offset for the element in this array
1321
  // that is equal to the given element. The array is assumed to be sorted.
1322
  // This method assumes that 'operator==' and 'operator<' are defined.
1323
  // @param aItem  The item to search for.
1324
  // @return       The index of the found element or NoIndex if not found.
1325
  template<class Item>
1326
  index_type BinaryIndexOf(const Item& aItem) const
1327
0
  {
1328
0
    return BinaryIndexOf(aItem, nsDefaultComparator<elem_type, Item>());
1329
0
  }
1330
1331
  //
1332
  // Mutation methods
1333
  //
1334
1335
  template<class Allocator, typename ActualAlloc = Alloc>
1336
  typename ActualAlloc::ResultType Assign(
1337
      const nsTArray_Impl<E, Allocator>& aOther)
1338
  {
1339
    return ActualAlloc::ConvertBoolToResultType(
1340
      !!ReplaceElementsAt<E, ActualAlloc>(0, Length(),
1341
                                          aOther.Elements(), aOther.Length()));
1342
  }
1343
1344
  template<class Allocator>
1345
  MOZ_MUST_USE
1346
  bool Assign(const nsTArray_Impl<E, Allocator>& aOther,
1347
              const mozilla::fallible_t&)
1348
  {
1349
    return Assign<Allocator, FallibleAlloc>(aOther);
1350
  }
1351
1352
  template<class Allocator>
1353
  void Assign(nsTArray_Impl<E, Allocator>&& aOther)
1354
  {
1355
    Clear();
1356
    SwapElements(aOther);
1357
  }
1358
1359
  // This method call the destructor on each element of the array, empties it,
1360
  // but does not shrink the array's capacity.
1361
  // See also SetLengthAndRetainStorage.
1362
  // Make sure to call Compact() if needed to avoid keeping a huge array
1363
  // around.
1364
  void ClearAndRetainStorage()
1365
147
  {
1366
147
    if (base_type::mHdr == EmptyHdr()) {
1367
129
      return;
1368
129
    }
1369
18
1370
18
    DestructRange(0, Length());
1371
18
    base_type::mHdr->mLength = 0;
1372
18
  }
Unexecuted instantiation: nsTArray_Impl<mozilla::CycleCollectedJSContext::PendingIDBTransactionData, nsTArrayInfallibleAllocator>::ClearAndRetainStorage()
Unexecuted instantiation: nsTArray_Impl<nsCOMPtr<nsIRunnable>, nsTArrayInfallibleAllocator>::ClearAndRetainStorage()
Unexecuted instantiation: nsTArray_Impl<nsCOMPtr<nsISupports>, nsTArrayInfallibleAllocator>::ClearAndRetainStorage()
nsTArray_Impl<mozilla::DeferredFinalizeFunctionHolder, nsTArrayInfallibleAllocator>::ClearAndRetainStorage()
Line
Count
Source
1365
18
  {
1366
18
    if (base_type::mHdr == EmptyHdr()) {
1367
0
      return;
1368
0
    }
1369
18
1370
18
    DestructRange(0, Length());
1371
18
    base_type::mHdr->mLength = 0;
1372
18
  }
Unexecuted instantiation: nsTArray_Impl<mozilla::UniquePtr<mozilla::TokenizerBase<char>::Token, mozilla::DefaultDelete<mozilla::TokenizerBase<char>::Token> >, nsTArrayInfallibleAllocator>::ClearAndRetainStorage()
nsTArray_Impl<mozilla::dom::ContentParent*, nsTArrayInfallibleAllocator>::ClearAndRetainStorage()
Line
Count
Source
1365
129
  {
1366
129
    if (base_type::mHdr == EmptyHdr()) {
1367
129
      return;
1368
129
    }
1369
0
1370
0
    DestructRange(0, Length());
1371
0
    base_type::mHdr->mLength = 0;
1372
0
  }
Unexecuted instantiation: nsTArray_Impl<RefPtr<mozilla::MemoryReportingProcess>, nsTArrayInfallibleAllocator>::ClearAndRetainStorage()
Unexecuted instantiation: nsTArray_Impl<mozilla::MemoryMapping, nsTArrayInfallibleAllocator>::ClearAndRetainStorage()
Unexecuted instantiation: nsTArray_Impl<BloatEntry*, nsTArrayInfallibleAllocator>::ClearAndRetainStorage()
Unexecuted instantiation: nsTArray_Impl<ThreadsReporter::CollectReports(nsIHandleReportCallback*, nsISupports*, bool)::ThreadData, nsTArrayInfallibleAllocator>::ClearAndRetainStorage()
Unexecuted instantiation: Unified_cpp_xpcom_components0.cpp:nsTArray_Impl<(anonymous namespace)::CachedDirective, nsTArrayInfallibleAllocator>::ClearAndRetainStorage()
Unexecuted instantiation: nsTArray_Impl<mozilla::Module const*, nsTArrayInfallibleAllocator>::ClearAndRetainStorage()
Unexecuted instantiation: nsTArray_Impl<nsComponentManagerImpl::ComponentLocation, nsTArrayInfallibleAllocator>::ClearAndRetainStorage()
Unexecuted instantiation: nsTArray_Impl<nsComponentManagerImpl::PendingServiceInfo, nsTArrayInfallibleAllocator>::ClearAndRetainStorage()
Unexecuted instantiation: nsTArray_Impl<nsAutoPtr<nsComponentManagerImpl::KnownModule>, nsTArrayInfallibleAllocator>::ClearAndRetainStorage()
Unexecuted instantiation: nsTArray_Impl<mozilla::dom::StringBundleDescriptor, nsTArrayInfallibleAllocator>::ClearAndRetainStorage()
Unexecuted instantiation: nsTArray_Impl<nsAttrValue::EnumTable const*, nsTArrayInfallibleAllocator>::ClearAndRetainStorage()
1373
1374
  // This method modifies the length of the array, but unlike SetLength
1375
  // it doesn't deallocate/reallocate the current internal storage.
1376
  // The new length MUST be shorter than or equal to the current capacity.
1377
  // If the new length is larger than the existing length of the array,
1378
  // then new elements will be constructed using elem_type's default
1379
  // constructor.  If shorter, elements will be destructed and removed.
1380
  // See also ClearAndRetainStorage.
1381
  // @param aNewLen  The desired length of this array.
1382
  void SetLengthAndRetainStorage(size_type aNewLen)
1383
  {
1384
    MOZ_ASSERT(aNewLen <= base_type::Capacity());
1385
    size_type oldLen = Length();
1386
    if (aNewLen > oldLen) {
1387
      InsertElementsAt(oldLen, aNewLen - oldLen);
1388
      return;
1389
    }
1390
    if (aNewLen < oldLen) {
1391
      DestructRange(aNewLen, oldLen - aNewLen);
1392
      base_type::mHdr->mLength = aNewLen;
1393
    }
1394
  }
1395
1396
  // This method replaces a range of elements in this array.
1397
  // @param aStart    The starting index of the elements to replace.
1398
  // @param aCount    The number of elements to replace.  This may be zero to
1399
  //                  insert elements without removing any existing elements.
1400
  // @param aArray    The values to copy into this array.  Must be non-null,
1401
  //                  and these elements must not already exist in the array
1402
  //                  being modified.
1403
  // @param aArrayLen The number of values to copy into this array.
1404
  // @return          A pointer to the new elements in the array, or null if
1405
  //                  the operation failed due to insufficient memory.
1406
protected:
1407
  template<class Item, typename ActualAlloc = Alloc>
1408
  elem_type* ReplaceElementsAt(index_type aStart, size_type aCount,
1409
                               const Item* aArray, size_type aArrayLen);
1410
1411
public:
1412
1413
  template<class Item>
1414
  MOZ_MUST_USE
1415
  elem_type* ReplaceElementsAt(index_type aStart, size_type aCount,
1416
                               const Item* aArray, size_type aArrayLen,
1417
                               const mozilla::fallible_t&)
1418
  {
1419
    return ReplaceElementsAt<Item, FallibleAlloc>(aStart, aCount,
1420
                                                  aArray, aArrayLen);
1421
  }
1422
1423
  // A variation on the ReplaceElementsAt method defined above.
1424
protected:
1425
  template<class Item, typename ActualAlloc = Alloc>
1426
  elem_type* ReplaceElementsAt(index_type aStart, size_type aCount,
1427
                               const nsTArray<Item>& aArray)
1428
  {
1429
    return ReplaceElementsAt<Item, ActualAlloc>(
1430
      aStart, aCount, aArray.Elements(), aArray.Length());
1431
  }
1432
1433
  template<class Item, typename ActualAlloc = Alloc>
1434
  elem_type* ReplaceElementsAt(index_type aStart,
1435
                               size_type aCount,
1436
                               mozilla::Span<const Item> aSpan)
1437
  {
1438
    return ReplaceElementsAt<Item, ActualAlloc>(
1439
      aStart, aCount, aSpan.Elements(), aSpan.Length());
1440
  }
1441
1442
public:
1443
1444
  template<class Item>
1445
  MOZ_MUST_USE
1446
  elem_type* ReplaceElementsAt(index_type aStart, size_type aCount,
1447
                               const nsTArray<Item>& aArray,
1448
                               const mozilla::fallible_t&)
1449
  {
1450
    return ReplaceElementsAt<Item, FallibleAlloc>(aStart, aCount, aArray);
1451
  }
1452
1453
  template<class Item>
1454
  MOZ_MUST_USE elem_type* ReplaceElementsAt(index_type aStart,
1455
                                            size_type aCount,
1456
                                            mozilla::Span<const Item> aSpan,
1457
                                            const mozilla::fallible_t&)
1458
  {
1459
    return ReplaceElementsAt<Item, FallibleAlloc>(aStart, aCount, aSpan);
1460
  }
1461
1462
  // A variation on the ReplaceElementsAt method defined above.
1463
protected:
1464
  template<class Item, typename ActualAlloc = Alloc>
1465
  elem_type* ReplaceElementsAt(index_type aStart, size_type aCount,
1466
                               const Item& aItem)
1467
  {
1468
    return ReplaceElementsAt<Item, ActualAlloc>(aStart, aCount, &aItem, 1);
1469
  }
1470
public:
1471
1472
  template<class Item>
1473
  MOZ_MUST_USE
1474
  elem_type* ReplaceElementsAt(index_type aStart, size_type aCount,
1475
                               const Item& aItem, const mozilla::fallible_t&)
1476
  {
1477
    return ReplaceElementsAt<Item, FallibleAlloc>(aStart, aCount, aItem);
1478
  }
1479
1480
  // A variation on the ReplaceElementsAt method defined above.
1481
  template<class Item>
1482
  elem_type* ReplaceElementAt(index_type aIndex, const Item& aItem)
1483
  {
1484
    return ReplaceElementsAt(aIndex, 1, &aItem, 1);
1485
  }
1486
1487
  // A variation on the ReplaceElementsAt method defined above.
1488
protected:
1489
  template<class Item, typename ActualAlloc = Alloc>
1490
  elem_type* InsertElementsAt(index_type aIndex, const Item* aArray,
1491
                              size_type aArrayLen)
1492
  {
1493
    return ReplaceElementsAt<Item, ActualAlloc>(aIndex, 0, aArray, aArrayLen);
1494
  }
1495
public:
1496
1497
  template<class Item>
1498
  MOZ_MUST_USE
1499
  elem_type* InsertElementsAt(index_type aIndex, const Item* aArray,
1500
                              size_type aArrayLen, const mozilla::fallible_t&)
1501
  {
1502
    return InsertElementsAt<Item, FallibleAlloc>(aIndex, aArray, aArrayLen);
1503
  }
1504
1505
  // A variation on the ReplaceElementsAt method defined above.
1506
protected:
1507
  template<class Item, class Allocator, typename ActualAlloc = Alloc>
1508
  elem_type* InsertElementsAt(index_type aIndex,
1509
                              const nsTArray_Impl<Item, Allocator>& aArray)
1510
  {
1511
    return ReplaceElementsAt<Item, ActualAlloc>(
1512
      aIndex, 0, aArray.Elements(), aArray.Length());
1513
  }
1514
1515
  template<class Item, typename ActualAlloc = Alloc>
1516
  elem_type* InsertElementsAt(index_type aIndex,
1517
                              mozilla::Span<const Item> aSpan)
1518
  {
1519
    return ReplaceElementsAt<Item, ActualAlloc>(
1520
      aIndex, 0, aSpan.Elements(), aSpan.Length());
1521
  }
1522
1523
public:
1524
1525
  template<class Item, class Allocator>
1526
  MOZ_MUST_USE
1527
  elem_type* InsertElementsAt(index_type aIndex,
1528
                              const nsTArray_Impl<Item, Allocator>& aArray,
1529
                              const mozilla::fallible_t&)
1530
  {
1531
    return InsertElementsAt<Item, Allocator, FallibleAlloc>(aIndex, aArray);
1532
  }
1533
1534
  template<class Item>
1535
  MOZ_MUST_USE elem_type* InsertElementsAt(index_type aIndex,
1536
                                           mozilla::Span<const Item> aSpan,
1537
                                           const mozilla::fallible_t&)
1538
  {
1539
    return InsertElementsAt<Item, FallibleAlloc>(aIndex, aSpan);
1540
  }
1541
1542
  // Insert a new element without copy-constructing. This is useful to avoid
1543
  // temporaries.
1544
  // @return A pointer to the newly inserted element, or null on OOM.
1545
protected:
1546
  template<typename ActualAlloc = Alloc>
1547
  elem_type* InsertElementAt(index_type aIndex);
1548
1549
public:
1550
1551
  MOZ_MUST_USE
1552
  elem_type* InsertElementAt(index_type aIndex, const mozilla::fallible_t&)
1553
  {
1554
    return InsertElementAt<FallibleAlloc>(aIndex);
1555
  }
1556
1557
  // Insert a new element, move constructing if possible.
1558
protected:
1559
  template<class Item, typename ActualAlloc = Alloc>
1560
  elem_type* InsertElementAt(index_type aIndex, Item&& aItem);
1561
1562
public:
1563
1564
  template<class Item>
1565
  MOZ_MUST_USE
1566
  elem_type* InsertElementAt(index_type aIndex, Item&& aItem,
1567
                             const mozilla::fallible_t&)
1568
  {
1569
    return InsertElementAt<Item, FallibleAlloc>(aIndex,
1570
                                                std::forward<Item>(aItem));
1571
  }
1572
1573
  // Reconstruct the element at the given index, and return a pointer to the
1574
  // reconstructed element.  This will destroy the existing element and
1575
  // default-construct a new one, giving you a state much like what single-arg
1576
  // InsertElementAt(), or no-arg AppendElement() does, but without changing the
1577
  // length of the array.
1578
  //
1579
  // array[idx] = T()
1580
  //
1581
  // would accomplish the same thing as long as T has the appropriate moving
1582
  // operator=, but some types don't for various reasons.
1583
  elem_type* ReconstructElementAt(index_type aIndex)
1584
  {
1585
    elem_type* elem = &ElementAt(aIndex);
1586
    elem_traits::Destruct(elem);
1587
    elem_traits::Construct(elem);
1588
    return elem;
1589
  }
1590
1591
  // This method searches for the smallest index of an element that is strictly
1592
  // greater than |aItem|. If |aItem| is inserted at this index, the array will
1593
  // remain sorted and |aItem| would come after all elements that are equal to
1594
  // it. If |aItem| is greater than or equal to all elements in the array, the
1595
  // array length is returned.
1596
  //
1597
  // Note that consumers who want to know whether there are existing items equal
1598
  // to |aItem| in the array can just check that the return value here is > 0
1599
  // and indexing into the previous slot gives something equal to |aItem|.
1600
  //
1601
  //
1602
  // @param aItem  The item to search for.
1603
  // @param aComp  The Comparator used.
1604
  // @return        The index of greatest element <= to |aItem|
1605
  // @precondition The array is sorted
1606
  template<class Item, class Comparator>
1607
  index_type IndexOfFirstElementGt(const Item& aItem,
1608
                                   const Comparator& aComp) const
1609
  {
1610
    using mozilla::BinarySearchIf;
1611
    ::detail::CompareWrapper<Comparator, Item> comp(aComp);
1612
1613
    size_t index;
1614
    BinarySearchIf(*this, 0, Length(),
1615
                   [&] (const elem_type& aElement) { return comp.Compare(aElement, aItem) <= 0 ? 1 : -1; },
1616
                   &index);
1617
    return index;
1618
  }
1619
1620
  // A variation on the IndexOfFirstElementGt method defined above.
1621
  template<class Item>
1622
  index_type
1623
  IndexOfFirstElementGt(const Item& aItem) const
1624
  {
1625
    return IndexOfFirstElementGt(aItem, nsDefaultComparator<elem_type, Item>());
1626
  }
1627
1628
  // Inserts |aItem| at such an index to guarantee that if the array
1629
  // was previously sorted, it will remain sorted after this
1630
  // insertion.
1631
protected:
1632
  template<class Item, class Comparator, typename ActualAlloc = Alloc>
1633
  elem_type* InsertElementSorted(Item&& aItem, const Comparator& aComp)
1634
  {
1635
    index_type index = IndexOfFirstElementGt<Item, Comparator>(aItem, aComp);
1636
    return InsertElementAt<Item, ActualAlloc>(
1637
      index, std::forward<Item>(aItem));
1638
  }
1639
public:
1640
1641
  template<class Item, class Comparator>
1642
  MOZ_MUST_USE
1643
  elem_type* InsertElementSorted(Item&& aItem, const Comparator& aComp,
1644
                                 const mozilla::fallible_t&)
1645
  {
1646
    return InsertElementSorted<Item, Comparator, FallibleAlloc>(
1647
      std::forward<Item>(aItem), aComp);
1648
  }
1649
1650
  // A variation on the InsertElementSorted method defined above.
1651
protected:
1652
  template<class Item, typename ActualAlloc = Alloc>
1653
  elem_type* InsertElementSorted(Item&& aItem)
1654
  {
1655
    nsDefaultComparator<elem_type, Item> comp;
1656
    return InsertElementSorted<Item, decltype(comp), ActualAlloc>(
1657
      std::forward<Item>(aItem), comp);
1658
  }
1659
public:
1660
1661
  template<class Item>
1662
  MOZ_MUST_USE
1663
  elem_type* InsertElementSorted(Item&& aItem, const mozilla::fallible_t&)
1664
  {
1665
    return InsertElementSorted<Item, FallibleAlloc>(
1666
      std::forward<Item>(aItem));
1667
  }
1668
1669
  // This method appends elements to the end of this array.
1670
  // @param aArray    The elements to append to this array.
1671
  // @param aArrayLen The number of elements to append to this array.
1672
  // @return          A pointer to the new elements in the array, or null if
1673
  //                  the operation failed due to insufficient memory.
1674
protected:
1675
  template<class Item, typename ActualAlloc = Alloc>
1676
  elem_type* AppendElements(const Item* aArray, size_type aArrayLen);
1677
1678
  template<class Item, typename ActualAlloc = Alloc>
1679
  elem_type* AppendElements(mozilla::Span<const Item> aSpan)
1680
  {
1681
    return AppendElements<Item, FallibleAlloc>(aSpan.Elements(),
1682
                                               aSpan.Length());
1683
  }
1684
1685
  template<class Item, size_t Length, typename ActualAlloc = Alloc>
1686
  elem_type* AppendElements(const mozilla::Array<Item, Length>& aArray)
1687
  {
1688
    return AppendElements<Item, ActualAlloc>(&aArray[0], Length);
1689
  }
1690
1691
public:
1692
1693
  template<class Item>
1694
  /* MOZ_MUST_USE */
1695
  elem_type* AppendElements(const Item* aArray, size_type aArrayLen,
1696
                            const mozilla::fallible_t&)
1697
  {
1698
    return AppendElements<Item, FallibleAlloc>(aArray, aArrayLen);
1699
  }
1700
1701
  template<class Item>
1702
  /* MOZ_MUST_USE */
1703
  elem_type* AppendElements(mozilla::Span<const Item> aSpan,
1704
                            const mozilla::fallible_t&)
1705
  {
1706
    return AppendElements<Item, FallibleAlloc>(aSpan.Elements(),
1707
                                               aSpan.Length());
1708
  }
1709
1710
  // A variation on the AppendElements method defined above.
1711
protected:
1712
  template<class Item, class Allocator, typename ActualAlloc = Alloc>
1713
  elem_type* AppendElements(const nsTArray_Impl<Item, Allocator>& aArray)
1714
0
  {
1715
0
    return AppendElements<Item, ActualAlloc>(aArray.Elements(), aArray.Length());
1716
0
  }
Unexecuted instantiation: mozilla::CycleCollectedJSContext::PendingIDBTransactionData* nsTArray_Impl<mozilla::CycleCollectedJSContext::PendingIDBTransactionData, nsTArrayInfallibleAllocator>::AppendElements<mozilla::CycleCollectedJSContext::PendingIDBTransactionData, nsTArrayInfallibleAllocator, nsTArrayInfallibleAllocator>(nsTArray_Impl<mozilla::CycleCollectedJSContext::PendingIDBTransactionData, nsTArrayInfallibleAllocator> const&)
Unexecuted instantiation: RefPtr<nsAtom>* nsTArray_Impl<RefPtr<nsAtom>, nsTArrayInfallibleAllocator>::AppendElements<RefPtr<nsAtom>, nsTArrayInfallibleAllocator, nsTArrayInfallibleAllocator>(nsTArray_Impl<RefPtr<nsAtom>, nsTArrayInfallibleAllocator> const&)
1717
public:
1718
1719
  template<class Item, class Allocator>
1720
  /* MOZ_MUST_USE */
1721
  elem_type* AppendElements(const nsTArray_Impl<Item, Allocator>& aArray,
1722
                            const mozilla::fallible_t&)
1723
  {
1724
    return AppendElements<Item, Allocator, FallibleAlloc>(aArray);
1725
  }
1726
1727
  // Move all elements from another array to the end of this array.
1728
  // @return A pointer to the newly appended elements, or null on OOM.
1729
protected:
1730
  template<class Item, class Allocator, typename ActualAlloc = Alloc>
1731
  elem_type* AppendElements(nsTArray_Impl<Item, Allocator>&& aArray);
1732
1733
public:
1734
1735
  template<class Item, class Allocator, typename ActualAlloc = Alloc>
1736
  /* MOZ_MUST_USE */
1737
  elem_type* AppendElements(nsTArray_Impl<Item, Allocator>&& aArray,
1738
                            const mozilla::fallible_t&)
1739
  {
1740
    return AppendElements<Item, Allocator>(std::move(aArray));
1741
  }
1742
1743
  // Append a new element, move constructing if possible.
1744
protected:
1745
  template<class Item, typename ActualAlloc = Alloc>
1746
  elem_type* AppendElement(Item&& aItem);
1747
1748
public:
1749
1750
  template<class Item>
1751
  /* MOZ_MUST_USE */
1752
  elem_type* AppendElement(Item&& aItem,
1753
                           const mozilla::fallible_t&)
1754
  {
1755
    return AppendElement<Item, FallibleAlloc>(std::forward<Item>(aItem));
1756
  }
1757
1758
  // Append new elements without copy-constructing. This is useful to avoid
1759
  // temporaries.
1760
  // @return A pointer to the newly appended elements, or null on OOM.
1761
protected:
1762
  template<typename ActualAlloc = Alloc>
1763
124
  elem_type* AppendElements(size_type aCount) {
1764
124
    if (!ActualAlloc::Successful(this->template EnsureCapacity<ActualAlloc>(
1765
124
          Length() + aCount, sizeof(elem_type)))) {
1766
0
      return nullptr;
1767
0
    }
1768
124
    elem_type* elems = Elements() + Length();
1769
124
    size_type i;
1770
248
    for (i = 0; i < aCount; ++i) {
1771
124
      elem_traits::Construct(elems + i);
1772
124
    }
1773
124
    this->IncrementLength(aCount);
1774
124
    return elems;
1775
124
  }
mozilla::DeferredFinalizeFunctionHolder* nsTArray_Impl<mozilla::DeferredFinalizeFunctionHolder, nsTArrayInfallibleAllocator>::AppendElements<nsTArrayInfallibleAllocator>(unsigned long)
Line
Count
Source
1763
18
  elem_type* AppendElements(size_type aCount) {
1764
18
    if (!ActualAlloc::Successful(this->template EnsureCapacity<ActualAlloc>(
1765
18
          Length() + aCount, sizeof(elem_type)))) {
1766
0
      return nullptr;
1767
0
    }
1768
18
    elem_type* elems = Elements() + Length();
1769
18
    size_type i;
1770
36
    for (i = 0; i < aCount; ++i) {
1771
18
      elem_traits::Construct(elems + i);
1772
18
    }
1773
18
    this->IncrementLength(aCount);
1774
18
    return elems;
1775
18
  }
nsComponentManagerImpl::PendingServiceInfo* nsTArray_Impl<nsComponentManagerImpl::PendingServiceInfo, nsTArrayInfallibleAllocator>::AppendElements<nsTArrayInfallibleAllocator>(unsigned long)
Line
Count
Source
1763
100
  elem_type* AppendElements(size_type aCount) {
1764
100
    if (!ActualAlloc::Successful(this->template EnsureCapacity<ActualAlloc>(
1765
100
          Length() + aCount, sizeof(elem_type)))) {
1766
0
      return nullptr;
1767
0
    }
1768
100
    elem_type* elems = Elements() + Length();
1769
100
    size_type i;
1770
200
    for (i = 0; i < aCount; ++i) {
1771
100
      elem_traits::Construct(elems + i);
1772
100
    }
1773
100
    this->IncrementLength(aCount);
1774
100
    return elems;
1775
100
  }
nsComponentManagerImpl::ComponentLocation* nsTArray_Impl<nsComponentManagerImpl::ComponentLocation, nsTArrayInfallibleAllocator>::AppendElements<nsTArrayInfallibleAllocator>(unsigned long)
Line
Count
Source
1763
6
  elem_type* AppendElements(size_type aCount) {
1764
6
    if (!ActualAlloc::Successful(this->template EnsureCapacity<ActualAlloc>(
1765
6
          Length() + aCount, sizeof(elem_type)))) {
1766
0
      return nullptr;
1767
0
    }
1768
6
    elem_type* elems = Elements() + Length();
1769
6
    size_type i;
1770
12
    for (i = 0; i < aCount; ++i) {
1771
6
      elem_traits::Construct(elems + i);
1772
6
    }
1773
6
    this->IncrementLength(aCount);
1774
6
    return elems;
1775
6
  }
1776
public:
1777
1778
  /* MOZ_MUST_USE */
1779
  elem_type* AppendElements(size_type aCount,
1780
                            const mozilla::fallible_t&)
1781
  {
1782
    return AppendElements<FallibleAlloc>(aCount);
1783
  }
1784
1785
  // Append a new element without copy-constructing. This is useful to avoid
1786
  // temporaries.
1787
  // @return A pointer to the newly appended element, or null on OOM.
1788
protected:
1789
  template<typename ActualAlloc = Alloc>
1790
  elem_type* AppendElement()
1791
124
  {
1792
124
    return AppendElements<ActualAlloc>(1);
1793
124
  }
mozilla::DeferredFinalizeFunctionHolder* nsTArray_Impl<mozilla::DeferredFinalizeFunctionHolder, nsTArrayInfallibleAllocator>::AppendElement<nsTArrayInfallibleAllocator>()
Line
Count
Source
1791
18
  {
1792
18
    return AppendElements<ActualAlloc>(1);
1793
18
  }
nsComponentManagerImpl::PendingServiceInfo* nsTArray_Impl<nsComponentManagerImpl::PendingServiceInfo, nsTArrayInfallibleAllocator>::AppendElement<nsTArrayInfallibleAllocator>()
Line
Count
Source
1791
100
  {
1792
100
    return AppendElements<ActualAlloc>(1);
1793
100
  }
nsComponentManagerImpl::ComponentLocation* nsTArray_Impl<nsComponentManagerImpl::ComponentLocation, nsTArrayInfallibleAllocator>::AppendElement<nsTArrayInfallibleAllocator>()
Line
Count
Source
1791
6
  {
1792
6
    return AppendElements<ActualAlloc>(1);
1793
6
  }
1794
public:
1795
1796
  /* MOZ_MUST_USE */
1797
  elem_type* AppendElement(const mozilla::fallible_t&)
1798
  {
1799
    return AppendElement<FallibleAlloc>();
1800
  }
1801
1802
  // This method removes a range of elements from this array.
1803
  // @param aStart The starting index of the elements to remove.
1804
  // @param aCount The number of elements to remove.
1805
  void RemoveElementsAt(index_type aStart, size_type aCount);
1806
1807
private:
1808
  // Remove a range of elements from this array, but do not check that
1809
  // the range is in bounds.
1810
  // @param aStart The starting index of the elements to remove.
1811
  // @param aCount The number of elements to remove.
1812
  void RemoveElementsAtUnsafe(index_type aStart, size_type aCount);
1813
1814
public:
1815
  // A variation on the RemoveElementsAt method defined above.
1816
100
  void RemoveElementAt(index_type aIndex) { RemoveElementsAt(aIndex, 1); }
Unexecuted instantiation: nsTArray_Impl<mozilla::CycleCollectedJSContext::PendingIDBTransactionData, nsTArrayInfallibleAllocator>::RemoveElementAt(unsigned long)
nsTArray_Impl<nsComponentManagerImpl::PendingServiceInfo, nsTArrayInfallibleAllocator>::RemoveElementAt(unsigned long)
Line
Count
Source
1816
100
  void RemoveElementAt(index_type aIndex) { RemoveElementsAt(aIndex, 1); }
1817
1818
  // A variation on the RemoveElementAt that removes the last element.
1819
0
  void RemoveLastElement() { RemoveElementAt(Length() - 1); }
1820
1821
  // Removes the last element of the array and returns a copy of it.
1822
  MOZ_MUST_USE
1823
  elem_type PopLastElement()
1824
  {
1825
    elem_type elem = std::move(LastElement());
1826
    RemoveLastElement();
1827
    return elem;
1828
  }
1829
1830
  // This method performs index-based removals from an array without preserving
1831
  // the order of the array. This is useful if you are using the array as a
1832
  // set-like data structure.
1833
  //
1834
  // These removals are efficient, as they move as few elements as possible. At
1835
  // most N elements, where N is the number of removed elements, will have to
1836
  // be relocated.
1837
  //
1838
  // ## Examples
1839
  //
1840
  // When removing an element from the end of the array, it can be removed in
1841
  // place, by destroying it and decrementing the length.
1842
  //
1843
  // [ 1, 2, 3 ] => [ 1, 2 ]
1844
  //         ^
1845
  //
1846
  // When removing any other single element, it is removed by swapping it with
1847
  // the last element, and then decrementing the length as before.
1848
  //
1849
  // [ 1, 2, 3, 4, 5, 6 ]  => [ 1, 6, 3, 4, 5 ]
1850
  //      ^
1851
  //
1852
  // This method also supports efficiently removing a range of elements. If they
1853
  // are at the end, then they can all be removed like in the one element case.
1854
  //
1855
  // [ 1, 2, 3, 4, 5, 6 ] => [ 1, 2 ]
1856
  //         ^--------^
1857
  //
1858
  // If more elements are removed than exist after the removed section, the
1859
  // remaining elements will be shifted down like in a normal removal.
1860
  //
1861
  // [ 1, 2, 3, 4, 5, 6, 7, 8 ] => [ 1, 2, 7, 8 ]
1862
  //         ^--------^
1863
  //
1864
  // And if fewer elements are removed than exist after the removed section,
1865
  // elements will be moved from the end of the array to fill the vacated space.
1866
  //
1867
  // [ 1, 2, 3, 4, 5, 6, 7, 8 ] => [ 1, 7, 8, 4, 5, 6 ]
1868
  //      ^--^
1869
  //
1870
  // @param aStart The starting index of the elements to remove. @param aCount
1871
  // The number of elements to remove.
1872
  void UnorderedRemoveElementsAt(index_type aStart, size_type aCount);
1873
1874
  // A variation on the UnorderedRemoveElementsAt method defined above to remove
1875
  // a single element. This operation is sometimes called `SwapRemove`.
1876
  //
1877
  // This method is O(1), but does not preserve the order of the elements.
1878
  void UnorderedRemoveElementAt(index_type aIndex) {
1879
    UnorderedRemoveElementsAt(aIndex, 1);
1880
  }
1881
1882
18
  void Clear() {
1883
18
    ClearAndRetainStorage();
1884
18
    Compact();
1885
18
  }
Unexecuted instantiation: nsTArray_Impl<nsCOMPtr<nsIRunnable>, nsTArrayInfallibleAllocator>::Clear()
nsTArray_Impl<mozilla::DeferredFinalizeFunctionHolder, nsTArrayInfallibleAllocator>::Clear()
Line
Count
Source
1882
18
  void Clear() {
1883
18
    ClearAndRetainStorage();
1884
18
    Compact();
1885
18
  }
Unexecuted instantiation: nsTArray_Impl<RefPtr<nsAtom>, nsTArrayInfallibleAllocator>::Clear()
Unexecuted instantiation: nsTArray_Impl<nsAutoPtr<nsComponentManagerImpl::KnownModule>, nsTArrayInfallibleAllocator>::Clear()
1886
1887
  // This method removes elements based on the return value of the
1888
  // callback function aPredicate. If the function returns true for
1889
  // an element, the element is removed. aPredicate will be called
1890
  // for each element in order. It is not safe to access the array
1891
  // inside aPredicate.
1892
  template<typename Predicate>
1893
  void RemoveElementsBy(Predicate aPredicate);
1894
1895
  // This helper function combines IndexOf with RemoveElementAt to "search
1896
  // and destroy" the first element that is equal to the given element.
1897
  // @param aItem The item to search for.
1898
  // @param aComp The Comparator used to determine element equality.
1899
  // @return true if the element was found
1900
  template<class Item, class Comparator>
1901
  bool RemoveElement(const Item& aItem, const Comparator& aComp)
1902
0
  {
1903
0
    index_type i = IndexOf(aItem, 0, aComp);
1904
0
    if (i == NoIndex) {
1905
0
      return false;
1906
0
    }
1907
0
1908
0
    RemoveElementsAtUnsafe(i, 1);
1909
0
    return true;
1910
0
  }
1911
1912
  // A variation on the RemoveElement method defined above that assumes
1913
  // that 'operator==' is defined for elem_type.
1914
  template<class Item>
1915
  bool RemoveElement(const Item& aItem)
1916
  {
1917
    return RemoveElement(aItem, nsDefaultComparator<elem_type, Item>());
1918
  }
1919
1920
  // This helper function combines IndexOfFirstElementGt with
1921
  // RemoveElementAt to "search and destroy" the last element that
1922
  // is equal to the given element.
1923
  // @param aItem The item to search for.
1924
  // @param aComp The Comparator used to determine element equality.
1925
  // @return true if the element was found
1926
  template<class Item, class Comparator>
1927
  bool RemoveElementSorted(const Item& aItem, const Comparator& aComp)
1928
  {
1929
    index_type index = IndexOfFirstElementGt(aItem, aComp);
1930
    if (index > 0 && aComp.Equals(ElementAt(index - 1), aItem)) {
1931
      RemoveElementsAtUnsafe(index - 1, 1);
1932
      return true;
1933
    }
1934
    return false;
1935
  }
1936
1937
  // A variation on the RemoveElementSorted method defined above.
1938
  template<class Item>
1939
  bool RemoveElementSorted(const Item& aItem)
1940
  {
1941
    return RemoveElementSorted(aItem, nsDefaultComparator<elem_type, Item>());
1942
  }
1943
1944
  // This method causes the elements contained in this array and the given
1945
  // array to be swapped.
1946
  template<class Allocator>
1947
  typename Alloc::ResultType SwapElements(nsTArray_Impl<E, Allocator>& aOther)
1948
0
  {
1949
0
    return Alloc::Result(this->template SwapArrayElements<Alloc>(
1950
0
      aOther, sizeof(elem_type), MOZ_ALIGNOF(elem_type)));
1951
0
  }
1952
1953
private:
1954
  // Used by ApplyIf functions to invoke a callable that takes either:
1955
  // - Nothing: F(void)
1956
  // - Index only: F(size_t)
1957
  // - Reference to element only: F(maybe-const elem_type&)
1958
  // - Both index and reference: F(size_t, maybe-const elem_type&)
1959
  // `elem_type` must be const when called from const method.
1960
  template<typename T, typename Param0, typename Param1>
1961
  struct InvokeWithIndexAndOrReferenceHelper
1962
  {
1963
    static constexpr bool valid = false;
1964
  };
1965
  template<typename T>
1966
  struct InvokeWithIndexAndOrReferenceHelper<T, void, void>
1967
  {
1968
    static constexpr bool valid = true;
1969
    template<typename F>
1970
0
    static auto Invoke(F&& f, size_t, T&) { return f(); }
Unexecuted instantiation: auto nsTArray_Impl<unsigned int, nsTArrayInfallibleAllocator>::InvokeWithIndexAndOrReferenceHelper<unsigned int const, void, void>::Invoke<bool nsTArray_Impl<unsigned int, nsTArrayInfallibleAllocator>::Contains<unsigned int, nsDefaultComparator<unsigned int, unsigned int> >(unsigned int const&, nsDefaultComparator<unsigned int, unsigned int> const&) const::{lambda()#1}>(bool nsTArray_Impl<unsigned int, nsTArrayInfallibleAllocator>::Contains<unsigned int, nsDefaultComparator<unsigned int, unsigned int> >(unsigned int const&, nsDefaultComparator<unsigned int, unsigned int> const&) const::{lambda()#1}&&, unsigned long, unsigned int const&)
Unexecuted instantiation: auto nsTArray_Impl<RefPtr<nsAtom>, nsTArrayInfallibleAllocator>::InvokeWithIndexAndOrReferenceHelper<RefPtr<nsAtom> const, void, void>::Invoke<bool nsTArray_Impl<RefPtr<nsAtom>, nsTArrayInfallibleAllocator>::Contains<nsTSubstring<char16_t>, AtomArrayStringComparator>(nsTSubstring<char16_t> const&, AtomArrayStringComparator const&) const::{lambda()#1}>(bool nsTArray_Impl<RefPtr<nsAtom>, nsTArrayInfallibleAllocator>::Contains<nsTSubstring<char16_t>, AtomArrayStringComparator>(nsTSubstring<char16_t> const&, AtomArrayStringComparator const&) const::{lambda()#1}&&, unsigned long, RefPtr<nsAtom> const&)
1971
  };
1972
  template<typename T>
1973
  struct InvokeWithIndexAndOrReferenceHelper<T, size_t, void>
1974
  {
1975
    static constexpr bool valid = true;
1976
    template<typename F>
1977
    static auto Invoke(F&& f, size_t i, T&) { return f(i); }
1978
  };
1979
  template<typename T>
1980
  struct InvokeWithIndexAndOrReferenceHelper<T, T&, void>
1981
  {
1982
    static constexpr bool valid = true;
1983
    template<typename F>
1984
    static auto Invoke(F&& f, size_t, T& e) { return f(e); }
1985
  };
1986
  template<typename T>
1987
  struct InvokeWithIndexAndOrReferenceHelper<T, const T&, void>
1988
  {
1989
    static constexpr bool valid = true;
1990
    template<typename F>
1991
    static auto Invoke(F&& f, size_t, T& e) { return f(e); }
1992
  };
1993
  template<typename T>
1994
  struct InvokeWithIndexAndOrReferenceHelper<T, size_t, T&>
1995
  {
1996
    static constexpr bool valid = true;
1997
    template<typename F>
1998
    static auto Invoke(F&& f, size_t i, T& e) { return f(i, e); }
1999
  };
2000
  template<typename T>
2001
  struct InvokeWithIndexAndOrReferenceHelper<T, size_t, const T&>
2002
  {
2003
    static constexpr bool valid = true;
2004
    template<typename F>
2005
    static auto Invoke(F&& f, size_t i, T& e) { return f(i, e); }
2006
  };
2007
  template<typename T, typename F>
2008
  static auto InvokeWithIndexAndOrReference(F&& f, size_t i, T& e)
2009
0
  {
2010
0
    using Invoker =
2011
0
      InvokeWithIndexAndOrReferenceHelper<
2012
0
        T,
2013
0
        typename mozilla::FunctionTypeTraits<F>::template ParameterType<0>,
2014
0
        typename mozilla::FunctionTypeTraits<F>::template ParameterType<1>>;
2015
0
    static_assert(Invoker::valid,
2016
0
                  "ApplyIf's Function parameters must match either: (void), "
2017
0
                  "(size_t), (maybe-const elem_type&), or "
2018
0
                  "(size_t, maybe-const elem_type&)");
2019
0
    return Invoker::Invoke(std::forward<F>(f), i, e);
2020
0
  }
Unexecuted instantiation: auto nsTArray_Impl<unsigned int, nsTArrayInfallibleAllocator>::InvokeWithIndexAndOrReference<unsigned int const, bool nsTArray_Impl<unsigned int, nsTArrayInfallibleAllocator>::Contains<unsigned int, nsDefaultComparator<unsigned int, unsigned int> >(unsigned int const&, nsDefaultComparator<unsigned int, unsigned int> const&) const::{lambda()#1}>(bool nsTArray_Impl<unsigned int, nsTArrayInfallibleAllocator>::Contains<unsigned int, nsDefaultComparator<unsigned int, unsigned int> >(unsigned int const&, nsDefaultComparator<unsigned int, unsigned int> const&) const::{lambda()#1}&&, unsigned long, unsigned int const&)
Unexecuted instantiation: auto nsTArray_Impl<RefPtr<nsAtom>, nsTArrayInfallibleAllocator>::InvokeWithIndexAndOrReference<RefPtr<nsAtom> const, bool nsTArray_Impl<RefPtr<nsAtom>, nsTArrayInfallibleAllocator>::Contains<nsTSubstring<char16_t>, AtomArrayStringComparator>(nsTSubstring<char16_t> const&, AtomArrayStringComparator const&) const::{lambda()#1}>(bool nsTArray_Impl<RefPtr<nsAtom>, nsTArrayInfallibleAllocator>::Contains<nsTSubstring<char16_t>, AtomArrayStringComparator>(nsTSubstring<char16_t> const&, AtomArrayStringComparator const&) const::{lambda()#1}&&, unsigned long, RefPtr<nsAtom> const&)
2021
2022
public:
2023
  // 'Apply' family of methods.
2024
  //
2025
  // The advantages of using Apply methods with lambdas include:
2026
  // - Safety of accessing elements from within the call, when the array cannot
2027
  //   have been modified between the iteration and the subsequent access.
2028
  // - Avoiding moot conversions: pointer->index during a search, followed by
2029
  //   index->pointer after the search when accessing the element.
2030
  // - Embedding your code into the algorithm, giving the compiler more chances
2031
  //   to optimize.
2032
2033
  // Search for the first element comparing equal to aItem with the given
2034
  // comparator (`==` by default).
2035
  // If such an element exists, return the result of evaluating either:
2036
  // - `aFunction()`
2037
  // - `aFunction(index_type)`
2038
  // - `aFunction(maybe-const? elem_type&)`
2039
  // - `aFunction(index_type, maybe-const? elem_type&)`
2040
  // (`aFunction` must have one of the above signatures with these exact types,
2041
  //  including references; implicit conversions or generic types not allowed.
2042
  //  If `this` array is const, the referenced `elem_type` must be const too;
2043
  //  otherwise it may be either const or non-const.)
2044
  // But if the element is not found, return the result of evaluating
2045
  // `aFunctionElse()`.
2046
  template<class Item, class Comparator, class Function, class FunctionElse>
2047
  auto ApplyIf(const Item& aItem, index_type aStart,
2048
               const Comparator& aComp,
2049
               Function&& aFunction, FunctionElse&& aFunctionElse) const
2050
0
  {
2051
0
    static_assert(
2052
0
      mozilla::IsSame<
2053
0
        typename mozilla::FunctionTypeTraits<Function>::ReturnType,
2054
0
        typename mozilla::FunctionTypeTraits<FunctionElse>::ReturnType>::value,
2055
0
      "ApplyIf's `Function` and `FunctionElse` must return the same type.");
2056
0
2057
0
    ::detail::CompareWrapper<Comparator, Item> comp(aComp);
2058
0
2059
0
    const elem_type* const elements = Elements();
2060
0
    const elem_type* const iend = elements + Length();
2061
0
    for (const elem_type* iter = elements + aStart; iter != iend; ++iter) {
2062
0
      if (comp.Equals(*iter, aItem)) {
2063
0
        return InvokeWithIndexAndOrReference<const elem_type>(
2064
0
                 std::forward<Function>(aFunction), iter - elements, *iter);
2065
0
      }
2066
0
    }
2067
0
    return aFunctionElse();
2068
0
  }
Unexecuted instantiation: auto nsTArray_Impl<unsigned int, nsTArrayInfallibleAllocator>::ApplyIf<unsigned int, nsDefaultComparator<unsigned int, unsigned int>, bool nsTArray_Impl<unsigned int, nsTArrayInfallibleAllocator>::Contains<unsigned int, nsDefaultComparator<unsigned int, unsigned int> >(unsigned int const&, nsDefaultComparator<unsigned int, unsigned int> const&) const::{lambda()#1}, bool nsTArray_Impl<unsigned int, nsTArrayInfallibleAllocator>::Contains<unsigned int, nsDefaultComparator<unsigned int, unsigned int> >(unsigned int const&, nsDefaultComparator<unsigned int, unsigned int> const&) const::{lambda()#2}>(unsigned int const&, unsigned long, nsDefaultComparator<unsigned int, unsigned int> const&, bool nsTArray_Impl<unsigned int, nsTArrayInfallibleAllocator>::Contains<unsigned int, nsDefaultComparator<unsigned int, unsigned int> >(unsigned int const&, nsDefaultComparator<unsigned int, unsigned int> const&) const::{lambda()#1}&&, bool nsTArray_Impl<unsigned int, nsTArrayInfallibleAllocator>::Contains<unsigned int, nsDefaultComparator<unsigned int, unsigned int> >(unsigned int const&, nsDefaultComparator<unsigned int, unsigned int> const&) const::{lambda()#2}&&) const
Unexecuted instantiation: auto nsTArray_Impl<RefPtr<nsAtom>, nsTArrayInfallibleAllocator>::ApplyIf<nsTSubstring<char16_t>, AtomArrayStringComparator, bool nsTArray_Impl<RefPtr<nsAtom>, nsTArrayInfallibleAllocator>::Contains<nsTSubstring<char16_t>, AtomArrayStringComparator>(nsTSubstring<char16_t> const&, AtomArrayStringComparator const&) const::{lambda()#1}, bool nsTArray_Impl<RefPtr<nsAtom>, nsTArrayInfallibleAllocator>::Contains<nsTSubstring<char16_t>, AtomArrayStringComparator>(nsTSubstring<char16_t> const&, AtomArrayStringComparator const&) const::{lambda()#2}>(nsTSubstring<char16_t> const&, unsigned long, AtomArrayStringComparator const&, bool nsTArray_Impl<RefPtr<nsAtom>, nsTArrayInfallibleAllocator>::Contains<nsTSubstring<char16_t>, AtomArrayStringComparator>(nsTSubstring<char16_t> const&, AtomArrayStringComparator const&) const::{lambda()#1}&&, bool nsTArray_Impl<RefPtr<nsAtom>, nsTArrayInfallibleAllocator>::Contains<nsTSubstring<char16_t>, AtomArrayStringComparator>(nsTSubstring<char16_t> const&, AtomArrayStringComparator const&) const::{lambda()#2}&&) const
2069
  template<class Item, class Comparator, class Function, class FunctionElse>
2070
  auto ApplyIf(const Item& aItem, index_type aStart,
2071
               const Comparator& aComp,
2072
               Function&& aFunction, FunctionElse&& aFunctionElse)
2073
  {
2074
    static_assert(
2075
      mozilla::IsSame<
2076
        typename mozilla::FunctionTypeTraits<Function>::ReturnType,
2077
        typename mozilla::FunctionTypeTraits<FunctionElse>::ReturnType>::value,
2078
      "ApplyIf's `Function` and `FunctionElse` must return the same type.");
2079
2080
    ::detail::CompareWrapper<Comparator, Item> comp(aComp);
2081
2082
    elem_type* const elements = Elements();
2083
    elem_type* const iend = elements + Length();
2084
    for (elem_type* iter = elements + aStart; iter != iend; ++iter) {
2085
      if (comp.Equals(*iter, aItem)) {
2086
        return InvokeWithIndexAndOrReference<elem_type>(
2087
                 std::forward<Function>(aFunction), iter - elements, *iter);
2088
      }
2089
    }
2090
    return aFunctionElse();
2091
  }
2092
  template<class Item, class Function, class FunctionElse>
2093
  auto ApplyIf(const Item& aItem, index_type aStart,
2094
               Function&& aFunction, FunctionElse&& aFunctionElse) const
2095
  {
2096
    return ApplyIf(aItem,
2097
                   aStart,
2098
                   nsDefaultComparator<elem_type, Item>(),
2099
                   std::forward<Function>(aFunction),
2100
                   std::forward<FunctionElse>(aFunctionElse));
2101
  }
2102
  template<class Item, class Function, class FunctionElse>
2103
  auto ApplyIf(const Item& aItem, index_type aStart,
2104
               Function&& aFunction, FunctionElse&& aFunctionElse)
2105
  {
2106
    return ApplyIf(aItem,
2107
                   aStart,
2108
                   nsDefaultComparator<elem_type, Item>(),
2109
                   std::forward<Function>(aFunction),
2110
                   std::forward<FunctionElse>(aFunctionElse));
2111
  }
2112
  template<class Item, class Function, class FunctionElse>
2113
  auto ApplyIf(const Item& aItem,
2114
               Function&& aFunction, FunctionElse&& aFunctionElse) const
2115
  {
2116
    return ApplyIf(aItem,
2117
                   0,
2118
                   std::forward<Function>(aFunction),
2119
                   std::forward<FunctionElse>(aFunctionElse));
2120
  }
2121
  template<class Item, class Function, class FunctionElse>
2122
  auto ApplyIf(const Item& aItem,
2123
               Function&& aFunction, FunctionElse&& aFunctionElse)
2124
  {
2125
    return ApplyIf(aItem,
2126
                   0,
2127
                   std::forward<Function>(aFunction),
2128
                   std::forward<FunctionElse>(aFunctionElse));
2129
  }
2130
2131
  //
2132
  // Allocation
2133
  //
2134
2135
  // This method may increase the capacity of this array object to the
2136
  // specified amount.  This method may be called in advance of several
2137
  // AppendElement operations to minimize heap re-allocations.  This method
2138
  // will not reduce the number of elements in this array.
2139
  // @param aCapacity The desired capacity of this array.
2140
  // @return True if the operation succeeded; false if we ran out of memory
2141
protected:
2142
  template<typename ActualAlloc = Alloc>
2143
  typename ActualAlloc::ResultType SetCapacity(size_type aCapacity)
2144
0
  {
2145
0
    return ActualAlloc::Result(this->template EnsureCapacity<ActualAlloc>(
2146
0
      aCapacity, sizeof(elem_type)));
2147
0
  }
2148
public:
2149
2150
  MOZ_MUST_USE
2151
  bool SetCapacity(size_type aCapacity, const mozilla::fallible_t&)
2152
  {
2153
    return SetCapacity<FallibleAlloc>(aCapacity);
2154
  }
2155
2156
  // This method modifies the length of the array.  If the new length is
2157
  // larger than the existing length of the array, then new elements will be
2158
  // constructed using elem_type's default constructor.  Otherwise, this call
2159
  // removes elements from the array (see also RemoveElementsAt).
2160
  // @param aNewLen The desired length of this array.
2161
  // @return True if the operation succeeded; false otherwise.
2162
  // See also TruncateLength if the new length is guaranteed to be smaller than
2163
  // the old.
2164
protected:
2165
  template<typename ActualAlloc = Alloc>
2166
  typename ActualAlloc::ResultType SetLength(size_type aNewLen)
2167
  {
2168
    size_type oldLen = Length();
2169
    if (aNewLen > oldLen) {
2170
      return ActualAlloc::ConvertBoolToResultType(
2171
        InsertElementsAt<ActualAlloc>(oldLen, aNewLen - oldLen) != nullptr);
2172
    }
2173
2174
    TruncateLength(aNewLen);
2175
    return ActualAlloc::ConvertBoolToResultType(true);
2176
  }
2177
public:
2178
2179
  MOZ_MUST_USE
2180
  bool SetLength(size_type aNewLen, const mozilla::fallible_t&)
2181
  {
2182
    return SetLength<FallibleAlloc>(aNewLen);
2183
  }
2184
2185
  // This method modifies the length of the array, but may only be
2186
  // called when the new length is shorter than the old.  It can
2187
  // therefore be called when elem_type has no default constructor,
2188
  // unlike SetLength.  It removes elements from the array (see also
2189
  // RemoveElementsAt).
2190
  // @param aNewLen The desired length of this array.
2191
  void TruncateLength(size_type aNewLen)
2192
0
  {
2193
0
    size_type oldLen = Length();
2194
0
    MOZ_ASSERT(aNewLen <= oldLen,
2195
0
               "caller should use SetLength instead");
2196
0
    RemoveElementsAt(aNewLen, oldLen - aNewLen);
2197
0
  }
2198
2199
  // This method ensures that the array has length at least the given
2200
  // length.  If the current length is shorter than the given length,
2201
  // then new elements will be constructed using elem_type's default
2202
  // constructor.
2203
  // @param aMinLen The desired minimum length of this array.
2204
  // @return True if the operation succeeded; false otherwise.
2205
protected:
2206
  template<typename ActualAlloc = Alloc>
2207
  typename ActualAlloc::ResultType EnsureLengthAtLeast(size_type aMinLen)
2208
  {
2209
    size_type oldLen = Length();
2210
    if (aMinLen > oldLen) {
2211
      return ActualAlloc::ConvertBoolToResultType(
2212
        !!InsertElementsAt<ActualAlloc>(oldLen, aMinLen - oldLen));
2213
    }
2214
    return ActualAlloc::ConvertBoolToResultType(true);
2215
  }
2216
public:
2217
2218
  MOZ_MUST_USE
2219
  bool EnsureLengthAtLeast(size_type aMinLen, const mozilla::fallible_t&)
2220
  {
2221
    return EnsureLengthAtLeast<FallibleAlloc>(aMinLen);
2222
  }
2223
2224
  // This method inserts elements into the array, constructing
2225
  // them using elem_type's default constructor.
2226
  // @param aIndex the place to insert the new elements. This must be no
2227
  //               greater than the current length of the array.
2228
  // @param aCount the number of elements to insert
2229
protected:
2230
  template<typename ActualAlloc = Alloc>
2231
  elem_type* InsertElementsAt(index_type aIndex, size_type aCount)
2232
  {
2233
    if (!base_type::template InsertSlotsAt<ActualAlloc>(aIndex, aCount,
2234
                                                        sizeof(elem_type),
2235
                                                        MOZ_ALIGNOF(elem_type))) {
2236
      return nullptr;
2237
    }
2238
2239
    // Initialize the extra array elements
2240
    elem_type* iter = Elements() + aIndex;
2241
    elem_type* iend = iter + aCount;
2242
    for (; iter != iend; ++iter) {
2243
      elem_traits::Construct(iter);
2244
    }
2245
2246
    return Elements() + aIndex;
2247
  }
2248
public:
2249
2250
  MOZ_MUST_USE
2251
  elem_type* InsertElementsAt(index_type aIndex, size_type aCount,
2252
                              const mozilla::fallible_t&)
2253
  {
2254
    return InsertElementsAt<FallibleAlloc>(aIndex, aCount);
2255
  }
2256
2257
  // This method inserts elements into the array, constructing them
2258
  // elem_type's copy constructor (or whatever one-arg constructor
2259
  // happens to match the Item type).
2260
  // @param aIndex the place to insert the new elements. This must be no
2261
  //               greater than the current length of the array.
2262
  // @param aCount the number of elements to insert.
2263
  // @param aItem the value to use when constructing the new elements.
2264
protected:
2265
  template<class Item, typename ActualAlloc = Alloc>
2266
  elem_type* InsertElementsAt(index_type aIndex, size_type aCount,
2267
                              const Item& aItem);
2268
2269
public:
2270
2271
  template<class Item>
2272
  MOZ_MUST_USE
2273
  elem_type* InsertElementsAt(index_type aIndex, size_type aCount,
2274
                              const Item& aItem, const mozilla::fallible_t&)
2275
  {
2276
    return InsertElementsAt<Item, FallibleAlloc>(aIndex, aCount, aItem);
2277
  }
2278
2279
  // This method may be called to minimize the memory used by this array.
2280
  void Compact()
2281
18
  {
2282
18
    ShrinkCapacity(sizeof(elem_type), MOZ_ALIGNOF(elem_type));
2283
18
  }
Unexecuted instantiation: nsTArray_Impl<nsCOMPtr<nsIRunnable>, nsTArrayInfallibleAllocator>::Compact()
nsTArray_Impl<mozilla::DeferredFinalizeFunctionHolder, nsTArrayInfallibleAllocator>::Compact()
Line
Count
Source
2281
18
  {
2282
18
    ShrinkCapacity(sizeof(elem_type), MOZ_ALIGNOF(elem_type));
2283
18
  }
Unexecuted instantiation: nsTArray_Impl<RefPtr<nsAtom>, nsTArrayInfallibleAllocator>::Compact()
Unexecuted instantiation: nsTArray_Impl<nsAutoPtr<nsComponentManagerImpl::KnownModule>, nsTArrayInfallibleAllocator>::Compact()
2284
2285
  //
2286
  // Sorting
2287
  //
2288
2289
  // This function is meant to be used with the NS_QuickSort function.  It
2290
  // maps the callback API expected by NS_QuickSort to the Comparator API
2291
  // used by nsTArray_Impl.  See nsTArray_Impl::Sort.
2292
  template<class Comparator>
2293
  static int Compare(const void* aE1, const void* aE2, void* aData)
2294
0
  {
2295
0
    const Comparator* c = reinterpret_cast<const Comparator*>(aData);
2296
0
    const elem_type* a = static_cast<const elem_type*>(aE1);
2297
0
    const elem_type* b = static_cast<const elem_type*>(aE2);
2298
0
    return c->Compare(*a, *b);
2299
0
  }
2300
2301
  // This method sorts the elements of the array.  It uses the LessThan
2302
  // method defined on the given Comparator object to collate elements.
2303
  // @param aComp The Comparator used to collate elements.
2304
  template<class Comparator>
2305
  void Sort(const Comparator& aComp)
2306
0
  {
2307
0
    ::detail::CompareWrapper<Comparator, elem_type> comp(aComp);
2308
0
2309
0
    NS_QuickSort(Elements(), Length(), sizeof(elem_type),
2310
0
                 Compare<decltype(comp)>, &comp);
2311
0
  }
2312
2313
  // A variation on the Sort method defined above that assumes that
2314
  // 'operator<' is defined for elem_type.
2315
0
  void Sort() { Sort(nsDefaultComparator<elem_type, elem_type>()); }
2316
2317
  // This method reverses the array in place.
2318
  void Reverse()
2319
  {
2320
    elem_type* elements = Elements();
2321
    const size_type len = Length();
2322
    for (index_type i = 0, iend = len / 2; i < iend; ++i) {
2323
      mozilla::Swap(elements[i], elements[len - i - 1]);
2324
    }
2325
  }
2326
2327
protected:
2328
  using base_type::Hdr;
2329
  using base_type::ShrinkCapacity;
2330
2331
  // This method invokes elem_type's destructor on a range of elements.
2332
  // @param aStart The index of the first element to destroy.
2333
  // @param aCount The number of elements to destroy.
2334
  void DestructRange(index_type aStart, size_type aCount)
2335
118
  {
2336
118
    elem_type* iter = Elements() + aStart;
2337
118
    elem_type *iend = iter + aCount;
2338
236
    for (; iter != iend; ++iter) {
2339
118
      elem_traits::Destruct(iter);
2340
118
    }
2341
118
  }
Unexecuted instantiation: nsTArray_Impl<mozilla::CycleCollectedJSContext::PendingIDBTransactionData, nsTArrayInfallibleAllocator>::DestructRange(unsigned long, unsigned long)
Unexecuted instantiation: nsTArray_Impl<nsCOMPtr<nsIRunnable>, nsTArrayInfallibleAllocator>::DestructRange(unsigned long, unsigned long)
Unexecuted instantiation: nsTArray_Impl<nsCOMPtr<nsISupports>, nsTArrayInfallibleAllocator>::DestructRange(unsigned long, unsigned long)
nsTArray_Impl<mozilla::DeferredFinalizeFunctionHolder, nsTArrayInfallibleAllocator>::DestructRange(unsigned long, unsigned long)
Line
Count
Source
2335
18
  {
2336
18
    elem_type* iter = Elements() + aStart;
2337
18
    elem_type *iend = iter + aCount;
2338
36
    for (; iter != iend; ++iter) {
2339
18
      elem_traits::Destruct(iter);
2340
18
    }
2341
18
  }
Unexecuted instantiation: nsTArray_Impl<mozilla::UniquePtr<mozilla::TokenizerBase<char>::Token, mozilla::DefaultDelete<mozilla::TokenizerBase<char>::Token> >, nsTArrayInfallibleAllocator>::DestructRange(unsigned long, unsigned long)
Unexecuted instantiation: nsTArray_Impl<mozilla::dom::ContentParent*, nsTArrayInfallibleAllocator>::DestructRange(unsigned long, unsigned long)
Unexecuted instantiation: nsTArray_Impl<RefPtr<mozilla::MemoryReportingProcess>, nsTArrayInfallibleAllocator>::DestructRange(unsigned long, unsigned long)
Unexecuted instantiation: nsTArray_Impl<mozilla::MemoryMapping, nsTArrayInfallibleAllocator>::DestructRange(unsigned long, unsigned long)
Unexecuted instantiation: nsTArray_Impl<BloatEntry*, nsTArrayInfallibleAllocator>::DestructRange(unsigned long, unsigned long)
Unexecuted instantiation: nsTArray_Impl<ThreadsReporter::CollectReports(nsIHandleReportCallback*, nsISupports*, bool)::ThreadData, nsTArrayInfallibleAllocator>::DestructRange(unsigned long, unsigned long)
Unexecuted instantiation: Unified_cpp_xpcom_components0.cpp:nsTArray_Impl<(anonymous namespace)::CachedDirective, nsTArrayInfallibleAllocator>::DestructRange(unsigned long, unsigned long)
Unexecuted instantiation: nsTArray_Impl<mozilla::Module const*, nsTArrayInfallibleAllocator>::DestructRange(unsigned long, unsigned long)
Unexecuted instantiation: nsTArray_Impl<nsComponentManagerImpl::ComponentLocation, nsTArrayInfallibleAllocator>::DestructRange(unsigned long, unsigned long)
nsTArray_Impl<nsComponentManagerImpl::PendingServiceInfo, nsTArrayInfallibleAllocator>::DestructRange(unsigned long, unsigned long)
Line
Count
Source
2335
100
  {
2336
100
    elem_type* iter = Elements() + aStart;
2337
100
    elem_type *iend = iter + aCount;
2338
200
    for (; iter != iend; ++iter) {
2339
100
      elem_traits::Destruct(iter);
2340
100
    }
2341
100
  }
Unexecuted instantiation: nsTArray_Impl<nsAutoPtr<nsComponentManagerImpl::KnownModule>, nsTArrayInfallibleAllocator>::DestructRange(unsigned long, unsigned long)
Unexecuted instantiation: nsTArray_Impl<mozilla::dom::StringBundleDescriptor, nsTArrayInfallibleAllocator>::DestructRange(unsigned long, unsigned long)
Unexecuted instantiation: nsTArray_Impl<nsAttrValue::EnumTable const*, nsTArrayInfallibleAllocator>::DestructRange(unsigned long, unsigned long)
2342
2343
  // This method invokes elem_type's copy-constructor on a range of elements.
2344
  // @param aStart  The index of the first element to construct.
2345
  // @param aCount  The number of elements to construct.
2346
  // @param aValues The array of elements to copy.
2347
  template<class Item>
2348
  void AssignRange(index_type aStart, size_type aCount, const Item* aValues)
2349
0
  {
2350
0
    AssignRangeAlgorithm<mozilla::IsPod<Item>::value,
2351
0
                         mozilla::IsSame<Item, elem_type>::value>
2352
0
                         ::implementation(Elements(), aStart, aCount, aValues);
2353
0
  }
Unexecuted instantiation: void nsTArray_Impl<mozilla::CycleCollectedJSContext::PendingIDBTransactionData, nsTArrayInfallibleAllocator>::AssignRange<mozilla::CycleCollectedJSContext::PendingIDBTransactionData>(unsigned long, unsigned long, mozilla::CycleCollectedJSContext::PendingIDBTransactionData const*)
Unexecuted instantiation: void nsTArray_Impl<RefPtr<nsAtom>, nsTArrayInfallibleAllocator>::AssignRange<RefPtr<nsAtom> >(unsigned long, unsigned long, RefPtr<nsAtom> const*)
2354
};
2355
2356
template<typename E, class Alloc>
2357
template<class Item, typename ActualAlloc>
2358
auto
2359
nsTArray_Impl<E, Alloc>::ReplaceElementsAt(index_type aStart, size_type aCount,
2360
                                           const Item* aArray, size_type aArrayLen) -> elem_type*
2361
{
2362
  if (MOZ_UNLIKELY(aStart > Length())) {
2363
    InvalidArrayIndex_CRASH(aStart, Length());
2364
  }
2365
2366
  // Adjust memory allocation up-front to catch errors.
2367
  if (!ActualAlloc::Successful(this->template EnsureCapacity<ActualAlloc>(
2368
        Length() + aArrayLen - aCount, sizeof(elem_type)))) {
2369
    return nullptr;
2370
  }
2371
  DestructRange(aStart, aCount);
2372
  this->template ShiftData<ActualAlloc>(aStart, aCount, aArrayLen,
2373
                                        sizeof(elem_type),
2374
                                        MOZ_ALIGNOF(elem_type));
2375
  AssignRange(aStart, aArrayLen, aArray);
2376
  return Elements() + aStart;
2377
}
2378
2379
template<typename E, class Alloc>
2380
void
2381
nsTArray_Impl<E, Alloc>::RemoveElementsAt(index_type aStart, size_type aCount)
2382
100
{
2383
100
  MOZ_ASSERT(aCount == 0 || aStart < Length(), "Invalid aStart index");
2384
100
2385
100
  mozilla::CheckedInt<index_type> rangeEnd = aStart;
2386
100
  rangeEnd += aCount;
2387
100
2388
100
  if (MOZ_UNLIKELY(!rangeEnd.isValid() || rangeEnd.value() > Length())) {
2389
0
    InvalidArrayIndex_CRASH(aStart, Length());
2390
0
  }
2391
100
2392
100
  RemoveElementsAtUnsafe(aStart, aCount);
2393
100
}
Unexecuted instantiation: nsTArray_Impl<mozilla::CycleCollectedJSContext::PendingIDBTransactionData, nsTArrayInfallibleAllocator>::RemoveElementsAt(unsigned long, unsigned long)
Unexecuted instantiation: nsTArray_Impl<RefPtr<mozilla::MemoryReportingProcess>, nsTArrayInfallibleAllocator>::RemoveElementsAt(unsigned long, unsigned long)
nsTArray_Impl<nsComponentManagerImpl::PendingServiceInfo, nsTArrayInfallibleAllocator>::RemoveElementsAt(unsigned long, unsigned long)
Line
Count
Source
2382
100
{
2383
100
  MOZ_ASSERT(aCount == 0 || aStart < Length(), "Invalid aStart index");
2384
100
2385
100
  mozilla::CheckedInt<index_type> rangeEnd = aStart;
2386
100
  rangeEnd += aCount;
2387
100
2388
100
  if (MOZ_UNLIKELY(!rangeEnd.isValid() || rangeEnd.value() > Length())) {
2389
0
    InvalidArrayIndex_CRASH(aStart, Length());
2390
0
  }
2391
100
2392
100
  RemoveElementsAtUnsafe(aStart, aCount);
2393
100
}
2394
2395
template<typename E, class Alloc>
2396
void
2397
nsTArray_Impl<E, Alloc>::RemoveElementsAtUnsafe(index_type aStart, size_type aCount)
2398
100
{
2399
100
  DestructRange(aStart, aCount);
2400
100
  this->template ShiftData<InfallibleAlloc>(aStart, aCount, 0,
2401
100
                                            sizeof(elem_type),
2402
100
                                            MOZ_ALIGNOF(elem_type));
2403
100
}
Unexecuted instantiation: nsTArray_Impl<mozilla::CycleCollectedJSContext::PendingIDBTransactionData, nsTArrayInfallibleAllocator>::RemoveElementsAtUnsafe(unsigned long, unsigned long)
Unexecuted instantiation: nsTArray_Impl<RefPtr<mozilla::MemoryReportingProcess>, nsTArrayInfallibleAllocator>::RemoveElementsAtUnsafe(unsigned long, unsigned long)
nsTArray_Impl<nsComponentManagerImpl::PendingServiceInfo, nsTArrayInfallibleAllocator>::RemoveElementsAtUnsafe(unsigned long, unsigned long)
Line
Count
Source
2398
100
{
2399
100
  DestructRange(aStart, aCount);
2400
100
  this->template ShiftData<InfallibleAlloc>(aStart, aCount, 0,
2401
100
                                            sizeof(elem_type),
2402
100
                                            MOZ_ALIGNOF(elem_type));
2403
100
}
Unexecuted instantiation: nsTArray_Impl<nsComponentManagerImpl::ComponentLocation, nsTArrayInfallibleAllocator>::RemoveElementsAtUnsafe(unsigned long, unsigned long)
2404
2405
template<typename E, class Alloc>
2406
void
2407
nsTArray_Impl<E, Alloc>::UnorderedRemoveElementsAt(index_type aStart, size_type aCount)
2408
{
2409
  MOZ_ASSERT(aCount == 0 || aStart < Length(), "Invalid aStart index");
2410
2411
  mozilla::CheckedInt<index_type> rangeEnd = aStart;
2412
  rangeEnd += aCount;
2413
2414
  if (MOZ_UNLIKELY(!rangeEnd.isValid() || rangeEnd.value() > Length())) {
2415
    InvalidArrayIndex_CRASH(aStart, Length());
2416
  }
2417
2418
  // Destroy the elements which are being removed, and then swap elements in to
2419
  // replace them from the end. See the docs on the declaration of this
2420
  // function.
2421
  DestructRange(aStart, aCount);
2422
  this->template SwapFromEnd<InfallibleAlloc>(aStart, aCount,
2423
                                              sizeof(elem_type),
2424
                                              MOZ_ALIGNOF(elem_type));
2425
}
2426
2427
template<typename E, class Alloc>
2428
template<typename Predicate>
2429
void
2430
nsTArray_Impl<E, Alloc>::RemoveElementsBy(Predicate aPredicate)
2431
{
2432
  if (base_type::mHdr == EmptyHdr()) {
2433
    return;
2434
  }
2435
2436
  index_type j = 0;
2437
  index_type len = Length();
2438
  for (index_type i = 0; i < len; ++i) {
2439
    if (aPredicate(Elements()[i])) {
2440
      elem_traits::Destruct(Elements() + i);
2441
    } else {
2442
      if (j < i) {
2443
        copy_type::MoveNonOverlappingRegion(Elements() + j, Elements() + i,
2444
                                            1, sizeof(elem_type));
2445
      }
2446
      ++j;
2447
    }
2448
  }
2449
  base_type::mHdr->mLength = j;
2450
}
2451
2452
template<typename E, class Alloc>
2453
template<class Item, typename ActualAlloc>
2454
auto
2455
nsTArray_Impl<E, Alloc>::InsertElementsAt(index_type aIndex, size_type aCount,
2456
                                          const Item& aItem) -> elem_type*
2457
{
2458
  if (!base_type::template InsertSlotsAt<ActualAlloc>(aIndex, aCount,
2459
                                                      sizeof(elem_type),
2460
                                                      MOZ_ALIGNOF(elem_type))) {
2461
    return nullptr;
2462
  }
2463
2464
  // Initialize the extra array elements
2465
  elem_type* iter = Elements() + aIndex;
2466
  elem_type* iend = iter + aCount;
2467
  for (; iter != iend; ++iter) {
2468
    elem_traits::Construct(iter, aItem);
2469
  }
2470
2471
  return Elements() + aIndex;
2472
}
2473
2474
template<typename E, class Alloc>
2475
template<typename ActualAlloc>
2476
auto
2477
nsTArray_Impl<E, Alloc>::InsertElementAt(index_type aIndex) -> elem_type*
2478
{
2479
  if (MOZ_UNLIKELY(aIndex > Length())) {
2480
    InvalidArrayIndex_CRASH(aIndex, Length());
2481
  }
2482
2483
  if (!ActualAlloc::Successful(this->template EnsureCapacity<ActualAlloc>(
2484
        Length() + 1, sizeof(elem_type)))) {
2485
    return nullptr;
2486
  }
2487
  this->template ShiftData<ActualAlloc>(aIndex, 0, 1, sizeof(elem_type),
2488
                                        MOZ_ALIGNOF(elem_type));
2489
  elem_type* elem = Elements() + aIndex;
2490
  elem_traits::Construct(elem);
2491
  return elem;
2492
}
2493
2494
template<typename E, class Alloc>
2495
template<class Item, typename ActualAlloc>
2496
auto
2497
nsTArray_Impl<E, Alloc>::InsertElementAt(index_type aIndex, Item&& aItem) -> elem_type*
2498
{
2499
  if (MOZ_UNLIKELY(aIndex > Length())) {
2500
    InvalidArrayIndex_CRASH(aIndex, Length());
2501
  }
2502
2503
  if (!ActualAlloc::Successful(this->template EnsureCapacity<ActualAlloc>(
2504
         Length() + 1, sizeof(elem_type)))) {
2505
    return nullptr;
2506
  }
2507
  this->template ShiftData<ActualAlloc>(aIndex, 0, 1, sizeof(elem_type),
2508
                                        MOZ_ALIGNOF(elem_type));
2509
  elem_type* elem = Elements() + aIndex;
2510
  elem_traits::Construct(elem, std::forward<Item>(aItem));
2511
  return elem;
2512
}
2513
2514
template<typename E, class Alloc>
2515
template<class Item, typename ActualAlloc>
2516
auto
2517
nsTArray_Impl<E, Alloc>::AppendElements(const Item* aArray, size_type aArrayLen) -> elem_type*
2518
0
{
2519
0
  if (!ActualAlloc::Successful(this->template EnsureCapacity<ActualAlloc>(
2520
0
        Length() + aArrayLen, sizeof(elem_type)))) {
2521
0
    return nullptr;
2522
0
  }
2523
0
  index_type len = Length();
2524
0
  AssignRange(len, aArrayLen, aArray);
2525
0
  this->IncrementLength(aArrayLen);
2526
0
  return Elements() + len;
2527
0
}
Unexecuted instantiation: mozilla::CycleCollectedJSContext::PendingIDBTransactionData* nsTArray_Impl<mozilla::CycleCollectedJSContext::PendingIDBTransactionData, nsTArrayInfallibleAllocator>::AppendElements<mozilla::CycleCollectedJSContext::PendingIDBTransactionData, nsTArrayInfallibleAllocator>(mozilla::CycleCollectedJSContext::PendingIDBTransactionData const*, unsigned long)
Unexecuted instantiation: RefPtr<nsAtom>* nsTArray_Impl<RefPtr<nsAtom>, nsTArrayInfallibleAllocator>::AppendElements<RefPtr<nsAtom>, nsTArrayInfallibleAllocator>(RefPtr<nsAtom> const*, unsigned long)
2528
2529
template<typename E, class Alloc>
2530
template<class Item, class Allocator, typename ActualAlloc>
2531
auto
2532
nsTArray_Impl<E, Alloc>::AppendElements(nsTArray_Impl<Item, Allocator>&& aArray) -> elem_type*
2533
{
2534
  MOZ_ASSERT(&aArray != this, "argument must be different aArray");
2535
  if (Length() == 0) {
2536
    SwapElements<ActualAlloc>(aArray);
2537
    return Elements();
2538
  }
2539
2540
  index_type len = Length();
2541
  index_type otherLen = aArray.Length();
2542
  if (!Alloc::Successful(this->template EnsureCapacity<Alloc>(
2543
        len + otherLen, sizeof(elem_type)))) {
2544
    return nullptr;
2545
  }
2546
  copy_type::MoveNonOverlappingRegion(Elements() + len, aArray.Elements(), otherLen,
2547
                                      sizeof(elem_type));
2548
  this->IncrementLength(otherLen);
2549
  aArray.template ShiftData<Alloc>(0, otherLen, 0, sizeof(elem_type),
2550
                                   MOZ_ALIGNOF(elem_type));
2551
  return Elements() + len;
2552
}
2553
2554
template<typename E, class Alloc>
2555
template<class Item, typename ActualAlloc>
2556
auto
2557
nsTArray_Impl<E, Alloc>::AppendElement(Item&& aItem) -> elem_type*
2558
180
{
2559
180
  if (!ActualAlloc::Successful(this->template EnsureCapacity<ActualAlloc>(
2560
180
         Length() + 1, sizeof(elem_type)))) {
2561
0
    return nullptr;
2562
0
  }
2563
180
  elem_type* elem = Elements() + Length();
2564
180
  elem_traits::Construct(elem, std::forward<Item>(aItem));
2565
180
  this->mHdr->mLength += 1;
2566
180
  return elem;
2567
180
}
Unexecuted instantiation: nsCOMPtr<nsIRunnable>* nsTArray_Impl<nsCOMPtr<nsIRunnable>, nsTArrayInfallibleAllocator>::AppendElement<already_AddRefed<nsIRunnable>, nsTArrayInfallibleAllocator>(already_AddRefed<nsIRunnable>&&)
Unexecuted instantiation: mozilla::CycleCollectedJSContext::PendingIDBTransactionData* nsTArray_Impl<mozilla::CycleCollectedJSContext::PendingIDBTransactionData, nsTArrayInfallibleAllocator>::AppendElement<mozilla::CycleCollectedJSContext::PendingIDBTransactionData, nsTArrayInfallibleAllocator>(mozilla::CycleCollectedJSContext::PendingIDBTransactionData&&)
Unexecuted instantiation: mozilla::MemoryMapping* nsTArray_Impl<mozilla::MemoryMapping, nsTArrayInfallibleAllocator>::AppendElement<mozilla::MemoryMapping, nsTArrayInfallibleAllocator>(mozilla::MemoryMapping&&)
Unexecuted instantiation: ThreadsReporter::CollectReports(nsIHandleReportCallback*, nsISupports*, bool)::ThreadData* nsTArray_Impl<ThreadsReporter::CollectReports(nsIHandleReportCallback*, nsISupports*, bool)::ThreadData, nsTArrayInfallibleAllocator>::AppendElement<ThreadsReporter::CollectReports(nsIHandleReportCallback*, nsISupports*, bool)::ThreadData, nsTArrayInfallibleAllocator>(ThreadsReporter::CollectReports(nsIHandleReportCallback*, nsISupports*, bool)::ThreadData&&)
Unexecuted instantiation: RefPtr<mozilla::MemoryReportingProcess>* nsTArray_Impl<RefPtr<mozilla::MemoryReportingProcess>, nsTArrayInfallibleAllocator>::AppendElement<mozilla::dom::ContentParent*&, nsTArrayInfallibleAllocator>(mozilla::dom::ContentParent*&)
Unexecuted instantiation: RefPtr<mozilla::MemoryReportingProcess>* nsTArray_Impl<RefPtr<mozilla::MemoryReportingProcess>, nsTArrayInfallibleAllocator>::AppendElement<already_AddRefed<mozilla::MemoryReportingProcess>, nsTArrayInfallibleAllocator>(already_AddRefed<mozilla::MemoryReportingProcess>&&)
Unexecuted instantiation: BloatEntry** nsTArray_Impl<BloatEntry*, nsTArrayInfallibleAllocator>::AppendElement<nsAutoPtr<BloatEntry>&, nsTArrayInfallibleAllocator>(nsAutoPtr<BloatEntry>&)
nsAutoPtr<nsComponentManagerImpl::KnownModule>* nsTArray_Impl<nsAutoPtr<nsComponentManagerImpl::KnownModule>, nsTArrayInfallibleAllocator>::AppendElement<nsComponentManagerImpl::KnownModule*&, nsTArrayInfallibleAllocator>(nsComponentManagerImpl::KnownModule*&)
Line
Count
Source
2558
180
{
2559
180
  if (!ActualAlloc::Successful(this->template EnsureCapacity<ActualAlloc>(
2560
180
         Length() + 1, sizeof(elem_type)))) {
2561
0
    return nullptr;
2562
0
  }
2563
180
  elem_type* elem = Elements() + Length();
2564
180
  elem_traits::Construct(elem, std::forward<Item>(aItem));
2565
180
  this->mHdr->mLength += 1;
2566
180
  return elem;
2567
180
}
Unexecuted instantiation: nsTString<char>* nsTArray_Impl<nsTString<char>, nsTArrayInfallibleAllocator>::AppendElement<nsTSubstring<char> const&, nsTArrayInfallibleAllocator>(nsTSubstring<char> const&)
Unexecuted instantiation: mozilla::Module const** nsTArray_Impl<mozilla::Module const*, nsTArrayInfallibleAllocator>::AppendElement<mozilla::Module const*&, nsTArrayInfallibleAllocator>(mozilla::Module const*&)
Unexecuted instantiation: mozilla::dom::StringBundleDescriptor* nsTArray_Impl<mozilla::dom::StringBundleDescriptor, nsTArrayInfallibleAllocator>::AppendElement<mozilla::dom::StringBundleDescriptor, nsTArrayInfallibleAllocator>(mozilla::dom::StringBundleDescriptor&&)
Unexecuted instantiation: RefPtr<nsAtom>* nsTArray_Impl<RefPtr<nsAtom>, nsTArrayInfallibleAllocator>::AppendElement<RefPtr<nsAtom>, nsTArrayInfallibleAllocator>(RefPtr<nsAtom>&&)
Unexecuted instantiation: nsAttrValue::EnumTable const** nsTArray_Impl<nsAttrValue::EnumTable const*, nsTArrayInfallibleAllocator>::AppendElement<nsAttrValue::EnumTable const*&, nsTArrayInfallibleAllocator>(nsAttrValue::EnumTable const*&)
2568
2569
template<typename E, typename Alloc>
2570
inline void
2571
ImplCycleCollectionUnlink(nsTArray_Impl<E, Alloc>& aField)
2572
{
2573
  aField.Clear();
2574
}
2575
2576
template<typename E, typename Alloc>
2577
inline void
2578
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
2579
                            nsTArray_Impl<E, Alloc>& aField,
2580
                            const char* aName,
2581
                            uint32_t aFlags = 0)
2582
{
2583
  aFlags |= CycleCollectionEdgeNameArrayFlag;
2584
  size_t length = aField.Length();
2585
  for (size_t i = 0; i < length; ++i) {
2586
    ImplCycleCollectionTraverse(aCallback, aField[i], aName, aFlags);
2587
  }
2588
}
2589
2590
//
2591
// nsTArray is an infallible vector class.  See the comment at the top of this
2592
// file for more details.
2593
//
2594
template<class E>
2595
class nsTArray : public nsTArray_Impl<E, nsTArrayInfallibleAllocator>
2596
{
2597
public:
2598
  typedef nsTArray_Impl<E, nsTArrayInfallibleAllocator> base_type;
2599
  typedef nsTArray<E>                                   self_type;
2600
  typedef typename base_type::size_type                 size_type;
2601
2602
186
  nsTArray() {}
nsTArray<nsCOMPtr<nsISupports> >::nsTArray()
Line
Count
Source
2602
3
  nsTArray() {}
nsTArray<nsCOMPtr<nsIRunnable> >::nsTArray()
Line
Count
Source
2602
6
  nsTArray() {}
nsTArray<mozilla::CycleCollectedJSContext::PendingIDBTransactionData>::nsTArray()
Line
Count
Source
2602
3
  nsTArray() {}
nsTArray<mozilla::DeferredFinalizeFunctionHolder>::nsTArray()
Line
Count
Source
2602
18
  nsTArray() {}
Unexecuted instantiation: nsTArray<ThreadsReporter::CollectReports(nsIHandleReportCallback*, nsISupports*, bool)::ThreadData>::nsTArray()
nsTArray<mozilla::dom::ContentParent*>::nsTArray()
Line
Count
Source
2602
129
  nsTArray() {}
Unexecuted instantiation: nsTArray<RefPtr<mozilla::MemoryReportingProcess> >::nsTArray()
Unexecuted instantiation: nsTArray<BloatEntry*>::nsTArray()
Unified_cpp_xpcom_components0.cpp:nsTArray<(anonymous namespace)::CachedDirective>::nsTArray()
Line
Count
Source
2602
12
  nsTArray() {}
nsTArray<nsAutoPtr<nsComponentManagerImpl::KnownModule> >::nsTArray()
Line
Count
Source
2602
3
  nsTArray() {}
nsTArray<nsComponentManagerImpl::PendingServiceInfo>::nsTArray()
Line
Count
Source
2602
3
  nsTArray() {}
nsTArray<mozilla::Module const*>::nsTArray()
Line
Count
Source
2602
3
  nsTArray() {}
nsTArray<nsComponentManagerImpl::ComponentLocation>::nsTArray()
Line
Count
Source
2602
3
  nsTArray() {}
Unexecuted instantiation: nsTArray<mozilla::dom::StringBundleDescriptor>::nsTArray()
nsTArray<nsAttrValue::EnumTable const*>::nsTArray()
Line
Count
Source
2602
3
  nsTArray() {}
2603
0
  explicit nsTArray(size_type aCapacity) : base_type(aCapacity) {}
2604
  explicit nsTArray(const nsTArray& aOther) : base_type(aOther) {}
2605
0
  MOZ_IMPLICIT nsTArray(nsTArray&& aOther) : base_type(std::move(aOther)) {}
2606
  MOZ_IMPLICIT nsTArray(std::initializer_list<E> aIL) : base_type(aIL) {}
2607
2608
  template<class Allocator>
2609
  explicit nsTArray(const nsTArray_Impl<E, Allocator>& aOther)
2610
    : base_type(aOther)
2611
  {
2612
  }
2613
  template<class Allocator>
2614
  MOZ_IMPLICIT nsTArray(nsTArray_Impl<E, Allocator>&& aOther)
2615
    : base_type(std::move(aOther))
2616
  {
2617
  }
2618
2619
  self_type& operator=(const self_type& aOther)
2620
  {
2621
    base_type::operator=(aOther);
2622
    return *this;
2623
  }
2624
  template<class Allocator>
2625
  self_type& operator=(const nsTArray_Impl<E, Allocator>& aOther)
2626
  {
2627
    base_type::operator=(aOther);
2628
    return *this;
2629
  }
2630
  self_type& operator=(self_type&& aOther)
2631
  {
2632
    base_type::operator=(std::move(aOther));
2633
    return *this;
2634
  }
2635
  template<class Allocator>
2636
  self_type& operator=(nsTArray_Impl<E, Allocator>&& aOther)
2637
  {
2638
    base_type::operator=(std::move(aOther));
2639
    return *this;
2640
  }
2641
2642
  using base_type::AppendElement;
2643
  using base_type::AppendElements;
2644
  using base_type::EnsureLengthAtLeast;
2645
  using base_type::InsertElementAt;
2646
  using base_type::InsertElementsAt;
2647
  using base_type::InsertElementSorted;
2648
  using base_type::ReplaceElementsAt;
2649
  using base_type::SetCapacity;
2650
  using base_type::SetLength;
2651
};
2652
2653
//
2654
// FallibleTArray is a fallible vector class.
2655
//
2656
template<class E>
2657
class FallibleTArray : public nsTArray_Impl<E, nsTArrayFallibleAllocator>
2658
{
2659
public:
2660
  typedef nsTArray_Impl<E, nsTArrayFallibleAllocator>   base_type;
2661
  typedef FallibleTArray<E>                             self_type;
2662
  typedef typename base_type::size_type                 size_type;
2663
2664
  FallibleTArray() {}
2665
  explicit FallibleTArray(size_type aCapacity) : base_type(aCapacity) {}
2666
  explicit FallibleTArray(const FallibleTArray<E>& aOther) : base_type(aOther) {}
2667
  FallibleTArray(FallibleTArray<E>&& aOther)
2668
    : base_type(std::move(aOther))
2669
  {
2670
  }
2671
2672
  template<class Allocator>
2673
  explicit FallibleTArray(const nsTArray_Impl<E, Allocator>& aOther)
2674
    : base_type(aOther)
2675
  {
2676
  }
2677
  template<class Allocator>
2678
  explicit FallibleTArray(nsTArray_Impl<E, Allocator>&& aOther)
2679
    : base_type(std::move(aOther))
2680
  {
2681
  }
2682
2683
  self_type& operator=(const self_type& aOther)
2684
  {
2685
    base_type::operator=(aOther);
2686
    return *this;
2687
  }
2688
  template<class Allocator>
2689
  self_type& operator=(const nsTArray_Impl<E, Allocator>& aOther)
2690
  {
2691
    base_type::operator=(aOther);
2692
    return *this;
2693
  }
2694
  self_type& operator=(self_type&& aOther)
2695
  {
2696
    base_type::operator=(std::move(aOther));
2697
    return *this;
2698
  }
2699
  template<class Allocator>
2700
  self_type& operator=(nsTArray_Impl<E, Allocator>&& aOther)
2701
  {
2702
    base_type::operator=(std::move(aOther));
2703
    return *this;
2704
  }
2705
};
2706
2707
//
2708
// AutoTArray<E, N> is like nsTArray<E>, but with N elements of inline storage.
2709
// Storing more than N elements is fine, but it will cause a heap allocation.
2710
//
2711
template<class E, size_t N>
2712
class MOZ_NON_MEMMOVABLE AutoTArray : public nsTArray<E>
2713
{
2714
  static_assert(N != 0, "AutoTArray<E, 0> should be specialized");
2715
public:
2716
  typedef AutoTArray<E, N> self_type;
2717
  typedef nsTArray<E> base_type;
2718
  typedef typename base_type::Header Header;
2719
  typedef typename base_type::elem_type elem_type;
2720
2721
  AutoTArray()
2722
    : mAlign()
2723
18
  {
2724
18
    Init();
2725
18
  }
AutoTArray<mozilla::DeferredFinalizeFunctionHolder, 16ul>::AutoTArray()
Line
Count
Source
2723
18
  {
2724
18
    Init();
2725
18
  }
Unexecuted instantiation: AutoTArray<ThreadsReporter::CollectReports(nsIHandleReportCallback*, nsISupports*, bool)::ThreadData, 32ul>::AutoTArray()
Unexecuted instantiation: AutoTArray<unsigned int, 2ul>::AutoTArray()
2726
2727
  AutoTArray(const self_type& aOther)
2728
    : nsTArray<E>()
2729
  {
2730
    Init();
2731
    this->AppendElements(aOther);
2732
  }
2733
2734
  AutoTArray(self_type&& aOther)
2735
    : nsTArray<E>()
2736
  {
2737
    Init();
2738
    this->SwapElements(aOther);
2739
  }
2740
2741
  explicit AutoTArray(const base_type& aOther)
2742
    : mAlign()
2743
  {
2744
    Init();
2745
    this->AppendElements(aOther);
2746
  }
2747
2748
  explicit AutoTArray(base_type&& aOther)
2749
    : mAlign()
2750
  {
2751
    Init();
2752
    this->SwapElements(aOther);
2753
  }
2754
2755
  template<typename Allocator>
2756
  explicit AutoTArray(nsTArray_Impl<elem_type, Allocator>&& aOther)
2757
  {
2758
    Init();
2759
    this->SwapElements(aOther);
2760
  }
2761
2762
  MOZ_IMPLICIT AutoTArray(std::initializer_list<E> aIL)
2763
    : mAlign()
2764
  {
2765
    Init();
2766
    this->AppendElements(aIL.begin(), aIL.size());
2767
  }
2768
2769
  self_type& operator=(const self_type& aOther)
2770
  {
2771
    base_type::operator=(aOther);
2772
    return *this;
2773
  }
2774
2775
  self_type& operator=(self_type&& aOther)
2776
  {
2777
    base_type::operator=(std::move(aOther));
2778
    return *this;
2779
  }
2780
2781
  template<typename Allocator>
2782
  self_type& operator=(const nsTArray_Impl<elem_type, Allocator>& aOther)
2783
  {
2784
    base_type::operator=(aOther);
2785
    return *this;
2786
  }
2787
2788
private:
2789
  // nsTArray_base casts itself as an nsAutoArrayBase in order to get a pointer
2790
  // to mAutoBuf.
2791
  template<class Allocator, class Copier>
2792
  friend class nsTArray_base;
2793
2794
  void Init()
2795
18
  {
2796
18
    static_assert(MOZ_ALIGNOF(elem_type) <= 8,
2797
18
                  "can't handle alignments greater than 8, "
2798
18
                  "see nsTArray_base::UsesAutoArrayBuffer()");
2799
18
    // Temporary work around for VS2012 RC compiler crash
2800
18
    Header** phdr = base_type::PtrToHdr();
2801
18
    *phdr = reinterpret_cast<Header*>(&mAutoBuf);
2802
18
    (*phdr)->mLength = 0;
2803
18
    (*phdr)->mCapacity = N;
2804
18
    (*phdr)->mIsAutoArray = 1;
2805
18
2806
18
    MOZ_ASSERT(base_type::GetAutoArrayBuffer(MOZ_ALIGNOF(elem_type)) ==
2807
18
               reinterpret_cast<Header*>(&mAutoBuf),
2808
18
               "GetAutoArrayBuffer needs to be fixed");
2809
18
  }
AutoTArray<mozilla::DeferredFinalizeFunctionHolder, 16ul>::Init()
Line
Count
Source
2795
18
  {
2796
18
    static_assert(MOZ_ALIGNOF(elem_type) <= 8,
2797
18
                  "can't handle alignments greater than 8, "
2798
18
                  "see nsTArray_base::UsesAutoArrayBuffer()");
2799
18
    // Temporary work around for VS2012 RC compiler crash
2800
18
    Header** phdr = base_type::PtrToHdr();
2801
18
    *phdr = reinterpret_cast<Header*>(&mAutoBuf);
2802
18
    (*phdr)->mLength = 0;
2803
18
    (*phdr)->mCapacity = N;
2804
18
    (*phdr)->mIsAutoArray = 1;
2805
18
2806
18
    MOZ_ASSERT(base_type::GetAutoArrayBuffer(MOZ_ALIGNOF(elem_type)) ==
2807
18
               reinterpret_cast<Header*>(&mAutoBuf),
2808
18
               "GetAutoArrayBuffer needs to be fixed");
2809
18
  }
Unexecuted instantiation: AutoTArray<ThreadsReporter::CollectReports(nsIHandleReportCallback*, nsISupports*, bool)::ThreadData, 32ul>::Init()
Unexecuted instantiation: AutoTArray<unsigned int, 2ul>::Init()
2810
2811
  // Declare mAutoBuf aligned to the maximum of the header's alignment and
2812
  // elem_type's alignment.  We need to use a union rather than
2813
  // MOZ_ALIGNED_DECL because GCC is picky about what goes into
2814
  // __attribute__((aligned(foo))).
2815
  union
2816
  {
2817
    char mAutoBuf[sizeof(nsTArrayHeader) + N * sizeof(elem_type)];
2818
    // Do the max operation inline to ensure that it is a compile-time constant.
2819
    mozilla::AlignedElem<(MOZ_ALIGNOF(Header) > MOZ_ALIGNOF(elem_type)) ?
2820
                         MOZ_ALIGNOF(Header) : MOZ_ALIGNOF(elem_type)> mAlign;
2821
  };
2822
};
2823
2824
//
2825
// Specialization of AutoTArray<E, N> for the case where N == 0.
2826
// AutoTArray<E, 0> behaves exactly like nsTArray<E>, but without this
2827
// specialization, it stores a useless inline header.
2828
//
2829
// We do have many AutoTArray<E, 0> objects in memory: about 2,000 per tab as
2830
// of May 2014. These are typically not explicitly AutoTArray<E, 0> but rather
2831
// AutoTArray<E, N> for some value N depending on template parameters, in
2832
// generic code.
2833
//
2834
// For that reason, we optimize this case with the below partial specialization,
2835
// which ensures that AutoTArray<E, 0> is just like nsTArray<E>, without any
2836
// inline header overhead.
2837
//
2838
template<class E>
2839
class AutoTArray<E, 0> : public nsTArray<E>
2840
{
2841
};
2842
2843
template<class E, size_t N>
2844
struct nsTArray_CopyChooser<AutoTArray<E, N>>
2845
{
2846
  typedef nsTArray_CopyWithConstructors<AutoTArray<E, N>> Type;
2847
};
2848
2849
// Span integration
2850
namespace mozilla {
2851
2852
template<class ElementType, class TArrayAlloc>
2853
Span<ElementType>
2854
MakeSpan(nsTArray_Impl<ElementType, TArrayAlloc>& aTArray)
2855
{
2856
  return aTArray;
2857
}
2858
2859
template<class ElementType, class TArrayAlloc>
2860
Span<const ElementType>
2861
MakeSpan(const nsTArray_Impl<ElementType, TArrayAlloc>& aTArray)
2862
{
2863
  return aTArray;
2864
}
2865
2866
} // namespace mozilla
2867
2868
// Assert that AutoTArray doesn't have any extra padding inside.
2869
//
2870
// It's important that the data stored in this auto array takes up a multiple of
2871
// 8 bytes; e.g. AutoTArray<uint32_t, 1> wouldn't work.  Since AutoTArray
2872
// contains a pointer, its size must be a multiple of alignof(void*).  (This is
2873
// because any type may be placed into an array, and there's no padding between
2874
// elements of an array.)  The compiler pads the end of the structure to
2875
// enforce this rule.
2876
//
2877
// If we used AutoTArray<uint32_t, 1> below, this assertion would fail on a
2878
// 64-bit system, where the compiler inserts 4 bytes of padding at the end of
2879
// the auto array to make its size a multiple of alignof(void*) == 8 bytes.
2880
2881
static_assert(sizeof(AutoTArray<uint32_t, 2>) ==
2882
              sizeof(void*) + sizeof(nsTArrayHeader) + sizeof(uint32_t) * 2,
2883
              "AutoTArray shouldn't contain any extra padding, "
2884
              "see the comment");
2885
2886
// Definitions of nsTArray_Impl methods
2887
#include "nsTArray-inl.h"
2888
2889
#endif  // nsTArray_h__