/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__ |