lzham_traits.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // File: lzham_traits.h
  2. // See Copyright Notice and license at the end of include/lzham.h
  3. #pragma once
  4. namespace lzham
  5. {
  6. template<typename T>
  7. struct scalar_type
  8. {
  9. enum { cFlag = false };
  10. static inline void construct(T* p) { helpers::construct(p); }
  11. static inline void construct(T* p, const T& init) { helpers::construct(p, init); }
  12. static inline void construct_array(T* p, uint n) { helpers::construct_array(p, n); }
  13. static inline void destruct(T* p) { helpers::destruct(p); }
  14. static inline void destruct_array(T* p, uint n) { helpers::destruct_array(p, n); }
  15. };
  16. template<typename T> struct scalar_type<T*>
  17. {
  18. enum { cFlag = true };
  19. static inline void construct(T** p) { memset(p, 0, sizeof(T*)); }
  20. static inline void construct(T** p, T* init) { *p = init; }
  21. static inline void construct_array(T** p, uint n) { memset(p, 0, sizeof(T*) * n); }
  22. static inline void destruct(T** p) { LZHAM_NOTE_UNUSED(p); }
  23. static inline void destruct_array(T** p, uint n) { LZHAM_NOTE_UNUSED(p); LZHAM_NOTE_UNUSED(n); }
  24. };
  25. #define LZHAM_DEFINE_BUILT_IN_TYPE(X) \
  26. template<> struct scalar_type<X> { \
  27. enum { cFlag = true }; \
  28. static inline void construct(X* p) { memset(p, 0, sizeof(X)); } \
  29. static inline void construct(X* p, const X& init) { memcpy(p, &init, sizeof(X)); } \
  30. static inline void construct_array(X* p, uint n) { memset(p, 0, sizeof(X) * n); } \
  31. static inline void destruct(X* p) { LZHAM_NOTE_UNUSED(p); } \
  32. static inline void destruct_array(X* p, uint n) { LZHAM_NOTE_UNUSED(p); LZHAM_NOTE_UNUSED(n); } };
  33. LZHAM_DEFINE_BUILT_IN_TYPE(bool)
  34. LZHAM_DEFINE_BUILT_IN_TYPE(char)
  35. LZHAM_DEFINE_BUILT_IN_TYPE(unsigned char)
  36. LZHAM_DEFINE_BUILT_IN_TYPE(short)
  37. LZHAM_DEFINE_BUILT_IN_TYPE(unsigned short)
  38. LZHAM_DEFINE_BUILT_IN_TYPE(int)
  39. LZHAM_DEFINE_BUILT_IN_TYPE(unsigned int)
  40. LZHAM_DEFINE_BUILT_IN_TYPE(long)
  41. LZHAM_DEFINE_BUILT_IN_TYPE(unsigned long)
  42. LZHAM_DEFINE_BUILT_IN_TYPE(float)
  43. LZHAM_DEFINE_BUILT_IN_TYPE(double)
  44. LZHAM_DEFINE_BUILT_IN_TYPE(long double)
  45. #if defined(WIN32)
  46. LZHAM_DEFINE_BUILT_IN_TYPE(__int64)
  47. LZHAM_DEFINE_BUILT_IN_TYPE(unsigned __int64)
  48. #endif
  49. #undef LZHAM_DEFINE_BUILT_IN_TYPE
  50. // See: http://erdani.org/publications/cuj-2004-06.pdf
  51. template<typename T>
  52. struct bitwise_movable { enum { cFlag = false }; };
  53. // Defines type Q as bitwise movable.
  54. #define LZHAM_DEFINE_BITWISE_MOVABLE(Q) template<> struct bitwise_movable<Q> { enum { cFlag = true }; };
  55. template<typename T>
  56. struct bitwise_copyable { enum { cFlag = false }; };
  57. // Defines type Q as bitwise copyable.
  58. #define LZHAM_DEFINE_BITWISE_COPYABLE(Q) template<> struct bitwise_copyable<Q> { enum { cFlag = true }; };
  59. #if defined(__APPLE__)
  60. #define LZHAM_IS_POD(T) std::is_pod<T>::value
  61. #elif defined(__NetBSD__)
  62. #define LZHAM_IS_POD(T) std::__is_pod<T>::__value
  63. #else
  64. #define LZHAM_IS_POD(T) __is_pod(T)
  65. #endif
  66. #define LZHAM_IS_SCALAR_TYPE(T) (scalar_type<T>::cFlag)
  67. #define LZHAM_IS_BITWISE_COPYABLE(T) ((scalar_type<T>::cFlag) || (bitwise_copyable<T>::cFlag) || LZHAM_IS_POD(T))
  68. #define LZHAM_IS_BITWISE_MOVABLE(T) (LZHAM_IS_BITWISE_COPYABLE(T) || (bitwise_movable<T>::cFlag))
  69. #define LZHAM_HAS_DESTRUCTOR(T) ((!scalar_type<T>::cFlag) && (!LZHAM_IS_POD(T)))
  70. // From yasli_traits.h:
  71. // Credit goes to Boost;
  72. // also found in the C++ Templates book by Vandevoorde and Josuttis
  73. typedef char (&yes_t)[1];
  74. typedef char (&no_t)[2];
  75. template <class U> yes_t class_test(int U::*);
  76. template <class U> no_t class_test(...);
  77. template <class T> struct is_class
  78. {
  79. enum { value = (sizeof(class_test<T>(0)) == sizeof(yes_t)) };
  80. };
  81. template <typename T> struct is_pointer
  82. {
  83. enum { value = false };
  84. };
  85. template <typename T> struct is_pointer<T*>
  86. {
  87. enum { value = true };
  88. };
  89. LZHAM_DEFINE_BITWISE_COPYABLE(empty_type);
  90. LZHAM_DEFINE_BITWISE_MOVABLE(empty_type);
  91. namespace helpers
  92. {
  93. template <typename T>
  94. inline void construct_array(T* p, uint n)
  95. {
  96. if (LZHAM_IS_SCALAR_TYPE(T))
  97. {
  98. memset(p, 0, sizeof(T) * n);
  99. }
  100. else
  101. {
  102. T* q = p + n;
  103. for ( ; p != q; ++p)
  104. new (static_cast<void*>(p)) T;
  105. }
  106. }
  107. template <typename T>
  108. inline void destruct_array(T* p, uint n)
  109. {
  110. if ( LZHAM_HAS_DESTRUCTOR(T) )
  111. {
  112. T* q = p + n;
  113. for ( ; p != q; ++p)
  114. p->~T();
  115. }
  116. }
  117. }
  118. } // namespace lzham