/gecko_api/include/nsTArray.h
http://firefox-mac-pdf.googlecode.com/ · C Header · 796 lines · 382 code · 96 blank · 318 comment · 40 complexity · 85c29b6209d7e3a531da96045eb46cf2 MD5 · raw file
- /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* vim:set ts=2 sw=2 sts=2 et cindent: */
- /* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is C++ array template.
- *
- * The Initial Developer of the Original Code is Google Inc.
- * Portions created by the Initial Developer are Copyright (C) 2005
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Darin Fisher <darin@meer.net>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
- #ifndef nsTArray_h__
- #define nsTArray_h__
- #include "prtypes.h"
- #include "nsQuickSort.h"
- #include "nsDebug.h"
- #include "nsTraceRefcnt.h"
- #include NEW_H
- //
- // This class serves as a base class for nsTArray. It shouldn't be used
- // directly. It holds common implementation code that does not depend on the
- // element type of the nsTArray.
- //
- class NS_COM_GLUE nsTArray_base {
- public:
- typedef PRUint32 size_type;
- typedef PRUint32 index_type;
- // A special value that is used to indicate an invalid or unknown index
- // into the array.
- enum {
- NoIndex = index_type(-1)
- };
- // @return The number of elements in the array.
- size_type Length() const {
- return mHdr->mLength;
- }
- // @return True if the array is empty or false otherwise.
- PRBool IsEmpty() const {
- return Length() == 0;
- }
- // @return The number of elements that can fit in the array without forcing
- // the array to be re-allocated. The length of an array is always less
- // than or equal to its capacity.
- size_type Capacity() const {
- return mHdr->mCapacity;
- }
- #ifdef DEBUG
- void* DebugGetHeader() {
- return mHdr;
- }
- #endif
- protected:
- nsTArray_base();
- ~nsTArray_base();
- // Resize the storage if necessary to achieve the requested capacity.
- // @param capacity The requested number of array elements.
- // @param elementSize The size of an array element.
- // @return False if insufficient memory is available; true otherwise.
- PRBool EnsureCapacity(size_type capacity, size_type elementSize);
- // Resize the storage to the minimum required amount.
- // @param elementSize The size of an array element.
- void ShrinkCapacity(size_type elementSize);
-
- // This method may be called to resize a "gap" in the array by shifting
- // elements around. It updates mLength appropriately. If the resulting
- // array has zero elements, then the array's memory is free'd.
- // @param start The starting index of the gap.
- // @param oldLen The current length of the gap.
- // @param newLen The desired length of the gap.
- // @param elementSize The size of an array element.
- void ShiftData(index_type start, size_type oldLen, size_type newLen,
- size_type elementSize);
- // This method increments the length member of the array's header.
- // Note that mHdr may actually be sEmptyHdr in the case where a
- // zero-length array is inserted into our array. But then n should
- // always be 0.
- void IncrementLength(PRUint32 n) {
- NS_ASSERTION(mHdr != &sEmptyHdr || n == 0, "bad data pointer");
- mHdr->mLength += n;
- }
- // This method inserts blank slots into the array.
- // @param index the place to insert the new elements. This must be no
- // greater than the current length of the array.
- // @param count the number of slots to insert
- // @param elementSize the size of an array element.
- PRBool InsertSlotsAt(index_type index, size_type count,
- size_type elementSize);
- protected:
- // NOTE: This method isn't heavily optimized if either array is an
- // nsAutoTArray.
- PRBool SwapArrayElements(nsTArray_base& other, size_type elementSize);
- // Helper function for SwapArrayElements. Ensures that if the array
- // is an nsAutoTArray that it doesn't use the built-in buffer.
- PRBool EnsureNotUsingAutoArrayBuffer(size_type elemSize);
- // We prefix mData with a structure of this type. This is done to minimize
- // the size of the nsTArray object when it is empty.
- struct Header {
- PRUint32 mLength;
- PRUint32 mCapacity : 31;
- PRUint32 mIsAutoArray : 1;
- };
- // Returns true if this nsTArray is an nsAutoTArray with a built-in buffer.
- PRBool IsAutoArray() {
- return mHdr->mIsAutoArray;
- }
- // Returns a Header for the built-in buffer of this nsAutoTArray.
- Header* GetAutoArrayBuffer() {
- NS_ASSERTION(IsAutoArray(), "Should be an auto array to call this");
- return reinterpret_cast<Header*>(&mHdr + 1);
- }
- // Returns true if this is an nsAutoTArray and it currently uses the
- // built-in buffer to store its elements.
- PRBool UsesAutoArrayBuffer() {
- return mHdr->mIsAutoArray && mHdr == GetAutoArrayBuffer();
- }
- // This is not const since we may actually write to it. However we will
- // always write to it the same data that it already contains. See
- // IncrementLength
- static Header sEmptyHdr;
- // The array's elements (prefixed with a Header). This pointer is never
- // null. If the array is empty, then this will point to sEmptyHdr.
- Header *mHdr;
- };
- //
- // This class defines convenience functions for element specific operations.
- // Specialize this template if necessary.
- //
- template<class E>
- class nsTArrayElementTraits {
- public:
- // Invoke the default constructor in place.
- static inline void Construct(E *e) {
- // Do NOT call "E()"! That triggers C++ "default initialization"
- // which zeroes out POD ("plain old data") types such as regular ints.
- // We don't want that because it can be a performance issue and people
- // don't expect it; nsTArray should work like a regular C/C++ array in
- // this respect.
- new (static_cast<void *>(e)) E;
- }
- // Invoke the copy-constructor in place.
- template<class A>
- static inline void Construct(E *e, const A &arg) {
- new (static_cast<void *>(e)) E(arg);
- }
- // Invoke the destructor in place.
- static inline void Destruct(E *e) {
- e->~E();
- }
- };
- // This class exists because VC6 cannot handle static template functions.
- // Otherwise, the Compare method would be defined directly on nsTArray.
- template <class E, class Comparator>
- class nsQuickSortComparator {
- public:
- typedef E elem_type;
- // This function is meant to be used with the NS_QuickSort function. It
- // maps the callback API expected by NS_QuickSort to the Comparator API
- // used by nsTArray. See nsTArray::Sort.
- static int Compare(const void* e1, const void* e2, void *data) {
- const Comparator* c = reinterpret_cast<const Comparator*>(data);
- const elem_type* a = static_cast<const elem_type*>(e1);
- const elem_type* b = static_cast<const elem_type*>(e2);
- return c->LessThan(*a, *b) ? -1 : (c->Equals(*a, *b) ? 0 : 1);
- }
- };
- // The default comparator used by nsTArray
- template<class A, class B>
- class nsDefaultComparator {
- public:
- PRBool Equals(const A& a, const B& b) const {
- return a == b;
- }
- PRBool LessThan(const A& a, const B& b) const {
- return a < b;
- }
- };
- //
- // The templatized array class that dynamically resizes its storage as elements
- // are added. This class is designed to behave a bit like std::vector.
- //
- // The template parameter specifies the type of the elements (elem_type), and
- // has the following requirements:
- //
- // elem_type MUST define a copy-constructor.
- // elem_type MAY define operator< for sorting.
- // elem_type MAY define operator== for searching.
- //
- // For methods taking a Comparator instance, the Comparator must be a class
- // defining the following methods:
- //
- // class Comparator {
- // public:
- // /** @return True if the elements are equals; false otherwise. */
- // PRBool Equals(const elem_type& a, const elem_type& b) const;
- //
- // /** @return True if (a < b); false otherwise. */
- // PRBool LessThan(const elem_type& a, const elem_type& b) const;
- // };
- //
- // The Equals method is used for searching, and the LessThan method is used
- // for sorting.
- //
- template<class E>
- class nsTArray : public nsTArray_base {
- public:
- typedef E elem_type;
- typedef nsTArray<E> self_type;
- typedef nsTArrayElementTraits<E> elem_traits;
- //
- // Finalization method
- //
- ~nsTArray() { Clear(); }
- //
- // Initialization methods
- //
- nsTArray() {}
- // Initialize this array and pre-allocate some number of elements.
- explicit nsTArray(size_type capacity) {
- SetCapacity(capacity);
- }
-
- // The array's copy-constructor performs a 'deep' copy of the given array.
- // @param other The array object to copy.
- nsTArray(const self_type& other) {
- AppendElements(other);
- }
- // The array's assignment operator performs a 'deep' copy of the given
- // array. It is optimized to reuse existing storage if possible.
- // @param other The array object to copy.
- nsTArray& operator=(const self_type& other) {
- ReplaceElementsAt(0, Length(), other.Elements(), other.Length());
- return *this;
- }
- //
- // Accessor methods
- //
- // This method provides direct access to the array elements.
- // @return A pointer to the first element of the array. If the array is
- // empty, then this pointer must not be dereferenced.
- elem_type* Elements() {
- return reinterpret_cast<elem_type *>(mHdr + 1);
- }
- // This method provides direct, readonly access to the array elements.
- // @return A pointer to the first element of the array. If the array is
- // empty, then this pointer must not be dereferenced.
- const elem_type* Elements() const {
- return reinterpret_cast<const elem_type *>(mHdr + 1);
- }
-
- // This method provides direct access to the i'th element of the array.
- // The given index must be within the array bounds.
- // @param i The index of an element in the array.
- // @return A reference to the i'th element of the array.
- elem_type& ElementAt(index_type i) {
- NS_ASSERTION(i < Length(), "invalid array index");
- return Elements()[i];
- }
- // This method provides direct, readonly access to the i'th element of the
- // array. The given index must be within the array bounds.
- // @param i The index of an element in the array.
- // @return A const reference to the i'th element of the array.
- const elem_type& ElementAt(index_type i) const {
- NS_ASSERTION(i < Length(), "invalid array index");
- return Elements()[i];
- }
- // This method provides direct access to the i'th element of the array in
- // a bounds safe manner. If the requested index is out of bounds the
- // provided default value is returned.
- // @param i The index of an element in the array.
- // @param def The value to return if the index is out of bounds.
- elem_type& SafeElementAt(index_type i, elem_type& def) {
- return i < Length() ? Elements()[i] : def;
- }
- // This method provides direct access to the i'th element of the array in
- // a bounds safe manner. If the requested index is out of bounds the
- // provided default value is returned.
- // @param i The index of an element in the array.
- // @param def The value to return if the index is out of bounds.
- const elem_type& SafeElementAt(index_type i, const elem_type& def) const {
- return i < Length() ? Elements()[i] : def;
- }
- // Shorthand for ElementAt(i)
- elem_type& operator[](index_type i) {
- return ElementAt(i);
- }
- // Shorthand for ElementAt(i)
- const elem_type& operator[](index_type i) const {
- return ElementAt(i);
- }
- //
- // Search methods
- //
- // This method searches for the first element in this array that is equal
- // to the given element.
- // @param item The item to search for.
- // @param comp The Comparator used to determine element equality.
- // @return PR_TRUE if the element was found.
- template<class Item, class Comparator>
- PRBool Contains(const Item& item, const Comparator& comp) const {
- return IndexOf(item, 0, comp) != NoIndex;
- }
- // This method searches for the first element in this array that is equal
- // to the given element. This method assumes that 'operator==' is defined
- // for elem_type.
- // @param item The item to search for.
- // @return PR_TRUE if the element was found.
- template<class Item>
- PRBool Contains(const Item& item) const {
- return IndexOf(item) != NoIndex;
- }
- // This method searches for the offset of the first element in this
- // array that is equal to the given element.
- // @param item The item to search for.
- // @param start The index to start from.
- // @param comp The Comparator used to determine element equality.
- // @return The index of the found element or NoIndex if not found.
- template<class Item, class Comparator>
- index_type IndexOf(const Item& item, index_type start,
- const Comparator& comp) const {
- const elem_type* iter = Elements() + start, *end = iter + Length();
- for (; iter != end; ++iter) {
- if (comp.Equals(*iter, item))
- return iter - Elements();
- }
- return NoIndex;
- }
- // This method searches for the offset of the first element in this
- // array that is equal to the given element. This method assumes
- // that 'operator==' is defined for elem_type.
- // @param item The item to search for.
- // @param start The index to start from.
- // @return The index of the found element or NoIndex if not found.
- template<class Item>
- index_type IndexOf(const Item& item, index_type start = 0) const {
- return IndexOf(item, start, nsDefaultComparator<elem_type, Item>());
- }
- // This method searches for the offset of the last element in this
- // array that is equal to the given element.
- // @param item The item to search for.
- // @param start The index to start from. If greater than or equal to the
- // length of the array, then the entire array is searched.
- // @param comp The Comparator used to determine element equality.
- // @return The index of the found element or NoIndex if not found.
- template<class Item, class Comparator>
- index_type LastIndexOf(const Item& item, index_type start,
- const Comparator& comp) const {
- if (start >= Length())
- start = Length() - 1;
- const elem_type* end = Elements() - 1, *iter = end + start + 1;
- for (; iter != end; --iter) {
- if (comp.Equals(*iter, item))
- return iter - Elements();
- }
- return NoIndex;
- }
- // This method searches for the offset of the last element in this
- // array that is equal to the given element. This method assumes
- // that 'operator==' is defined for elem_type.
- // @param item The item to search for.
- // @param start The index to start from. If greater than or equal to the
- // length of the array, then the entire array is searched.
- // @return The index of the found element or NoIndex if not found.
- template<class Item>
- index_type LastIndexOf(const Item& item,
- index_type start = NoIndex) const {
- return LastIndexOf(item, start, nsDefaultComparator<elem_type, Item>());
- }
- // This method searches for the offset for the element in this array
- // that is equal to the given element. The array is assumed to be sorted.
- // @param item The item to search for.
- // @param comp The Comparator used.
- // @return The index of the found element or NoIndex if not found.
- template<class Item, class Comparator>
- index_type BinaryIndexOf(const Item& item, const Comparator& comp) const {
- index_type low = 0, high = Length();
- while (high > low) {
- index_type mid = (high + low) >> 1;
- if (comp.Equals(ElementAt(mid), item))
- return mid;
- if (comp.LessThan(ElementAt(mid), item))
- low = mid + 1;
- else
- high = mid;
- }
- return NoIndex;
- }
- // This method searches for the offset for the element in this array
- // that is equal to the given element. The array is assumed to be sorted.
- // This method assumes that 'operator==' and 'operator<' are defined.
- // @param item The item to search for.
- // @return The index of the found element or NoIndex if not found.
- template<class Item>
- index_type BinaryIndexOf(const Item& item) const {
- return BinaryIndexOf(item, nsDefaultComparator<elem_type, Item>());
- }
- //
- // Mutation methods
- //
- // This method replaces a range of elements in this array.
- // @param start The starting index of the elements to replace.
- // @param count The number of elements to replace. This may be zero to
- // insert elements without removing any existing elements.
- // @param array The values to copy into this array. Must be non-null,
- // and these elements must not already exist in the array
- // being modified.
- // @param arrayLen The number of values to copy into this array.
- // @return A pointer to the new elements in the array, or null if
- // the operation failed due to insufficient memory.
- template<class Item>
- elem_type *ReplaceElementsAt(index_type start, size_type count,
- const Item* array, size_type arrayLen) {
- // Adjust memory allocation up-front to catch errors.
- if (!EnsureCapacity(Length() + arrayLen - count, sizeof(elem_type)))
- return nsnull;
- DestructRange(start, count);
- ShiftData(start, count, arrayLen, sizeof(elem_type));
- AssignRange(start, arrayLen, array);
- return Elements() + start;
- }
- // A variation on the ReplaceElementsAt method defined above.
- template<class Item>
- elem_type *ReplaceElementsAt(index_type start, size_type count,
- const nsTArray<Item>& array) {
- return ReplaceElementsAt(start, count, array.Elements(), array.Length());
- }
- // A variation on the ReplaceElementsAt method defined above.
- template<class Item>
- elem_type *ReplaceElementsAt(index_type start, size_type count,
- const Item& item) {
- return ReplaceElementsAt(start, count, &item, 1);
- }
-
- // A variation on the ReplaceElementsAt method defined above.
- template<class Item>
- elem_type *InsertElementsAt(index_type index, const Item* array,
- size_type arrayLen) {
- return ReplaceElementsAt(index, 0, array, arrayLen);
- }
- // A variation on the ReplaceElementsAt method defined above.
- template<class Item>
- elem_type *InsertElementsAt(index_type index, const nsTArray<Item>& array) {
- return ReplaceElementsAt(index, 0, array.Elements(), array.Length());
- }
- // A variation on the ReplaceElementsAt method defined above.
- template<class Item>
- elem_type *InsertElementAt(index_type index, const Item& item) {
- return ReplaceElementsAt(index, 0, &item, 1);
- }
- // Insert a new element without copy-constructing. This is useful to avoid
- // temporaries.
- // @return A pointer to the newly inserted element, or null on OOM.
- elem_type* InsertElementAt(index_type index) {
- if (!EnsureCapacity(Length() + 1, sizeof(elem_type)))
- return nsnull;
- ShiftData(index, 0, 1, sizeof(elem_type));
- elem_type *elem = Elements() + index;
- elem_traits::Construct(elem);
- return elem;
- }
- // This method appends elements to the end of this array.
- // @param array The elements to append to this array.
- // @param arrayLen The number of elements to append to this array.
- // @return A pointer to the new elements in the array, or null if
- // the operation failed due to insufficient memory.
- template<class Item>
- elem_type *AppendElements(const Item* array, size_type arrayLen) {
- if (!EnsureCapacity(Length() + arrayLen, sizeof(elem_type)))
- return nsnull;
- index_type len = Length();
- AssignRange(len, arrayLen, array);
- IncrementLength(arrayLen);
- return Elements() + len;
- }
- // A variation on the AppendElements method defined above.
- template<class Item>
- elem_type *AppendElements(const nsTArray<Item>& array) {
- return AppendElements(array.Elements(), array.Length());
- }
- // A variation on the AppendElements method defined above.
- template<class Item>
- elem_type *AppendElement(const Item& item) {
- return AppendElements(&item, 1);
- }
- // Append new elements without copy-constructing. This is useful to avoid
- // temporaries.
- // @return A pointer to the newly appended elements, or null on OOM.
- elem_type *AppendElements(size_type count) {
- if (!EnsureCapacity(Length() + count, sizeof(elem_type)))
- return nsnull;
- elem_type *elems = Elements() + Length();
- size_type i;
- for (i = 0; i < count; ++i) {
- elem_traits::Construct(elems + i);
- }
- IncrementLength(count);
- return elems;
- }
- // Append a new element without copy-constructing. This is useful to avoid
- // temporaries.
- // @return A pointer to the newly appended element, or null on OOM.
- elem_type *AppendElement() {
- return AppendElements(1);
- }
- // This method removes a range of elements from this array.
- // @param start The starting index of the elements to remove.
- // @param count The number of elements to remove.
- void RemoveElementsAt(index_type start, size_type count) {
- NS_ASSERTION(count == 0 || start < Length(), "Invalid start index");
- NS_ASSERTION(start + count <= Length(), "Invalid length");
- DestructRange(start, count);
- ShiftData(start, count, 0, sizeof(elem_type));
- }
- // A variation on the RemoveElementsAt method defined above.
- void RemoveElementAt(index_type index) {
- RemoveElementsAt(index, 1);
- }
- // A variation on the RemoveElementsAt method defined above.
- void Clear() {
- RemoveElementsAt(0, Length());
- }
- // This helper function combines IndexOf with RemoveElementAt to "search
- // and destroy" the first element that is equal to the given element.
- // @param item The item to search for.
- // @param comp The Comparator used to determine element equality.
- // @return PR_TRUE if the element was found
- template<class Item, class Comparator>
- PRBool RemoveElement(const Item& item, const Comparator& comp) {
- index_type i = IndexOf(item, 0, comp);
- if (i == NoIndex)
- return PR_FALSE;
- RemoveElementAt(i);
- return PR_TRUE;
- }
- // A variation on the RemoveElement method defined above that assumes
- // that 'operator==' is defined for elem_type.
- template<class Item>
- PRBool RemoveElement(const Item& item) {
- return RemoveElement(item, nsDefaultComparator<elem_type, Item>());
- }
- // This method causes the elements contained in this array and the given
- // array to be swapped.
- // NOTE: This method isn't heavily optimized if either array is an
- // nsAutoTArray.
- PRBool SwapElements(self_type& other) {
- return SwapArrayElements(other, sizeof(elem_type));
- }
- //
- // Allocation
- //
- // This method may increase the capacity of this array object by the
- // specified amount. This method may be called in advance of several
- // AppendElement operations to minimize heap re-allocations. This method
- // will not reduce the number of elements in this array.
- // @param capacity The desired capacity of this array.
- // @return True if the operation succeeded; false if we ran out of memory
- PRBool SetCapacity(size_type capacity) {
- return EnsureCapacity(capacity, sizeof(elem_type));
- }
- // This method modifies the length of the array. If the new length is
- // larger than the existing length of the array, then new elements will be
- // constructed using elem_type's default constructor. Otherwise, this call
- // removes elements from the array (see also RemoveElementsAt).
- // @param newLen The desired length of this array.
- // @return True if the operation succeeded; false otherwise.
- PRBool SetLength(size_type newLen) {
- size_type oldLen = Length();
- if (newLen > oldLen) {
- return InsertElementsAt(oldLen, newLen - oldLen) != nsnull;
- }
-
- RemoveElementsAt(newLen, oldLen - newLen);
- return PR_TRUE;
- }
- // This method inserts elements into the array, constructing
- // them using elem_type's default constructor.
- // @param index the place to insert the new elements. This must be no
- // greater than the current length of the array.
- // @param count the number of elements to insert
- elem_type *InsertElementsAt(index_type index, size_type count) {
- if (!nsTArray_base::InsertSlotsAt(index, count, sizeof(elem_type))) {
- return nsnull;
- }
- // Initialize the extra array elements
- elem_type *iter = Elements() + index, *end = iter + count;
- for (; iter != end; ++iter) {
- elem_traits::Construct(iter);
- }
- return Elements() + index;
- }
- // This method inserts elements into the array, constructing them
- // elem_type's copy constructor (or whatever one-arg constructor
- // happens to match the Item type).
- // @param index the place to insert the new elements. This must be no
- // greater than the current length of the array.
- // @param count the number of elements to insert.
- // @param item the value to use when constructing the new elements.
- template<class Item>
- elem_type *InsertElementsAt(index_type index, size_type count,
- const Item& item) {
- if (!nsTArray_base::InsertSlotsAt(index, count, sizeof(elem_type))) {
- return nsnull;
- }
- // Initialize the extra array elements
- elem_type *iter = Elements() + index, *end = iter + count;
- for (; iter != end; ++iter) {
- elem_traits::Construct(iter, item);
- }
- return Elements() + index;
- }
- // This method may be called to minimize the memory used by this array.
- void Compact() {
- ShrinkCapacity(sizeof(elem_type));
- }
- //
- // Sorting
- //
- // This method sorts the elements of the array. It uses the LessThan
- // method defined on the given Comparator object to collate elements.
- // @param c The Comparator to used to collate elements.
- template<class Comparator>
- void Sort(const Comparator& comp) {
- NS_QuickSort(Elements(), Length(), sizeof(elem_type),
- nsQuickSortComparator<elem_type, Comparator>::Compare,
- const_cast<Comparator*>(&comp));
- }
- // A variation on the Sort method defined above that assumes that
- // 'operator<' is defined for elem_type.
- void Sort() {
- Sort(nsDefaultComparator<elem_type, elem_type>());
- }
- protected:
- // This method invokes elem_type's destructor on a range of elements.
- // @param start The index of the first element to destroy.
- // @param count The number of elements to destroy.
- void DestructRange(index_type start, size_type count) {
- elem_type *iter = Elements() + start, *end = iter + count;
- for (; iter != end; ++iter) {
- elem_traits::Destruct(iter);
- }
- }
- // This method invokes elem_type's copy-constructor on a range of elements.
- // @param start The index of the first element to construct.
- // @param count The number of elements to construct.
- // @param values The array of elements to copy.
- template<class Item>
- void AssignRange(index_type start, size_type count,
- const Item *values) {
- elem_type *iter = Elements() + start, *end = iter + count;
- for (; iter != end; ++iter, ++values) {
- elem_traits::Construct(iter, *values);
- }
- }
- };
- template<class E, PRUint32 N>
- class nsAutoTArray : public nsTArray<E> {
- public:
- typedef nsTArray<E> base_type;
- typedef typename base_type::Header Header;
- typedef typename base_type::elem_type elem_type;
- nsAutoTArray() {
- base_type::mHdr = reinterpret_cast<Header*>(&mAutoBuf);
- base_type::mHdr->mLength = 0;
- base_type::mHdr->mCapacity = N;
- base_type::mHdr->mIsAutoArray = 1;
- NS_ASSERTION(base_type::GetAutoArrayBuffer() ==
- reinterpret_cast<Header*>(&mAutoBuf),
- "GetAutoArrayBuffer needs to be fixed");
- }
- protected:
- char mAutoBuf[sizeof(Header) + N * sizeof(elem_type)];
- };
- // specialization for N = 0. this makes the inheritance model easier for
- // templated users of nsAutoTArray.
- template<class E>
- class nsAutoTArray<E, 0> : public nsTArray<E> {
- public:
- nsAutoTArray() {}
- };
- #endif // nsTArray_h__