summaryrefslogtreecommitdiffhomepage
path: root/src/langext.h
diff options
context:
space:
mode:
authorMichael Smith <mikesmiffy128@gmail.com>2024-08-03 23:40:31 +0100
committerMichael Smith <mikesmiffy128@gmail.com>2024-08-23 20:37:37 +0100
commit83da606072ce272eb053d4e1497d77e647cfecae (patch)
tree71d0110881ff8685184c5f4ab720cc8d49c24678 /src/langext.h
parentacbd30e0427b16f885f96aed59881ec04eff25bc (diff)
Revise syntax macros and add a ton of branch hints
My new programming style is branch hints. All non-confusing branches must be hinted when I can be bothered. It's faster, sometimes, maybe. Also, start trying to use more signed sizes in at least some of the places where it makes sense. Unsigned sizes are surprisingly error-prone!
Diffstat (limited to 'src/langext.h')
-rw-r--r--src/langext.h64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/langext.h b/src/langext.h
new file mode 100644
index 0000000..ef0f18d
--- /dev/null
+++ b/src/langext.h
@@ -0,0 +1,64 @@
+/* This file is dedicated to the public domain. */
+
+#ifndef INC_LANGEXT_H
+#define INC_LANGEXT_H
+
+#include "intdefs.h"
+
+#define ssizeof(x) ((ssize)sizeof(x))
+#define countof(x) (ssizeof(x) / ssizeof(*x))
+
+#if defined(__GNUC__) || defined(__clang__)
+#define if_hot(x) if (__builtin_expect(!!(x), 1))
+#define if_cold(x) if (__builtin_expect(!!(x), 0))
+#define if_random(x) if (__builtin_expect_with_probability(!!(x), 1, 0.5))
+#define unreachable __builtin_unreachable()
+#define assume(x) ((void)(!!(x) || (unreachable, 0)))
+#define cold __attribute__((__cold__, __noinline__))
+#else
+#define if_hot(x) if (x)
+#define if_cold(x) if (x)
+#define if_random(x) if (x)
+#ifdef _MSC_VER
+#define unreachable __assume(0)
+#define assume(x) ((void)(__assume(x), 0))
+#define cold __declspec(noinline)
+#else
+#define unreachable ((void)(0)) // might still give some warnings, but too bad
+#define assume(x) ((void)0)
+#define cold
+#endif
+#endif
+
+#define switch_exhaust(x) switch (x) if (0) default: unreachable; else
+#if defined(__GNUC__) || defined(__clang__)
+#define switch_exhaust_enum(E, x) \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic error \"-Wswitch-enum\"") \
+ switch_exhaust ((enum E)(x)) \
+ _Pragma("GCC diagnostic pop")
+#else
+// NOTE: pragma trick doesn't work in MSVC (the pop seems to happen before the
+// switch is evaluated, so nothing happens) but you can still get errors using
+// -we4061. This doesn't matter for sst but might come in handy elsewhere...
+#define switch_exhaust_enum(E, x) switch_exhaust ((enum E)(x))
+#endif
+
+#define noreturn _Noreturn void
+
+#ifdef _WIN32
+#define import __declspec(dllimport) // only needed for variables
+#define export __declspec(dllexport)
+#else
+#define import
+#ifdef __GNUC__
+// N.B. we assume -fvisibility=hidden
+#define export __attribute__((visibility("default"))
+#else
+#define export int exp[-!!"compiler needs a way to export symbols!"];
+#endif
+#endif
+
+#endif
+
+// vi: sw=4 ts=4 noet tw=80 cc=80