2024-01-18 02:58:55 +03:00
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
2010-07-22 01:46:14 -05:00
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
# ifndef COMMONMACROS_H
# define COMMONMACROS_H
# ifdef _WIN32
# pragma once
# endif
// -------------------------------------------------------
//
// commonmacros.h
//
// This should contain ONLY general purpose macros that are
// appropriate for use in engine/launcher/all tools
//
// -------------------------------------------------------
// Makes a 4-byte "packed ID" int out of 4 characters
# define MAKEID(d,c,b,a) ( ((int)(a) << 24) | ((int)(b) << 16) | ((int)(c) << 8) | ((int)(d)) )
// Compares a string with a 4-byte packed ID constant
# 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 SETBITS(iBitVector, bits) ((iBitVector) |= (bits))
# define CLEARBITS(iBitVector, bits) ((iBitVector) &= ~(bits))
# define FBitSet(iBitVector, bits) ((iBitVector) & (bits))
2025-03-06 21:56:48 +03:00
template < typename T >
inline bool IsPowerOfTwo ( T value )
2010-07-22 01:46:14 -05:00
{
2025-03-06 21:56:48 +03:00
return ( value & ( value - ( T ) 1 ) ) = = ( T ) 0 ;
2010-07-22 01:46:14 -05:00
}
# ifndef REFERENCE
# define REFERENCE(arg) ((void)arg)
# endif
# define CONST_INTEGER_AS_STRING(x) #x //Wraps the integer in quotes, allowing us to form constant strings with it
# define __HACK_LINE_AS_STRING__(x) CONST_INTEGER_AS_STRING(x) //__LINE__ can only be converted to an actual number by going through this, otherwise the output is literally "__LINE__"
# define __LINE__AS_STRING __HACK_LINE_AS_STRING__(__LINE__) //Gives you the line number in constant string form
// Using ARRAYSIZE implementation from winnt.h:
# ifdef ARRAYSIZE
# undef ARRAYSIZE
# endif
// Return the number of elements in a statically sized array.
// DWORD Buffer[100];
// RTL_NUMBER_OF(Buffer) == 100
// This is also popularly known as: NUMBER_OF, ARRSIZE, _countof, NELEM, etc.
//
# define RTL_NUMBER_OF_V1(A) (sizeof(A) / sizeof((A)[0]))
# if defined(__cplusplus) && \
! defined ( MIDL_PASS ) & & \
! defined ( RC_INVOKED ) & & \
! defined ( _PREFAST_ ) & & \
( _MSC_FULL_VER > = 13009466 ) & & \
! defined ( SORTPP_PASS )
// From crtdefs.h
# if !defined(UNALIGNED)
# if defined(_M_IA64) || defined(_M_AMD64)
# define UNALIGNED __unaligned
# else
# define UNALIGNED
# endif
# endif
// RtlpNumberOf is a function that takes a reference to an array of N Ts.
//
// typedef T array_of_T[N];
// typedef array_of_T &reference_to_array_of_T;
//
// RtlpNumberOf returns a pointer to an array of N chars.
// We could return a reference instead of a pointer but older compilers do not accept that.
//
// typedef char array_of_char[N];
// typedef array_of_char *pointer_to_array_of_char;
//
// sizeof(array_of_char) == N
// sizeof(*pointer_to_array_of_char) == N
//
// pointer_to_array_of_char RtlpNumberOf(reference_to_array_of_T);
//
// We never even call RtlpNumberOf, we just take the size of dereferencing its return type.
// We do not even implement RtlpNumberOf, we just decare it.
//
// Attempts to pass pointers instead of arrays to this macro result in compile time errors.
// That is the point.
extern " C++ " // templates cannot be declared to have 'C' linkage
template < typename T , size_t N >
char ( * RtlpNumberOf ( UNALIGNED T ( & ) [ N ] ) ) [ N ] ;
2025-03-06 21:56:48 +03:00
# 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
2010-07-22 01:46:14 -05:00
# define RTL_NUMBER_OF_V2(A) (sizeof(*RtlpNumberOf(A)))
2025-03-06 21:56:48 +03:00
# endif
2010-07-22 01:46:14 -05:00
// This does not work with:
//
// void Foo()
// {
// struct { int x; } y[2];
// RTL_NUMBER_OF_V2(y); // illegal use of anonymous local type in template instantiation
// }
//
// You must instead do:
//
// struct Foo1 { int x; };
//
// void Foo()
// {
// Foo1 y[2];
// RTL_NUMBER_OF_V2(y); // ok
// }
//
// OR
//
// void Foo()
// {
// struct { int x; } y[2];
// RTL_NUMBER_OF_V1(y); // ok
// }
//
// OR
//
// void Foo()
// {
// struct { int x; } y[2];
// _ARRAYSIZE(y); // ok
// }
# else
# define RTL_NUMBER_OF_V2(A) RTL_NUMBER_OF_V1(A)
# endif
// ARRAYSIZE is more readable version of RTL_NUMBER_OF_V2
// _ARRAYSIZE is a version useful for anonymous types
# define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)
# define _ARRAYSIZE(A) RTL_NUMBER_OF_V1(A)
2025-03-06 21:56:48 +03:00
# 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 ] ;
}
2025-06-05 16:34:12 +03:00
// Would double old_count until it's greater or equal the requested_count and is clamped to min/max bounds.
inline int CalcNewDoublingCount ( int old_count , int requested_count , int min_count , int max_count )
{
int new_count = old_count ;
while ( new_count < requested_count )
{
if ( new_count < max_count / 2 )
{
new_count * = 2 ;
if ( new_count < min_count )
new_count = min_count ;
}
else
{
new_count = max_count ;
break ;
}
}
return new_count ;
}
2010-07-22 01:46:14 -05:00
# endif // COMMONMACROS_H