00001
00002
00003
00004 #ifndef _UTILITYMACROS_H_
00005 #define _UTILITYMACROS_H_
00006
00009
00018
00020
00052
00055
00056
00057
00058
00059
00060 #ifdef UTILITYMACROS_H
00061 # error Multiple #included file!
00062 #endif
00063 #define UTILITYMACROS_H
00064
00065
00066
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
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;
00291 Type itsValue;
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)
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];
00383 public:
00384
00385 template <class From>
00386 UnivesalStorage_T (const From& from)
00387 {
00388
00389 typedef char assertSize [sizeof (from) == SIZE];
00390
00391 if(const Base* assertInheritence = &from)
00392 (void)0;
00393
00394 new (itsStorage) From (from);
00395 }
00396
00397 ~UnivesalStorage_T()
00398 {
00399 ((Base*)itsStorage)->~Base();
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
00431
00432 #endif