util.hpp

Go to the documentation of this file.
00001 /* $Id: util.hpp 26756 2008-05-21 18:25:25Z mordante $ */
00002 /*
00003    Copyright (C) 2003 - 2008 by David White <dave@whitevine.net>
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License version 2
00008    or at your option any later version.
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY.
00011 
00012    See the COPYING file for more details.
00013 */
00014 
00015 /**
00016  *  @file util.hpp
00017  *  Templates and utility-routines for strings and numbers.
00018  */
00019 
00020 #ifndef UTIL_H_INCLUDED
00021 #define UTIL_H_INCLUDED
00022 
00023 #include "global.hpp"
00024 #include <cmath>
00025 #include <map>
00026 #include <sstream>
00027 
00028 // instead of playing with VC++'s crazy definitions of min and max,
00029 // just define our own
00030 /** Replacement for VC++'s definitions of min and max. */
00031 template<typename T>
00032 inline T& minimum(T& a, T& b) { return a < b ? a : b; }
00033 
00034 template<typename T>
00035 inline const T& minimum(const T& a, const T& b) { return a < b ? a : b; }
00036 
00037 template<typename T>
00038 inline T& maximum(T& a, T& b) { return a < b ? b : a; }
00039 
00040 template<typename T>
00041 inline const T& maximum(const T& a, const T& b) { return a < b ? b : a; }
00042 
00043 template<typename T>
00044 inline bool is_odd(T num) {
00045   int n = static_cast< int >(num);
00046   return static_cast< unsigned int >(n >= 0 ? n : -n) & 1;
00047 }
00048 
00049 template<typename T>
00050 inline bool is_even(T num) { return !is_odd(num); }
00051 
00052 /** Guarantees portable results for division by 100; round towards 0 */
00053 inline int div100rounded(int num) {
00054     return (num < 0) ? -(((-num) + 49) / 100) : (num + 49) / 100;
00055 }
00056 
00057 /**
00058  *  round (base_damage * bonus / divisor) to the closest integer,
00059  *  but up or down towards base_damage
00060  */
00061 inline int round_damage(int base_damage, int bonus, int divisor) {
00062     const int rounding = divisor / 2 - (bonus < divisor ? 0 : 1);
00063     return maximum<int>(1, (base_damage * bonus + rounding) / divisor);
00064 }
00065 
00066 // not guaranteed to have exactly the same result on different platforms
00067 inline int round_double(double d) {
00068 #ifdef HAVE_ROUND
00069     return static_cast<int>(std::round(d)); //surprisingly, not implemented everywhere
00070 #else
00071     return static_cast<int>((d >= 0.0)? std::floor(d + 0.5) : std::ceil(d - 0.5));
00072 #endif
00073 }
00074 
00075 struct bad_lexical_cast {};
00076 
00077 template<typename To, typename From>
00078 To lexical_cast(From a)
00079 {
00080     To res;
00081     std::stringstream str;
00082 
00083     if(!(str << a && str >> res)) {
00084         throw bad_lexical_cast();
00085     } else {
00086         return res;
00087     }
00088 }
00089 
00090 template<typename To, typename From>
00091 To lexical_cast_default(From a, To def=To())
00092 {
00093     To res;
00094     std::stringstream str;
00095 
00096     if(!(str << a && str >> res)) {
00097         return def;
00098     } else {
00099         return res;
00100     }
00101 }
00102 
00103 template<>
00104 int lexical_cast<int, const std::string&>(const std::string& a);
00105 
00106 template<>
00107 int lexical_cast<int, const char*>(const char* a);
00108 
00109 template<>
00110 int lexical_cast_default<int, const std::string&>(const std::string& a, int def);
00111 
00112 template<>
00113 int lexical_cast_default<int, const char*>(const char* a, int def);
00114 
00115 template<typename From>
00116 std::string str_cast(From a)
00117 {
00118     return lexical_cast<std::string,From>(a);
00119 }
00120 
00121 template<typename To, typename From>
00122 To lexical_cast_in_range(From a, To def, To min, To max)
00123 {
00124     To res;
00125     std::stringstream str;
00126 
00127     if(!(str << a && str >> res)) {
00128         return def;
00129     } else {
00130         if(res < min) {
00131             return min;
00132         }
00133         if(res > max) {
00134             return max;
00135         }
00136         return res;
00137     }
00138 }
00139 
00140 inline bool chars_equal_insensitive(char a, char b) { return tolower(a) == tolower(b); }
00141 inline bool chars_less_insensitive(char a, char b) { return tolower(a) < tolower(b); }
00142 
00143 /**
00144  *  A definition of 'push_back' for strings,
00145  * since some implementations don't support string::push_back
00146  */
00147 template<typename T, typename C>
00148 void push_back(T& str, C c)
00149 {
00150     str.resize(str.size()+1);
00151     str[str.size()-1] = c;
00152 }
00153 
00154 #ifdef __GNUC__
00155 #define LIKELY(a)    __builtin_expect((a),1) // Tells GCC to optimize code so that if is likely to happen
00156 #define UNLIKELY(a)  __builtin_expect((a),0) // Tells GCC to optimize code so that if is unlikely to happen
00157 #else
00158 #define LIKELY(a)    a
00159 #define UNLIKELY(a)  a
00160 #endif
00161 
00162 
00163 #if 1
00164 # include <SDL_types.h>
00165 typedef Sint32 fixed_t;
00166 # define fxp_shift 8
00167 # define fxp_base (1 << fxp_shift)
00168 
00169 /** IN: float or int - OUT: fixed_t */
00170 # define ftofxp(x) (fixed_t((x) * fxp_base))
00171 
00172 /** IN: unsigned and fixed_t - OUT: unsigned */
00173 # define fxpmult(x,y) (((x)*(y)) >> fxp_shift)
00174 
00175 /** IN: unsigned and int - OUT: fixed_t */
00176 # define fxpdiv(x,y) (((x) << fxp_shift) / (y))
00177 
00178 /** IN: fixed_t - OUT: int */
00179 # define fxptoi(x) ( ((x)>0) ? ((x) >> fxp_shift) : (-((-(x)) >> fxp_shift)) )
00180 
00181 #else
00182 typedef float fixed_t;
00183 # define ftofxp(x) (x)
00184 # define fxpmult(x,y) ((x)*(y))
00185 # define fxpdiv(x,y) (static_cast<float>(x) / static_cast<float>(y))
00186 # define fxptoi(x) ( static_cast<int>(x) )
00187 #endif
00188 
00189 #endif

Generated by doxygen 1.5.5 on 23 May 2008 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs