179 lines
4.9 KiB
C++
179 lines
4.9 KiB
C++
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose:
|
|
//
|
|
// $NoKeywords: $
|
|
//
|
|
//=============================================================================//
|
|
#ifndef COMMONMACROS_H
|
|
#define COMMONMACROS_H
|
|
|
|
#ifdef _WIN32
|
|
#pragma once
|
|
#endif
|
|
|
|
#include "platform.h"
|
|
|
|
// -------------------------------------------------------
|
|
//
|
|
// 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))
|
|
|
|
template <typename T>
|
|
inline bool IsPowerOfTwo(T value) {
|
|
return (value & (value - (T)1)) == (T)0;
|
|
}
|
|
|
|
#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) && \
|
|
(_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];
|
|
|
|
#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:
|
|
//
|
|
// 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)
|
|
|
|
#define Q_ARRAYSIZE(p) ARRAYSIZE(p)
|
|
|
|
template <typename IndexType, typename T, unsigned int N>
|
|
IndexType ClampedArrayIndex(const T (&buffer)[N], IndexType index) {
|
|
NOTE_UNUSED(buffer);
|
|
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
|