ScummVM API documentation
algorithm.h
1/* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22#ifndef COMMON_ALGORITHM_H
23#define COMMON_ALGORITHM_H
24
25#include "common/scummsys.h"
26#include "common/func.h"
27#include "common/util.h"
28
29namespace Common {
30
51template<class In, class Out>
52Out copy(In first, In last, Out dst) {
53 while (first != last)
54 *dst++ = *first++;
55 return dst;
56}
57
66template<class In, class Out>
67Out copy_backward(In first, In last, Out dst) {
68 while (first != last)
69 *--dst = *--last;
70 return dst;
71}
72
83template<class In, class Out, class Op>
84Out copy_if(In first, In last, Out dst, Op op) {
85 while (first != last) {
86 if (op(*first))
87 *dst++ = *first;
88 ++first;
89 }
90 return dst;
91}
92
108template<class In, class Out>
109Out move(In first, In last, Out dst) {
110 while (first != last)
111 *dst++ = Common::move(*first++);
112 return dst;
113}
114
123template<class In, class Out>
124Out move_backward(In first, In last, Out dst) {
125 while (first != last)
126 *--dst = Common::move(*--last);
127 return dst;
128}
129
140template<class In, class Out, class Op>
141Out move_if(In first, In last, Out dst, Op op) {
142 while (first != last) {
143 if (op(*first))
144 *dst++ = Common::move(*first);
145 ++first;
146 }
147 return dst;
148}
149
167template<class Value>
168signed char *fill(signed char *first, signed char *last, Value val) {
169 memset(first, (val & 0xFF), last - first);
170 return last;
171}
172
181template<class Value>
182unsigned char *fill(unsigned char *first, unsigned char *last, Value val) {
183 memset(first, (val & 0xFF), last - first);
184 return last;
185}
186
195template<class Value>
196char *fill(char *first, char *last, Value val) {
197 memset(first, (val & 0xFF), last - first);
198 return last;
199}
200
213template<class In, class Value>
214In fill(In first, In last, const Value &val) {
215 while (first != last)
216 *first++ = val;
217 return first;
218}
219
224template<class In, class T>
225In find(In first, In last, const T &v) {
226 while (first != last) {
227 if (*first == v)
228 return first;
229 ++first;
230 }
231 return last;
232}
233
238template<class In, class Pred>
239In find_if(In first, In last, Pred p) {
240 while (first != last) {
241 if (p(*first))
242 return first;
243 ++first;
244 }
245 return last;
246}
247
252template<class In, class Op>
253Op for_each(In first, In last, Op f) {
254 while (first != last)
255 f(*first++);
256 return f;
257}
258
259template<typename T>
260void reverse(T first, T last) {
261 for (; first != last && first != --last; ++first)
262 SWAP(*first, *last);
263}
264
269template<typename T>
270unsigned int distance(T *first, T *last) {
271 return last - first;
272}
273
274template<typename T>
275unsigned int distance(T first, T last) {
276 unsigned int n = 0;
277 while (first != last) {
278 ++n;
279 ++first;
280 }
281 return n;
282}
283
284template<typename T>
285T *sortChoosePivot(T *first, T *last) {
286 return first + distance(first, last) / 2;
287}
288
289template<typename T>
290T sortChoosePivot(T first, T last) {
291 unsigned int n = distance(first, last);
292 n /= 2;
293 while (n--)
294 ++first;
295 return first;
296}
297
298template<typename T, class StrictWeakOrdering>
299T sortPartition(T first, T last, T pivot, StrictWeakOrdering &comp) {
300 --last;
301 if (pivot != last)
302 SWAP(*pivot, *last);
303
304 T sorted;
305 for (sorted = first; first != last; ++first) {
306 if (!comp(*last, *first)) {
307 if (first != sorted)
308 SWAP(*first, *sorted);
309 ++sorted;
310 }
311 }
312
313 if (last != sorted)
314 SWAP(*last, *sorted);
315 return sorted;
316}
317
348template<typename T, class StrictWeakOrdering>
349void sort(T first, T last, StrictWeakOrdering comp) {
350 if (first == last)
351 return;
352
353 T pivot = sortChoosePivot(first, last);
354 pivot = sortPartition(first, last, pivot, comp);
355 sort<T, StrictWeakOrdering>(first, pivot, comp);
356 sort<T, StrictWeakOrdering>(++pivot, last, comp);
357}
358
365template<typename T>
366void sort(T *first, T *last) {
367 sort(first, last, Less<T>());
368}
369
377template<class T>
378void sort(T first, T last) {
379 sort(first, last, Less<typename T::ValueType>());
380}
381
386// MSVC is complaining about the minus operator being applied to an unsigned type
387// We disable this warning for the affected section of code
388#if defined(_MSC_VER)
389#pragma warning(push)
390#pragma warning(disable: 4146)
391#endif
392
396template<class T>
397T gcd(T a, T b) {
398 // Note: We check for <= instead of < to avoid spurious compiler
399 // warnings if T is an unsigned type, i.e. warnings like "comparison
400 // of unsigned expression < 0 is always false".
401 if (a <= 0)
402 a = -a;
403 if (b <= 0)
404 b = -b;
405
406 while (a > 0) {
407 T tmp = a;
408 a = b % a;
409 b = tmp;
410 }
411
412 return b;
413}
414
415#if defined(_MSC_VER)
416#pragma warning(pop)
417#endif
418
422template<class T>
424 if (v == 0)
425 return 1;
426 v--;
427 v |= v >> 1;
428 v |= v >> 2;
429 v |= v >> 4;
430 v |= v >> 8;
431 v |= v >> 16;
432 return ++v;
433}
434
447template<class It, class Dat>
448void replace(It begin, It end, const Dat &original, const Dat &replaced) {
449 for (; begin != end; ++begin) {
450 if (*begin == original) {
451 *begin = replaced;
452 }
453 }
454}
455
465template<class It, class T>
466It remove(It first, It last, const T& val) {
467 first = find(first, last, val);
468 if (first != last) {
469 It i = first;
470 while (++i != last) {
471 if (!(*i == val)) {
472 *first = move(*i);
473 first++;
474 }
475 }
476 }
477 return first;
478}
479
490template<typename RandomIt, typename V, typename Comp = Less<V> >
491RandomIt lowerBound(RandomIt first, RandomIt last, const V &val, Comp comp = {}) {
492 while (first < last) {
493 const RandomIt mid = first + distance(first, last) / 2;
494 if (comp(*mid, val))
495 first = mid + 1;
496 else
497 last = mid;
498 }
499 return first;
500}
501
512template<typename RandomIt, typename V, typename Comp = Less<V> >
513RandomIt upperBound(RandomIt first, RandomIt last, const V &val, Comp comp = {}) {
514 while (first < last) {
515 const RandomIt mid = first + distance(first, last) / 2;
516 if (!comp(val, *mid))
517 first = mid + 1;
518 else
519 last = mid;
520 }
521 return first;
522}
523
526} // End of namespace Common
527
528#endif
Out move(In first, In last, Out dst)
Definition: algorithm.h:109
T nextHigher2(T v)
Definition: algorithm.h:423
T gcd(T a, T b)
Definition: algorithm.h:397
Out copy_if(In first, In last, Out dst, Op op)
Definition: algorithm.h:84
void replace(It begin, It end, const Dat &original, const Dat &replaced)
Definition: algorithm.h:448
RandomIt lowerBound(RandomIt first, RandomIt last, const V &val, Comp comp={})
Definition: algorithm.h:491
Op for_each(In first, In last, Op f)
Definition: algorithm.h:253
It remove(It first, It last, const T &val)
Definition: algorithm.h:466
In find_if(In first, In last, Pred p)
Definition: algorithm.h:239
Out copy_backward(In first, In last, Out dst)
Definition: algorithm.h:67
void sort(T first, T last, StrictWeakOrdering comp)
Definition: algorithm.h:349
Out copy(In first, In last, Out dst)
Definition: algorithm.h:52
In find(In first, In last, const T &v)
Definition: algorithm.h:225
Out move_if(In first, In last, Out dst, Op op)
Definition: algorithm.h:141
Out move_backward(In first, In last, Out dst)
Definition: algorithm.h:124
signed char * fill(signed char *first, signed char *last, Value val)
Definition: algorithm.h:168
RandomIt upperBound(RandomIt first, RandomIt last, const V &val, Comp comp={})
Definition: algorithm.h:513
void SWAP(T &a, T &b)
Definition: util.h:467
Definition: algorithm.h:29
Definition: func.h:70
Definition: lobject.h:59