Yes I was very bored and skimming through DXUT source file when I spotted those:
#define SET_ACCESSOR( x, y ) inline void Set##y( x t ) { DXUTLock l; m_state.m_##y = t; }; #define GET_ACCESSOR( x, y ) inline x Get##y() { DXUTLock l; return m_state.m_##y; }; #define GET_SET_ACCESSOR( x, y ) SET_ACCESSOR( x, y ) GET_ACCESSOR( x, y ) #define SETP_ACCESSOR( x, y ) inline void Set##y( x* t ) { DXUTLock l; m_state.m_##y = *t; }; #define GETP_ACCESSOR( x, y ) inline x* Get##y() { DXUTLock l; return &m_state.m_##y; }; #define GETP_SETP_ACCESSOR( x, y ) SETP_ACCESSOR( x, y ) GETP_ACCESSOR( x, y )
and I instantly wanted the same type of macros, except with all the genericity and safety of C++0x.
Setters were a walk in the park:
#define Nitro_PropertySet(name) inline void set##name(decltype(m##name) t) { m##name = t; }
Getters not so much; I initially thought that I could use the trailing-type feature of C++0x to get an auto-magic return type, unfortunately it behaves differently and would not accept the member name for an answer.
So I used a little trick, I declare a template structure with a default template parameter (the decltype with the member name), add a typedef, inject the whole in the inline getters and there it is !
#define Nitro_PropertyGet(name) template < typename T = decltype(m##name)> struct __##name { typedef typename T type; }; inline __##name<>::type get##name() { return m##name; }
For a member named mNumSplits, that expands to:
template < typename T = decltype(mNumSplits)> struct __mNumSplits { typedef typename T type; }; inline __mNumSplits<>::type getNumSplits() { return mNumSplits; }
Neat. And all that while eating breakfast :)
Aucun commentaire:
Enregistrer un commentaire