base_funcs.hh

Go to the documentation of this file.
00001 /*
00011  * LEGAL:   COPYRIGHT (C) 2004 JIM E. BROOKS
00012  *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
00013  *          OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
00014  *****************************************************************************/
00015 
00016 #ifndef DOXYGEN  // doxygen can't parse this correctly
00017 #ifndef BASE_FUNCS_HH
00018 #define BASE_FUNCS_HH 1
00019 
00020 namespace base {
00021 
00025 
00026 // Min()/Max() is strongly recommended and faster if either arg is a computation,
00027 // but requires both args to be the same type.
00028 // Macro MIN()/MAX() lets the compiler automatically convert args of different types,
00029 // but be warned: has the well-known side-effect of compiling each arg twice!
00030 template<typename T> inline T Min( T a, T b ) { return (a < b) ? a : b; }
00031 template<typename T> inline T Max( T a, T b ) { return (a > b) ? a : b; }
00032 #ifndef MIN
00033 #define MIN(A,B) ( ((A) < (B)) ? (A) : (B) )
00034 #endif
00035 #ifndef MAX
00036 #define MAX(A,B) ( ((A) > (B)) ? (A) : (B) )
00037 #endif
00038 
00039 // Uses overloaded abs() from <cmath>.
00040 #define ABS(X) abs((X))
00041 
00042 // DEPRECATED
00043 #ifndef STREQ
00044 #define STREQ(A,B) ( strcmp((A),(B)) == 0 )
00045 #endif
00046 #ifndef STRNE
00047 #define STRNE(A,B) ( strcmp((A),(B)) != 0 )
00048 #endif
00049 #ifndef STREMPTY
00050 #define STREMPTY(S) ( ((S) == NULL) || ((S)[0] == '\0') )
00051 #endif
00052 #ifndef MEMEQ
00053 #define MEMEQ(S1,S2,LEN) ( memcmp((S1),(S2),(LEN)) == 0 )
00054 #endif
00055 #ifndef MENNE
00056 #define MEMNE(S1,S2,LEN) ( memcmp((S1),(S2),(LEN)) != 0 )
00057 #endif
00058 #define ELEMS(ARRAY) (uint( sizeof((ARRAY)) / sizeof((ARRAY)[0]) ))  // DEPRECATED
00059 
00060 // Read/write 32-bits by pointer portably.
00061 #define READ_UINT32( PTR )       ( (*reinterpret_cast<uint32*>((PTR))) )
00062 #define WRITE_UINT32( PTR, VAL ) ( (*reinterpret_cast<uint32*>((PTR))) = (VAL) )
00063 #define COPY_UINT32( DEST, SRC ) ( (*reinterpret_cast<uint32*>((DEST))) = (*reinterpret_cast<const uint32*>((SRC))) )
00064 
00066 #define DELETE_NULL( OBJ ) delete (OBJ), (OBJ) = NULL
00067 
00077 #define RETURN_LT_TRUE_GT_FALSE( X, Y )         \
00078 {                                               \
00079     if ( (X) < (Y) ) return true;               \
00080     if ( (Y) < (X) ) return false;              \
00081 }
00082 
00083 // Put this in destructors of globals which may call other globals
00084 // to avoid pitfall of undefined order of destruction.
00085 #define RETURN_IF_EXITING  if ( base::global.mExiting ) return;
00086 
00087 // In case some cleanup function should be called instead.
00088 void EXIT( int exitCode );
00089 
00092 #define CLEAR_BIT_FIELDS( BIT_FIELD_PTR ) ( *(reinterpret_cast<unsigned int*>( (BIT_FIELD_PTR) )) = 0 )
00093 
00094 // Arcane indirect trick to give a variable a unique name.
00095 // Subtlety: If written on the same line, UNIQUE_NAME() expands the same name.
00096 // That's a feature not a bug.  BEGIN_ONCE depends on it.
00097 #define UNIQUE_NAME__(NAME,LINE) NAME##LINE
00098 #define UNIQUE_NAME_(NAME,LINE)  UNIQUE_NAME__(NAME,LINE)
00099 #define UNIQUE_NAME(NAME)        UNIQUE_NAME_(NAME,__LINE__)
00100 
00102 // BEGIN_ONCE {  <-- write brace  // thread-safe
00103 // ...
00104 // } END_ONCE
00105 // Subtlety: This must be one-line because of UNIQUE_NAME().
00106 // Needs to be locked since BEGIN_ONCE is often placed in threadable code.
00107 #define BEGIN_ONCE                          \
00108  {                                          \
00109     PERSISTENT FastLock sLockOnce_;         \
00110     FastLock::Auto autolock(&sLockOnce_);   \
00111     PERSISTENT int UNIQUE_NAME(once);       \
00112     ++UNIQUE_NAME(once);                    \
00113     if ( UNIQUE_NAME(once) == 1 )
00114 
00115 #define END_ONCE \
00116  }
00117 
00120 #if __GNUC__ >= 3
00121 #define likely(x)   __builtin_expect((x),1)
00122 #define unlikely(x) __builtin_expect((x),0)
00123 #else
00124 #define likely(x) (x)
00125 #define unlikely(x) (x)
00126 #endif
00127 #define EX(x) likely((x))   
00128 #define UX(x) unlikely((x)) 
00129 
00132 #if GCC_VERSION >= 30100  // if gcc-3.1 or later
00133 #define UNUSED    __attribute__ ((unused))
00134 #define DEBUG_VAR __attribute__ ((unused))
00135 #define NOINLINE  __attribute__ ((noinline))
00136 #else
00137 #define UNUSED
00138 #define DEBUG_VAR
00139 #define NOINLINE
00140 #endif
00141 
00143 #if DEBUG
00144 #define  CODE
00145 #else
00146 #define 
00147 #endif
00148 
00149 // Pedantic excruciatingly slow debug code.
00150 #if DEBUG == 2
00151 #define  CODE
00152 #else
00153 #define 
00154 #endif
00155 
00156 // To mark where code needs implementing.
00157 #define UNIMPLEMENTED() ASSERT(0)
00158 
00159 // C++ stream field formatting.
00160 #define OMANIP_FIELD(CHARS) std::setw(CHARS) << std::right
00161 
00162 // Prevent copying an object.  Put these in the private section of a class.
00163 // The copy methods are prototypes without definitions, so usage causes a linker error.
00164 #define                     \
00165 private:                                            \
00166     CLASS( const CLASS& );                          \
00167     CLASS& operator=( const CLASS& );
00168 
00169 // To mark classes that are copyable.
00170 #define           // means class is copyable by user-defined copying methods
00171 #define   // means class is copyable by compiler-generated copying methods
00172 #define      // synonym
00173 
00174 // To mark class that shouldn't be instantiated
00175 #define PREVENT_INSTANTIATING( CLASS )  // NOP
00176 #define PREVENT_INSTANCE( CLASS )  // NOP
00177 
00181 
00183 INLINE void
00184 CLEAR( void* p, uint n )
00185 {
00186     memset( p, 0, n );
00187 }
00188 
00190 INLINE int         NEG( int         x ) { return (x < 0) ? x : -x; }
00191 INLINE long int    NEG( long int    x ) { return (x < 0) ? x : -x; }
00192 INLINE float       NEG( float       x ) { return (x < 0) ? x : -x; }
00193 INLINE double      NEG( double      x ) { return (x < 0) ? x : -x; }
00194 INLINE long double NEG( long double x ) { return (x < 0) ? x : -x; }
00195 
00196 INLINE bool
00197 IfPow2( int n )
00198 {
00199     // Trick: result is 0 if n is a power of 2.
00200     return (n & (n-1)) == 0;
00201 }
00202 
00203 INLINE bool IfEven( int n ) { return (n & 1) == 0; }
00204 INLINE bool IfOdd( int n )  { return (n & 1) == 1; }
00205 
00206 // +1 or -1 if true or false
00207 INLINE int
00208 PLUS_MINUS_1( bool plus )
00209 {
00210     return plus ? 1 : -1;
00211 }
00212 
00216 
00220 template<typename T>
00221 inline void
00222 Swap( T& a, T& b )
00223 {
00224     T a2 = a;
00225     a = b;
00226     b = a2;
00227 }
00228 
00229 } // namespace base
00230 
00231 #endif // BASE_FUNCS_HH
00232 #endif // DOXYGEN
Palomino 3D Engine documents generated by doxygen 1.5.3 on Fri Nov 23 11:26:06 2007