more generic type-punning helper

This commit is contained in:
Glenn Maynard
2006-10-07 08:17:15 +00:00
parent 586c1fc497
commit 82f51bc3d4
3 changed files with 50 additions and 39 deletions
-38
View File
@@ -9,44 +9,6 @@ extern "C"
#include "lua-5.1/src/lua.h"
}
/*
* Safely add an integer to an enum.
*
* This is illegal:
*
* ((int&)val) += iAmt;
*
* It breaks aliasing rules; the compiler is allowed to assume that "val" doesn't
* change (unless it's declared volatile), and in some cases, you'll end up getting
* old values for "val" following the add. (What's probably really happening is
* that the memory location is being added to, but the value is stored in a register,
* and breaking aliasing rules means the compiler doesn't know that the register
* value is invalid.)
*
* Always do these conversions through a union.
*/
template<typename T>
static inline void enum_add( T &val, int iAmt )
{
union conv
{
T value;
int i;
};
conv c;
c.value = val;
c.i += iAmt;
val = c.value;
}
template<typename T>
static inline T enum_add2( T val, int iAmt )
{
enum_add( val, iAmt );
return val;
}
#define FOREACH_ENUM_N( e, max, var ) for( e var=(e)0; var<max; enum_add<e>( var, +1 ) )
#define FOREACH_ENUM( e, var ) for( e var=(e)0; var<NUM_##e; enum_add<e>( var, +1 ) )
#define FOREACH_ENUM2 FOREACH_ENUM