Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(434)

Side by Side Diff: include/core/SkTSearch.h

Issue 15070011: One SkTSearch to rule them all. Allow key to be of different type than the array. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: fixes to compile on gcc Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/core/SkBitmapHeap.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2006 The Android Open Source Project 3 * Copyright 2006 The Android Open Source Project
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 9
10 #ifndef SkTSearch_DEFINED 10 #ifndef SkTSearch_DEFINED
(...skipping 12 matching lines...) Expand all
23 * 23 *
24 * int index = SkTSearch(...); 24 * int index = SkTSearch(...);
25 * if (index >= 0) { 25 * if (index >= 0) {
26 * // found at index 26 * // found at index
27 * } else { 27 * } else {
28 * index = ~index; // now we are positive 28 * index = ~index; // now we are positive
29 * // insert at index 29 * // insert at index
30 * } 30 * }
31 */ 31 */
32 32
33 template <typename T>
34 int SkTSearch(const T* base, int count, const T& target, size_t elemSize)
35 {
36 SkASSERT(count >= 0);
37 if (count <= 0)
38 return ~0;
39 33
40 SkASSERT(base != NULL); // base may be NULL if count is zero 34 // The most general form of SkTSearch takes an array of T and a key of type K. A functor, less, is
41 35 // used to perform comparisons. It has two function operators:
42 int lo = 0; 36 // bool operator() (const T& t, const K& k)
43 int hi = count - 1; 37 // bool operator() (const K& t, const T& k)
44 38 template <typename T, typename K, typename LESS>
45 while (lo < hi) 39 int SkTSearch(const T base[], int count, const K& key, size_t elemSize, LESS& le ss)
46 {
47 int mid = (hi + lo) >> 1;
48 const T* elem = (const T*)((const char*)base + mid * elemSize);
49
50 if (*elem < target)
51 lo = mid + 1;
52 else
53 hi = mid;
54 }
55
56 const T* elem = (const T*)((const char*)base + hi * elemSize);
57 if (*elem != target)
58 {
59 if (*elem < target)
60 hi += 1;
61 hi = ~hi;
62 }
63 return hi;
64 }
65
66 template <typename T, int (COMPARE)(const T*, const T*)>
67 int SkTSearch(const T* base, int count, const T& target, size_t elemSize)
68 { 40 {
69 SkASSERT(count >= 0); 41 SkASSERT(count >= 0);
70 if (count <= 0) { 42 if (count <= 0) {
71 return ~0; 43 return ~0;
72 } 44 }
73 45
74 SkASSERT(base != NULL); // base may be NULL if count is zero 46 SkASSERT(base != NULL); // base may be NULL if count is zero
75 47
76 int lo = 0; 48 int lo = 0;
77 int hi = count - 1; 49 int hi = count - 1;
78 50
79 while (lo < hi) { 51 while (lo < hi) {
80 int mid = (hi + lo) >> 1; 52 int mid = (hi + lo) >> 1;
81 const T* elem = (const T*)((const char*)base + mid * elemSize); 53 const T* elem = (const T*)((const char*)base + mid * elemSize);
82 54
83 if (COMPARE(elem, &target) < 0) 55 if (less(*elem, key))
84 lo = mid + 1; 56 lo = mid + 1;
85 else 57 else
86 hi = mid; 58 hi = mid;
87 } 59 }
88 60
89 const T* elem = (const T*)((const char*)base + hi * elemSize); 61 const T* elem = (const T*)((const char*)base + hi * elemSize);
90 int pred = COMPARE(elem, &target); 62 if (less(*elem, key)) {
91 if (pred != 0) { 63 hi += 1;
92 if (pred < 0) 64 hi = ~hi;
93 hi += 1; 65 } else if (less(key, *elem)) {
94 hi = ~hi; 66 hi = ~hi;
95 } 67 }
96 return hi; 68 return hi;
97 } 69 }
98 70
99 template <typename T> 71 // Adapts a less-than function to a functor.
100 int SkTSearch(const T* base, int count, const T& target, size_t elemSize, 72 template <typename T, bool (LESS)(const T&, const T&)> struct SkTLessFunctionToF unctorAdaptor {
101 int (*compare)(const T*, const T*)) 73 bool operator()(const T& a, const T& b) { return LESS(a, b); }
102 { 74 };
103 SkASSERT(count >= 0);
104 if (count <= 0) {
105 return ~0;
106 }
107 75
108 SkASSERT(base != NULL); // base may be NULL if count is zero 76 // Specialization for case when T==K and the caller wants to use a function rath er than functor.
109 77 template <typename T, bool (LESS)(const T&, const T&)>
110 int lo = 0; 78 int SkTSearch(const T base[], int count, const T& target, size_t elemSize) {
111 int hi = count - 1; 79 static SkTLessFunctionToFunctorAdaptor<T, LESS> functor;
112 80 return SkTSearch(base, count, target, elemSize, functor);
113 while (lo < hi) {
114 int mid = (hi + lo) >> 1;
115 const T* elem = (const T*)((const char*)base + mid * elemSize);
116
117 if ((*compare)(elem, &target) < 0)
118 lo = mid + 1;
119 else
120 hi = mid;
121 }
122
123 const T* elem = (const T*)((const char*)base + hi * elemSize);
124 int pred = (*compare)(elem, &target);
125 if (pred != 0) {
126 if (pred < 0)
127 hi += 1;
128 hi = ~hi;
129 }
130 return hi;
131 } 81 }
132 82
83 // Adapts operator < to a functor.
84 template <typename T> struct SkTLessFunctor {
85 bool operator()(const T& a, const T& b) { return a < b; }
86 };
87
88 // Specialization for T==K, compare using op <.
133 template <typename T> 89 template <typename T>
134 int SkTSearch(const T** base, int count, const T* target, size_t elemSize, 90 int SkTSearch(const T base[], int count, const T& target, size_t elemSize) {
135 int (*compare)(const T*, const T*)) 91 static SkTLessFunctor<T> functor;
136 { 92 return SkTSearch(base, count, target, elemSize, functor);
137 SkASSERT(count >= 0);
138 if (count <= 0)
139 return ~0;
140
141 SkASSERT(base != NULL); // base may be NULL if count is zero
142
143 int lo = 0;
144 int hi = count - 1;
145
146 while (lo < hi)
147 {
148 int mid = (hi + lo) >> 1;
149 const T* elem = *(const T**)((const char*)base + mid * elemSize);
150
151 if ((*compare)(elem, target) < 0)
152 lo = mid + 1;
153 else
154 hi = mid;
155 }
156
157 const T* elem = *(const T**)((const char*)base + hi * elemSize);
158 int pred = (*compare)(elem, target);
159 if (pred != 0)
160 {
161 if (pred < 0)
162 hi += 1;
163 hi = ~hi;
164 }
165 return hi;
166 } 93 }
167 94
168 template <typename T, int (COMPARE)(const T*, const T*)> 95 // Similar to SkLessFunctionToFunctorAdaptor but makes the functor interface tak e T* rather than T.
169 int SkTSearch(const T** base, int count, const T* target, size_t elemSize) 96 template <typename T, bool (LESS)(const T&, const T&)> struct SkTLessFunctionToP trFunctorAdaptor {
170 { 97 bool operator() (const T* t, const T* k) { return LESS(*t, *k); }
171 SkASSERT(count >= 0); 98 };
172 if (count <= 0)
173 return ~0;
174 99
175 SkASSERT(base != NULL); // base may be NULL if count is zero 100 // Specialization for case where domain is an array of T* and the key value is a T*, and you want
101 // to compare the T objects, not the pointers.
102 template <typename T, bool (LESS)(const T&, const T&)>
103 int SkTSearch(T* base[], int count, T* target, size_t elemSize) {
104 static SkTLessFunctionToPtrFunctorAdaptor<T, LESS> functor;
105 return SkTSearch(base, count, target, elemSize, functor);
106 }
176 107
177 int lo = 0;
178 int hi = count - 1;
179
180 while (lo < hi)
181 {
182 int mid = (hi + lo) >> 1;
183 const T* elem = *(const T**)((const char*)base + mid * elemSize);
184
185 if (COMPARE(elem, target) < 0)
186 lo = mid + 1;
187 else
188 hi = mid;
189 }
190
191 const T* elem = *(const T**)((const char*)base + hi * elemSize);
192 int pred = COMPARE(elem, target);
193 if (pred != 0)
194 {
195 if (pred < 0)
196 hi += 1;
197 hi = ~hi;
198 }
199 return hi;
200 }
201 int SkStrSearch(const char*const* base, int count, const char target[], 108 int SkStrSearch(const char*const* base, int count, const char target[],
202 size_t target_len, size_t elemSize); 109 size_t target_len, size_t elemSize);
203 int SkStrSearch(const char*const* base, int count, const char target[], 110 int SkStrSearch(const char*const* base, int count, const char target[],
204 size_t elemSize); 111 size_t elemSize);
205 112
206 /** Like SkStrSearch, but treats target as if it were all lower-case. Assumes th at 113 /** Like SkStrSearch, but treats target as if it were all lower-case. Assumes th at
207 base points to a table of lower-case strings. 114 base points to a table of lower-case strings.
208 */ 115 */
209 int SkStrLCSearch(const char*const* base, int count, const char target[], 116 int SkStrLCSearch(const char*const* base, int count, const char target[],
210 size_t target_len, size_t elemSize); 117 size_t target_len, size_t elemSize);
(...skipping 19 matching lines...) Expand all
230 enum { 137 enum {
231 STORAGE = 64 138 STORAGE = 64
232 }; 139 };
233 char fStorage[STORAGE+1]; 140 char fStorage[STORAGE+1];
234 }; 141 };
235 142
236 // Helper when calling qsort with a compare proc that has typed its arguments 143 // Helper when calling qsort with a compare proc that has typed its arguments
237 #define SkCastForQSort(compare) reinterpret_cast<int (*)(const void*, const void *)>(compare) 144 #define SkCastForQSort(compare) reinterpret_cast<int (*)(const void*, const void *)>(compare)
238 145
239 #endif 146 #endif
OLDNEW
« no previous file with comments | « no previous file | src/core/SkBitmapHeap.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698