utilities.h
Go to the documentation of this file.00001 /**<!--------------------------------------------------------------------> 00002 @file utilities.h 00003 @author Travis Fischer (fisch0920@gmail.com) 00004 @date Summer 2008 00005 00006 @brief 00007 Contains utility definitions used throughout all of my projects 00008 @note 00009 Some of these definitions assume the availability of GCC preprocessor 00010 extensions 00011 <!-------------------------------------------------------------------->**/ 00012 00013 #ifndef UTILITIES_H_ 00014 #define UTILITIES_H_ 00015 00016 // Common includes 00017 #include <iostream> 00018 #include <vector> 00019 #include <string> 00020 00021 #include <stdlib.h> 00022 #include <string.h> 00023 #include <math.h> 00024 00025 // ------------- 00026 // STL utilities 00027 // ------------- 00028 00029 /// Declare typedefs along with iterators and const_iterators 00030 /// Ex: 00031 /// DECLARE_STL_TYPEDEF(std::vector<Shape>, ShapeList); 00032 /// => 00033 /// typedef std::vector<Shape> ShapeList; 00034 /// typedef ShapeList::iterator ShapeListIter; 00035 /// typedef ShapeList::connst_iterator ShapeListConnstIter; 00036 #define DECLARE_STL_TYPEDEF(type, def) \ 00037 typedef type def; \ 00038 typedef def::iterator def##Iter; \ 00039 typedef def::const_iterator def##ConstIter 00040 00041 /// Use for stl types which contain a comma (commas are not allowed 00042 /// otherwise in preprocessor macro invocations) 00043 #define DECLARE_STL_TYPEDEF2(type1, type2, def) \ 00044 typedef type1,type2 def; \ 00045 typedef def::iterator def##Iter; \ 00046 typedef def::const_iterator def##ConstIter 00047 00048 /// Use for stl types which contain two commas (commas are not allowed 00049 /// otherwise in preprocessor macro invocations) 00050 #define DECLARE_STL_TYPEDEF3(typeP, type2, type3, def)\ 00051 typedef type2,type2,type3 def; \ 00052 typedef def::iterator def##Iter; \ 00053 typedef def::const_iterator def##ConstIter 00054 00055 /// Iterate over all elements in an stl container 00056 #define FOREACH(iterator_type, container, iter) \ 00057 for(iterator_type (iter) = (container).begin(); \ 00058 (iter) != (container).end(); ++(iter)) 00059 00060 00061 // --------------------------- 00062 // Error / debugging utilities 00063 // --------------------------- 00064 00065 // Debug printf; use just like printf 00066 #define dprintf(__s_, ...) { \ 00067 fprintf(stderr, "%s::%s (%d): ", __FILE__, __func__, __LINE__); \ 00068 fprintf(stderr, (__s_), ## __VA_ARGS__); \ 00069 } 00070 00071 // Ensure debugging is enabled unless specifically turned off via NDEBUG 00072 #if (!defined(NDEBUG) && !defined(DEBUG)) 00073 # define DEBUG 1 00074 #endif 00075 00076 #if (defined(DEBUG) || !defined(NDEBUG)) 00077 # include <assert.h> 00078 // Assertion macro which is only evaluated during debugging 00079 # define ASSERT(exp) \ 00080 do { \ 00081 if ((exp) == false) { \ 00082 fprintf(stderr, "\n"); \ 00083 dprintf("Assertion FAILED: '" #exp "'\n\n"); \ 00084 abort(); \ 00085 } \ 00086 } while(0) 00087 // Macro for not implemented functions 00088 # define NYI() \ 00089 do { \ 00090 dprintf("Not Yet Implemented!"); \ 00091 ASSERT(0); \ 00092 } while(0) 00093 #else 00094 # define ASSERT(exp) 00095 # define NYI() 00096 #endif 00097 00098 00099 // ---------------------- 00100 // Deallocation Utilities 00101 // ---------------------- 00102 00103 #define safeFree(p) \ 00104 do { \ 00105 if ((p)) { \ 00106 free((p)); \ 00107 (p) = NULL; \ 00108 } \ 00109 } while(0) 00110 00111 #define safeDelete(p) \ 00112 do { \ 00113 if ((p)) { \ 00114 delete ((p)); \ 00115 (p) = NULL; \ 00116 } \ 00117 } while(0) 00118 00119 #define safeDeleteArray(p) \ 00120 do { \ 00121 if ((p)) { \ 00122 delete[] ((p)); \ 00123 (p) = NULL; \ 00124 } \ 00125 } while(0) 00126 00127 00128 // --------------------- 00129 // Common math utilities 00130 // --------------------- 00131 00132 #ifdef MIN 00133 #undef MIN 00134 #endif 00135 00136 #ifdef MAX 00137 #undef MAX 00138 #endif 00139 00140 #ifdef MIN3 00141 #undef MIN3 00142 #endif 00143 00144 #ifdef MAX3 00145 #undef MAX3 00146 #endif 00147 00148 #ifdef ABS 00149 #undef ABS 00150 #endif 00151 00152 #define MIN(x, y) ({ \ 00153 const typeof (x) x_ = (x); \ 00154 const typeof (y) y_ = (y); \ 00155 ((x_ < y_) ? x_ : y_); \ 00156 }) 00157 00158 #define MAX(x, y) ({ \ 00159 const typeof (x) _x_ = (x); \ 00160 const typeof (y) _y_ = (y); \ 00161 ((_x_ > _y_) ? _x_ : _y_); \ 00162 }) 00163 00164 #define MIN3(x, y, z) ({ \ 00165 const typeof (x) x__ = (x); \ 00166 const typeof (y) y__ = (y); \ 00167 const typeof (z) z__ = (z); \ 00168 ((x__ < y__) ? (x__ < z__ ? x__ : z__) : (y__ < z__ ? y__ : z__)); \ 00169 }) 00170 00171 #define MAX3(x, y, z) ({ \ 00172 const typeof (x) __x = (x); \ 00173 const typeof (y) __y = (y); \ 00174 const typeof (z) __z = (z); \ 00175 ((__x > __y) ? (__x > __z ? __x: __z) : (__y > __z ? __y : __z)); \ 00176 }) 00177 00178 //#define MAXN(a, b, ...) MAXN(MAX(a, b), ## __VA_ARGS__) 00179 00180 #define ABS(x) ({ \ 00181 register const typeof(x) ___tx = (x); \ 00182 (___tx >= 0 ? ___tx : -___tx); \ 00183 }) 00184 00185 00186 #define EQ(a, b) (fabs((a) - (b)) < EPSILON) 00187 #define NEQ(a, b) (fabs((a) - (b)) > EPSILON) 00188 00189 #define DEGREES_TO_RADIANS(d) ((d) * (M_PI / 180.0)) 00190 #define RADIANS_TO_DEGREES(r) ((r) * (180.0 / M_PI)) 00191 00192 // caps val within the inclusive interval (min, max), assuming max >= min 00193 #define CAP(val, min, max) ({ \ 00194 const typeof (val) val__ = (val); \ 00195 const typeof (min) min__ = (min); \ 00196 const typeof (max) max__ = (max); \ 00197 ((val__ >= max__) ? max__ : (val__ <= min__ ? min__ : val__)); \ 00198 }) 00199 00200 #define CAPMAX(val,max) CAP((val), 0, (max)) 00201 #define CAPMIN(val,min) CAP((val), (min), 1) 00202 #define CAP01(val) CAP((val), 0, 1) 00203 00204 00205 //---------------------------------------- 00206 // Utilities geared towards optimization 00207 //---------------------------------------- 00208 00209 /** 00210 * A pure function is a function that has no side effects, whose 00211 * return value depends soley on the values of its arguments. 00212 * Multiple calls to a pure function with the same arguments can 00213 * be optimized in subexpressions because they are guaranteed to 00214 * produce the same result. (available on Linux only) 00215 * 00216 * "Optimizing Software in C++", Agner Fog, 2008 00217 */ 00218 #ifdef __GNUC__ 00219 # define PURE_FUNCTION __attribute__((const)) 00220 #else 00221 # define PURE_FUNCTION 00222 #endif 00223 00224 00225 //---------------------------------------- 00226 // Helper macros to build member functions 00227 //---------------------------------------- 00228 00229 /* Ex usage: GET_SET(int, error, Error) -> 00230 * void setError(int); 00231 * int getError(); 00232 * int m_error; 00233 */ 00234 #define GET_SET(type, l, L) \ 00235 GET(type, l, L) \ 00236 SET(type, l, L) \ 00237 MEMBER(type, l) 00238 00239 /* Ex Usage: GET_SET_BOOL(is, Working) -> 00240 * void setWorking(bool); 00241 * bool getWorking(); 00242 * bool m_isWorking; 00243 */ 00244 #define GET_SET_BOOL(pre, L) \ 00245 GET_BOOL(pre, L) \ 00246 SET_BOOL(pre, L) \ 00247 MEMBER(bool, pre ## L) 00248 00249 #define MEMBER(type, l) \ 00250 protected: \ 00251 type m_##l; \ 00252 public: 00253 00254 #define GET(type, l, L) \ 00255 GET_GENERIC(type, l, get##L) 00256 00257 #define SET(type, l, L) \ 00258 SET_GENERIC(type, l, L) 00259 00260 #define GET_BOOL(pre, L) \ 00261 GET_GENERIC(bool, pre ## L, pre ## L) 00262 00263 #define SET_BOOL(pre, L) \ 00264 SET_GENERIC(bool, pre ## L, L) 00265 00266 #define GET_GENERIC(type, l, L) \ 00267 public: \ 00268 inline type L() const __attribute__((always_inline)) { \ 00269 return m_##l; \ 00270 } 00271 00272 #define SET_GENERIC(type, l, L) \ 00273 public: \ 00274 inline void set##L(type newVal) __attribute__((always_inline)) { \ 00275 m_##l = newVal; \ 00276 } 00277 00278 #endif // UTILITIES_H_ 00279
Generated on 28 Feb 2009 for Milton by
1.5.6