check.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. /* Check (assertions)
  2. * Portable Snippets - https://gitub.com/nemequ/portable-snippets
  3. * Created by Evan Nemerson <[email protected]>
  4. *
  5. * To the extent possible under law, the authors have waived all
  6. * copyright and related or neighboring rights to this code. For
  7. * details, see the Creative Commons Zero 1.0 Universal license at
  8. * https://creativecommons.org/publicdomain/zero/1.0/
  9. *
  10. * SPDX-License-Identifier: CC0-1.0
  11. */
  12. #if !defined(SIMDE_CHECK_H)
  13. #define SIMDE_CHECK_H
  14. #if !defined(SIMDE_NDEBUG) && !defined(SIMDE_DEBUG)
  15. #define SIMDE_NDEBUG 1
  16. #endif
  17. #include "hedley.h"
  18. #include "simde-diagnostic.h"
  19. #include <stdint.h>
  20. #if !defined(_WIN32)
  21. #define SIMDE_SIZE_MODIFIER "z"
  22. #define SIMDE_CHAR_MODIFIER "hh"
  23. #define SIMDE_SHORT_MODIFIER "h"
  24. #else
  25. #if defined(_M_X64) || defined(__amd64__)
  26. #define SIMDE_SIZE_MODIFIER "I64"
  27. #else
  28. #define SIMDE_SIZE_MODIFIER ""
  29. #endif
  30. #define SIMDE_CHAR_MODIFIER ""
  31. #define SIMDE_SHORT_MODIFIER ""
  32. #endif
  33. #if defined(_MSC_VER) && (_MSC_VER >= 1500)
  34. #define SIMDE_PUSH_DISABLE_MSVC_C4127_ \
  35. __pragma(warning(push)) __pragma(warning(disable : 4127))
  36. #define SIMDE_POP_DISABLE_MSVC_C4127_ __pragma(warning(pop))
  37. #else
  38. #define SIMDE_PUSH_DISABLE_MSVC_C4127_
  39. #define SIMDE_POP_DISABLE_MSVC_C4127_
  40. #endif
  41. #if !defined(simde_errorf)
  42. #if defined(__has_include)
  43. #if __has_include(<stdio.h>)
  44. #include <stdio.h>
  45. #endif
  46. #elif defined(SIMDE_STDC_HOSTED)
  47. #if SIMDE_STDC_HOSTED == 1
  48. #include <stdio.h>
  49. #endif
  50. #elif defined(__STDC_HOSTED__)
  51. #if __STDC_HOSTETD__ == 1
  52. #include <stdio.h>
  53. #endif
  54. #endif
  55. #include "debug-trap.h"
  56. HEDLEY_DIAGNOSTIC_PUSH
  57. SIMDE_DIAGNOSTIC_DISABLE_VARIADIC_MACROS_
  58. #if defined(EOF)
  59. #define simde_errorf(format, ...) \
  60. (fprintf(stderr, format, __VA_ARGS__), abort())
  61. #else
  62. #define simde_errorf(format, ...) (simde_trap())
  63. #endif
  64. HEDLEY_DIAGNOSTIC_POP
  65. #endif
  66. #define simde_error(msg) simde_errorf("%s", msg)
  67. #if defined(SIMDE_NDEBUG) || \
  68. (defined(__cplusplus) && (__cplusplus < 201103L)) || \
  69. (defined(__STDC__) && (__STDC__ < 199901L))
  70. #if defined(SIMDE_CHECK_FAIL_DEFINED)
  71. #define simde_assert(expr)
  72. #else
  73. #if defined(HEDLEY_ASSUME)
  74. #define simde_assert(expr) HEDLEY_ASSUME(expr)
  75. #elif HEDLEY_GCC_VERSION_CHECK(4, 5, 0)
  76. #define simde_assert(expr) ((void)(!!(expr) ? 1 : (__builtin_unreachable(), 1)))
  77. #elif HEDLEY_MSVC_VERSION_CHECK(13, 10, 0)
  78. #define simde_assert(expr) __assume(expr)
  79. #else
  80. #define simde_assert(expr)
  81. #endif
  82. #endif
  83. #define simde_assert_true(expr) simde_assert(expr)
  84. #define simde_assert_false(expr) simde_assert(!(expr))
  85. #define simde_assert_type_full(prefix, suffix, T, fmt, a, op, b) \
  86. simde_assert(((a)op(b)))
  87. #define simde_assert_double_equal(a, b, precision)
  88. #define simde_assert_string_equal(a, b)
  89. #define simde_assert_string_not_equal(a, b)
  90. #define simde_assert_memory_equal(size, a, b)
  91. #define simde_assert_memory_not_equal(size, a, b)
  92. #else
  93. #define simde_assert(expr) \
  94. do { \
  95. if (!HEDLEY_LIKELY(expr)) { \
  96. simde_error("assertion failed: " #expr "\n"); \
  97. } \
  98. SIMDE_PUSH_DISABLE_MSVC_C4127_ \
  99. } while (0) SIMDE_POP_DISABLE_MSVC_C4127_
  100. #define simde_assert_true(expr) \
  101. do { \
  102. if (!HEDLEY_LIKELY(expr)) { \
  103. simde_error("assertion failed: " #expr \
  104. " is not true\n"); \
  105. } \
  106. SIMDE_PUSH_DISABLE_MSVC_C4127_ \
  107. } while (0) SIMDE_POP_DISABLE_MSVC_C4127_
  108. #define simde_assert_false(expr) \
  109. do { \
  110. if (!HEDLEY_LIKELY(!(expr))) { \
  111. simde_error("assertion failed: " #expr \
  112. " is not false\n"); \
  113. } \
  114. SIMDE_PUSH_DISABLE_MSVC_C4127_ \
  115. } while (0) SIMDE_POP_DISABLE_MSVC_C4127_
  116. #define simde_assert_type_full(prefix, suffix, T, fmt, a, op, b) \
  117. do { \
  118. T simde_tmp_a_ = (a); \
  119. T simde_tmp_b_ = (b); \
  120. if (!(simde_tmp_a_ op simde_tmp_b_)) { \
  121. simde_errorf("assertion failed: %s %s %s (" prefix \
  122. "%" fmt suffix " %s " prefix \
  123. "%" fmt suffix ")\n", \
  124. #a, #op, #b, simde_tmp_a_, #op, \
  125. simde_tmp_b_); \
  126. } \
  127. SIMDE_PUSH_DISABLE_MSVC_C4127_ \
  128. } while (0) SIMDE_POP_DISABLE_MSVC_C4127_
  129. #define simde_assert_double_equal(a, b, precision) \
  130. do { \
  131. const double simde_tmp_a_ = (a); \
  132. const double simde_tmp_b_ = (b); \
  133. const double simde_tmp_diff_ = \
  134. ((simde_tmp_a_ - simde_tmp_b_) < 0) \
  135. ? -(simde_tmp_a_ - simde_tmp_b_) \
  136. : (simde_tmp_a_ - simde_tmp_b_); \
  137. if (HEDLEY_UNLIKELY(simde_tmp_diff_ > 1e-##precision)) { \
  138. simde_errorf( \
  139. "assertion failed: %s == %s (%0." #precision \
  140. "g == %0." #precision "g)\n", \
  141. #a, #b, simde_tmp_a_, simde_tmp_b_); \
  142. } \
  143. SIMDE_PUSH_DISABLE_MSVC_C4127_ \
  144. } while (0) SIMDE_POP_DISABLE_MSVC_C4127_
  145. #include <string.h>
  146. #define simde_assert_string_equal(a, b) \
  147. do { \
  148. const char *simde_tmp_a_ = a; \
  149. const char *simde_tmp_b_ = b; \
  150. if (HEDLEY_UNLIKELY(strcmp(simde_tmp_a_, simde_tmp_b_) != \
  151. 0)) { \
  152. simde_errorf( \
  153. "assertion failed: string %s == %s (\"%s\" == \"%s\")\n", \
  154. #a, #b, simde_tmp_a_, simde_tmp_b_); \
  155. } \
  156. SIMDE_PUSH_DISABLE_MSVC_C4127_ \
  157. } while (0) SIMDE_POP_DISABLE_MSVC_C4127_
  158. #define simde_assert_string_not_equal(a, b) \
  159. do { \
  160. const char *simde_tmp_a_ = a; \
  161. const char *simde_tmp_b_ = b; \
  162. if (HEDLEY_UNLIKELY(strcmp(simde_tmp_a_, simde_tmp_b_) == \
  163. 0)) { \
  164. simde_errorf( \
  165. "assertion failed: string %s != %s (\"%s\" == \"%s\")\n", \
  166. #a, #b, simde_tmp_a_, simde_tmp_b_); \
  167. } \
  168. SIMDE_PUSH_DISABLE_MSVC_C4127_ \
  169. } while (0) SIMDE_POP_DISABLE_MSVC_C4127_
  170. #define simde_assert_memory_equal(size, a, b) \
  171. do { \
  172. const unsigned char *simde_tmp_a_ = \
  173. (const unsigned char *)(a); \
  174. const unsigned char *simde_tmp_b_ = \
  175. (const unsigned char *)(b); \
  176. const size_t simde_tmp_size_ = (size); \
  177. if (HEDLEY_UNLIKELY(memcmp(simde_tmp_a_, simde_tmp_b_, \
  178. simde_tmp_size_)) != 0) { \
  179. size_t simde_tmp_pos_; \
  180. for (simde_tmp_pos_ = 0; \
  181. simde_tmp_pos_ < simde_tmp_size_; \
  182. simde_tmp_pos_++) { \
  183. if (simde_tmp_a_[simde_tmp_pos_] != \
  184. simde_tmp_b_[simde_tmp_pos_]) { \
  185. simde_errorf( \
  186. "assertion failed: memory %s == %s, at offset %" SIMDE_SIZE_MODIFIER \
  187. "u\n", \
  188. #a, #b, simde_tmp_pos_); \
  189. break; \
  190. } \
  191. } \
  192. } \
  193. SIMDE_PUSH_DISABLE_MSVC_C4127_ \
  194. } while (0) SIMDE_POP_DISABLE_MSVC_C4127_
  195. #define simde_assert_memory_not_equal(size, a, b) \
  196. do { \
  197. const unsigned char *simde_tmp_a_ = \
  198. (const unsigned char *)(a); \
  199. const unsigned char *simde_tmp_b_ = \
  200. (const unsigned char *)(b); \
  201. const size_t simde_tmp_size_ = (size); \
  202. if (HEDLEY_UNLIKELY(memcmp(simde_tmp_a_, simde_tmp_b_, \
  203. simde_tmp_size_)) == 0) { \
  204. simde_errorf( \
  205. "assertion failed: memory %s != %s (%" SIMDE_SIZE_MODIFIER \
  206. "u bytes)\n", \
  207. #a, #b, simde_tmp_size_); \
  208. } \
  209. SIMDE_PUSH_DISABLE_MSVC_C4127_ \
  210. } while (0) SIMDE_POP_DISABLE_MSVC_C4127_
  211. #endif
  212. #define simde_assert_type(T, fmt, a, op, b) \
  213. simde_assert_type_full("", "", T, fmt, a, op, b)
  214. #define simde_assert_char(a, op, b) \
  215. simde_assert_type_full("'\\x", "'", char, \
  216. "02" SIMDE_CHAR_MODIFIER "x", a, op, b)
  217. #define simde_assert_uchar(a, op, b) \
  218. simde_assert_type_full("'\\x", "'", unsigned char, \
  219. "02" SIMDE_CHAR_MODIFIER "x", a, op, b)
  220. #define simde_assert_short(a, op, b) \
  221. simde_assert_type(short, SIMDE_SHORT_MODIFIER "d", a, op, b)
  222. #define simde_assert_ushort(a, op, b) \
  223. simde_assert_type(unsigned short, SIMDE_SHORT_MODIFIER "u", a, op, b)
  224. #define simde_assert_int(a, op, b) simde_assert_type(int, "d", a, op, b)
  225. #define simde_assert_uint(a, op, b) \
  226. simde_assert_type(unsigned int, "u", a, op, b)
  227. #define simde_assert_long(a, op, b) simde_assert_type(long int, "ld", a, op, b)
  228. #define simde_assert_ulong(a, op, b) \
  229. simde_assert_type(unsigned long int, "lu", a, op, b)
  230. #define simde_assert_llong(a, op, b) \
  231. simde_assert_type(long long int, "lld", a, op, b)
  232. #define simde_assert_ullong(a, op, b) \
  233. simde_assert_type(unsigned long long int, "llu", a, op, b)
  234. #define simde_assert_size(a, op, b) \
  235. simde_assert_type(size_t, SIMDE_SIZE_MODIFIER "u", a, op, b)
  236. #define simde_assert_float(a, op, b) simde_assert_type(float, "f", a, op, b)
  237. #define simde_assert_double(a, op, b) simde_assert_type(double, "g", a, op, b)
  238. #define simde_assert_ptr(a, op, b) \
  239. simde_assert_type(const void *, "p", a, op, b)
  240. #define simde_assert_int8(a, op, b) simde_assert_type(int8_t, PRIi8, a, op, b)
  241. #define simde_assert_uint8(a, op, b) simde_assert_type(uint8_t, PRIu8, a, op, b)
  242. #define simde_assert_int16(a, op, b) \
  243. simde_assert_type(int16_t, PRIi16, a, op, b)
  244. #define simde_assert_uint16(a, op, b) \
  245. simde_assert_type(uint16_t, PRIu16, a, op, b)
  246. #define simde_assert_int32(a, op, b) \
  247. simde_assert_type(int32_t, PRIi32, a, op, b)
  248. #define simde_assert_uint32(a, op, b) \
  249. simde_assert_type(uint32_t, PRIu32, a, op, b)
  250. #define simde_assert_int64(a, op, b) \
  251. simde_assert_type(int64_t, PRIi64, a, op, b)
  252. #define simde_assert_uint64(a, op, b) \
  253. simde_assert_type(uint64_t, PRIu64, a, op, b)
  254. #define simde_assert_ptr_equal(a, b) simde_assert_ptr(a, ==, b)
  255. #define simde_assert_ptr_not_equal(a, b) simde_assert_ptr(a, !=, b)
  256. #define simde_assert_null(ptr) simde_assert_ptr(ptr, ==, NULL)
  257. #define simde_assert_not_null(ptr) simde_assert_ptr(ptr, !=, NULL)
  258. #define simde_assert_ptr_null(ptr) simde_assert_ptr(ptr, ==, NULL)
  259. #define simde_assert_ptr_not_null(ptr) simde_assert_ptr(ptr, !=, NULL)
  260. #endif /* !defined(SIMDE_CHECK_H) */