Listing 1: UtilityMacros.h
//////////////////// UtilityMacros.h ///////////////// rado //// // // // Copyright (c) 1999 Radoslav Getov // // // // Permission to use, copy, modify and distribute this // // software is granted without fee, provided that the above // // copyright notice and this permission notice appear in the // // modified source and the source files that #include it. // // // //////////////////////////////////////////////////////////////// // not shown: include guards, conditional compilation // directives for portability //===================| #REPEAT_xxx (text) |===================== #define REPEAT_2(x) x x #define REPEAT_4(x) REPEAT_2 (x) REPEAT_2 (x) #define REPEAT_8(x) REPEAT_4 (x) REPEAT_4 (x) #define REPEAT_16(x) REPEAT_8 (x) REPEAT_8 (x) #define REPEAT_32(x) REPEAT_16 (x) REPEAT_16 (x) #define REPEAT_64(x) REPEAT_32 (x) REPEAT_32 (x) #define REPEAT_128(x) REPEAT_64 (x) REPEAT_64 (x) #define REPEAT_256(x) REPEAT_128 (x) REPEAT_128 (x) #define REPEAT_512(x) REPEAT_256 (x) REPEAT_256 (x) #define REPEAT_1024(x) REPEAT_512 (x) REPEAT_512 (x) // not shown: definitions for REPEAT (count, text), // REPEAT_WC_xxx, and REPEAT_WC (count, text) // ... //====================| #UNIQUE_NAME |========================== #define UNIQUE_NAME_1(prefix, x) prefix##x #define UNIQUE_NAME_2(prefix, x) UNIQUE_NAME_1 (prefix, x) #define UNIQUE_NAME_WP(prefix) UNIQUE_NAME_2 (prefix, __LINE__) #define UNIQUE_NAME UNIQUE_NAME_WP (uniqueNameOnLine_) //====================| #LINE_STRING |========================== #define LINE_STRING_1(x) #x #define LINE_STRING_2(x) LINE_STRING_1 (x) #define LINE_STRING LINE_STRING_2 (__LINE__) //=====================| #HERE |================================ #define HERE __FILE__ "(" LINE_STRING "):" //===================| #ONCE(execution_code) |================== #define ONCE(execution_code) \ { \ static int UNIQUE_NAME = 0; \ if (!UNIQUE_NAME) \ { \ UNIQUE_NAME = 1; \ { execution_code } \ } \ } //=====================| #SKIP(cnt,code) |====================== #define SKIP(skip_count, execution_code) \ { \ static int UNIQUE_NAME = 0; \ if (++UNIQUE_NAME >= (skip_count)) \ { \ UNIQUE_NAME = 0; \ { execution_code } \ } \ } //=====================| #REV_SKIP(cnt,code) |================== #define REV_SKIP(skip_count, execution_code) \ { \ static int UNIQUE_NAME = 0; \ if (++UNIQUE_NAME >= (skip_count)) \ UNIQUE_NAME = 0; \ else \ { \ execution_code \ } \ } //=====================| #LOOP_C |============================== #define LOOP_C(count, loop_code) \ \ { \ int UNIQUE_NAME = (count); \ for (; UNIQUE_NAME > 0; --UNIQUE_NAME) \ { loop_code } \ } //////////// C++ compatible only templates and macros ////////// #if CPP_MODE_COMPILATION //=====================| #LOOP |================================ #define LOOP(count) for (int UNIQUE_NAME = (count); \ UNIQUE_NAME > 0; \ --UNIQUE_NAME) // loop body here //========================| #AT_START |========================= #define AT_START(execution_code) \ \ static struct UNIQUE_NAME \ { \ UNIQUE_NAME() \ { \ execution_code \ } \ } \ UNIQUE_NAME_WP (atStartVarOnLine_); //=======================| #AT_END |============================ #define AT_END(execution_code) \ \ static struct UNIQUE_NAME \ { \ ~UNIQUE_NAME() \ { \ execution_code \ } \ } \ UNIQUE_NAME_WP (atStartVarOnLine_); //*************| class DelayedAssigner_T_Base |***************** class DelayedAssigner_T_Base { public: virtual ~DelayedAssigner_T_Base() {} }; //***************| class DelayedAssigner_T |******************** template <class Type> class DelayedAssigner_T : public DelayedAssigner_T_Base { Type& itsVarRef; // Reference to be assigned to Type itsValue; // Value to be remembered and assigned public: DelayedAssigner_T (Type &var_ref) : itsVarRef (var_ref) , itsValue (var_ref) {} DelayedAssigner_T (Type &var_ref, const Type &value) // separate : itsVarRef (var_ref) , itsValue (value) {} ~DelayedAssigner_T() { itsVarRef = itsValue; } }; //==================| #DELAYED_ASSIGN_T |======================= #define DELAYED_ASSIGN_T(Type, var_ref, value) \ \ DelayedAssigner_T<Type> UNIQUE_NAME (var_ref, value); //===================| #SAVE_T |================================ #define SAVE_T(Type, var_ref) \ \ DelayedAssigner_T<Type> UNIQUE_NAME (var_ref); //===============| makeDelayedAssigner_T |====================== template <class Type> inline DelayedAssigner_T<Type> makeDelayedAssigner_T (Type &var) { return DelayedAssigner_T<Type> (var); } //===============| makeDelayedAssigner_T(2) |=================== template <class Type> inline DelayedAssigner_T <Type> makeDelayedAssigner_T (Type &var, const Type& value) { return DelayedAssigner_T<Type> (var, value); } //==================| newDelayedAssigner_T |==================== template <class Type> inline DelayedAssigner_T_Base* newDelayedAssigner_T (Type &var) { return new DelayedAssigner_T<Type> (var); } //======================| UnivesalStorage_T |=================== template <class Base, size_t SIZE> class UnivesalStorage_T { char itsStorage [SIZE]; // binary storage public: template <class From> UnivesalStorage_T (const From& from) { // Static checks for mismatched parameter type: typedef char assertSize [sizeof (from) == SIZE]; // will not compile if sizeof 'From' is wrong if (const Base* assertInheritence = &from) 0;// will not compile if 'From' is not : public Base new (itsStorage) From (from); // placement new & copy ctor } ~UnivesalStorage_T() { ((Base*)itsStorage)->~Base(); // hopefully virtual } }; //=====================| #SAVE(var_ref) |======================= #define SAVE(var_ref) \ \ UnivesalStorage_T \ < DelayedAssigner_T_Base, \ sizeof (makeDelayedAssigner_T (var_ref)) > \ UNIQUE_NAME (makeDelayedAssigner_T (var_ref)); //======================| #DELAYED_ASSIGN |====================== #define DELAYED_ASSIGN(var_ref, value) \ \ UnivesalStorage_T \ < DelayedAssigner_T_Base, \ sizeof (makeDelayedAssigner_T (var_ref)) > \ UNIQUE_NAME (makeDelayedAssigner_T ((var_ref), (value))); #endif // CPP_MODE_COMPILATION