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