//////////////////// 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