зеркало из https://github.com/mozilla/gecko-dev.git
fixes bug 325331 "Make nsTArray a bit more useful" r=bsmedberg (relanding)
This commit is contained in:
Родитель
14e56de3fd
Коммит
f1141fd8e2
|
@ -235,7 +235,7 @@ class nsTArray : public nsTArray_base {
|
|||
// 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);
|
||||
ReplaceElementsAt(0, Length(), other.Elements(), other.Length());
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -362,44 +362,51 @@ class nsTArray : public nsTArray_base {
|
|||
// and these elements must not already exist in the array
|
||||
// being modified.
|
||||
// @param arrayLen The number of values to copy into this array.
|
||||
// @return True if the operation succeeded; false otherwise.
|
||||
PRBool ReplaceElementsAt(index_type start, size_type count,
|
||||
const elem_type* array, size_type arrayLen) {
|
||||
// @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 PR_FALSE;
|
||||
return nsnull;
|
||||
DestructRange(start, count);
|
||||
ShiftData(start, count, arrayLen, sizeof(elem_type));
|
||||
AssignRange(start, arrayLen, array);
|
||||
return PR_TRUE;
|
||||
return Elements() + start;
|
||||
}
|
||||
|
||||
// A variation on the ReplaceElementsAt method defined above.
|
||||
PRBool ReplaceElementsAt(index_type start, size_type count,
|
||||
const self_type& array) {
|
||||
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.
|
||||
PRBool ReplaceElementsAt(index_type start, size_type count,
|
||||
const elem_type& elem) {
|
||||
return ReplaceElementsAt(start, count, &elem, 1);
|
||||
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.
|
||||
PRBool InsertElementsAt(index_type index, const elem_type* array,
|
||||
size_type arrayLen) {
|
||||
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.
|
||||
PRBool InsertElementsAt(index_type index, const self_type& array) {
|
||||
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.
|
||||
PRBool InsertElementAt(index_type index, const elem_type& elem) {
|
||||
return ReplaceElementsAt(index, 0, &elem, 1);
|
||||
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
|
||||
|
@ -417,29 +424,34 @@ class nsTArray : public nsTArray_base {
|
|||
// 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 True if the operation succeeded; false otherwise.
|
||||
PRBool AppendElements(const elem_type* array, size_type arrayLen) {
|
||||
// @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 PR_FALSE;
|
||||
AssignRange(Length(), arrayLen, array);
|
||||
return nsnull;
|
||||
index_type len = Length();
|
||||
AssignRange(len, arrayLen, array);
|
||||
IncrementLength(arrayLen);
|
||||
return PR_TRUE;
|
||||
return Elements() + len;
|
||||
}
|
||||
|
||||
// A variation on the AppendElements method defined above.
|
||||
PRBool AppendElements(const self_type& array) {
|
||||
template<class Item>
|
||||
elem_type *AppendElements(const nsTArray<Item>& array) {
|
||||
return AppendElements(array.Elements(), array.Length());
|
||||
}
|
||||
|
||||
// A variation on the AppendElements method defined above.
|
||||
PRBool AppendElement(const elem_type& elem) {
|
||||
return AppendElements(&elem, 1);
|
||||
template<class Item>
|
||||
elem_type *AppendElement(const Item& item) {
|
||||
return AppendElements(&item, 1);
|
||||
}
|
||||
|
||||
// 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() {
|
||||
elem_type *AppendElement() {
|
||||
if (!EnsureCapacity(Length() + 1, sizeof(elem_type)))
|
||||
return nsnull;
|
||||
elem_type *elem = Elements() + Length();
|
||||
|
@ -562,8 +574,9 @@ class nsTArray : public nsTArray_base {
|
|||
// @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 elem_type *values) {
|
||||
const Item *values) {
|
||||
elem_type *iter = Elements() + start, *end = iter + count;
|
||||
for (; iter != end; ++iter, ++values) {
|
||||
elem_traits::Construct(iter, *values);
|
||||
|
|
|
@ -116,9 +116,17 @@ static PRBool test_basic_array(ElementType *data,
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (!ary.InsertElementsAt(0, copy))
|
||||
return PR_FALSE;
|
||||
ary.RemoveElementsAt(0, copy.Length());
|
||||
for (i = 0; i < copy.Length(); ++i) {
|
||||
if (ary[i] != copy[i])
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// These shouldn't crash!
|
||||
nsTArray<ElementType> empty;
|
||||
ary.AppendElements(nsnull, 0);
|
||||
ary.AppendElements(NS_REINTERPRET_CAST(ElementType *, 0), 0);
|
||||
ary.AppendElements(empty);
|
||||
|
||||
// See bug 324981
|
||||
|
@ -250,6 +258,14 @@ static PRBool test_string_array() {
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
const char kextra[] = "foo bar";
|
||||
PRUint32 oldLen = strArray.Length();
|
||||
if (!strArray.AppendElement(kextra))
|
||||
return PR_FALSE;
|
||||
strArray.RemoveElement(kextra);
|
||||
if (oldLen != strArray.Length())
|
||||
return PR_FALSE;
|
||||
|
||||
if (strArray.IndexOf("e") != 1)
|
||||
return PR_FALSE;
|
||||
|
||||
|
@ -320,8 +336,8 @@ class RefcountedObject {
|
|||
if (--rc == 0)
|
||||
delete this;
|
||||
}
|
||||
private:
|
||||
~RefcountedObject() {}
|
||||
private:
|
||||
PRInt32 rc;
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче