The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
util.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2016 by David White <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 /**
16  * @file
17  * Templates and utility-routines for strings and numbers.
18  */
19 
20 #ifndef UTIL_H_INCLUDED
21 #define UTIL_H_INCLUDED
22 
23 #include "global.hpp"
24 #include <cmath>
25 #include <cstddef>
26 #include <cstdint>
27 #include <limits>
28 #include <math.h> // cmath may not provide round()
29 #include <vector>
30 #include <sstream>
31 #include <algorithm>
32 
33 template<typename T>
34 inline bool is_even(T num) { return num % 2 == 0; }
35 
36 template<typename T>
37 inline bool is_odd(T num) { return !is_even(num); }
38 
39 /**
40  * Returns base + increment, but will not increase base above max_sum, nor
41  * decrease it below min_sum.
42  * (If base is already beyond the applicable limit, base will be returned.)
43  */
44 inline int bounded_add(int base, int increment, int max_sum, int min_sum=0) {
45  if ( increment >= 0 )
46  return std::min(base+increment, std::max(base, max_sum));
47  else
48  return std::max(base+increment, std::min(base, min_sum));
49 }
50 
51 /** Guarantees portable results for division by 100; round towards 0 */
52 inline int div100rounded(int num) {
53  return (num < 0) ? -(((-num) + 50) / 100) : (num + 50) / 100;
54 }
55 
56 /**
57  * round (base_damage * bonus / divisor) to the closest integer,
58  * but up or down towards base_damage
59  */
60 inline int round_damage(int base_damage, int bonus, int divisor) {
61  if (base_damage==0) return 0;
62  const int rounding = divisor / 2 - (bonus < divisor || divisor==1 ? 0 : 1);
63  return std::max<int>(1, (base_damage * bonus + rounding) / divisor);
64 }
65 
66 // not guaranteed to have exactly the same result on different platforms
67 inline int round_double(double d) {
68 #ifdef HAVE_ROUND
69  return static_cast<int>(round(d)); //surprisingly, not implemented everywhere
70 #else
71  return static_cast<int>((d >= 0.0)? std::floor(d + 0.5) : std::ceil(d - 0.5));
72 #endif
73 }
74 
75 // Guaranteed to have portable results across different platforms
76 inline double round_portable(double d) {
77  return (d >= 0.0) ? std::floor(d + 0.5) : std::ceil(d - 0.5);
78 }
79 
80 struct bad_lexical_cast : public std::exception
81 {
82  const char *what() const throw()
83  {
84  return "bad_lexical_cast";
85  }
86 };
87 
88 
89 template<typename To, typename From>
90 To lexical_cast(From a)
91 {
92  To res = To();
93  std::stringstream str;
94 
95  if(str << a && str >> res) {
96  return res;
97  } else {
98  throw bad_lexical_cast();
99  }
100 }
101 
102 template<typename To, typename From>
103 To lexical_cast_default(From a, To def=To())
104 {
105  To res = To();
106  std::stringstream str;
107 
108  if(str << a && str >> res) {
109  return res;
110  } else {
111  return def;
112  }
113 }
114 
115 template<>
116 size_t lexical_cast<size_t, const std::string&>(const std::string& a);
117 
118 template<>
119 size_t lexical_cast<size_t, const char*>(const char* a);
120 
121 template<>
122 size_t lexical_cast_default<size_t, const std::string&>(const std::string& a, size_t def);
123 
124 template<>
125 size_t lexical_cast_default<size_t, const char*>(const char* a, size_t def);
126 
127 template<>
128 long lexical_cast<long, const std::string&>(const std::string& a);
129 
130 template<>
131 long lexical_cast<long, const char*>(const char* a);
132 
133 template<>
134 long lexical_cast_default<long, const std::string&>(const std::string& a, long def);
135 
136 template<>
137 long lexical_cast_default<long, const char*>(const char* a, long def);
138 
139 template<>
140 int lexical_cast<int, const std::string&>(const std::string& a);
141 
142 template<>
143 int lexical_cast<int, const char*>(const char* a);
144 
145 template<>
146 int lexical_cast_default<int, const std::string&>(const std::string& a, int def);
147 
148 template<>
149 int lexical_cast_default<int, const char*>(const char* a, int def);
150 
151 template<>
152 double lexical_cast<double, const std::string&>(const std::string& a);
153 
154 template<>
155 double lexical_cast<double, const char*>(const char* a);
156 
157 template<>
158 double lexical_cast_default<double, const std::string&>(const std::string& a, double def);
159 
160 template<>
161 double lexical_cast_default<double, const char*>(const char* a, double def);
162 
163 template<>
164 float lexical_cast<float, const std::string&>(const std::string& a);
165 
166 template<>
167 float lexical_cast<float, const char*>(const char* a);
168 
169 template<>
170 float lexical_cast_default<float, const std::string&>(const std::string& a, float def);
171 
172 template<>
173 float lexical_cast_default<float, const char*>(const char* a, float def);
174 
175 template<typename To, typename From>
176 To lexical_cast_in_range(From a, To def, To min, To max)
177 {
178  To res;
179  std::stringstream str;
180 
181  if(str << a && str >> res) {
182  if(res < min) {
183  return min;
184  }
185  if(res > max) {
186  return max;
187  }
188  return res;
189  } else {
190  return def;
191  }
192 }
193 
194 template<typename Cmp>
195 bool in_ranges(const Cmp c, const std::vector<std::pair<Cmp, Cmp> >&ranges) {
196  typename std::vector<std::pair<Cmp,Cmp> >::const_iterator range,
197  range_end = ranges.end();
198  for (range = ranges.begin(); range != range_end; ++range) {
199  if(range->first <= c && c <= range->second) {
200  return true;
201  }
202  }
203  return false;
204 }
205 
206 inline bool chars_equal_insensitive(char a, char b) { return tolower(a) == tolower(b); }
207 inline bool chars_less_insensitive(char a, char b) { return tolower(a) < tolower(b); }
208 
209 /**
210  * Returns the size, in bits, of an instance of type `T`, providing a
211  * convenient and self-documenting name for the underlying expression:
212  *
213  * sizeof(T) * std::numeric_limits<unsigned char>::digits
214  *
215  * @tparam T The return value is the size, in bits, of an instance of this
216  * type.
217  *
218  * @returns the size, in bits, of an instance of type `T`.
219  */
220 template<typename T>
221 inline std::size_t bit_width() {
222  return sizeof(T) * std::numeric_limits<unsigned char>::digits;
223 }
224 
225 /**
226  * Returns the size, in bits, of `x`, providing a convenient and
227  * self-documenting name for the underlying expression:
228  *
229  * sizeof(x) * std::numeric_limits<unsigned char>::digits
230  *
231  * @tparam T The type of `x`.
232  *
233  * @param x The return value is the size, in bits, of this object.
234  *
235  * @returns the size, in bits, of an instance of type `T`.
236  */
237 template<typename T>
238 inline std::size_t bit_width(const T&) {
239  return sizeof(T) * std::numeric_limits<unsigned char>::digits;
240 }
241 
242 /**
243  * Returns the quantity of `1` bits in `n` — i.e., `n`’s population count.
244  *
245  * Algorithm adapted from:
246  * <https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan>
247  *
248  * This algorithm was chosen for relative simplicity, not for speed.
249  *
250  * @tparam N The type of `n`. This should be a fundamental integer type no
251  * greater than `UINT_MAX` bits in width; if it is not, the return value is
252  * undefined.
253  *
254  * @param n An integer upon which to operate.
255  *
256  * @returns the quantity of `1` bits in `n`, if `N` is a fundamental integer
257  * type.
258  */
259 template<typename N>
260 inline unsigned int count_ones(N n) {
261  unsigned int r = 0;
262  while (n) {
263  n &= n-1;
264  ++r;
265  }
266  return r;
267 }
268 
269 // Support functions for `count_leading_zeros`.
270 #if defined(__GNUC__) || defined(__clang__)
271 inline unsigned int count_leading_zeros_impl(
272  unsigned char n, std::size_t w) {
273  // Returns the result of the compiler built-in function, adjusted for
274  // the difference between the width, in bits, of the built-in
275  // function’s parameter’s type (which is `unsigned int`, at the
276  // smallest) and the width, in bits, of the input to this function, as
277  // specified at the call-site in `count_leading_zeros`.
278  return static_cast<unsigned int>(__builtin_clz(n))
279  - static_cast<unsigned int>(
280  bit_width<unsigned int>() - w);
281 }
282 inline unsigned int count_leading_zeros_impl(
283  unsigned short int n, std::size_t w) {
284  return static_cast<unsigned int>(__builtin_clz(n))
285  - static_cast<unsigned int>(
286  bit_width<unsigned int>() - w);
287 }
288 inline unsigned int count_leading_zeros_impl(
289  unsigned int n, std::size_t w) {
290  return static_cast<unsigned int>(__builtin_clz(n))
291  - static_cast<unsigned int>(
292  bit_width<unsigned int>() - w);
293 }
294 inline unsigned int count_leading_zeros_impl(
295  unsigned long int n, std::size_t w) {
296  return static_cast<unsigned int>(__builtin_clzl(n))
297  - static_cast<unsigned int>(
298  bit_width<unsigned long int>() - w);
299 }
300 inline unsigned int count_leading_zeros_impl(
301  unsigned long long int n, std::size_t w) {
302  return static_cast<unsigned int>(__builtin_clzll(n))
303  - static_cast<unsigned int>(
304  bit_width<unsigned long long int>() - w);
305 }
306 inline unsigned int count_leading_zeros_impl(
307  char n, std::size_t w) {
309  static_cast<unsigned char>(n), w);
310 }
311 inline unsigned int count_leading_zeros_impl(
312  signed char n, std::size_t w) {
314  static_cast<unsigned char>(n), w);
315 }
316 inline unsigned int count_leading_zeros_impl(
317  signed short int n, std::size_t w) {
319  static_cast<unsigned short int>(n), w);
320 }
321 inline unsigned int count_leading_zeros_impl(
322  signed int n, std::size_t w) {
324  static_cast<unsigned int>(n), w);
325 }
326 inline unsigned int count_leading_zeros_impl(
327  signed long int n, std::size_t w) {
329  static_cast<unsigned long int>(n), w);
330 }
331 inline unsigned int count_leading_zeros_impl(
332  signed long long int n, std::size_t w) {
334  static_cast<unsigned long long int>(n), w);
335 }
336 #else
337 template<typename N>
338 inline unsigned int count_leading_zeros_impl(N n, std::size_t w) {
339  // Algorithm adapted from:
340  // <http://aggregate.org/MAGIC/#Leading%20Zero%20Count>
341  for (unsigned int shift = 1; shift < w; shift *= 2) {
342  n |= (n >> shift);
343  }
344  return static_cast<unsigned int>(w) - count_ones(n);
345 }
346 #endif
347 
348 /**
349  * Returns the quantity of leading `0` bits in `n` — i.e., the quantity of
350  * bits in `n`, minus the 1-based bit index of the most significant `1` bit in
351  * `n`, or minus 0 if `n` is 0.
352  *
353  * @tparam N The type of `n`. This should be a fundamental integer type that
354  * (a) is not wider than `unsigned long long int` (the GCC
355  * count-leading-zeros built-in functions are defined for `unsigned int`,
356  * `unsigned long int`, and `unsigned long long int`), and
357  * (b) is no greater than `INT_MAX` bits in width (the GCC built-in functions
358  * return instances of type `int`);
359  * if `N` does not satisfy these constraints, the return value is undefined.
360  *
361  * @param n An integer upon which to operate.
362  *
363  * @returns the quantity of leading `0` bits in `n`, if `N` satisfies the
364  * above constraints.
365  *
366  * @see count_leading_ones()
367  */
368 template<typename N>
369 inline unsigned int count_leading_zeros(N n) {
370 #if defined(__GNUC__) || defined(__clang__)
371  // GCC’s `__builtin_clz` returns an undefined value when called with 0
372  // as argument.
373  // [<http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html>]
374  if (n == 0) {
375  // Return the quantity of zero bits in `n` rather than
376  // returning that undefined value.
377  return static_cast<unsigned int>(bit_width(n));
378  }
379 #endif
380  // Dispatch, on the static type of `n`, to one of the
381  // `count_leading_zeros_impl` functions.
382  return count_leading_zeros_impl(n, bit_width(n));
383  // The second argument to `count_leading_zeros_impl` specifies the
384  // width, in bits, of `n`.
385  //
386  // This is necessary because `n` may be widened (or, alas, shrunk),
387  // and thus the information of `n`’s true width may be lost.
388  //
389  // At least, this *was* necessary before there were so many overloads
390  // of `count_leading_zeros_impl`, but I’ve kept it anyway as an extra
391  // precautionary measure, that will (I hope) be optimized out.
392  //
393  // To be clear, `n` would only be shrunk in cases noted above as
394  // having an undefined result.
395 }
396 
397 /**
398  * Returns the quantity of leading `1` bits in `n` — i.e., the quantity of
399  * bits in `n`, minus the 1-based bit index of the most significant `0` bit in
400  * `n`, or minus 0 if `n` contains no `0` bits.
401  *
402  * @tparam N The type of `n`. This should be a fundamental integer type that
403  * (a) is not wider than `unsigned long long int`, and
404  * (b) is no greater than `INT_MAX` bits in width;
405  * if `N` does not satisfy these constraints, the return value is undefined.
406  *
407  * @param n An integer upon which to operate.
408  *
409  * @returns the quantity of leading `1` bits in `n`, if `N` satisfies the
410  * above constraints.
411  *
412  * @see count_leading_zeros()
413  */
414 template<typename N>
415 inline unsigned int count_leading_ones(N n) {
416  // Explicitly specify the type for which to instantiate
417  // `count_leading_zeros` in case `~n` is of a different type.
418  return count_leading_zeros<N>(~n);
419 }
420 
421 #ifdef __GNUC__
422 #define LIKELY(a) __builtin_expect((a),1) // Tells GCC to optimize code so that if is likely to happen
423 #define UNLIKELY(a) __builtin_expect((a),0) // Tells GCC to optimize code so that if is unlikely to happen
424 #else
425 #define LIKELY(a) a
426 #define UNLIKELY(a) a
427 #endif
428 
429 namespace util {
430 
431 template<class T>
433 {
434  T *ptr_;
435  // Neither copyable nor assignable.
436  unique_ptr(const unique_ptr &);
437  unique_ptr &operator=(const unique_ptr &);
438 public:
439  unique_ptr(T *p = nullptr): ptr_(p) {}
440  ~unique_ptr() { delete ptr_; }
441 
442  void reset(T *p = nullptr)
443  {
444  delete ptr_;
445  ptr_ = p;
446  }
447 
448  T *release()
449  {
450  T *p = ptr_;
451  ptr_ = nullptr;
452  return p;
453  }
454 
455  T *get() { return ptr_; }
456  T *operator->() const { return ptr_; }
457  T &operator*() const { return *ptr_; }
458 };
459 
460 namespace detail {
461  /// A struct that exists to implement a generic wrapper for std::find.
462  /// Container should "look like" an STL container of Values.
463  template<typename Container, typename Value> struct contains_impl {
464  static bool eval(const Container & container, const Value & value)
465  {
466  typename Container::const_iterator end = container.end();
467  return std::find(container.begin(), end, value) != end;
468  }
469  };
470  /// A struct that exists to implement a generic wrapper for the find()
471  /// member of associative containers.
472  /// Container should "look like" an STL associative container.
473  template<typename Container>
474  struct contains_impl<Container, typename Container::key_type> {
475  static bool eval(const Container & container,
476  const typename Container::key_type & value)
477  {
478  return container.find(value) != container.end();
479  }
480  };
481 }//namespace detail
482 
483 /// Returns true iff @a value is found in @a container.
484 /// This should work whenever Container "looks like" an STL container of Values.
485 /// Normally this uses std::find(), but a simulated partial template specialization
486 /// exists when Value is Container::key_type. In this case, Container is assumed
487 /// an associative container, and the member function find() is used.
488 template<typename Container, typename Value>
489 inline bool contains(const Container & container, const Value & value)
490 {
491  return detail::contains_impl<Container, Value>::eval(container, value);
492 }
493 
494 }//namespace util
495 
496 
497 #if 1
498 typedef int32_t fixed_t;
499 # define fxp_shift 8
500 # define fxp_base (1 << fxp_shift)
501 
502 /** IN: float or int - OUT: fixed_t */
503 # define ftofxp(x) (fixed_t((x) * fxp_base))
504 
505 /** IN: unsigned and fixed_t - OUT: unsigned */
506 # define fxpmult(x,y) (((x)*(y)) >> fxp_shift)
507 
508 /** IN: unsigned and int - OUT: fixed_t */
509 # define fxpdiv(x,y) (((x) << fxp_shift) / (y))
510 
511 /** IN: fixed_t - OUT: int */
512 # define fxptoi(x) ( ((x)>0) ? ((x) >> fxp_shift) : (-((-(x)) >> fxp_shift)) )
513 
514 #else
515 typedef float fixed_t;
516 # define ftofxp(x) (x)
517 # define fxpmult(x,y) ((x)*(y))
518 # define fxpdiv(x,y) (static_cast<float>(x) / static_cast<float>(y))
519 # define fxptoi(x) ( static_cast<int>(x) )
520 #endif
521 
522 #endif
To lexical_cast(From a)
Definition: util.hpp:90
int lexical_cast_default< int, const char * >(const char *a, int def)
Definition: util.cpp:185
unsigned int count_leading_ones(N n)
Returns the quantity of leading 1 bits in n — i.e., the quantity of bits in n, minus the 1-based bit...
Definition: util.hpp:415
GLenum GLint * range
Definition: glew.h:3025
const GLfloat * c
Definition: glew.h:12741
bool contains(const Container &container, const Value &value)
Returns true iff value is found in container.
Definition: util.hpp:489
int div100rounded(int num)
Guarantees portable results for division by 100; round towards 0.
Definition: util.hpp:52
A struct that exists to implement a generic wrapper for std::find.
Definition: util.hpp:463
bool is_odd(T num)
Definition: util.hpp:37
double lexical_cast_default< double, const char * >(const char *a, double def)
Definition: util.cpp:241
T * operator->() const
Definition: util.hpp:456
GLuint divisor
Definition: glew.h:2358
#define d
int round_double(double d)
Definition: util.hpp:67
unique_ptr(const unique_ptr &)
Definition: lobject.h:387
GLdouble GLdouble GLdouble b
Definition: glew.h:6966
const char * what() const
Definition: util.hpp:82
bool chars_less_insensitive(char a, char b)
Definition: util.hpp:207
bool chars_equal_insensitive(char a, char b)
Definition: util.hpp:206
GLuint GLuint end
Definition: glew.h:1221
GLubyte GLubyte GLubyte GLubyte w
Definition: glew.h:1858
GLsizei const GLfloat * value
Definition: glew.h:1817
unsigned int count_leading_zeros(N n)
Returns the quantity of leading 0 bits in n — i.e., the quantity of bits in n, minus the 1-based bit...
Definition: util.hpp:369
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:7319
GLuint num
Definition: glew.h:2552
void reset(T *p=nullptr)
Definition: util.hpp:442
unique_ptr & operator=(const unique_ptr &)
GLfloat GLfloat p
Definition: glew.h:12766
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
long lexical_cast_default< long, const char * >(const char *a, long def)
Definition: util.cpp:124
float lexical_cast_default< float, const char * >(const char *a, float def)
Definition: util.cpp:292
std::size_t bit_width()
Returns the size, in bits, of an instance of type T, providing a convenient and self-documenting name...
Definition: util.hpp:221
unique_ptr(T *p=nullptr)
Definition: util.hpp:439
double round_portable(double d)
Definition: util.hpp:76
GLuint res
Definition: glew.h:9258
int round_damage(int base_damage, int bonus, int divisor)
round (base_damage * bonus / divisor) to the closest integer, but up or down towards base_damage ...
Definition: util.hpp:60
T & operator*() const
Definition: util.hpp:457
static bool eval(const Container &container, const typename Container::key_type &value)
Definition: util.hpp:475
static bool eval(const Container &container, const Value &value)
Definition: util.hpp:464
GLdouble GLdouble GLdouble r
Definition: glew.h:1374
To lexical_cast_in_range(From a, To def, To min, To max)
Definition: util.hpp:176
int bounded_add(int base, int increment, int max_sum, int min_sum=0)
Returns base + increment, but will not increase base above max_sum, nor decrease it below min_sum...
Definition: util.hpp:44
GLclampd n
Definition: glew.h:5903
unsigned int count_ones(N n)
Returns the quantity of 1 bits in n — i.e., n’s population count.
Definition: util.hpp:260
size_t lexical_cast_default< size_t, const char * >(const char *a, size_t def)
Definition: util.cpp:67
T * release()
Definition: util.hpp:448
bool find(E event, F functor)
Tests whether an event handler is available.
To lexical_cast_default(From a, To def=To())
Definition: util.hpp:103
int32_t fixed_t
Definition: util.hpp:498
Thrown when a lexical_cast fails.
GLsizei const GLcharARB ** string
Definition: glew.h:4503
unsigned int count_leading_zeros_impl(N n, std::size_t w)
Definition: util.hpp:338
bool in_ranges(const Cmp c, const std::vector< std::pair< Cmp, Cmp > > &ranges)
Definition: util.hpp:195
bool is_even(T num)
Definition: util.hpp:34