1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
3 /* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
16 * The Original Code is C++ array template.
18 * The Initial Developer of the Original Code is Google Inc.
19 * Portions created by the Initial Developer are Copyright (C) 2005
20 * the Initial Developer. All Rights Reserved.
23 * Darin Fisher <darin@meer.net>
25 * Alternatively, the contents of this file may be used under the terms of
26 * either the GNU General Public License Version 2 or later (the "GPL"), or
27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
43 #include "nsQuickSort.h"
45 #include "nsTraceRefcnt.h"
49 // This class serves as a base class for nsTArray. It shouldn't be used
50 // directly. It holds common implementation code that does not depend on the
51 // element type of the nsTArray.
53 class NS_COM_GLUE nsTArray_base
{
55 typedef PRUint32 size_type
;
56 typedef PRUint32 index_type
;
58 // A special value that is used to indicate an invalid or unknown index
61 NoIndex
= index_type(-1)
64 // @return The number of elements in the array.
65 size_type
Length() const {
69 // @return True if the array is empty or false otherwise.
70 PRBool
IsEmpty() const {
74 // @return The number of elements that can fit in the array without forcing
75 // the array to be re-allocated. The length of an array is always less
76 // than or equal to its capacity.
77 size_type
Capacity() const {
78 return mHdr
->mCapacity
;
82 void* DebugGetHeader() {
91 // Resize the storage if necessary to achieve the requested capacity.
92 // @param capacity The requested number of array elements.
93 // @param elementSize The size of an array element.
94 // @return False if insufficient memory is available; true otherwise.
95 PRBool
EnsureCapacity(size_type capacity
, size_type elementSize
);
97 // Resize the storage to the minimum required amount.
98 // @param elementSize The size of an array element.
99 void ShrinkCapacity(size_type elementSize
);
101 // This method may be called to resize a "gap" in the array by shifting
102 // elements around. It updates mLength appropriately. If the resulting
103 // array has zero elements, then the array's memory is free'd.
104 // @param start The starting index of the gap.
105 // @param oldLen The current length of the gap.
106 // @param newLen The desired length of the gap.
107 // @param elementSize The size of an array element.
108 void ShiftData(index_type start
, size_type oldLen
, size_type newLen
,
109 size_type elementSize
);
111 // This method increments the length member of the array's header.
112 // Note that mHdr may actually be sEmptyHdr in the case where a
113 // zero-length array is inserted into our array. But then n should
115 void IncrementLength(PRUint32 n
) {
116 NS_ASSERTION(mHdr
!= &sEmptyHdr
|| n
== 0, "bad data pointer");
120 // This method inserts blank slots into the array.
121 // @param index the place to insert the new elements. This must be no
122 // greater than the current length of the array.
123 // @param count the number of slots to insert
124 // @param elementSize the size of an array element.
125 PRBool
InsertSlotsAt(index_type index
, size_type count
,
126 size_type elementSize
);
130 // NOTE: This method isn't heavily optimized if either array is an
132 PRBool
SwapArrayElements(nsTArray_base
& other
, size_type elementSize
);
134 // Helper function for SwapArrayElements. Ensures that if the array
135 // is an nsAutoTArray that it doesn't use the built-in buffer.
136 PRBool
EnsureNotUsingAutoArrayBuffer(size_type elemSize
);
138 // We prefix mData with a structure of this type. This is done to minimize
139 // the size of the nsTArray object when it is empty.
142 PRUint32 mCapacity
: 31;
143 PRUint32 mIsAutoArray
: 1;
146 // Returns true if this nsTArray is an nsAutoTArray with a built-in buffer.
147 PRBool
IsAutoArray() {
148 return mHdr
->mIsAutoArray
;
151 // Returns a Header for the built-in buffer of this nsAutoTArray.
152 Header
* GetAutoArrayBuffer() {
153 NS_ASSERTION(IsAutoArray(), "Should be an auto array to call this");
155 return reinterpret_cast<Header
*>(&mHdr
+ 1);
158 // Returns true if this is an nsAutoTArray and it currently uses the
159 // built-in buffer to store its elements.
160 PRBool
UsesAutoArrayBuffer() {
161 return mHdr
->mIsAutoArray
&& mHdr
== GetAutoArrayBuffer();
164 // This is not const since we may actually write to it. However we will
165 // always write to it the same data that it already contains. See
167 static Header sEmptyHdr
;
169 // The array's elements (prefixed with a Header). This pointer is never
170 // null. If the array is empty, then this will point to sEmptyHdr.
175 // This class defines convenience functions for element specific operations.
176 // Specialize this template if necessary.
179 class nsTArrayElementTraits
{
181 // Invoke the default constructor in place.
182 static inline void Construct(E
*e
) {
183 // Do NOT call "E()"! That triggers C++ "default initialization"
184 // which zeroes out POD ("plain old data") types such as regular ints.
185 // We don't want that because it can be a performance issue and people
186 // don't expect it; nsTArray should work like a regular C/C++ array in
188 new (static_cast<void *>(e
)) E
;
190 // Invoke the copy-constructor in place.
192 static inline void Construct(E
*e
, const A
&arg
) {
193 new (static_cast<void *>(e
)) E(arg
);
195 // Invoke the destructor in place.
196 static inline void Destruct(E
*e
) {
201 // This class exists because VC6 cannot handle static template functions.
202 // Otherwise, the Compare method would be defined directly on nsTArray.
203 template <class E
, class Comparator
>
204 class nsQuickSortComparator
{
207 // This function is meant to be used with the NS_QuickSort function. It
208 // maps the callback API expected by NS_QuickSort to the Comparator API
209 // used by nsTArray. See nsTArray::Sort.
210 static int Compare(const void* e1
, const void* e2
, void *data
) {
211 const Comparator
* c
= reinterpret_cast<const Comparator
*>(data
);
212 const elem_type
* a
= static_cast<const elem_type
*>(e1
);
213 const elem_type
* b
= static_cast<const elem_type
*>(e2
);
214 return c
->LessThan(*a
, *b
) ? -1 : (c
->Equals(*a
, *b
) ? 0 : 1);
218 // The default comparator used by nsTArray
219 template<class A
, class B
>
220 class nsDefaultComparator
{
222 PRBool
Equals(const A
& a
, const B
& b
) const {
225 PRBool
LessThan(const A
& a
, const B
& b
) const {
231 // The templatized array class that dynamically resizes its storage as elements
232 // are added. This class is designed to behave a bit like std::vector.
234 // The template parameter specifies the type of the elements (elem_type), and
235 // has the following requirements:
237 // elem_type MUST define a copy-constructor.
238 // elem_type MAY define operator< for sorting.
239 // elem_type MAY define operator== for searching.
241 // For methods taking a Comparator instance, the Comparator must be a class
242 // defining the following methods:
244 // class Comparator {
246 // /** @return True if the elements are equals; false otherwise. */
247 // PRBool Equals(const elem_type& a, const elem_type& b) const;
249 // /** @return True if (a < b); false otherwise. */
250 // PRBool LessThan(const elem_type& a, const elem_type& b) const;
253 // The Equals method is used for searching, and the LessThan method is used
257 class nsTArray
: public nsTArray_base
{
260 typedef nsTArray
<E
> self_type
;
261 typedef nsTArrayElementTraits
<E
> elem_traits
;
264 // Finalization method
267 ~nsTArray() { Clear(); }
270 // Initialization methods
275 // Initialize this array and pre-allocate some number of elements.
276 explicit nsTArray(size_type capacity
) {
277 SetCapacity(capacity
);
280 // The array's copy-constructor performs a 'deep' copy of the given array.
281 // @param other The array object to copy.
282 nsTArray(const self_type
& other
) {
283 AppendElements(other
);
286 // The array's assignment operator performs a 'deep' copy of the given
287 // array. It is optimized to reuse existing storage if possible.
288 // @param other The array object to copy.
289 nsTArray
& operator=(const self_type
& other
) {
290 ReplaceElementsAt(0, Length(), other
.Elements(), other
.Length());
298 // This method provides direct access to the array elements.
299 // @return A pointer to the first element of the array. If the array is
300 // empty, then this pointer must not be dereferenced.
301 elem_type
* Elements() {
302 return reinterpret_cast<elem_type
*>(mHdr
+ 1);
305 // This method provides direct, readonly access to the array elements.
306 // @return A pointer to the first element of the array. If the array is
307 // empty, then this pointer must not be dereferenced.
308 const elem_type
* Elements() const {
309 return reinterpret_cast<const elem_type
*>(mHdr
+ 1);
312 // This method provides direct access to the i'th element of the array.
313 // The given index must be within the array bounds.
314 // @param i The index of an element in the array.
315 // @return A reference to the i'th element of the array.
316 elem_type
& ElementAt(index_type i
) {
317 NS_ASSERTION(i
< Length(), "invalid array index");
318 return Elements()[i
];
321 // This method provides direct, readonly access to the i'th element of the
322 // array. The given index must be within the array bounds.
323 // @param i The index of an element in the array.
324 // @return A const reference to the i'th element of the array.
325 const elem_type
& ElementAt(index_type i
) const {
326 NS_ASSERTION(i
< Length(), "invalid array index");
327 return Elements()[i
];
330 // This method provides direct access to the i'th element of the array in
331 // a bounds safe manner. If the requested index is out of bounds the
332 // provided default value is returned.
333 // @param i The index of an element in the array.
334 // @param def The value to return if the index is out of bounds.
335 elem_type
& SafeElementAt(index_type i
, elem_type
& def
) {
336 return i
< Length() ? Elements()[i
] : def
;
339 // This method provides direct access to the i'th element of the array in
340 // a bounds safe manner. If the requested index is out of bounds the
341 // provided default value is returned.
342 // @param i The index of an element in the array.
343 // @param def The value to return if the index is out of bounds.
344 const elem_type
& SafeElementAt(index_type i
, const elem_type
& def
) const {
345 return i
< Length() ? Elements()[i
] : def
;
348 // Shorthand for ElementAt(i)
349 elem_type
& operator[](index_type i
) {
353 // Shorthand for ElementAt(i)
354 const elem_type
& operator[](index_type i
) const {
362 // This method searches for the first element in this array that is equal
363 // to the given element.
364 // @param item The item to search for.
365 // @param comp The Comparator used to determine element equality.
366 // @return PR_TRUE if the element was found.
367 template<class Item
, class Comparator
>
368 PRBool
Contains(const Item
& item
, const Comparator
& comp
) const {
369 return IndexOf(item
, 0, comp
) != NoIndex
;
372 // This method searches for the first element in this array that is equal
373 // to the given element. This method assumes that 'operator==' is defined
375 // @param item The item to search for.
376 // @return PR_TRUE if the element was found.
378 PRBool
Contains(const Item
& item
) const {
379 return IndexOf(item
) != NoIndex
;
382 // This method searches for the offset of the first element in this
383 // array that is equal to the given element.
384 // @param item The item to search for.
385 // @param start The index to start from.
386 // @param comp The Comparator used to determine element equality.
387 // @return The index of the found element or NoIndex if not found.
388 template<class Item
, class Comparator
>
389 index_type
IndexOf(const Item
& item
, index_type start
,
390 const Comparator
& comp
) const {
391 const elem_type
* iter
= Elements() + start
, *end
= iter
+ Length();
392 for (; iter
!= end
; ++iter
) {
393 if (comp
.Equals(*iter
, item
))
394 return iter
- Elements();
399 // This method searches for the offset of the first element in this
400 // array that is equal to the given element. This method assumes
401 // that 'operator==' is defined for elem_type.
402 // @param item The item to search for.
403 // @param start The index to start from.
404 // @return The index of the found element or NoIndex if not found.
406 index_type
IndexOf(const Item
& item
, index_type start
= 0) const {
407 return IndexOf(item
, start
, nsDefaultComparator
<elem_type
, Item
>());
410 // This method searches for the offset of the last element in this
411 // array that is equal to the given element.
412 // @param item The item to search for.
413 // @param start The index to start from. If greater than or equal to the
414 // length of the array, then the entire array is searched.
415 // @param comp The Comparator used to determine element equality.
416 // @return The index of the found element or NoIndex if not found.
417 template<class Item
, class Comparator
>
418 index_type
LastIndexOf(const Item
& item
, index_type start
,
419 const Comparator
& comp
) const {
420 if (start
>= Length())
421 start
= Length() - 1;
422 const elem_type
* end
= Elements() - 1, *iter
= end
+ start
+ 1;
423 for (; iter
!= end
; --iter
) {
424 if (comp
.Equals(*iter
, item
))
425 return iter
- Elements();
430 // This method searches for the offset of the last element in this
431 // array that is equal to the given element. This method assumes
432 // that 'operator==' is defined for elem_type.
433 // @param item The item to search for.
434 // @param start The index to start from. If greater than or equal to the
435 // length of the array, then the entire array is searched.
436 // @return The index of the found element or NoIndex if not found.
438 index_type
LastIndexOf(const Item
& item
,
439 index_type start
= NoIndex
) const {
440 return LastIndexOf(item
, start
, nsDefaultComparator
<elem_type
, Item
>());
443 // This method searches for the offset for the element in this array
444 // that is equal to the given element. The array is assumed to be sorted.
445 // @param item The item to search for.
446 // @param comp The Comparator used.
447 // @return The index of the found element or NoIndex if not found.
448 template<class Item
, class Comparator
>
449 index_type
BinaryIndexOf(const Item
& item
, const Comparator
& comp
) const {
450 index_type low
= 0, high
= Length();
452 index_type mid
= (high
+ low
) >> 1;
453 if (comp
.Equals(ElementAt(mid
), item
))
455 if (comp
.LessThan(ElementAt(mid
), item
))
463 // This method searches for the offset for the element in this array
464 // that is equal to the given element. The array is assumed to be sorted.
465 // This method assumes that 'operator==' and 'operator<' are defined.
466 // @param item The item to search for.
467 // @return The index of the found element or NoIndex if not found.
469 index_type
BinaryIndexOf(const Item
& item
) const {
470 return BinaryIndexOf(item
, nsDefaultComparator
<elem_type
, Item
>());
477 // This method replaces a range of elements in this array.
478 // @param start The starting index of the elements to replace.
479 // @param count The number of elements to replace. This may be zero to
480 // insert elements without removing any existing elements.
481 // @param array The values to copy into this array. Must be non-null,
482 // and these elements must not already exist in the array
484 // @param arrayLen The number of values to copy into this array.
485 // @return A pointer to the new elements in the array, or null if
486 // the operation failed due to insufficient memory.
488 elem_type
*ReplaceElementsAt(index_type start
, size_type count
,
489 const Item
* array
, size_type arrayLen
) {
490 // Adjust memory allocation up-front to catch errors.
491 if (!EnsureCapacity(Length() + arrayLen
- count
, sizeof(elem_type
)))
493 DestructRange(start
, count
);
494 ShiftData(start
, count
, arrayLen
, sizeof(elem_type
));
495 AssignRange(start
, arrayLen
, array
);
496 return Elements() + start
;
499 // A variation on the ReplaceElementsAt method defined above.
501 elem_type
*ReplaceElementsAt(index_type start
, size_type count
,
502 const nsTArray
<Item
>& array
) {
503 return ReplaceElementsAt(start
, count
, array
.Elements(), array
.Length());
506 // A variation on the ReplaceElementsAt method defined above.
508 elem_type
*ReplaceElementsAt(index_type start
, size_type count
,
510 return ReplaceElementsAt(start
, count
, &item
, 1);
513 // A variation on the ReplaceElementsAt method defined above.
515 elem_type
*InsertElementsAt(index_type index
, const Item
* array
,
516 size_type arrayLen
) {
517 return ReplaceElementsAt(index
, 0, array
, arrayLen
);
520 // A variation on the ReplaceElementsAt method defined above.
522 elem_type
*InsertElementsAt(index_type index
, const nsTArray
<Item
>& array
) {
523 return ReplaceElementsAt(index
, 0, array
.Elements(), array
.Length());
526 // A variation on the ReplaceElementsAt method defined above.
528 elem_type
*InsertElementAt(index_type index
, const Item
& item
) {
529 return ReplaceElementsAt(index
, 0, &item
, 1);
532 // Insert a new element without copy-constructing. This is useful to avoid
534 // @return A pointer to the newly inserted element, or null on OOM.
535 elem_type
* InsertElementAt(index_type index
) {
536 if (!EnsureCapacity(Length() + 1, sizeof(elem_type
)))
538 ShiftData(index
, 0, 1, sizeof(elem_type
));
539 elem_type
*elem
= Elements() + index
;
540 elem_traits::Construct(elem
);
544 // This method appends elements to the end of this array.
545 // @param array The elements to append to this array.
546 // @param arrayLen The number of elements to append to this array.
547 // @return A pointer to the new elements in the array, or null if
548 // the operation failed due to insufficient memory.
550 elem_type
*AppendElements(const Item
* array
, size_type arrayLen
) {
551 if (!EnsureCapacity(Length() + arrayLen
, sizeof(elem_type
)))
553 index_type len
= Length();
554 AssignRange(len
, arrayLen
, array
);
555 IncrementLength(arrayLen
);
556 return Elements() + len
;
559 // A variation on the AppendElements method defined above.
561 elem_type
*AppendElements(const nsTArray
<Item
>& array
) {
562 return AppendElements(array
.Elements(), array
.Length());
565 // A variation on the AppendElements method defined above.
567 elem_type
*AppendElement(const Item
& item
) {
568 return AppendElements(&item
, 1);
571 // Append new elements without copy-constructing. This is useful to avoid
573 // @return A pointer to the newly appended elements, or null on OOM.
574 elem_type
*AppendElements(size_type count
) {
575 if (!EnsureCapacity(Length() + count
, sizeof(elem_type
)))
577 elem_type
*elems
= Elements() + Length();
579 for (i
= 0; i
< count
; ++i
) {
580 elem_traits::Construct(elems
+ i
);
582 IncrementLength(count
);
586 // Append a new element without copy-constructing. This is useful to avoid
588 // @return A pointer to the newly appended element, or null on OOM.
589 elem_type
*AppendElement() {
590 return AppendElements(1);
593 // This method removes a range of elements from this array.
594 // @param start The starting index of the elements to remove.
595 // @param count The number of elements to remove.
596 void RemoveElementsAt(index_type start
, size_type count
) {
597 NS_ASSERTION(count
== 0 || start
< Length(), "Invalid start index");
598 NS_ASSERTION(start
+ count
<= Length(), "Invalid length");
599 DestructRange(start
, count
);
600 ShiftData(start
, count
, 0, sizeof(elem_type
));
603 // A variation on the RemoveElementsAt method defined above.
604 void RemoveElementAt(index_type index
) {
605 RemoveElementsAt(index
, 1);
608 // A variation on the RemoveElementsAt method defined above.
610 RemoveElementsAt(0, Length());
613 // This helper function combines IndexOf with RemoveElementAt to "search
614 // and destroy" the first element that is equal to the given element.
615 // @param item The item to search for.
616 // @param comp The Comparator used to determine element equality.
617 // @return PR_TRUE if the element was found
618 template<class Item
, class Comparator
>
619 PRBool
RemoveElement(const Item
& item
, const Comparator
& comp
) {
620 index_type i
= IndexOf(item
, 0, comp
);
628 // A variation on the RemoveElement method defined above that assumes
629 // that 'operator==' is defined for elem_type.
631 PRBool
RemoveElement(const Item
& item
) {
632 return RemoveElement(item
, nsDefaultComparator
<elem_type
, Item
>());
635 // This method causes the elements contained in this array and the given
636 // array to be swapped.
637 // NOTE: This method isn't heavily optimized if either array is an
639 PRBool
SwapElements(self_type
& other
) {
640 return SwapArrayElements(other
, sizeof(elem_type
));
647 // This method may increase the capacity of this array object by the
648 // specified amount. This method may be called in advance of several
649 // AppendElement operations to minimize heap re-allocations. This method
650 // will not reduce the number of elements in this array.
651 // @param capacity The desired capacity of this array.
652 // @return True if the operation succeeded; false if we ran out of memory
653 PRBool
SetCapacity(size_type capacity
) {
654 return EnsureCapacity(capacity
, sizeof(elem_type
));
657 // This method modifies the length of the array. If the new length is
658 // larger than the existing length of the array, then new elements will be
659 // constructed using elem_type's default constructor. Otherwise, this call
660 // removes elements from the array (see also RemoveElementsAt).
661 // @param newLen The desired length of this array.
662 // @return True if the operation succeeded; false otherwise.
663 PRBool
SetLength(size_type newLen
) {
664 size_type oldLen
= Length();
665 if (newLen
> oldLen
) {
666 return InsertElementsAt(oldLen
, newLen
- oldLen
) != nsnull
;
669 RemoveElementsAt(newLen
, oldLen
- newLen
);
673 // This method inserts elements into the array, constructing
674 // them using elem_type's default constructor.
675 // @param index the place to insert the new elements. This must be no
676 // greater than the current length of the array.
677 // @param count the number of elements to insert
678 elem_type
*InsertElementsAt(index_type index
, size_type count
) {
679 if (!nsTArray_base::InsertSlotsAt(index
, count
, sizeof(elem_type
))) {
683 // Initialize the extra array elements
684 elem_type
*iter
= Elements() + index
, *end
= iter
+ count
;
685 for (; iter
!= end
; ++iter
) {
686 elem_traits::Construct(iter
);
689 return Elements() + index
;
692 // This method inserts elements into the array, constructing them
693 // elem_type's copy constructor (or whatever one-arg constructor
694 // happens to match the Item type).
695 // @param index the place to insert the new elements. This must be no
696 // greater than the current length of the array.
697 // @param count the number of elements to insert.
698 // @param item the value to use when constructing the new elements.
700 elem_type
*InsertElementsAt(index_type index
, size_type count
,
702 if (!nsTArray_base::InsertSlotsAt(index
, count
, sizeof(elem_type
))) {
706 // Initialize the extra array elements
707 elem_type
*iter
= Elements() + index
, *end
= iter
+ count
;
708 for (; iter
!= end
; ++iter
) {
709 elem_traits::Construct(iter
, item
);
712 return Elements() + index
;
715 // This method may be called to minimize the memory used by this array.
717 ShrinkCapacity(sizeof(elem_type
));
724 // This method sorts the elements of the array. It uses the LessThan
725 // method defined on the given Comparator object to collate elements.
726 // @param c The Comparator to used to collate elements.
727 template<class Comparator
>
728 void Sort(const Comparator
& comp
) {
729 NS_QuickSort(Elements(), Length(), sizeof(elem_type
),
730 nsQuickSortComparator
<elem_type
, Comparator
>::Compare
,
731 const_cast<Comparator
*>(&comp
));
734 // A variation on the Sort method defined above that assumes that
735 // 'operator<' is defined for elem_type.
737 Sort(nsDefaultComparator
<elem_type
, elem_type
>());
742 // This method invokes elem_type's destructor on a range of elements.
743 // @param start The index of the first element to destroy.
744 // @param count The number of elements to destroy.
745 void DestructRange(index_type start
, size_type count
) {
746 elem_type
*iter
= Elements() + start
, *end
= iter
+ count
;
747 for (; iter
!= end
; ++iter
) {
748 elem_traits::Destruct(iter
);
752 // This method invokes elem_type's copy-constructor on a range of elements.
753 // @param start The index of the first element to construct.
754 // @param count The number of elements to construct.
755 // @param values The array of elements to copy.
757 void AssignRange(index_type start
, size_type count
,
758 const Item
*values
) {
759 elem_type
*iter
= Elements() + start
, *end
= iter
+ count
;
760 for (; iter
!= end
; ++iter
, ++values
) {
761 elem_traits::Construct(iter
, *values
);
766 template<class E
, PRUint32 N
>
767 class nsAutoTArray
: public nsTArray
<E
> {
769 typedef nsTArray
<E
> base_type
;
770 typedef typename
base_type::Header Header
;
771 typedef typename
base_type::elem_type elem_type
;
774 base_type::mHdr
= reinterpret_cast<Header
*>(&mAutoBuf
);
775 base_type::mHdr
->mLength
= 0;
776 base_type::mHdr
->mCapacity
= N
;
777 base_type::mHdr
->mIsAutoArray
= 1;
779 NS_ASSERTION(base_type::GetAutoArrayBuffer() ==
780 reinterpret_cast<Header
*>(&mAutoBuf
),
781 "GetAutoArrayBuffer needs to be fixed");
785 char mAutoBuf
[sizeof(Header
) + N
* sizeof(elem_type
)];
788 // specialization for N = 0. this makes the inheritance model easier for
789 // templated users of nsAutoTArray.
791 class nsAutoTArray
<E
, 0> : public nsTArray
<E
> {
796 #endif // nsTArray_h__