StdTypes.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. // Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <AnKi/Util/Common.h>
  7. #include <cstdint>
  8. #include <cstddef>
  9. #include <limits>
  10. #include <type_traits>
  11. namespace anki {
  12. /// @addtogroup util_other
  13. /// @{
  14. using I8 = int8_t; ///< Integer 8bit
  15. constexpr I8 MAX_I8 = std::numeric_limits<I8>::max();
  16. constexpr I8 MIN_I8 = std::numeric_limits<I8>::min();
  17. using I16 = int16_t; ///< Integer 16bit
  18. constexpr I16 MAX_I16 = std::numeric_limits<I16>::max();
  19. constexpr I16 MIN_I16 = std::numeric_limits<I16>::min();
  20. using I32 = int32_t; ///< Integer 32bit
  21. constexpr I32 MAX_I32 = std::numeric_limits<I32>::max();
  22. constexpr I32 MIN_I32 = std::numeric_limits<I32>::min();
  23. using I64 = int64_t; ///< Integer 64bit
  24. constexpr I64 MAX_I64 = std::numeric_limits<I64>::max();
  25. constexpr I64 MIN_I64 = std::numeric_limits<I64>::min();
  26. using I = int_fast32_t; ///< Fast signed integer at least 32bit
  27. constexpr I MAX_I = std::numeric_limits<I>::max();
  28. constexpr I MIN_I = std::numeric_limits<I>::min();
  29. using U8 = uint8_t; ///< Unsigned integer 8bit
  30. constexpr U8 MAX_U8 = std::numeric_limits<U8>::max();
  31. constexpr U8 MIN_U8 = std::numeric_limits<U8>::min();
  32. using U16 = uint16_t; ///< Unsigned integer 16bit
  33. constexpr U16 MAX_U16 = std::numeric_limits<U16>::max();
  34. constexpr U16 MIN_U16 = std::numeric_limits<U16>::min();
  35. using U32 = uint32_t; ///< Unsigned integer 32bit
  36. constexpr U32 MAX_U32 = std::numeric_limits<U32>::max();
  37. constexpr U32 MIN_U32 = std::numeric_limits<U32>::min();
  38. using U64 = uint64_t; ///< Unsigned integer 64bit
  39. constexpr U64 MAX_U64 = std::numeric_limits<U64>::max();
  40. constexpr U64 MIN_U64 = std::numeric_limits<U64>::min();
  41. using U = uint_fast32_t; ///< Fast unsigned integer at least 32bit
  42. constexpr U MAX_U = std::numeric_limits<U>::max();
  43. constexpr U MIN_U = std::numeric_limits<U>::min();
  44. using PtrSize = size_t; ///< Like size_t
  45. constexpr PtrSize MAX_PTR_SIZE = std::numeric_limits<PtrSize>::max();
  46. constexpr PtrSize MIN_PTR_SIZE = std::numeric_limits<PtrSize>::min();
  47. static_assert(sizeof(PtrSize) == sizeof(void*), "Wrong size for size_t");
  48. using F32 = float; ///< Floating point 32bit
  49. constexpr F32 MAX_F32 = std::numeric_limits<F32>::max();
  50. constexpr F32 MIN_F32 = -std::numeric_limits<F32>::max();
  51. using F64 = double; ///< Floating point 64bit
  52. constexpr F64 MAX_F64 = std::numeric_limits<F64>::max();
  53. constexpr F64 MIN_F64 = -std::numeric_limits<F64>::max();
  54. using Bool = bool; ///< 1 byte boolean type. The same as C++'s bool.
  55. static_assert(sizeof(bool) == 1, "Wrong size for bool");
  56. using Bool32 = I32;
  57. using Char = char;
  58. using Second = F64; ///< The base time unit is second.
  59. constexpr Second MAX_SECOND = MAX_F64;
  60. constexpr Second MIN_SECOND = MIN_F64;
  61. using Timestamp = U64; ///< Timestamp type.
  62. constexpr Timestamp MAX_TIMESTAMP = MAX_U64;
  63. // Numeric limits
  64. template<typename T>
  65. constexpr T getMinNumericLimit();
  66. template<typename T>
  67. constexpr T getMaxNumericLimit();
  68. #define ANKI_DO_LIMIT(type, min, max) \
  69. template<> \
  70. constexpr type getMinNumericLimit() \
  71. { \
  72. return min; \
  73. } \
  74. template<> \
  75. constexpr type getMaxNumericLimit() \
  76. { \
  77. return max; \
  78. }
  79. ANKI_DO_LIMIT(I8, MIN_I8, MAX_I8)
  80. ANKI_DO_LIMIT(I16, MIN_I16, MAX_I16)
  81. ANKI_DO_LIMIT(I32, MIN_I32, MAX_I32)
  82. ANKI_DO_LIMIT(I64, MIN_I64, MAX_I64)
  83. ANKI_DO_LIMIT(U8, MIN_U8, MAX_U8)
  84. ANKI_DO_LIMIT(U16, MIN_U16, MAX_U16)
  85. ANKI_DO_LIMIT(U32, MIN_U32, MAX_U32)
  86. ANKI_DO_LIMIT(U64, MIN_U64, MAX_U64)
  87. ANKI_DO_LIMIT(F32, MIN_F32, MAX_F32)
  88. ANKI_DO_LIMIT(F64, MIN_F64, MAX_F64)
  89. #undef ANKI_DO_LIMIT
  90. /// Representation of error and a wrapper on top of error codes.
  91. class Error
  92. {
  93. public:
  94. /// @name Error codes
  95. /// @{
  96. static constexpr I32 NONE = 0;
  97. static constexpr I32 OUT_OF_MEMORY = 1;
  98. static constexpr I32 FUNCTION_FAILED = 2; ///< External operation failed
  99. static constexpr I32 USER_DATA = 3;
  100. // File errors
  101. static constexpr I32 FILE_NOT_FOUND = 4;
  102. static constexpr I32 FILE_ACCESS = 5; ///< Read/write access error
  103. static constexpr I32 UNKNOWN = 6;
  104. /// @}
  105. /// Construct using an error code.
  106. Error(I32 code)
  107. : m_code(code)
  108. {
  109. }
  110. /// Copy.
  111. Error(const Error& b)
  112. : m_code(b.m_code)
  113. {
  114. }
  115. /// Copy.
  116. Error& operator=(const Error& b)
  117. {
  118. m_code = b.m_code;
  119. return *this;
  120. }
  121. /// Compare.
  122. Bool operator==(const Error& b) const
  123. {
  124. return m_code == b.m_code;
  125. }
  126. /// Compare.
  127. Bool operator==(I32 code) const
  128. {
  129. return m_code == code;
  130. }
  131. /// Compare.
  132. Bool operator!=(const Error& b) const
  133. {
  134. return m_code != b.m_code;
  135. }
  136. /// Compare.
  137. Bool operator!=(I32 code) const
  138. {
  139. return m_code != code;
  140. }
  141. /// Check if it is an error.
  142. explicit operator Bool() const
  143. {
  144. return ANKI_UNLIKELY(m_code != NONE);
  145. }
  146. /// @privatesection
  147. /// @{
  148. I32 _getCode() const
  149. {
  150. return m_code;
  151. }
  152. /// @}
  153. private:
  154. I32 m_code = NONE;
  155. };
  156. /// Macro to check if a method/function returned an error. It will return on error.
  157. #define ANKI_CHECK(x_) \
  158. do \
  159. { \
  160. const Error retError = x_; \
  161. if(retError) \
  162. { \
  163. return retError; \
  164. } \
  165. } while(0)
  166. /// Macro to check if a method/function returned an error.
  167. #define ANKI_CHECK_AND_IGNORE(x_) \
  168. do \
  169. { \
  170. const Error retError = x_; \
  171. (void)retError; \
  172. } while(0)
  173. #if ANKI_EXTRA_CHECKS
  174. # define ANKI_DEBUG_CODE(x) x
  175. #else
  176. # define ANKI_DEBUG_CODE(x)
  177. #endif
  178. /// @name AnKi type user literals.
  179. /// @{
  180. inline constexpr U8 operator"" _U8(unsigned long long arg) noexcept
  181. {
  182. return static_cast<U8>(arg);
  183. }
  184. inline constexpr U16 operator"" _U16(unsigned long long arg) noexcept
  185. {
  186. return static_cast<U16>(arg);
  187. }
  188. inline constexpr U32 operator"" _U32(unsigned long long arg) noexcept
  189. {
  190. return static_cast<U32>(arg);
  191. }
  192. inline constexpr U64 operator"" _U64(unsigned long long arg) noexcept
  193. {
  194. return static_cast<U64>(arg);
  195. }
  196. /// @}
  197. /// @name Size user literals
  198. /// @{
  199. static constexpr unsigned long long int operator""_B(unsigned long long int x)
  200. {
  201. return x;
  202. }
  203. static constexpr unsigned long long int operator""_KB(unsigned long long int x)
  204. {
  205. return x * 1024;
  206. }
  207. static constexpr unsigned long long int operator""_MB(unsigned long long int x)
  208. {
  209. return x * (1024 * 1024);
  210. }
  211. static constexpr unsigned long long int operator""_GB(unsigned long long int x)
  212. {
  213. return x * (1024 * 1024 * 1024);
  214. }
  215. /// @}
  216. /// @name Time user literals
  217. /// @{
  218. static constexpr Second operator""_ms(long double x)
  219. {
  220. return Second(x) / 1000.0;
  221. }
  222. static constexpr Second operator""_ns(long double x)
  223. {
  224. return Second(x) / 1000000000.0;
  225. }
  226. /// @}
  227. /// @name Distance user literals
  228. /// @{
  229. static constexpr F32 operator""_dm(long double x)
  230. {
  231. return F32(x) / 10.0f;
  232. }
  233. static constexpr F32 operator""_cm(long double x)
  234. {
  235. return F32(x) / 100.0f;
  236. }
  237. static constexpr F32 operator""_mm(long double x)
  238. {
  239. return F32(x) / 1000.0f;
  240. }
  241. /// @}
  242. /// Convenience macro that defines the type of a class.
  243. #define ANKI_DEFINE_CLASS_SELF(selfType) \
  244. typedef auto _selfFn##selfType()->decltype(*this); \
  245. using _SelfRef##selfType = decltype(((_selfFn##selfType*)0)()); \
  246. using selfType = std::remove_reference<_SelfRef##selfType>::type;
  247. /// @}
  248. } // end namespace anki