//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // //=============================================================================// #ifndef RANGECHECKEDVAR_H #define RANGECHECKEDVAR_H #ifdef _WIN32 #pragma once #endif #include "tier0/dbg.h" #include "tier0/threadtools.h" #include "mathlib/vector.h" #include // Use this to disable range checks within a scope. class CDisableRangeChecks { public: CDisableRangeChecks(); ~CDisableRangeChecks(); }; template< class T > inline void RangeCheck( const T &value, int minValue, int maxValue ) { #ifdef _DEBUG extern bool g_bDoRangeChecks; if ( ThreadInMainThread() && g_bDoRangeChecks ) { // Ignore the min/max stuff for now.. just make sure it's not a NAN. Assert( _finite( value ) ); } #endif } inline void RangeCheck( const Vector &value, int minValue, int maxValue ) { #ifdef _DEBUG RangeCheck( value.x, minValue, maxValue ); RangeCheck( value.y, minValue, maxValue ); RangeCheck( value.z, minValue, maxValue ); #endif } template< class T, int minValue, int maxValue, int startValue > class CRangeCheckedVar { public: inline CRangeCheckedVar() { m_Val = startValue; } inline CRangeCheckedVar( const T &value ) { *this = value; } T GetRaw() const { return m_Val; } // Clamp the value to its limits. Interpolation code uses this after interpolating. inline void Clamp() { if ( m_Val < minValue ) m_Val = minValue; else if ( m_Val > maxValue ) m_Val = maxValue; } inline operator const T&() const { return m_Val; } inline CRangeCheckedVar& operator=( const T &value ) { RangeCheck( value, minValue, maxValue ); m_Val = value; return *this; } inline CRangeCheckedVar& operator+=( const T &value ) { return (*this = m_Val + value); } inline CRangeCheckedVar& operator-=( const T &value ) { return (*this = m_Val - value); } inline CRangeCheckedVar& operator*=( const T &value ) { return (*this = m_Val * value); } inline CRangeCheckedVar& operator/=( const T &value ) { return (*this = m_Val / value); } private: T m_Val; }; #endif // RANGECHECKEDVAR_H