DsrTraits.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. // zlib open source license
  2. //
  3. // Copyright (c) 2025 David Forsgren Piuva
  4. //
  5. // This software is provided 'as-is', without any express or implied
  6. // warranty. In no event will the authors be held liable for any damages
  7. // arising from the use of this software.
  8. //
  9. // Permission is granted to anyone to use this software for any purpose,
  10. // including commercial applications, and to alter it and redistribute it
  11. // freely, subject to the following restrictions:
  12. //
  13. // 1. The origin of this software must not be misrepresented; you must not
  14. // claim that you wrote the original software. If you use this software
  15. // in a product, an acknowledgment in the product documentation would be
  16. // appreciated but is not required.
  17. //
  18. // 2. Altered source versions must be plainly marked as such, and must not be
  19. // misrepresented as being the original software.
  20. //
  21. // 3. This notice may not be removed or altered from any source
  22. // distribution.
  23. // These custom traits allow implementing template functions that can work with SIMD types when needed, without exposing simd.h in headers.
  24. #ifndef DFPSR_TRAITS
  25. #define DFPSR_TRAITS
  26. #include <stdint.h>
  27. #include <type_traits>
  28. namespace dsr {
  29. // Subset of std::integral_constant.
  30. template <typename T, T VALUE>
  31. struct DSR_PROPERTY {
  32. static constexpr T value = VALUE;
  33. };
  34. // Custom implementation of std::false_type.
  35. using DSR_TRAIT_FALSE = DSR_PROPERTY<bool, false>;
  36. // Custom implementation of std::true_type.
  37. using DSR_TRAIT_TRUE = DSR_PROPERTY<bool, true>;
  38. // Custom implementation of std::is_same.
  39. template <typename T, typename U>
  40. struct DsrTrait_SameType { static const bool value = false; };
  41. template <typename T>
  42. struct DsrTrait_SameType<T, T> { static const bool value = true; };
  43. // Custom implementation of std::enable_if.
  44. template<bool B, class T = void>
  45. struct DsrTrait_EnableIf;
  46. template<class T>
  47. struct DsrTrait_EnableIf<true, T> {
  48. using type = T;
  49. };
  50. // Place this as a template argument to disable the template function when false.
  51. #define DSR_ENABLE_IF(TRAIT) \
  52. typename = typename DsrTrait_EnableIf<TRAIT>::type
  53. // Properties are given to single types.
  54. #define DSR_DECLARE_PROPERTY(PROPERTY_NAME) \
  55. template <typename T> struct PROPERTY_NAME : DSR_TRAIT_FALSE {};
  56. #define DSR_APPLY_PROPERTY(PROPERTY_NAME, TYPE_NAME) \
  57. template <> struct PROPERTY_NAME<TYPE_NAME> : DSR_TRAIT_TRUE {};
  58. #define DSR_CHECK_PROPERTY(PROPERTY_NAME, TYPE_NAME) \
  59. (PROPERTY_NAME<TYPE_NAME>::value)
  60. // Relations are given to pairs of types.
  61. #define DSR_DECLARE_RELATION(RELATION_NAME) \
  62. template <typename T, typename U> struct RELATION_NAME : DSR_TRAIT_FALSE {};
  63. #define DSR_APPLY_RELATION(RELATION_NAME, TYPE_A, TYPE_B) \
  64. template <> struct RELATION_NAME<TYPE_A, TYPE_B> : DSR_TRAIT_TRUE {};
  65. #define DSR_CHECK_RELATION(RELATION_NAME, TYPE_A, TYPE_B) \
  66. (RELATION_NAME<TYPE_A, TYPE_B>::value)
  67. // Checking types.
  68. #define DSR_SAME_TYPE(TYPE_A, TYPE_B) DsrTrait_SameType<TYPE_A, TYPE_B>::value
  69. #define DSR_UTF32_LITERAL(TYPE) std::is_convertible<TYPE, const char32_t*>::value
  70. #define DSR_ASCII_LITERAL(TYPE) std::is_convertible<TYPE, const char*>::value
  71. #define DSR_INHERITS_FROM(DERIVED, BASE) std::is_base_of<BASE, DERIVED>::value
  72. // Supress type safety when impossible conversions can never execute.
  73. template<typename TO, typename FROM>
  74. inline const TO& unsafeCast(const FROM &value) {
  75. const void *pointer = (const void*)&value;
  76. return *(const TO*)pointer;
  77. }
  78. DSR_DECLARE_PROPERTY(DsrTrait_Any_U8)
  79. DSR_APPLY_PROPERTY(DsrTrait_Any_U8, uint8_t)
  80. DSR_DECLARE_PROPERTY(DsrTrait_Any_U16)
  81. DSR_APPLY_PROPERTY(DsrTrait_Any_U16, uint16_t)
  82. DSR_DECLARE_PROPERTY(DsrTrait_Any_U32)
  83. DSR_APPLY_PROPERTY(DsrTrait_Any_U32, uint32_t)
  84. DSR_DECLARE_PROPERTY(DsrTrait_Any_I32)
  85. DSR_APPLY_PROPERTY(DsrTrait_Any_I32, int32_t)
  86. DSR_DECLARE_PROPERTY(DsrTrait_Any_F32)
  87. DSR_APPLY_PROPERTY(DsrTrait_Any_F32, float)
  88. DSR_DECLARE_PROPERTY(DsrTrait_Any)
  89. DSR_APPLY_PROPERTY(DsrTrait_Any, int8_t)
  90. DSR_APPLY_PROPERTY(DsrTrait_Any, int16_t)
  91. DSR_APPLY_PROPERTY(DsrTrait_Any, int32_t)
  92. DSR_APPLY_PROPERTY(DsrTrait_Any, int64_t)
  93. DSR_APPLY_PROPERTY(DsrTrait_Any, uint8_t)
  94. DSR_APPLY_PROPERTY(DsrTrait_Any, uint16_t)
  95. DSR_APPLY_PROPERTY(DsrTrait_Any, uint32_t)
  96. DSR_APPLY_PROPERTY(DsrTrait_Any, uint64_t)
  97. DSR_APPLY_PROPERTY(DsrTrait_Any, float)
  98. DSR_APPLY_PROPERTY(DsrTrait_Any, double)
  99. DSR_DECLARE_PROPERTY(DsrTrait_Scalar_SignedInteger)
  100. DSR_APPLY_PROPERTY(DsrTrait_Scalar_SignedInteger, int8_t)
  101. DSR_APPLY_PROPERTY(DsrTrait_Scalar_SignedInteger, int16_t)
  102. DSR_APPLY_PROPERTY(DsrTrait_Scalar_SignedInteger, int32_t)
  103. DSR_APPLY_PROPERTY(DsrTrait_Scalar_SignedInteger, int64_t)
  104. DSR_DECLARE_PROPERTY(DsrTrait_Scalar_UnsignedInteger)
  105. DSR_APPLY_PROPERTY(DsrTrait_Scalar_UnsignedInteger, uint8_t)
  106. DSR_APPLY_PROPERTY(DsrTrait_Scalar_UnsignedInteger, uint16_t)
  107. DSR_APPLY_PROPERTY(DsrTrait_Scalar_UnsignedInteger, uint32_t)
  108. DSR_APPLY_PROPERTY(DsrTrait_Scalar_UnsignedInteger, uint64_t)
  109. DSR_DECLARE_PROPERTY(DsrTrait_Scalar_Floating)
  110. DSR_APPLY_PROPERTY(DsrTrait_Scalar_Floating, float)
  111. DSR_APPLY_PROPERTY(DsrTrait_Scalar_Floating, double)
  112. DSR_DECLARE_PROPERTY(DsrTrait_Scalar_Integer)
  113. DSR_APPLY_PROPERTY(DsrTrait_Scalar_Integer, int8_t)
  114. DSR_APPLY_PROPERTY(DsrTrait_Scalar_Integer, int16_t)
  115. DSR_APPLY_PROPERTY(DsrTrait_Scalar_Integer, int32_t)
  116. DSR_APPLY_PROPERTY(DsrTrait_Scalar_Integer, int64_t)
  117. DSR_APPLY_PROPERTY(DsrTrait_Scalar_Integer, uint8_t)
  118. DSR_APPLY_PROPERTY(DsrTrait_Scalar_Integer, uint16_t)
  119. DSR_APPLY_PROPERTY(DsrTrait_Scalar_Integer, uint32_t)
  120. DSR_APPLY_PROPERTY(DsrTrait_Scalar_Integer, uint64_t)
  121. DSR_DECLARE_PROPERTY(DsrTrait_Scalar)
  122. DSR_APPLY_PROPERTY(DsrTrait_Scalar, int8_t)
  123. DSR_APPLY_PROPERTY(DsrTrait_Scalar, int16_t)
  124. DSR_APPLY_PROPERTY(DsrTrait_Scalar, int32_t)
  125. DSR_APPLY_PROPERTY(DsrTrait_Scalar, int64_t)
  126. DSR_APPLY_PROPERTY(DsrTrait_Scalar, uint8_t)
  127. DSR_APPLY_PROPERTY(DsrTrait_Scalar, uint16_t)
  128. DSR_APPLY_PROPERTY(DsrTrait_Scalar, uint32_t)
  129. DSR_APPLY_PROPERTY(DsrTrait_Scalar, uint64_t)
  130. DSR_APPLY_PROPERTY(DsrTrait_Scalar, float)
  131. DSR_APPLY_PROPERTY(DsrTrait_Scalar, double)
  132. }
  133. #endif