summaryrefslogtreecommitdiffhomepage
path: root/src/langext.h
blob: ef0f18dcaf159be9aff0b2004dc91d72955517bf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
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