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

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: Make functor for op < variant of SkTSearch, some renamings 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&)>
101 int (*compare)(const T*, const T*)) 73 class SkTLessFunctionToFunctorAdaptor {
bungeman-skia 2013/05/16 22:00:39 If this were a struct there would be no need for t
bsalomon 2013/05/17 14:24:30 Done.
102 { 74 public:
103 SkASSERT(count >= 0); 75 bool operator()(const T& a, const T& b) { return LESS(a, b); }
104 if (count <= 0) { 76 };
105 return ~0;
106 }
107 77
108 SkASSERT(base != NULL); // base may be NULL if count is zero 78 // Specialization for case when T==K and the caller wants to use a function rath er than functor.
109 79 template <typename T, bool (LESS)(const T&, const T&)>
110 int lo = 0; 80 int SkTSearch(const T base[], int count, const T& target, size_t elemSize) {
111 int hi = count - 1; 81 typedef SkTLessFunctionToFunctorAdaptor<T, LESS> Functor;
112 82 Functor functor;
113 while (lo < hi) { 83 return SkTSearch<T, T, Functor>(base, count, target, elemSize, functor);
bungeman-skia 2013/05/16 22:00:39 I think this can just be return SkTSearch(base, c
bsalomon 2013/05/17 14:24:30 Done.
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 } 84 }
132 85
86 // Adapts operator < to a functor.
87 template <typename T> struct SkTLessFunctor {
88 public:
bungeman-skia 2013/05/16 22:00:39 nit: This is a struct, so public is already implie
bsalomon 2013/05/17 14:24:30 Done.
89 bool operator()(const T& a, const T& b) { return a < b; }
90 };
91
92 // Specialization for T==K, compare using op <.
133 template <typename T> 93 template <typename T>
134 int SkTSearch(const T** base, int count, const T* target, size_t elemSize, 94 int SkTSearch(const T base[], int count, const T& target, size_t elemSize) {
135 int (*compare)(const T*, const T*)) 95 SkTLessFunctor<T> functor;
136 { 96 return SkTSearch<T, T, SkTLessFunctor<T> >(base, count, target, elemSize, fu nctor);
bungeman-skia 2013/05/16 22:00:39 This line can probably be return SkTSearch(base,
bsalomon 2013/05/17 14:24:30 Done. I'll leave fighting the const battle for ano
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 } 97 }
167 98
168 template <typename T, int (COMPARE)(const T*, const T*)> 99 // 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) 100 template <typename T, bool (LESS)(const T&, const T&)>
170 { 101 class SkTLessFunctionToPtrFunctorAdaptor {
bungeman-skia 2013/05/16 22:00:39 If this were a struct there would be no need for t
bsalomon 2013/05/17 14:24:30 Done.
171 SkASSERT(count >= 0); 102 public:
172 if (count <= 0) 103 bool operator() (const T* t, const T* k) { return LESS(*t, *k); }
173 return ~0; 104 };
174 105
175 SkASSERT(base != NULL); // base may be NULL if count is zero 106 // Specialization for case where domain is an array of T* and the key value is a T*, and you want
107 // to compare the T objects, not the pointers.
108 template <typename T, bool (LESS)(const T&, const T&)>
109 int SkTSearch(T* base[], int count, T* target, size_t elemSize) {
110 typedef SkTLessFunctionToPtrFunctorAdaptor<T, LESS> Functor;
111 Functor functor;
112 return SkTSearch<T*, T*, Functor>(base, count, target, elemSize, functor);
bungeman-skia 2013/05/16 22:00:39 Likewise, this line can probably be return SkTSea
bsalomon 2013/05/17 14:24:30 Actually only 99!
113 }
176 114
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[], 115 int SkStrSearch(const char*const* base, int count, const char target[],
202 size_t target_len, size_t elemSize); 116 size_t target_len, size_t elemSize);
203 int SkStrSearch(const char*const* base, int count, const char target[], 117 int SkStrSearch(const char*const* base, int count, const char target[],
204 size_t elemSize); 118 size_t elemSize);
205 119
206 /** Like SkStrSearch, but treats target as if it were all lower-case. Assumes th at 120 /** 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. 121 base points to a table of lower-case strings.
208 */ 122 */
209 int SkStrLCSearch(const char*const* base, int count, const char target[], 123 int SkStrLCSearch(const char*const* base, int count, const char target[],
210 size_t target_len, size_t elemSize); 124 size_t target_len, size_t elemSize);
(...skipping 19 matching lines...) Expand all
230 enum { 144 enum {
231 STORAGE = 64 145 STORAGE = 64
232 }; 146 };
233 char fStorage[STORAGE+1]; 147 char fStorage[STORAGE+1];
234 }; 148 };
235 149
236 // Helper when calling qsort with a compare proc that has typed its arguments 150 // 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) 151 #define SkCastForQSort(compare) reinterpret_cast<int (*)(const void*, const void *)>(compare)
238 152
239 #endif 153 #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