diff --git a/public/tier0/commonmacros.h b/public/tier0/commonmacros.h index 007220a1..33440087 100644 --- a/public/tier0/commonmacros.h +++ b/public/tier0/commonmacros.h @@ -28,15 +28,14 @@ #define STRING_MATCHES_ID( p, id ) ( (*((int *)(p)) == (id) ) ? true : false ) #define ID_TO_STRING( id, p ) ( (p)[3] = (((id)>>24) & 0xFF), (p)[2] = (((id)>>16) & 0xFF), (p)[1] = (((id)>>8) & 0xFF), (p)[0] = (((id)>>0) & 0xFF) ) -#define Q_ARRAYSIZE(p) (sizeof(p)/sizeof(p[0])) - #define SETBITS(iBitVector, bits) ((iBitVector) |= (bits)) #define CLEARBITS(iBitVector, bits) ((iBitVector) &= ~(bits)) #define FBitSet(iBitVector, bits) ((iBitVector) & (bits)) -inline bool IsPowerOfTwo( int value ) +template +inline bool IsPowerOfTwo( T value ) { - return (value & ( value - 1 )) == 0; + return (value & ( value - (T)1 )) == (T)0; } #ifndef REFERENCE @@ -100,7 +99,14 @@ extern "C++" // templates cannot be declared to have 'C' linkage template char (*RtlpNumberOf( UNALIGNED T (&)[N] ))[N]; +#ifdef _PREFAST_ +// The +0 is so that we can go: +// size = ARRAYSIZE(array) * sizeof(array[0]) without triggering a /analyze +// warning about multiplying sizeof. +#define RTL_NUMBER_OF_V2(A) (sizeof(*RtlpNumberOf(A))+0) +#else #define RTL_NUMBER_OF_V2(A) (sizeof(*RtlpNumberOf(A))) +#endif // This does not work with: // @@ -145,5 +151,23 @@ char (*RtlpNumberOf( UNALIGNED T (&)[N] ))[N]; #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A) #define _ARRAYSIZE(A) RTL_NUMBER_OF_V1(A) +#define Q_ARRAYSIZE(p) ARRAYSIZE(p) +#define V_ARRAYSIZE(p) ARRAYSIZE(p) + +template< typename IndexType, typename T, unsigned int N > +IndexType ClampedArrayIndex( const T (&buffer)[N], IndexType index ) +{ + return clamp( index, 0, (IndexType)N - 1 ); +} + +template< typename T, unsigned int N > +T ClampedArrayElement( const T (&buffer)[N], unsigned int uIndex ) +{ + // Put index in an unsigned type to halve the clamping. + if ( uIndex >= N ) + uIndex = N - 1; + return buffer[ uIndex ]; +} + #endif // COMMONMACROS_H