/** *AlloftheSkTSearchvariantswanttoreturntheindex(0...N-1)ofthe *foundelement,orthebit-notofwheretoinserttheelement. * *Atasimplelevel,ifthereturnvalueisnegative,itwasnotfound. * *Forclientsthatwanttoinsertthenewelementifitwasnotfound,use *thefollowinglogic: * *intindex=SkTSearch(...); *if(index>=0){ *// found at index *}else{ *index=~index;// now we are positive *// insert at index *}
*/
// 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, const LESS& less)
{
SkASSERT(count >= 0); if (count <= 0) { return ~0;
}
SkASSERT(base != nullptr); // base may be nullptr if count is zero
int lo = 0; int hi = count - 1;
while (lo < hi) { int mid = lo + ((hi - lo) >> 1); const T* elem = (const T*)((constchar*)base + mid * elemSize);
if (less(*elem, key))
lo = mid + 1; else
hi = mid;
}
const T* elem = (const T*)((constchar*)base + hi * elemSize); if (less(*elem, key)) {
hi += 1;
hi = ~hi;
} elseif (less(key, *elem)) {
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) { return SkTSearch(base, count, target, elemSize,
[](const T& a, const T& b) { return LESS(a, b); });
}
// Specialization for T==K, compare using op <. template <typename T> int SkTSearch(const T base[], int count, const T& target, size_t elemSize) { return SkTSearch(base, count, target, elemSize, [](const T& a, const T& b) { return a < b; });
}
// 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) { return SkTSearch(base, count, target, elemSize,
[](const T* t, const T* k) { return LESS(*t, *k); });
}
int SkStrSearch(constchar*const* base, int count, constchar target[],
size_t target_len, size_t elemSize); int SkStrSearch(constchar*const* base, int count, constchar target[],
size_t elemSize);
/** Like SkStrSearch, but treats target as if it were all lower-case. Assumes that basepointstoatableoflower-casestrings.
*/ int SkStrLCSearch(constchar*const* base, int count, constchar target[],
size_t target_len, size_t elemSize); int SkStrLCSearch(constchar*const* base, int count, constchar target[],
size_t elemSize);
/** Helper class to convert a string to lower-case, but only modifying the ascii characters.Thismakestheroutineveryfastandneverchangesthestring length,butitisnotsuitableforlinguisticpurposes.Normallythisis usedforbuidingandsearchingstringtables.
*/ class [[nodiscard]] SkAutoAsciiToLC {
public:
SkAutoAsciiToLC(constchar str[], size_t len = (size_t)-1);
~SkAutoAsciiToLC();
private: char* fLC; // points to either the heap or fStorage
size_t fLength; enum {
STORAGE = 64
}; char fStorage[STORAGE+1];
};
// Helper when calling qsort with a compare proc that has typed its arguments #define SkCastForQSort(compare) reinterpret_cast<int (*)(constvoid*, constvoid*)>(compare)
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.