#pragma once
// In this header some operator definitions.
// They are different from the STL <utility> defined ones, because they are AFXAPI (that is _stdcall, instead of _cdecl).
// CString operators don�t conflict with these operators (they appear to be specializations) but conflict with the STL ones because of the different calling convenction
//
namespace GE_{namespace Mfc{
}}
// define in case it is not yet defined
#ifndef AFXAPI
#define AFXAPI __stdcall
#endif
namespace GE_{ namespace Operators
{
using namespace GE_::Mfc; //required for some GE_::Mfc namespace operators
//comparisons, all in term of == and <
template <class T, class U>
bool AFXAPI operator!=(const T& t, const U& u)
{ return !(t==u); };
template <class T, class U>
bool AFXAPI operator<=(const T& t, const U& u)
{ return (t<u)||(t==u); };
template <class T, class U>
bool AFXAPI operator>=(const T& t, const U& u)
{ return (u<=t); };
template <class T, class U>
bool AFXAPI operator>(const T& t, const U& u)
{ return (u<t); };
// MAX and Min functions (not macros)
template <class T>
const T& AFXAPI Max(const T& t, const T& u)
{ return (t<u)? u: t; };
template <class T>
const T& AFXAPI Min(const T& t, const T& u)
{ return (t<u)? t: u; };
// Sampling to Max or Min: t=u if u> or <t.
template <class T, class U>
T& AFXAPI SampleMax(T& t, const U& u)
{ if (t<u) t=u; return t; };
template <class T, class U>
T& AFXAPI SampleMin(T& t, const U& u)
{ if (u<t) t=u; return t; };
// Clipping: t=u if u<t
template <class T, class U>
T& AFXAPI ClipMax(T& t, const U& u)
{ if (u<t) t=u; return t; };
template <class T, class U>
T& AFXAPI ClipMin(T& t, const U& u)
{ if (t<u) t=u; return t; };
// Swap two values
template <class T>
void AFXAPI Swap(T& a, T& b)
{ T c(a); a=b; b=c; };
// make t to stay between min and max
template <class T>
bool AFXAPI Limit(T& t, const T& min, const T& max)
{
bool b = false;
if (t<min)
b = true, t=min;
if(min<max && max<t)
b = true, t=max;
if(max < min)
b = true, t = min;
return b;
}
// make always a < b by swapping if needed
template <class T>
bool AFXAPI Sort(T& a, T& b)
{
if (a<b) return true;
Swap(a,b);
return false;
}
// check various type of ranges
template <class T, class U, class V>
bool IsInRangeLR(const T& t, const U& u, const V& v)
{ return u<=t && t<=v; }
template <class T, class U, class V>
bool IsInRangeL_(const T& t, const U& u, const V& v)
{ return u<=t && t<v; }
template <class T, class U, class V>
bool IsInRange_R(const T& t, const U& u, const V& v)
{ return u<t && t<=v; }
template <class T, class U, class V>
bool IsInRange__(const T& t, const U& u, const V& v)
{ return u<t && t<v; }
template <class T, class U, class V>
bool IsInGapL_(const T& t, const U& val, const V& size)
{ return val<=t && t<val+size; }
template <class T, class U, class V>
bool IsInGap_R(const T& t, const U& val, const V& size)
{ return val<t-size && t<=val; }
template <class T, class U, class V>
bool IsInGapLR(const T& t, const U& val, const V& size)
{ return val<=t-size && t<=val+size; }
template <class T, class U, class V>
bool IsInGap__(const T& t, const U& val, const V& size)
{ return val<t-size && t<val+size; }
// define operator i term of their correspondent assignments
template <class T, class U>
T AFXAPI operator+(const T& t, const U& u)
{ T r(t); r+=u; return r; }
template <class T, class U>
T AFXAPI operator-(const T& t, const U& u)
{ T r(t); r-=u; return r; }
template <class T, class U>
T AFXAPI operator*(const T& t, const U& u)
{ T r(t); r*=u; return r; }
template <class T, class U>
T AFXAPI operator/(const T& t, const U& u)
{ T r(t); r/=u; return r; }
template <class T, class U>
T AFXAPI operator%(const T& t, const U& u)
{ T r(t); r%=u; return r; }
template <class T, class U>
T AFXAPI operator&(const T& t, const U& u)
{ T r(t); r&=u; return r; }
template <class T, class U>
T AFXAPI operator|(const T& t, const U& u)
{ T r(t); r|=u; return r; }
template <class T, class U>
T AFXAPI operator^(const T& t, const U& u)
{ T r(t); r^=u; return r; }
//increment a passed counter, and decrement on destruction
// typical use:
// {
// SLockCount lock; lock(avariable);
// // do some action
// }
// "avariable" decremented reacing this brace
struct SLockCount
{
int* pLocks;
int Lock() {if(pLocks) (*pLocks)++; return *pLocks;}
int UnLock() {if(pLocks) (*pLocks)--; return *pLocks;}
int Lock(int& b) {pLocks = &b; return Lock();}
SLockCount() {pLocks = NULL;}
~SLockCount() {UnLock();}
};
// CMulticalstCall is a list of referred items, that calls items member functions in turn.
// The list can be abjusted on call by overriding UpdateMembersList
template<class I>
class CMulticastCall:
public std::list<I*>
{
public:
//called by "Call" functions, to give a chance to update the list
virtual void UpdateMembersList() {;} //does nothing
void Call(void (I::*pfnVoid)())
{ UpdateMembersList(); for(iterator i = begin(); i!=end(); i++) ((*i)->*pfnVoid)(); }
template<class A>
void Call(void (I::*pfn1)(A), A a)
{ UpdateMembersList(); for(iterator i = begin(); i!=end(); i++) ((*i)->*pfn1)(a); }
template<class A, class B>
void Call(void (I::*pfn2)(A,B), A a, B b)
{ UpdateMembersList(); for(iterator i = begin(); i!=end(); i++) ((*i)->*pfn2)(a,b); }
template<class A, class B, class C>
void Call(void (I::*pfn3)(A,B,C), A a, B b, C c)
{ UpdateMembersList(); for(iterator i = begin(); i!=end(); i++) ((*i)->*pfn3)(a,b,c); }
template<class A, class B, class C, class D>
void Call(void (I::*pfn4)(A,B,C,D), A a, B b, C c, D d)
{ UpdateMembersList(); for(iterator i = begin(); i!=end(); i++) ((*i)->*pfn4)(a,b,c,d); }
};
// STemAssign assign a value on construction and restore the previous value on destruction
// Typical use:
// {
// STempAssign<int> ta(a_int_member, a_value);
// // do some actions
// // �
// }
// // variable restored at this brace
template<class V>
class STempAssign
{
private:
V* _pVar;
V _prevVal;
public:
STempAssign(V& var, const V& val)
{
_pVar = &var;
_prevVal = var;
var = val;
}
~STempAssign()
{
*_pVar = _prevVal;
}
};
}}