From 2baddd84fc3a2f4f026a1de0311cc9a4bc1f98fc Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Wed, 27 Sep 2006 04:19:47 +0000 Subject: [PATCH] COMPILE_ASSERT XToString table sizes pull out common XToString code simplify XToString --- stepmania/src/EnumHelper.cpp | 21 +++++++++++++++++++++ stepmania/src/EnumHelper.h | 23 +++++------------------ 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/stepmania/src/EnumHelper.cpp b/stepmania/src/EnumHelper.cpp index 7ff8f53590..c32690961c 100644 --- a/stepmania/src/EnumHelper.cpp +++ b/stepmania/src/EnumHelper.cpp @@ -31,6 +31,27 @@ int CheckEnum( lua_State *L, LuaReference &table, int iPos, int iInvalid, const return iRet; } +// szNameArray is of size iMax; pNameCache is of size iMax+2. +const RString &EnumToString( int iVal, int iMax, const char **szNameArray, auto_ptr *pNameCache ) +{ + if( unlikely(pNameCache[0].get() == NULL) ) + { + for( int i = 0; i < iMax; ++i ) + { + auto_ptr ap( new RString( szNameArray[i] ) ); + pNameCache[i] = ap; + } + + auto_ptr ap( new RString ); + pNameCache[iMax+1] = ap; + } + + // iMax+1 is "Invalid". iMax+0 is the NUM_ size value, which can not be converted + // to a string. + ASSERT_M( iVal >= 0 && (iVal < iMax || iVal == iMax+1), ssprintf("%i, %i", iVal, iMax) ); + return *pNameCache[iVal]; +} + /* * (c) 2004 Chris Danford * All rights reserved. diff --git a/stepmania/src/EnumHelper.h b/stepmania/src/EnumHelper.h index 47ef4e5fd5..2fa0fb0664 100644 --- a/stepmania/src/EnumHelper.h +++ b/stepmania/src/EnumHelper.h @@ -80,28 +80,15 @@ namespace Enum }; static const RString EMPTY_STRING; +const RString &EnumToString( int iVal, int iMax, const char **szNameArray, auto_ptr *pNameCache ); // XToString helper -// TypeName[] must be an array of const char *, not RString, to -// avoid initialization order problems when calling XToString. -// Use Check##X##ToStringParamType to enforce that. -#define XToString(X, CNT) \ +#define XToString(X, CNT) \ static void Check##X##ToStringParamType( const char **p ) { } \ + COMPILE_ASSERT( NUM_##X == ARRAYLEN(X##Names) ); \ const RString& X##ToString( X x ) \ { \ - Check##X##ToStringParamType( X##Names ); \ - static auto_ptr as_##X##Name[NUM_##X]; \ - if( as_##X##Name[0].get() == NULL ) { \ - for( unsigned i = 0; i < NUM_##X; ++i ) \ - { \ - auto_ptr ap( new RString( X##Names[i] ) ); \ - as_##X##Name[i] = ap; \ - } \ - } \ - ASSERT( NUM_##X == ARRAYLEN(X##Names) ); \ - if( x == NUM_##X+1 ) \ - return EMPTY_STRING; \ - ASSERT( x < NUM_##X ); \ - return *as_##X##Name[x]; \ + static auto_ptr as_##X##Name[NUM_##X+2]; \ + return EnumToString( x, NUM_##X, X##Names, as_##X##Name ); \ } #define XToLocalizedString(X) \