| Index: include/core/SkTSearch.h
|
| diff --git a/include/core/SkTSearch.h b/include/core/SkTSearch.h
|
| index eaf5ee5934941e2552b6b519369854c7835b15d2..a4e4994ef378b2b14a39c1da2daa601c35677f71 100644
|
| --- a/include/core/SkTSearch.h
|
| +++ b/include/core/SkTSearch.h
|
| @@ -30,41 +30,13 @@
|
| * }
|
| */
|
|
|
| -template <typename T>
|
| -int SkTSearch(const T* base, int count, const T& target, size_t elemSize)
|
| -{
|
| - SkASSERT(count >= 0);
|
| - if (count <= 0)
|
| - return ~0;
|
| -
|
| - SkASSERT(base != NULL); // base may be NULL if count is zero
|
| -
|
| - int lo = 0;
|
| - int hi = count - 1;
|
| -
|
| - while (lo < hi)
|
| - {
|
| - int mid = (hi + lo) >> 1;
|
| - const T* elem = (const T*)((const char*)base + mid * elemSize);
|
| -
|
| - if (*elem < target)
|
| - lo = mid + 1;
|
| - else
|
| - hi = mid;
|
| - }
|
| -
|
| - const T* elem = (const T*)((const char*)base + hi * elemSize);
|
| - if (*elem != target)
|
| - {
|
| - if (*elem < target)
|
| - hi += 1;
|
| - hi = ~hi;
|
| - }
|
| - return hi;
|
| -}
|
|
|
| -template <typename T, int (COMPARE)(const T*, const T*)>
|
| -int SkTSearch(const T* base, int count, const T& target, size_t elemSize)
|
| +// The most general form of SkTSearch takes an array of T and a key of type K. A functor, less, is
|
| +// used to perform comparisons. It has two function operators:
|
| +// bool operator() (const T& t, const K& k)
|
| +// bool operator() (const K& t, const T& k)
|
| +template <typename T, typename K, typename LESS>
|
| +int SkTSearch(const T base[], int count, const K& key, size_t elemSize, LESS& less)
|
| {
|
| SkASSERT(count >= 0);
|
| if (count <= 0) {
|
| @@ -80,124 +52,59 @@ int SkTSearch(const T* base, int count, const T& target, size_t elemSize)
|
| int mid = (hi + lo) >> 1;
|
| const T* elem = (const T*)((const char*)base + mid * elemSize);
|
|
|
| - if (COMPARE(elem, &target) < 0)
|
| + if (less(*elem, key))
|
| lo = mid + 1;
|
| else
|
| hi = mid;
|
| }
|
|
|
| const T* elem = (const T*)((const char*)base + hi * elemSize);
|
| - int pred = COMPARE(elem, &target);
|
| - if (pred != 0) {
|
| - if (pred < 0)
|
| - hi += 1;
|
| + if (less(*elem, key)) {
|
| + hi += 1;
|
| hi = ~hi;
|
| - }
|
| - return hi;
|
| -}
|
| -
|
| -template <typename T>
|
| -int SkTSearch(const T* base, int count, const T& target, size_t elemSize,
|
| - int (*compare)(const T*, const T*))
|
| -{
|
| - SkASSERT(count >= 0);
|
| - if (count <= 0) {
|
| - return ~0;
|
| - }
|
| -
|
| - SkASSERT(base != NULL); // base may be NULL if count is zero
|
| -
|
| - int lo = 0;
|
| - int hi = count - 1;
|
| -
|
| - while (lo < hi) {
|
| - int mid = (hi + lo) >> 1;
|
| - const T* elem = (const T*)((const char*)base + mid * elemSize);
|
| -
|
| - if ((*compare)(elem, &target) < 0)
|
| - lo = mid + 1;
|
| - else
|
| - hi = mid;
|
| - }
|
| -
|
| - const T* elem = (const T*)((const char*)base + hi * elemSize);
|
| - int pred = (*compare)(elem, &target);
|
| - if (pred != 0) {
|
| - if (pred < 0)
|
| - hi += 1;
|
| + } else if (less(key, *elem)) {
|
| hi = ~hi;
|
| }
|
| return hi;
|
| }
|
|
|
| -template <typename T>
|
| -int SkTSearch(const T** base, int count, const T* target, size_t elemSize,
|
| - int (*compare)(const T*, const T*))
|
| -{
|
| - SkASSERT(count >= 0);
|
| - if (count <= 0)
|
| - return ~0;
|
| -
|
| - SkASSERT(base != NULL); // base may be NULL if count is zero
|
| -
|
| - int lo = 0;
|
| - int hi = count - 1;
|
| -
|
| - while (lo < hi)
|
| - {
|
| - int mid = (hi + lo) >> 1;
|
| - const T* elem = *(const T**)((const char*)base + mid * elemSize);
|
| -
|
| - if ((*compare)(elem, target) < 0)
|
| - lo = mid + 1;
|
| - else
|
| - hi = mid;
|
| - }
|
| +// Adapts a less-than function to a functor.
|
| +template <typename T, bool (LESS)(const T&, const T&)> struct SkTLessFunctionToFunctorAdaptor {
|
| + bool operator()(const T& a, const T& b) { return LESS(a, b); }
|
| +};
|
|
|
| - const T* elem = *(const T**)((const char*)base + hi * elemSize);
|
| - int pred = (*compare)(elem, target);
|
| - if (pred != 0)
|
| - {
|
| - if (pred < 0)
|
| - hi += 1;
|
| - hi = ~hi;
|
| - }
|
| - return hi;
|
| +// Specialization for case when T==K and the caller wants to use a function rather than functor.
|
| +template <typename T, bool (LESS)(const T&, const T&)>
|
| +int SkTSearch(const T base[], int count, const T& target, size_t elemSize) {
|
| + static SkTLessFunctionToFunctorAdaptor<T, LESS> functor;
|
| + return SkTSearch(base, count, target, elemSize, functor);
|
| }
|
|
|
| -template <typename T, int (COMPARE)(const T*, const T*)>
|
| -int SkTSearch(const T** base, int count, const T* target, size_t elemSize)
|
| -{
|
| - SkASSERT(count >= 0);
|
| - if (count <= 0)
|
| - return ~0;
|
| -
|
| - SkASSERT(base != NULL); // base may be NULL if count is zero
|
| -
|
| - int lo = 0;
|
| - int hi = count - 1;
|
| +// Adapts operator < to a functor.
|
| +template <typename T> struct SkTLessFunctor {
|
| + bool operator()(const T& a, const T& b) { return a < b; }
|
| +};
|
|
|
| - while (lo < hi)
|
| - {
|
| - int mid = (hi + lo) >> 1;
|
| - const T* elem = *(const T**)((const char*)base + mid * elemSize);
|
| +// Specialization for T==K, compare using op <.
|
| +template <typename T>
|
| +int SkTSearch(const T base[], int count, const T& target, size_t elemSize) {
|
| + static SkTLessFunctor<T> functor;
|
| + return SkTSearch(base, count, target, elemSize, functor);
|
| +}
|
|
|
| - if (COMPARE(elem, target) < 0)
|
| - lo = mid + 1;
|
| - else
|
| - hi = mid;
|
| - }
|
| +// Similar to SkLessFunctionToFunctorAdaptor but makes the functor interface take T* rather than T.
|
| +template <typename T, bool (LESS)(const T&, const T&)> struct SkTLessFunctionToPtrFunctorAdaptor {
|
| + bool operator() (const T* t, const T* k) { return LESS(*t, *k); }
|
| +};
|
|
|
| - const T* elem = *(const T**)((const char*)base + hi * elemSize);
|
| - int pred = COMPARE(elem, target);
|
| - if (pred != 0)
|
| - {
|
| - if (pred < 0)
|
| - hi += 1;
|
| - hi = ~hi;
|
| - }
|
| - return hi;
|
| +// Specialization for case where domain is an array of T* and the key value is a T*, and you want
|
| +// to compare the T objects, not the pointers.
|
| +template <typename T, bool (LESS)(const T&, const T&)>
|
| +int SkTSearch(T* base[], int count, T* target, size_t elemSize) {
|
| + static SkTLessFunctionToPtrFunctorAdaptor<T, LESS> functor;
|
| + return SkTSearch(base, count, target, elemSize, functor);
|
| }
|
| +
|
| int SkStrSearch(const char*const* base, int count, const char target[],
|
| size_t target_len, size_t elemSize);
|
| int SkStrSearch(const char*const* base, int count, const char target[],
|
|
|