gfx/skia/trunk/include/core/SkTSearch.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1
michael@0 2 /*
michael@0 3 * Copyright 2006 The Android Open Source Project
michael@0 4 *
michael@0 5 * Use of this source code is governed by a BSD-style license that can be
michael@0 6 * found in the LICENSE file.
michael@0 7 */
michael@0 8
michael@0 9
michael@0 10 #ifndef SkTSearch_DEFINED
michael@0 11 #define SkTSearch_DEFINED
michael@0 12
michael@0 13 #include "SkTypes.h"
michael@0 14
michael@0 15 /**
michael@0 16 * All of the SkTSearch variants want to return the index (0...N-1) of the
michael@0 17 * found element, or the bit-not of where to insert the element.
michael@0 18 *
michael@0 19 * At a simple level, if the return value is negative, it was not found.
michael@0 20 *
michael@0 21 * For clients that want to insert the new element if it was not found, use
michael@0 22 * the following logic:
michael@0 23 *
michael@0 24 * int index = SkTSearch(...);
michael@0 25 * if (index >= 0) {
michael@0 26 * // found at index
michael@0 27 * } else {
michael@0 28 * index = ~index; // now we are positive
michael@0 29 * // insert at index
michael@0 30 * }
michael@0 31 */
michael@0 32
michael@0 33
michael@0 34 // The most general form of SkTSearch takes an array of T and a key of type K. A functor, less, is
michael@0 35 // used to perform comparisons. It has two function operators:
michael@0 36 // bool operator() (const T& t, const K& k)
michael@0 37 // bool operator() (const K& t, const T& k)
michael@0 38 template <typename T, typename K, typename LESS>
michael@0 39 int SkTSearch(const T base[], int count, const K& key, size_t elemSize, LESS& less)
michael@0 40 {
michael@0 41 SkASSERT(count >= 0);
michael@0 42 if (count <= 0) {
michael@0 43 return ~0;
michael@0 44 }
michael@0 45
michael@0 46 SkASSERT(base != NULL); // base may be NULL if count is zero
michael@0 47
michael@0 48 int lo = 0;
michael@0 49 int hi = count - 1;
michael@0 50
michael@0 51 while (lo < hi) {
michael@0 52 int mid = (hi + lo) >> 1;
michael@0 53 const T* elem = (const T*)((const char*)base + mid * elemSize);
michael@0 54
michael@0 55 if (less(*elem, key))
michael@0 56 lo = mid + 1;
michael@0 57 else
michael@0 58 hi = mid;
michael@0 59 }
michael@0 60
michael@0 61 const T* elem = (const T*)((const char*)base + hi * elemSize);
michael@0 62 if (less(*elem, key)) {
michael@0 63 hi += 1;
michael@0 64 hi = ~hi;
michael@0 65 } else if (less(key, *elem)) {
michael@0 66 hi = ~hi;
michael@0 67 }
michael@0 68 return hi;
michael@0 69 }
michael@0 70
michael@0 71 // Adapts a less-than function to a functor.
michael@0 72 template <typename T, bool (LESS)(const T&, const T&)> struct SkTLessFunctionToFunctorAdaptor {
michael@0 73 bool operator()(const T& a, const T& b) { return LESS(a, b); }
michael@0 74 };
michael@0 75
michael@0 76 // Specialization for case when T==K and the caller wants to use a function rather than functor.
michael@0 77 template <typename T, bool (LESS)(const T&, const T&)>
michael@0 78 int SkTSearch(const T base[], int count, const T& target, size_t elemSize) {
michael@0 79 static SkTLessFunctionToFunctorAdaptor<T, LESS> functor;
michael@0 80 return SkTSearch(base, count, target, elemSize, functor);
michael@0 81 }
michael@0 82
michael@0 83 // Adapts operator < to a functor.
michael@0 84 template <typename T> struct SkTLessFunctor {
michael@0 85 bool operator()(const T& a, const T& b) { return a < b; }
michael@0 86 };
michael@0 87
michael@0 88 // Specialization for T==K, compare using op <.
michael@0 89 template <typename T>
michael@0 90 int SkTSearch(const T base[], int count, const T& target, size_t elemSize) {
michael@0 91 static SkTLessFunctor<T> functor;
michael@0 92 return SkTSearch(base, count, target, elemSize, functor);
michael@0 93 }
michael@0 94
michael@0 95 // Similar to SkLessFunctionToFunctorAdaptor but makes the functor interface take T* rather than T.
michael@0 96 template <typename T, bool (LESS)(const T&, const T&)> struct SkTLessFunctionToPtrFunctorAdaptor {
michael@0 97 bool operator() (const T* t, const T* k) { return LESS(*t, *k); }
michael@0 98 };
michael@0 99
michael@0 100 // Specialization for case where domain is an array of T* and the key value is a T*, and you want
michael@0 101 // to compare the T objects, not the pointers.
michael@0 102 template <typename T, bool (LESS)(const T&, const T&)>
michael@0 103 int SkTSearch(T* base[], int count, T* target, size_t elemSize) {
michael@0 104 static SkTLessFunctionToPtrFunctorAdaptor<T, LESS> functor;
michael@0 105 return SkTSearch(base, count, target, elemSize, functor);
michael@0 106 }
michael@0 107
michael@0 108 int SkStrSearch(const char*const* base, int count, const char target[],
michael@0 109 size_t target_len, size_t elemSize);
michael@0 110 int SkStrSearch(const char*const* base, int count, const char target[],
michael@0 111 size_t elemSize);
michael@0 112
michael@0 113 /** Like SkStrSearch, but treats target as if it were all lower-case. Assumes that
michael@0 114 base points to a table of lower-case strings.
michael@0 115 */
michael@0 116 int SkStrLCSearch(const char*const* base, int count, const char target[],
michael@0 117 size_t target_len, size_t elemSize);
michael@0 118 int SkStrLCSearch(const char*const* base, int count, const char target[],
michael@0 119 size_t elemSize);
michael@0 120
michael@0 121 /** Helper class to convert a string to lower-case, but only modifying the ascii
michael@0 122 characters. This makes the routine very fast and never changes the string
michael@0 123 length, but it is not suitable for linguistic purposes. Normally this is
michael@0 124 used for buiding and searching string tables.
michael@0 125 */
michael@0 126 class SkAutoAsciiToLC {
michael@0 127 public:
michael@0 128 SkAutoAsciiToLC(const char str[], size_t len = (size_t)-1);
michael@0 129 ~SkAutoAsciiToLC();
michael@0 130
michael@0 131 const char* lc() const { return fLC; }
michael@0 132 size_t length() const { return fLength; }
michael@0 133
michael@0 134 private:
michael@0 135 char* fLC; // points to either the heap or fStorage
michael@0 136 size_t fLength;
michael@0 137 enum {
michael@0 138 STORAGE = 64
michael@0 139 };
michael@0 140 char fStorage[STORAGE+1];
michael@0 141 };
michael@0 142
michael@0 143 // Helper when calling qsort with a compare proc that has typed its arguments
michael@0 144 #define SkCastForQSort(compare) reinterpret_cast<int (*)(const void*, const void*)>(compare)
michael@0 145
michael@0 146 #endif

mercurial