util.hpp

Go to the documentation of this file.
00001 /* $Id: util.hpp 54079 2012-05-03 02:07:45Z j_daniel $ */
00002 /*
00003    Copyright (C) 2003 - 2012 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 as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY.
00012 
00013    See the COPYING file for more details.
00014 */
00015 
00016 /**
00017  *  @file
00018  *  Templates and utility-routines for strings and numbers.
00019  */
00020 
00021 #ifndef UTIL_H_INCLUDED
00022 #define UTIL_H_INCLUDED
00023 
00024 #include "global.hpp"
00025 #include <cmath>
00026 #include <math.h> // cmath may not provide round()
00027 #include <vector>
00028 #include <sstream>
00029 
00030 template<typename T>
00031 inline bool is_odd(T num) {
00032   int n = static_cast< int >(num);
00033   return static_cast< unsigned int >(n >= 0 ? n : -n) & 1;
00034 }
00035 
00036 template<typename T>
00037 inline bool is_even(T num) { return !is_odd(num); }
00038 
00039 /** Guarantees portable results for division by 100; round towards 0 */
00040 inline int div100rounded(int num) {
00041     return (num < 0) ? -(((-num) + 50) / 100) : (num + 50) / 100;
00042 }
00043 
00044 /**
00045  *  round (base_damage * bonus / divisor) to the closest integer,
00046  *  but up or down towards base_damage
00047  */
00048 inline int round_damage(int base_damage, int bonus, int divisor) {
00049     if (base_damage==0) return 0;
00050     const int rounding = divisor / 2 - (bonus < divisor || divisor==1 ? 0 : 1);
00051     return std::max<int>(1, (base_damage * bonus + rounding) / divisor);
00052 }
00053 
00054 // not guaranteed to have exactly the same result on different platforms
00055 inline int round_double(double d) {
00056 #ifdef HAVE_ROUND
00057     return static_cast<int>(round(d)); //surprisingly, not implemented everywhere
00058 #else
00059     return static_cast<int>((d >= 0.0)? std::floor(d + 0.5) : std::ceil(d - 0.5));
00060 #endif
00061 }
00062 
00063 // Guaranteed to have portable results across different platforms
00064 inline double round_portable(double d) {
00065     return (d >= 0.0) ? std::floor(d + 0.5) : std::ceil(d - 0.5);
00066 }
00067 
00068 struct bad_lexical_cast {};
00069 
00070 template<typename To, typename From>
00071 To lexical_cast(From a)
00072 {
00073     To res;
00074     std::stringstream str;
00075 
00076     if(!(str << a && str >> res)) {
00077         throw bad_lexical_cast();
00078     } else {
00079         return res;
00080     }
00081 }
00082 
00083 template<typename To, typename From>
00084 To lexical_cast_default(From a, To def=To())
00085 {
00086     To res;
00087     std::stringstream str;
00088 
00089     if(!(str << a && str >> res)) {
00090         return def;
00091     } else {
00092         return res;
00093     }
00094 }
00095 
00096 template<>
00097 size_t lexical_cast<size_t, const std::string&>(const std::string& a);
00098 
00099 template<>
00100 size_t lexical_cast<size_t, const char*>(const char* a);
00101 
00102 template<>
00103 size_t lexical_cast_default<size_t, const std::string&>(const std::string& a, size_t def);
00104 
00105 template<>
00106 size_t lexical_cast_default<size_t, const char*>(const char* a, size_t def);
00107 
00108 template<>
00109 long lexical_cast<long, const std::string&>(const std::string& a);
00110 
00111 template<>
00112 long lexical_cast<long, const char*>(const char* a);
00113 
00114 template<>
00115 long lexical_cast_default<long, const std::string&>(const std::string& a, long def);
00116 
00117 template<>
00118 long lexical_cast_default<long, const char*>(const char* a, long def);
00119 
00120 template<>
00121 int lexical_cast<int, const std::string&>(const std::string& a);
00122 
00123 template<>
00124 int lexical_cast<int, const char*>(const char* a);
00125 
00126 template<>
00127 int lexical_cast_default<int, const std::string&>(const std::string& a, int def);
00128 
00129 template<>
00130 int lexical_cast_default<int, const char*>(const char* a, int def);
00131 
00132 template<>
00133 double lexical_cast<double, const std::string&>(const std::string& a);
00134 
00135 template<>
00136 double lexical_cast<double, const char*>(const char* a);
00137 
00138 template<>
00139 double lexical_cast_default<double, const std::string&>(const std::string& a, double def);
00140 
00141 template<>
00142 double lexical_cast_default<double, const char*>(const char* a, double def);
00143 
00144 template<>
00145 float lexical_cast<float, const std::string&>(const std::string& a);
00146 
00147 template<>
00148 float lexical_cast<float, const char*>(const char* a);
00149 
00150 template<>
00151 float lexical_cast_default<float, const std::string&>(const std::string& a, float def);
00152 
00153 template<>
00154 float lexical_cast_default<float, const char*>(const char* a, float def);
00155 
00156 template<typename From>
00157 std::string str_cast(From a)
00158 {
00159     return lexical_cast<std::string,From>(a);
00160 }
00161 
00162 template<typename To, typename From>
00163 To lexical_cast_in_range(From a, To def, To min, To max)
00164 {
00165     To res;
00166     std::stringstream str;
00167 
00168     if(!(str << a && str >> res)) {
00169         return def;
00170     } else {
00171         if(res < min) {
00172             return min;
00173         }
00174         if(res > max) {
00175             return max;
00176         }
00177         return res;
00178     }
00179 }
00180 
00181 template<typename Cmp>
00182 bool in_ranges(const Cmp c, const std::vector<std::pair<Cmp, Cmp> >&ranges) {
00183     typename std::vector<std::pair<Cmp,Cmp> >::const_iterator range,
00184         range_end = ranges.end();
00185     for (range = ranges.begin(); range != range_end; ++range) {
00186         if(range->first <= c && c <= range->second) {
00187             return true;
00188         }
00189     }
00190     return false;
00191 }
00192 
00193 inline bool chars_equal_insensitive(char a, char b) { return tolower(a) == tolower(b); }
00194 inline bool chars_less_insensitive(char a, char b) { return tolower(a) < tolower(b); }
00195 
00196 #ifdef __GNUC__
00197 #define LIKELY(a)    __builtin_expect((a),1) // Tells GCC to optimize code so that if is likely to happen
00198 #define UNLIKELY(a)  __builtin_expect((a),0) // Tells GCC to optimize code so that if is unlikely to happen
00199 #else
00200 #define LIKELY(a)    a
00201 #define UNLIKELY(a)  a
00202 #endif
00203 
00204 namespace util {
00205 
00206 template<class T>
00207 class unique_ptr
00208 {
00209     T *ptr_;
00210     // Neither copyable nor assignable.
00211     unique_ptr(const unique_ptr &);
00212     unique_ptr &operator=(const unique_ptr &);
00213 public:
00214     unique_ptr(T *p = NULL): ptr_(p) {}
00215     ~unique_ptr() { delete ptr_; }
00216 
00217     void reset(T *p = NULL)
00218     {
00219         delete ptr_;
00220         ptr_ = p;
00221     }
00222 
00223     T *release()
00224     {
00225         T *p = ptr_;
00226         ptr_ = NULL;
00227         return p;
00228     }
00229 
00230     T *get() { return ptr_; }
00231     T *operator->() const { return ptr_; }
00232     T &operator*() const { return *ptr_; }
00233 };
00234 
00235 }
00236 
00237 #if 1
00238 # include <SDL_types.h>
00239 typedef Sint32 fixed_t;
00240 # define fxp_shift 8
00241 # define fxp_base (1 << fxp_shift)
00242 
00243 /** IN: float or int - OUT: fixed_t */
00244 # define ftofxp(x) (fixed_t((x) * fxp_base))
00245 
00246 /** IN: unsigned and fixed_t - OUT: unsigned */
00247 # define fxpmult(x,y) (((x)*(y)) >> fxp_shift)
00248 
00249 /** IN: unsigned and int - OUT: fixed_t */
00250 # define fxpdiv(x,y) (((x) << fxp_shift) / (y))
00251 
00252 /** IN: fixed_t - OUT: int */
00253 # define fxptoi(x) ( ((x)>0) ? ((x) >> fxp_shift) : (-((-(x)) >> fxp_shift)) )
00254 
00255 #else
00256 typedef float fixed_t;
00257 # define ftofxp(x) (x)
00258 # define fxpmult(x,y) ((x)*(y))
00259 # define fxpdiv(x,y) (static_cast<float>(x) / static_cast<float>(y))
00260 # define fxptoi(x) ( static_cast<int>(x) )
00261 #endif
00262 
00263 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:03:14 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs