diff --git a/mozilla/xpcom/glue/nsTArray.h b/mozilla/xpcom/glue/nsTArray.h index 7dd93d2e3c3..aa8883081cc 100644 --- a/mozilla/xpcom/glue/nsTArray.h +++ b/mozilla/xpcom/glue/nsTArray.h @@ -154,6 +154,18 @@ class nsQuickSortComparator { } }; +// The default comparator used by nsTArray +template +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. @@ -270,16 +282,16 @@ class nsTArray : public nsTArray_base { // This method searches for the offset of the first element in this // array that is equal to the given element. - // @param elem The element to search for. + // @param item The item to search for. // @param comp The Comparator used to determine element equality. // @param start The index to start from. // @return The index of the found element or NoIndex if not found. - template - index_type IndexOf(const elem_type& elem, const Comparator& comp, + template + index_type IndexOf(const Item& item, const Comparator& comp, index_type start = 0) const { const elem_type* iter = Elements() + start, *end = iter + Length(); for (; iter != end; ++iter) { - if (comp.Equals(*iter, elem)) + if (comp.Equals(*iter, item)) return iter - Elements(); } return NoIndex; @@ -288,29 +300,30 @@ class nsTArray : public nsTArray_base { // 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 elem The element to search for. + // @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. - index_type IndexOf(const elem_type& elem, index_type start = 0) const { - return IndexOf(elem, DefaultComparator(), start); + template + index_type IndexOf(const Item& item, index_type start = 0) const { + return IndexOf(item, nsDefaultComparator(), start); } // This method searches for the offset of the last element in this // array that is equal to the given element. - // @param elem The element to search for. + // @param item The item to search for. // @param comp The Comparator used to determine element equality. // @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 - index_type LastIndexOf(const elem_type& elem, + template + index_type LastIndexOf(const Item& item, const Comparator& comp, index_type start = NoIndex) 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, elem)) + if (comp.Equals(*iter, item)) return iter - Elements(); } return NoIndex; @@ -319,13 +332,14 @@ class nsTArray : public nsTArray_base { // 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 elem The element to search for. + // @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. - index_type LastIndexOf(const elem_type& elem, + template + index_type LastIndexOf(const Item& item, index_type start = NoIndex) const { - return LastIndexOf(elem, DefaultComparator(), start); + return LastIndexOf(item, nsDefaultComparator(), start); } // @@ -446,19 +460,20 @@ class nsTArray : public nsTArray_base { // This helper function combines IndexOf with RemoveElementAt to "search // and destroy" the first element that is equal to the given element. - // @param elem The element to search for. + // @param item The item to search for. // @param comp The Comparator used to determine element equality. - template - void RemoveElement(const elem_type& elem, const Comparator& comp) { - index_type i = IndexOf(elem, comp); + template + void RemoveElement(const Item& item, const Comparator& comp) { + index_type i = IndexOf(item, comp); if (i >= 0) RemoveElementAt(i); } // A variation on the RemoveElement method defined above that assumes // that 'operator==' is defined for elem_type. - void RemoveElement(const elem_type& elem) { - RemoveElement(elem, DefaultComparator()); + template + void RemoveElement(const Item& item) { + RemoveElement(item, nsDefaultComparator()); } // @@ -520,22 +535,11 @@ class nsTArray : public nsTArray_base { // A variation on the Sort method defined above that assumes that // 'operator<' is defined for elem_type. void Sort() { - Sort(DefaultComparator()); + Sort(nsDefaultComparator()); } protected: - // The default comparator - class DefaultComparator { - public: - PRBool Equals(const elem_type& a, const elem_type& b) const { - return a == b; - } - PRBool LessThan(const elem_type& a, const elem_type& b) const { - return a < b; - } - }; - // 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. diff --git a/mozilla/xpcom/tests/TestTArray.cpp b/mozilla/xpcom/tests/TestTArray.cpp index 5b6050a2582..9ba89c04d1c 100644 --- a/mozilla/xpcom/tests/TestTArray.cpp +++ b/mozilla/xpcom/tests/TestTArray.cpp @@ -229,6 +229,10 @@ static PRBool test_autoptr_array() { //---- +static PRBool operator==(const nsCString &a, const char *b) { + return a.Equals(b); +} + static PRBool test_string_array() { nsTArray strArray; const char kdata[] = "hello world"; @@ -241,6 +245,10 @@ static PRBool test_string_array() { if (strArray[i].CharAt(0) != kdata[i]) return PR_FALSE; } + + if (strArray.IndexOf("e") != 1) + return PR_FALSE; + strArray.Sort(); const char ksorted[] = "\0 dehllloorw"; for (i = 0; i < NS_ARRAY_LENGTH(kdata)-1; ++i) { @@ -257,8 +265,18 @@ static PRBool test_string_array() { //---- +typedef nsCOMPtr FilePointer; + +class nsFileNameComparator { + public: + PRBool Equals(const FilePointer &a, const char *b) const { + nsCAutoString name; + a->GetNativeLeafName(name); + return name.Equals(b); + } +}; + static PRBool test_comptr_array() { - typedef nsCOMPtr FilePointer; FilePointer tmpDir; NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tmpDir)); if (!tmpDir) @@ -277,6 +295,10 @@ static PRBool test_comptr_array() { return PR_FALSE; fileArray.AppendElement(f); } + + if (fileArray.IndexOf(kNames[1], nsFileNameComparator()) != 1) + return PR_FALSE; + // It's unclear what 'operator<' means for nsCOMPtr, but whatever... return test_basic_array(fileArray.Elements(), fileArray.Length(), tmpDir); @@ -284,6 +306,45 @@ static PRBool test_comptr_array() { //---- +class RefcountedObject { + public: + RefcountedObject() : rc(0) {} + void AddRef() { + ++rc; + } + void Release() { + if (--rc == 0) + delete this; + } + private: + ~RefcountedObject() {} + PRInt32 rc; +}; + +static PRBool test_refptr_array() { + PRBool rv = PR_TRUE; + + nsTArray< nsRefPtr > objArray; + + RefcountedObject *a = new RefcountedObject(); a->AddRef(); + RefcountedObject *b = new RefcountedObject(); b->AddRef(); + RefcountedObject *c = new RefcountedObject(); c->AddRef(); + + objArray.AppendElement(a); + objArray.AppendElement(b); + objArray.AppendElement(c); + + if (objArray.IndexOf(b) != 1) + rv = PR_FALSE; + + a->Release(); + b->Release(); + c->Release(); + return rv; +} + +//---- + typedef PRBool (*TestFunc)(); #define DECL_TEST(name) { #name, name } @@ -298,6 +359,7 @@ static const struct Test { DECL_TEST(test_object_array), DECL_TEST(test_string_array), DECL_TEST(test_comptr_array), + DECL_TEST(test_refptr_array), { nsnull, nsnull } };