ScummVM API documentation
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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 
29 namespace Common {
30 
51 template<class In, class Out>
52 Out copy(In first, In last, Out dst) {
53  while (first != last)
54  *dst++ = *first++;
55  return dst;
56 }
57 
66 template<class In, class Out>
67 Out copy_backward(In first, In last, Out dst) {
68  while (first != last)
69  *--dst = *--last;
70  return dst;
71 }
72 
83 template<class In, class Out, class Op>
84 Out 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 
108 template<class In, class Out>
109 Out move(In first, In last, Out dst) {
110  while (first != last)
111  *dst++ = Common::move(*first++);
112  return dst;
113 }
114 
123 template<class In, class Out>
124 Out move_backward(In first, In last, Out dst) {
125  while (first != last)
126  *--dst = Common::move(*--last);
127  return dst;
128 }
129 
140 template<class In, class Out, class Op>
141 Out 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 
167 template<class Value>
168 signed char *fill(signed char *first, signed char *last, Value val) {
169  memset(first, (val & 0xFF), last - first);
170  return last;
171 }
172 
181 template<class Value>
182 unsigned char *fill(unsigned char *first, unsigned char *last, Value val) {
183  memset(first, (val & 0xFF), last - first);
184  return last;
185 }
186 
195 template<class Value>
196 char *fill(char *first, char *last, Value val) {
197  memset(first, (val & 0xFF), last - first);
198  return last;
199 }
200 
213 template<class In, class Value>
214 In fill(In first, In last, const Value &val) {
215  while (first != last)
216  *first++ = val;
217  return first;
218 }
219 
224 template<class In, class T>
225 In 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 
238 template<class In, class Pred>
239 In 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 
252 template<class In, class Op>
253 Op for_each(In first, In last, Op f) {
254  while (first != last)
255  f(*first++);
256  return f;
257 }
258 
259 template<typename T>
260 void reverse(T first, T last) {
261  for (; first != last && first != --last; ++first)
262  SWAP(*first, *last);
263 }
264 
269 template<typename T>
270 unsigned int distance(T *first, T *last) {
271  return last - first;
272 }
273 
274 template<typename T>
275 unsigned 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 
284 template<typename T>
285 T *sortChoosePivot(T *first, T *last) {
286  return first + distance(first, last) / 2;
287 }
288 
289 template<typename T>
290 T 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 
298 template<typename T, class StrictWeakOrdering>
299 T 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 
348 template<typename T, class StrictWeakOrdering>
349 void 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 
365 template<typename T>
366 void sort(T *first, T *last) {
367  sort(first, last, Less<T>());
368 }
369 
377 template<class T>
378 void 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 
396 template<class T>
397 T 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 
422 template<class T>
423 T nextHigher2(T v) {
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 
447 template<class It, class Dat>
448 void 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 
465 template<class It, class T>
466 It 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 
490 template<typename RandomIt, typename V, typename Comp = Less<V> >
491 RandomIt 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 
512 template<typename RandomIt, typename V, typename Comp = Less<V> >
513 RandomIt 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
Op for_each(In first, In last, Op f)
Definition: algorithm.h:253
T nextHigher2(T v)
Definition: algorithm.h:423
In find(In first, In last, const T &v)
Definition: algorithm.h:225
T gcd(T a, T b)
Definition: algorithm.h:397
void SWAP(T &a, T &b)
Definition: util.h:84
Out move_if(In first, In last, Out dst, Op op)
Definition: algorithm.h:141
Out copy(In first, In last, Out dst)
Definition: algorithm.h:52
RandomIt lowerBound(RandomIt first, RandomIt last, const V &val, Comp comp={})
Definition: algorithm.h:491
void replace(It begin, It end, const Dat &original, const Dat &replaced)
Definition: algorithm.h:448
Definition: lobject.h:59
RandomIt upperBound(RandomIt first, RandomIt last, const V &val, Comp comp={})
Definition: algorithm.h:513
Definition: algorithm.h:29
Out move(In first, In last, Out dst)
Definition: algorithm.h:109
Out move_backward(In first, In last, Out dst)
Definition: algorithm.h:124
Out copy_if(In first, In last, Out dst, Op op)
Definition: algorithm.h:84
signed char * fill(signed char *first, signed char *last, Value val)
Definition: algorithm.h:168
In find_if(In first, In last, Pred p)
Definition: algorithm.h:239
void sort(T first, T last, StrictWeakOrdering comp)
Definition: algorithm.h:349
Out copy_backward(In first, In last, Out dst)
Definition: algorithm.h:67
Definition: func.h:70