algorithm.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /* ScummVM Tools
  2. *
  3. * ScummVM Tools is the legal property of its developers, whose
  4. * names are too numerous to list here. Please refer to the
  5. * COPYRIGHT file distributed with this source distribution.
  6. *
  7. * Additionally this file is based on the ScummVM source code.
  8. * Copyright information for the ScummVM source code is
  9. * available in the COPYRIGHT file of the ScummVM source
  10. * distribution.
  11. *
  12. * This program is free software; you can redistribute it and/or
  13. * modify it under the terms of the GNU General Public License
  14. * as published by the Free Software Foundation; either version 2
  15. * of the License, or (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program; if not, write to the Free Software
  24. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  25. */
  26. #ifndef COMMON_ALGORITHM_H
  27. #define COMMON_ALGORITHM_H
  28. #include "common/scummsys.h"
  29. #include "common/func.h"
  30. namespace Common {
  31. /**
  32. * Copies data from the range [first, last) to [dst, dst + (last - first)).
  33. * It requires the range [dst, dst + (last - first)) to be valid.
  34. * It also requires dst not to be in the range [first, last).
  35. */
  36. template<class In, class Out>
  37. Out copy(In first, In last, Out dst) {
  38. while (first != last)
  39. *dst++ = *first++;
  40. return dst;
  41. }
  42. /**
  43. * Copies data from the range [first, last) to [dst - (last - first), dst).
  44. * It requires the range [dst - (last - first), dst) to be valid.
  45. * It also requires dst not to be in the range [first, last).
  46. *
  47. * Unlike copy copy_backward copies the data from the end to the beginning.
  48. */
  49. template<class In, class Out>
  50. Out copy_backward(In first, In last, Out dst) {
  51. while (first != last)
  52. *--dst = *--last;
  53. return dst;
  54. }
  55. /**
  56. * Copies data from the range [first, last) to [dst, dst + (last - first)).
  57. * It requires the range [dst, dst + (last - first)) to be valid.
  58. * It also requires dst not to be in the range [first, last).
  59. *
  60. * Unlike copy or copy_backward it does not copy all data. It only copies
  61. * a data element when operator() of the op parameter returns true for the
  62. * passed data element.
  63. */
  64. template<class In, class Out, class Op>
  65. Out copy_if(In first, In last, Out dst, Op op) {
  66. while (first != last) {
  67. if (op(*first))
  68. *dst++ = *first;
  69. ++first;
  70. }
  71. return dst;
  72. }
  73. // Our 'specialized' 'set_to' template for char, signed char and unsigned char arrays.
  74. // Since C++ doesn't support partial specialized template functions (currently) we
  75. // are going this way...
  76. // With this we assure the usage of memset for those, which should be
  77. // faster than a simple loop like for the generic 'set_to'.
  78. template<class Value>
  79. signed char *set_to(signed char *first, signed char *last, Value val) {
  80. memset(first, (val & 0xFF), last - first);
  81. return last;
  82. }
  83. template<class Value>
  84. unsigned char *set_to(unsigned char *first, unsigned char *last, Value val) {
  85. memset(first, (val & 0xFF), last - first);
  86. return last;
  87. }
  88. template<class Value>
  89. char *set_to(char *first, char *last, Value val) {
  90. memset(first, (val & 0xFF), last - first);
  91. return last;
  92. }
  93. /**
  94. * Sets all elements in the range [first, last) to val.
  95. */
  96. template<class In, class Value>
  97. In set_to(In first, In last, Value val) {
  98. while (first != last)
  99. *first++ = val;
  100. return first;
  101. }
  102. /**
  103. * Finds the first data value in the range [first, last) matching v.
  104. * For data comperance it uses operator == of the data elements.
  105. */
  106. template<class In, class T>
  107. In find(In first, In last, const T &v) {
  108. while (first != last) {
  109. if (*first == v)
  110. return first;
  111. ++first;
  112. }
  113. return last;
  114. }
  115. /**
  116. * Finds the first data value in the range [first, last) for which
  117. * the specified predicate p returns true.
  118. */
  119. template<class In, class Pred>
  120. In find_if(In first, In last, Pred p) {
  121. while (first != last) {
  122. if (p(*first))
  123. return first;
  124. ++first;
  125. }
  126. return last;
  127. }
  128. /**
  129. * Applies the function f on all elements of the range [first, last).
  130. * The processing order is from beginning to end.
  131. */
  132. template<class In, class Op>
  133. Op for_each(In first, In last, Op f) {
  134. while (first != last) f(*first++);
  135. return f;
  136. }
  137. template<typename T>
  138. unsigned int distance(T *first, T *last) {
  139. return last - first;
  140. }
  141. template<typename T>
  142. unsigned int distance(T first, T last) {
  143. unsigned int n = 0;
  144. while (first != last) {
  145. ++n;
  146. ++first;
  147. }
  148. return n;
  149. }
  150. template<typename T>
  151. T *sortChoosePivot(T *first, T *last) {
  152. return first + distance(first, last) / 2;
  153. }
  154. template<typename T>
  155. T sortChoosePivot(T first, T last) {
  156. unsigned int n = distance(first, last);
  157. n /= 2;
  158. while (n--)
  159. ++first;
  160. return first;
  161. }
  162. template<typename T, class StrictWeakOrdering>
  163. T sortPartition(T first, T last, T pivot, StrictWeakOrdering &comp) {
  164. --last;
  165. SWAP(*pivot, *last);
  166. T sorted;
  167. for (sorted = first; first != last; ++first) {
  168. if (!comp(*last, *first)) {
  169. if (first != sorted)
  170. SWAP(*first, *sorted);
  171. ++sorted;
  172. }
  173. }
  174. SWAP(*last, *sorted);
  175. return sorted;
  176. }
  177. /**
  178. * Simple sort function, modeled after std::sort.
  179. * It compares data with the given comparator object comp.
  180. */
  181. template<typename T, class StrictWeakOrdering>
  182. void sort(T first, T last, StrictWeakOrdering comp) {
  183. if (first == last)
  184. return;
  185. T pivot = sortChoosePivot(first, last);
  186. pivot = sortPartition(first, last, pivot, comp);
  187. sort<T, StrictWeakOrdering>(first, pivot, comp);
  188. sort<T, StrictWeakOrdering>(++pivot, last, comp);
  189. }
  190. /**
  191. * Simple sort function, modeled after std::sort.
  192. */
  193. template<typename T>
  194. void sort(T *first, T *last) {
  195. sort(first, last, Common::Less<T>());
  196. }
  197. template<class T>
  198. void sort(T first, T last) {
  199. sort(first, last, Common::Less<typename T::ValueType>());
  200. }
  201. } // End of namespace Common
  202. #endif