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 doxygen 1.5.6