summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsky@google.com <sky@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-24 05:14:04 +0000
committersky@google.com <sky@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-24 05:14:04 +0000
commit07ae2c333da12779c87eefcd65f4272e389766f3 (patch)
treed13dc876544bd5b65e00f1e4db8573c4551dcf8d
parenta53ef0492a5c34542d5b1d607f848fb7b45002ba (diff)
downloadchromium_src-07ae2c333da12779c87eefcd65f4272e389766f3.zip
chromium_src-07ae2c333da12779c87eefcd65f4272e389766f3.tar.gz
chromium_src-07ae2c333da12779c87eefcd65f4272e389766f3.tar.bz2
Adds a method to sort the elements of a vector by invoking a method on
each that returns a string. The strings are then compared using a collator, or operator < if no collator is found. I'm going to use this for sorting bookmarks. BUG=1750 TEST=none yet Review URL: http://codereview.chromium.org/20484 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10252 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/common/l10n_util.cc60
-rw-r--r--chrome/common/l10n_util.h70
-rw-r--r--chrome/common/l10n_util_unittest.cc32
3 files changed, 127 insertions, 35 deletions
diff --git a/chrome/common/l10n_util.cc b/chrome/common/l10n_util.cc
index 6fb5286..c576a4b 100644
--- a/chrome/common/l10n_util.cc
+++ b/chrome/common/l10n_util.cc
@@ -25,8 +25,6 @@
#if defined(OS_WIN)
#include "chrome/views/view.h"
#endif // defined(OS_WIN)
-#include "unicode/rbbi.h"
-#include "unicode/uchar.h"
// TODO(playmobil): remove this undef once SkPostConfig.h is fixed.
// skia/include/corecg/SkPostConfig.h #defines strcasecmp() so we can't use
@@ -210,35 +208,6 @@ std::wstring GetSystemLocale() {
return ASCIIToWide(ret);
}
-// Compares the character data stored in two different strings by specified
-// Collator instance.
-UCollationResult CompareStringWithCollator(const Collator* collator,
- const std::wstring& lhs,
- const std::wstring& rhs) {
- DCHECK(collator);
- UErrorCode error = U_ZERO_ERROR;
-#if defined(WCHAR_T_IS_UTF32)
- // Need to convert to UTF-16 to be compatible with UnicodeString's
- // constructor.
- string16 lhs_utf16 = WideToUTF16(lhs);
- string16 rhs_utf16 = WideToUTF16(rhs);
-
- UCollationResult result = collator->compare(
- static_cast<const UChar*>(lhs_utf16.c_str()),
- static_cast<int>(lhs_utf16.length()),
- static_cast<const UChar*>(rhs_utf16.c_str()),
- static_cast<int>(rhs_utf16.length()),
- error);
-#else
- UCollationResult result = collator->compare(
- static_cast<const UChar*>(lhs.c_str()), static_cast<int>(lhs.length()),
- static_cast<const UChar*>(rhs.c_str()), static_cast<int>(rhs.length()),
- error);
-#endif
- DCHECK(U_SUCCESS(error));
- return result;
-}
-
} // namespace
namespace l10n_util {
@@ -671,6 +640,35 @@ void HWNDSetRTLLayout(HWND hwnd) {
}
#endif // defined(OS_WIN)
+// Compares the character data stored in two different strings by specified
+// Collator instance.
+UCollationResult CompareStringWithCollator(const Collator* collator,
+ const std::wstring& lhs,
+ const std::wstring& rhs) {
+ DCHECK(collator);
+ UErrorCode error = U_ZERO_ERROR;
+#if defined(WCHAR_T_IS_UTF32)
+ // Need to convert to UTF-16 to be compatible with UnicodeString's
+ // constructor.
+ string16 lhs_utf16 = WideToUTF16(lhs);
+ string16 rhs_utf16 = WideToUTF16(rhs);
+
+ UCollationResult result = collator->compare(
+ static_cast<const UChar*>(lhs_utf16.c_str()),
+ static_cast<int>(lhs_utf16.length()),
+ static_cast<const UChar*>(rhs_utf16.c_str()),
+ static_cast<int>(rhs_utf16.length()),
+ error);
+#else
+ UCollationResult result = collator->compare(
+ static_cast<const UChar*>(lhs.c_str()), static_cast<int>(lhs.length()),
+ static_cast<const UChar*>(rhs.c_str()), static_cast<int>(rhs.length()),
+ error);
+#endif
+ DCHECK(U_SUCCESS(error));
+ return result;
+}
+
// Specialization of operator() method for std::wstring version.
template <>
bool StringComparator<std::wstring>::operator()(const std::wstring& lhs,
diff --git a/chrome/common/l10n_util.h b/chrome/common/l10n_util.h
index c0a5d0d..51160cd 100644
--- a/chrome/common/l10n_util.h
+++ b/chrome/common/l10n_util.h
@@ -23,9 +23,11 @@
#include "base/scoped_ptr.h"
#include "base/string16.h"
#include "base/string_util.h"
-#include "third_party/icu38/public/common/unicode/ubidi.h"
#include "unicode/coll.h"
#include "unicode/locid.h"
+#include "unicode/rbbi.h"
+#include "unicode/ubidi.h"
+#include "unicode/uchar.h"
class FilePath;
class PrefService;
@@ -198,6 +200,72 @@ int DefaultCanvasTextAlignment();
void HWNDSetRTLLayout(HWND hwnd);
#endif
+// Compares the two strings using the specified collator.
+UCollationResult CompareStringWithCollator(const Collator* collator,
+ const std::wstring& lhs,
+ const std::wstring& rhs);
+
+// Used by SortStringsUsingMethod. Invokes a method on the objects passed to
+// operator (), comparing the string results using a collator.
+template <class T, class Method>
+class StringMethodComparatorWithCollator :
+ public std::binary_function<const std::wstring&,
+ const std::wstring&,
+ bool> {
+ public:
+ StringMethodComparatorWithCollator(Collator* collator, Method method)
+ : collator_(collator),
+ method_(method) { }
+
+ // Returns true if lhs preceeds rhs.
+ bool operator() (T* lhs_t, T* rhs_t) {
+ return CompareStringWithCollator(collator_, (lhs_t->*method_)(),
+ (rhs_t->*method_)()) == UCOL_LESS;
+ }
+
+ private:
+ Collator* collator_;
+ Method method_;
+};
+
+// Used by SortStringsUsingMethod. Invokes a method on the objects passed to
+// operator (), comparing the string results using <.
+template <class T, class Method>
+class StringMethodComparator : public std::binary_function<const std::wstring&,
+ const std::wstring&,
+ bool> {
+ public:
+ explicit StringMethodComparator(Method method) : method_(method) { }
+
+ // Returns true if lhs preceeds rhs.
+ bool operator() (T* lhs_t, T* rhs_t) {
+ return (lhs_t->*method_)() < (rhs_t->*method_)();
+ }
+
+ private:
+ Method method_;
+};
+
+// Sorts the objects in |elements| using the method |method|, which must return
+// a string. Sorting is done using a collator, unless a collator can not be
+// found in which case the strings are sorted using the operator <.
+template <class T, class Method>
+void SortStringsUsingMethod(const std::wstring& locale,
+ std::vector<T*>* elements,
+ Method method) {
+ UErrorCode error = U_ZERO_ERROR;
+ Locale loc(WideToUTF8(locale).c_str());
+ scoped_ptr<Collator> collator(Collator::createInstance(loc, error));
+ if (U_FAILURE(error)) {
+ sort(elements->begin(), elements->end(),
+ StringMethodComparator<T,Method>(method));
+ return;
+ }
+
+ std::sort(elements->begin(), elements->end(),
+ StringMethodComparatorWithCollator<T,Method>(collator.get(), method));
+}
+
// Compares two elements' string keys and returns true if the first element's
// string key is less than the second element's string key. The Element must
// have a method like the follow format to return the string key.
diff --git a/chrome/common/l10n_util_unittest.cc b/chrome/common/l10n_util_unittest.cc
index 88c1cad..b308ffa4 100644
--- a/chrome/common/l10n_util_unittest.cc
+++ b/chrome/common/l10n_util_unittest.cc
@@ -10,6 +10,7 @@
#include "base/string_util.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/l10n_util.h"
+#include "chrome/common/stl_util-inl.h"
#if !defined(OS_MACOSX)
#include "chrome/test/data/resource.h"
#endif
@@ -19,7 +20,20 @@
namespace {
-class L10nUtilTest: public PlatformTest {
+class StringWrapper {
+ public:
+ explicit StringWrapper(const std::wstring& string) : string_(string) {}
+ const std::wstring& string() const { return string_; }
+
+ private:
+ std::wstring string_;
+
+ DISALLOW_COPY_AND_ASSIGN(StringWrapper);
+};
+
+} // namespace
+
+class L10nUtilTest : public PlatformTest {
};
#if defined(OS_WIN)
@@ -160,6 +174,20 @@ TEST_F(L10nUtilTest, GetAppLocale) {
Locale::setDefault(locale, error_code);
}
+TEST_F(L10nUtilTest, SortStringsUsingFunction) {
+ std::vector<StringWrapper*> strings;
+ strings.push_back(new StringWrapper(L"C"));
+ strings.push_back(new StringWrapper(L"d"));
+ strings.push_back(new StringWrapper(L"b"));
+ strings.push_back(new StringWrapper(L"a"));
+ l10n_util::SortStringsUsingMethod(L"en-US", &strings, &StringWrapper::string);
+ ASSERT_TRUE(L"a" == strings[0]->string());
+ ASSERT_TRUE(L"b" == strings[1]->string());
+ ASSERT_TRUE(L"C" == strings[2]->string());
+ ASSERT_TRUE(L"d" == strings[3]->string());
+ STLDeleteElements(&strings);
+}
+
TEST_F(L10nUtilTest, GetFirstStrongCharacterDirection) {
// Test pure LTR string.
std::wstring string(L"foo bar");
@@ -334,5 +362,3 @@ TEST_F(L10nUtilTest, WrapPathWithLTRFormatting) {
EXPECT_EQ(wrapped_path, test_data[i].wrapped_path);
}
}
-}
-