|
@@ -21,94 +21,6 @@
|
|
|
#ifndef __REFLECT_HH__
|
|
|
#define __REFLECT_HH__
|
|
|
|
|
|
-#if defined(_MSC_VER) && _MSC_VER == 1500
|
|
|
-namespace msvc_typeof_impl {
|
|
|
- /* This is a fusion of Igor Chesnokov's method (http://rsdn.ru/forum/src/1094305.aspx)
|
|
|
- and Steven Watanabe's method (http://lists.boost.org/Archives/boost/2006/12/115006.php)
|
|
|
-
|
|
|
- How it works:
|
|
|
- C++ allows template type inference for templated function parameters but nothing else.
|
|
|
- What we do is to pass the expression sent to typeof() into the templated function vartypeID()
|
|
|
- as its parameter, thus extracting its type. The big problem traditionally now is how to get
|
|
|
- that type out of the vartypeID() instance, and here's how we do it:
|
|
|
- 1. unique_type_id() returns a monotonically increasing integer for every unique type
|
|
|
- passed to it during this compilation unit. It also specialises an instance of
|
|
|
- msvc_extract_type<unique_type_id, type>::id2type_impl<true>.
|
|
|
- 2. vartypeID() returns a sized<unique_type_id> for the type where
|
|
|
- sizeof(sized<unique_type_id>)==unique_type_id. We vector through sized as a means
|
|
|
- of returning the unique_type_id at compile time rather than runtime.
|
|
|
- 3. msvc_extract_type<unique_type_id> then extracts the type by using a bug in MSVC to
|
|
|
- reselect the specialised child type (id2type_impl<true>) from within the specialisation
|
|
|
- of itself originally performed by the above instance of unique_type_id. This bug works
|
|
|
- because when MSVC calculated the signature of the specialised
|
|
|
- msvc_extract_type<unique_type_id, type>::id2type_impl<true>, it does not include the
|
|
|
- value of type in the signature of id2type_impl<true>. Therefore when we reselect
|
|
|
- msvc_extract_type<unique_type_id>::id2type_impl<true> it erroneously returns the one
|
|
|
- already in its list of instantiated types rather than correctly generating a newly
|
|
|
- specialised msvc_extract_type<unique_type_id, msvc_extract_type_default_param>::id2type_impl<true>
|
|
|
-
|
|
|
- This bug allows the impossible and gives us a working typeof() in MSVC. Hopefully Microsoft
|
|
|
- won't fix this bug until they implement a native typeof.
|
|
|
- */
|
|
|
-
|
|
|
- struct msvc_extract_type_default_param {};
|
|
|
- template<int ID, typename T = msvc_extract_type_default_param> struct msvc_extract_type;
|
|
|
-
|
|
|
- template<int ID> struct msvc_extract_type<ID, msvc_extract_type_default_param>
|
|
|
- {
|
|
|
- template<bool> struct id2type_impl;
|
|
|
-
|
|
|
- typedef id2type_impl<true> id2type;
|
|
|
- };
|
|
|
-
|
|
|
- template<int ID, typename T> struct msvc_extract_type : msvc_extract_type<ID, msvc_extract_type_default_param>
|
|
|
- {
|
|
|
- template<> struct id2type_impl<true> //VC8.0 specific bugfeature
|
|
|
- {
|
|
|
- typedef T type;
|
|
|
- };
|
|
|
- template<bool> struct id2type_impl;
|
|
|
-
|
|
|
- typedef id2type_impl<true> id2type;
|
|
|
- };
|
|
|
-
|
|
|
-
|
|
|
- template<int N> class CCounter;
|
|
|
-
|
|
|
- // TUnused is required to force compiler to recompile CCountOf class
|
|
|
- template<typename TUnused, int NTested = 0> struct CCountOf
|
|
|
- {
|
|
|
- enum
|
|
|
- {
|
|
|
- __if_exists(CCounter<NTested>) { count = CCountOf<TUnused, NTested + 1>::count }
|
|
|
- __if_not_exists(CCounter<NTested>) { count = NTested }
|
|
|
- };
|
|
|
- };
|
|
|
-
|
|
|
- template<class TTypeReg, class TUnused, int NValue> struct CProvideCounterValue { enum { value = NValue }; };
|
|
|
-
|
|
|
- // type_id
|
|
|
- #define unique_type_id(type) \
|
|
|
- (CProvideCounterValue< \
|
|
|
- /*register TYPE--ID*/ typename msvc_extract_type<CCountOf<type >::count, type>::id2type, \
|
|
|
- /*increment compile-time Counter*/ CCounter<CCountOf<type >::count>, \
|
|
|
- /*pass value of Counter*/CCountOf<type >::count \
|
|
|
- >::value)
|
|
|
-
|
|
|
- // Lets type_id() be > than 0
|
|
|
- class __Increment_type_id { enum { value = unique_type_id(__Increment_type_id) }; };
|
|
|
-
|
|
|
- // vartypeID() returns a type with sizeof(type_id)
|
|
|
- template<int NSize> class sized { char m_pad[NSize]; };
|
|
|
- template<typename T> typename sized<unique_type_id(T)> vartypeID(T&);
|
|
|
- template<typename T> typename sized<unique_type_id(const T)> vartypeID(const T&);
|
|
|
- template<typename T> typename sized<unique_type_id(volatile T)> vartypeID(volatile T&);
|
|
|
- template<typename T> typename sized<unique_type_id(const volatile T)> vartypeID(const volatile T&);
|
|
|
-}
|
|
|
-
|
|
|
-#define typeof(expression) msvc_typeof_impl::msvc_extract_type<sizeof(msvc_typeof_impl::vartypeID(expression))>::id2type::type
|
|
|
-#endif
|
|
|
-
|
|
|
#if defined(_MSC_VER) && _MSC_VER>=1600
|
|
|
#define typeof decltype
|
|
|
#endif
|