StdTypes.h 7.0 KB

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