implicitconversion.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name: wx/meta/implicitconversion.h
  3. // Purpose: Determine resulting type from implicit conversion
  4. // Author: Vaclav Slavik
  5. // Created: 2010-10-22
  6. // Copyright: (c) 2010 Vaclav Slavik
  7. // Licence: wxWindows licence
  8. /////////////////////////////////////////////////////////////////////////////
  9. #ifndef _WX_META_IMPLICITCONVERSION_H_
  10. #define _WX_META_IMPLICITCONVERSION_H_
  11. #include "wx/defs.h"
  12. #include "wx/meta/if.h"
  13. // C++ hierarchy of data types is:
  14. //
  15. // Long double (highest)
  16. // Double
  17. // Float
  18. // Unsigned long int
  19. // Long int
  20. // Unsigned int
  21. // Int (lowest)
  22. //
  23. // Types lower in the hierarchy are converted into ones higher up if both are
  24. // involved e.g. in arithmetic expressions.
  25. namespace wxPrivate
  26. {
  27. // Helper macro to define a constant inside a template class: it's needed
  28. // because MSVC6 doesn't support initializing static integer members but the
  29. // usual workaround of using enums instead doesn't work for Borland (at least
  30. // in template classes).
  31. #ifdef __VISUALC6__
  32. #define wxDEFINE_CLASS_INT_CONST(name, value) enum { name = value }
  33. #else
  34. #define wxDEFINE_CLASS_INT_CONST(name, value) static const int name = value
  35. #endif
  36. template<typename T>
  37. struct TypeHierarchy
  38. {
  39. // consider unknown types (e.g. objects, pointers) to be of highest
  40. // level, always convert to them if they occur
  41. wxDEFINE_CLASS_INT_CONST( level, 9999 );
  42. };
  43. #define WX_TYPE_HIERARCHY_LEVEL(level_num, type) \
  44. template<> struct TypeHierarchy<type> \
  45. { \
  46. wxDEFINE_CLASS_INT_CONST( level, level_num ); \
  47. }
  48. WX_TYPE_HIERARCHY_LEVEL( 1, char);
  49. WX_TYPE_HIERARCHY_LEVEL( 2, unsigned char);
  50. WX_TYPE_HIERARCHY_LEVEL( 3, short);
  51. WX_TYPE_HIERARCHY_LEVEL( 4, unsigned short);
  52. WX_TYPE_HIERARCHY_LEVEL( 5, int);
  53. WX_TYPE_HIERARCHY_LEVEL( 6, unsigned int);
  54. WX_TYPE_HIERARCHY_LEVEL( 7, long);
  55. WX_TYPE_HIERARCHY_LEVEL( 8, unsigned long);
  56. #ifdef wxLongLong_t
  57. WX_TYPE_HIERARCHY_LEVEL( 9, wxLongLong_t);
  58. WX_TYPE_HIERARCHY_LEVEL(10, wxULongLong_t);
  59. #endif
  60. WX_TYPE_HIERARCHY_LEVEL(11, float);
  61. WX_TYPE_HIERARCHY_LEVEL(12, double);
  62. WX_TYPE_HIERARCHY_LEVEL(13, long double);
  63. #if wxWCHAR_T_IS_REAL_TYPE
  64. #if SIZEOF_WCHAR_T == SIZEOF_SHORT
  65. template<> struct TypeHierarchy<wchar_t> : public TypeHierarchy<short> {};
  66. #elif SIZEOF_WCHAR_T == SIZEOF_INT
  67. template<> struct TypeHierarchy<wchar_t> : public TypeHierarchy<int> {};
  68. #elif SIZEOF_WCHAR_T == SIZEOF_LONG
  69. template<> struct TypeHierarchy<wchar_t> : public TypeHierarchy<long> {};
  70. #else
  71. #error "weird wchar_t size, please update this code"
  72. #endif
  73. #endif
  74. #undef WX_TYPE_HIERARCHY_LEVEL
  75. } // namespace wxPrivate
  76. // Helper to determine resulting type of implicit conversion in
  77. // an expression with two arithmetic types.
  78. template<typename T1, typename T2>
  79. struct wxImplicitConversionType
  80. {
  81. typedef typename wxIf
  82. <
  83. // if T2 is "higher" type, convert to it
  84. (int)(wxPrivate::TypeHierarchy<T1>::level) < (int)(wxPrivate::TypeHierarchy<T2>::level),
  85. T2,
  86. // otherwise use T1
  87. T1
  88. >::value
  89. value;
  90. };
  91. template<typename T1, typename T2, typename T3>
  92. struct wxImplicitConversionType3 : public wxImplicitConversionType<
  93. T1,
  94. typename wxImplicitConversionType<T2,T3>::value>
  95. {
  96. };
  97. #endif // _WX_META_IMPLICITCONVERSION_H_