cloudy trunk
|
00001 /* This file is part of Cloudy and is copyright (C)1978-2008 by Gary J. Ferland and 00002 * others. For conditions of distribution and use see copyright notice in license.txt */ 00003 00004 #ifndef _UTILITYMACROS_H_ 00005 #define _UTILITYMACROS_H_ 00006 00009 00018 00020 00052 00055 /* 00056 // ------------- include guards ----------------- 00057 */ 00058 00059 00060 #ifdef UTILITYMACROS_H 00061 # error Multiple #included file! 00062 #endif 00063 #define UTILITYMACROS_H 00064 00065 00066 /* --------------- definitions ------------------ */ 00067 00068 00074 #define REPEAT_2(x) x x 00075 #define REPEAT_4(x) REPEAT_2 (x) REPEAT_2 (x) 00076 #define REPEAT_8(x) REPEAT_4 (x) REPEAT_4 (x) 00077 #define REPEAT_16(x) REPEAT_8 (x) REPEAT_8 (x) 00078 #define REPEAT_32(x) REPEAT_16 (x) REPEAT_16 (x) 00079 #define REPEAT_64(x) REPEAT_32 (x) REPEAT_32 (x) 00080 #define REPEAT_128(x) REPEAT_64 (x) REPEAT_64 (x) 00081 #define REPEAT_256(x) REPEAT_128 (x) REPEAT_128 (x) 00082 #define REPEAT_512(x) REPEAT_256 (x) REPEAT_256 (x) 00083 #define REPEAT_1024(x) REPEAT_512 (x) REPEAT_512 (x) 00084 00085 00091 #define REPEAT(count, what) REPEAT_##count (what) 00092 00093 00099 #define REPEAT_WC_2(x) x, x 00100 #define REPEAT_WC_4(x) REPEAT_WC_2 (x), REPEAT_WC_2 (x) 00101 #define REPEAT_WC_8(x) REPEAT_WC_4 (x), REPEAT_WC_4 (x) 00102 #define REPEAT_WC_16(x) REPEAT_WC_8 (x), REPEAT_WC_8 (x) 00103 #define REPEAT_WC_32(x) REPEAT_WC_16 (x), REPEAT_WC_16 (x) 00104 #define REPEAT_WC_64(x) REPEAT_WC_32 (x), REPEAT_WC_32 (x) 00105 #define REPEAT_WC_128(x) REPEAT_WC_64 (x), REPEAT_WC_64 (x) 00106 #define REPEAT_WC_256(x) REPEAT_WC_128 (x), REPEAT_WC_128 (x) 00107 #define REPEAT_WC_512(x) REPEAT_WC_256 (x), REPEAT_WC_256 (x) 00108 #define REPEAT_WC_1024(x) REPEAT_WC_512 (x), REPEAT_WC_512 (x) 00109 00110 00116 #define REPEAT_WC(count, text) REPEAT_WC_##count (text) 00117 00118 00125 #define UNIQUE_NAME_1(prefix, x) prefix##x 00126 #define UNIQUE_NAME_2(prefix, x) UNIQUE_NAME_1 (prefix, x) 00127 00128 #define UNIQUE_NAME_WP(prefix) UNIQUE_NAME_2 (prefix, __LINE__) 00129 00130 #define UNIQUE_NAME UNIQUE_NAME_WP (uniqueNameOnLine_) 00131 00132 00138 #define LINE_STRING_1(x) #x 00139 #define LINE_STRING_2(x) LINE_STRING_1 (x) 00140 00141 #define LINE_STRING LINE_STRING_2 (__LINE__) 00142 00143 00151 #define HERE __FILE__ "(" LINE_STRING "):" 00152 00153 00160 #define ONCE(execution_code) \ 00161 { \ 00162 static int UNIQUE_NAME = 0; \ 00163 if( !UNIQUE_NAME ) \ 00164 { \ 00165 UNIQUE_NAME = 1; \ 00166 { execution_code } \ 00167 } \ 00168 } 00169 00170 00176 #define SKIP(skip_count, execution_code) \ 00177 { \ 00178 static int UNIQUE_NAME = 0; \ 00179 if( ++UNIQUE_NAME >= (skip_count) ) \ 00180 { \ 00181 UNIQUE_NAME = 0; \ 00182 { execution_code } \ 00183 } \ 00184 } 00185 00186 00192 #define REV_SKIP(skip_count, execution_code) \ 00193 { \ 00194 static int UNIQUE_NAME = 0; \ 00195 if( ++UNIQUE_NAME >= (skip_count) ) \ 00196 UNIQUE_NAME = 0; \ 00197 else \ 00198 { \ 00199 execution_code \ 00200 } \ 00201 } 00202 00203 00209 #define LOOP_C(count, loop_code) \ 00210 \ 00211 { \ 00212 int UNIQUE_NAME = (count); \ 00213 for(; UNIQUE_NAME > 0; --UNIQUE_NAME) \ 00214 { loop_code } \ 00215 } 00216 00217 00227 #define LOOP(count) for(int UNIQUE_NAME = (count); \ 00228 UNIQUE_NAME > 0; \ 00229 --UNIQUE_NAME) 00230 /* loop body here*/ 00231 00232 00239 #define AT_START(execution_code) \ 00240 \ 00241 static struct t_UNIQUE_NAME \ 00242 { \ 00243 UNIQUE_NAME() \ 00244 { \ 00245 execution_code \ 00246 } \ 00247 } \ 00248 UNIQUE_NAME_WP (atStartVarOnLine_); 00249 00250 00257 #define AT_END(execution_code) \ 00258 \ 00259 static struct t_UNIQUE_NAME \ 00260 { \ 00261 ~UNIQUE_NAME() \ 00262 { \ 00263 execution_code \ 00264 } \ 00265 } \ 00266 UNIQUE_NAME_WP (atStartVarOnLine_); 00267 00268 00273 class DelayedAssigner_T_Base 00274 { 00275 public: 00276 virtual ~DelayedAssigner_T_Base() 00277 {} 00278 }; 00279 00280 00287 template <class Type> 00288 class DelayedAssigner_T : public DelayedAssigner_T_Base 00289 { 00290 Type& itsVarRef; /* Reference to be assigned to*/ 00291 Type itsValue; /* Value to be remembered and assigned*/ 00292 00293 public: 00294 DelayedAssigner_T (Type &var_ref) 00295 : itsVarRef (var_ref) 00296 , itsValue (var_ref) 00297 {} 00298 00299 DelayedAssigner_T (Type &var_ref, const Type &value) /* separate*/ 00300 : itsVarRef (var_ref) 00301 , itsValue (value) 00302 {} 00303 00304 ~DelayedAssigner_T() 00305 { 00306 itsVarRef = itsValue; 00307 } 00308 }; 00309 00310 00316 #define DELAYED_ASSIGN_T(Type, var_ref, value) \ 00317 \ 00318 DelayedAssigner_T<Type> UNIQUE_NAME (var_ref, value); 00319 00320 00326 #define SAVE_T(Type, var_ref) \ 00327 \ 00328 DelayedAssigner_T<Type> UNIQUE_NAME (var_ref); 00329 00330 00337 template <class Type> inline 00338 DelayedAssigner_T<Type> makeDelayedAssigner_T (Type &var) 00339 { 00340 return DelayedAssigner_T<Type> (var); 00341 } 00342 00349 template <class Type> inline 00350 DelayedAssigner_T <Type> 00351 makeDelayedAssigner_T (Type &var, const Type& value) 00352 { 00353 return DelayedAssigner_T<Type> (var, value); 00354 } 00355 00356 00364 template <class Type> inline 00365 DelayedAssigner_T_Base* newDelayedAssigner_T (Type &var) 00366 { 00367 return new DelayedAssigner_T<Type> (var); 00368 } 00369 00370 00379 template <class Base, size_t SIZE> 00380 class UnivesalStorage_T 00381 { 00382 char itsStorage [SIZE]; /* binary storage*/ 00383 public: 00384 00385 template <class From> 00386 UnivesalStorage_T (const From& from) 00387 { 00388 /* Static checks for mismatched parameter type:*/ 00389 typedef char assertSize [sizeof (from) == SIZE]; 00390 /* will not compile if sizeof 'From' is wrong*/ 00391 if(const Base* assertInheritence = &from) 00392 (void)0;/* will not compile if 'From' is not : public Base */ 00393 00394 new (itsStorage) From (from); /* placement new & copy ctor*/ 00395 } 00396 00397 ~UnivesalStorage_T() 00398 { 00399 ((Base*)itsStorage)->~Base(); /* hopefully virtual*/ 00400 } 00401 }; 00402 00403 00409 #define SAVE(var_ref) \ 00410 \ 00411 UnivesalStorage_T \ 00412 < DelayedAssigner_T_Base, \ 00413 sizeof (makeDelayedAssigner_T (var_ref)) > \ 00414 UNIQUE_NAME (makeDelayedAssigner_T (var_ref)); 00415 00416 00422 #define DELAYED_ASSIGN(var_ref, value) \ 00423 \ 00424 UnivesalStorage_T \ 00425 < DelayedAssigner_T_Base, \ 00426 sizeof (makeDelayedAssigner_T (var_ref)) > \ 00427 UNIQUE_NAME (makeDelayedAssigner_T ((var_ref), (value))); 00428 00429 00430 /* ---------------------- end of file ------------------------*/ 00431 00432 #endif /* _UTILITYMACROS_H_ */