macros.h

View source code here on GitHub!

CL_COMPILER
CLANG_COMPILER
GCC_COMPILER
PCC_COMPILER
TCC_COMPILER

These macros detect which compiler the program is being made with. They will be 1 if it is that compiler, and 0 otherwise.

X64_COMPILER
X86_COMPILER
ARM_COMPILER
ARM_THUMB

These macros attempt to detect the architecture the program is being compiled for.

max(a, b)
min(a, b)

If these were not already defined, this header makes them.

swap(x, y)

Swap the names of two variables of the same type.

likely(x)
unlikely(x)

These macros implement the likely() and unlikely() flags, as in the Linux kernel to assist in branch prediction. On tcc and cl it has no effect.

MAX_FACTORIAL_64
MAX_FACTORIAL_128
PCC_SQRT_ACCURACY
MAX_POW_10_16
POW_OF_MAX_POW_10_16
MAX_POW_10_32
POW_OF_MAX_POW_10_32
MAX_POW_10_64
POW_OF_MAX_POW_10_64
MAX_POW_10_128
POW_OF_MAX_POW_10_128
PROGRAM_TAIL(type, prob)

Conditionally generates a main() function if running under the Python test runner or compiling as a standalone program. Takes in as an argument printf() formatting argument and the name of the function which implements this Project Euler solution.

  1#pragma once
  2
  3// compiler info section
  4
  5#if (defined(_MSC_VER) && !defined(__clang__))
  6    #define CL_COMPILER 1
  7#else
  8    #define CL_COMPILER 0
  9#endif
 10#if defined(__clang__)
 11    #define CLANG_COMPILER 1
 12#else
 13    #define CLANG_COMPILER 0
 14#endif
 15#if (defined(__GNUC__) && !defined(__clang__)) && !defined(__PCC__)
 16    #define GCC_COMPILER 1
 17#else
 18    #define GCC_COMPILER 0
 19#endif
 20#ifdef __PCC__
 21    #define PCC_COMPILER 1
 22#else
 23    #define PCC_COMPILER 0
 24#endif
 25#ifdef __EMSCRIPTEN__
 26    #define EMCC_COMPILER 1
 27#else
 28    #define EMCC_COMPILER 0
 29#endif
 30#define TCC_COMPILER (!(CL_COMPILER || CLANG_COMPILER || GCC_COMPILER || PCC_COMPILER || EMCC_COMPILER))
 31
 32#if (defined(_M_X64) || defined(_M_AMD64) || defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64))
 33    #define X64_COMPILER 1
 34#else
 35    #define X64_COMPILER 0
 36#endif
 37#if (!X64_COMPILER && (defined(_M_X86) || defined(_M_IX86) || defined(i386) || defined(__i386) || defined(__i386__) || defined(_X86_)))
 38    #define X86_COMPILER 1
 39#else
 40    #define X86_COMPILER 0
 41#endif
 42#if (defined(__arm__) || defined(__aarch64__) || defined(__thumb__) || defined(_M_ARM) || defined(_M_ARMT) || defined(__ARM_ARCH))
 43    #define ARM_COMPILER 1
 44#else
 45    #define ARM_COMPILER 0
 46#endif
 47#if (ARM_COMPILER && (defined(__thumb__) || defined(_M_ARMT)))
 48    #define ARM_THUMB 1
 49#else
 50    #define ARM_THUMB 0
 51#endif
 52#if (defined(__wasm__) || defined(__wasm32__) || defined(__wasm64__))
 53    #define WASM_COMPILER 1
 54    #include <emscripten.h>
 55#else
 56    #define WASM_COMPILER 0
 57    #define EMSCRIPTEN_KEEPALIVE
 58#endif
 59
 60// compiler workaround section
 61
 62#if PCC_COMPILER
 63    #warning static is being redefined to '' because you are on PCC. \
 64    This is happening because PCC does not allow reproducible builds with the static keyword used globally. \
 65    Make sure this does not have side effects, or undefine/redefine static per-usage.
 66    #define static
 67#endif
 68
 69// helper macro function section
 70
 71#ifndef max
 72    #define max(a, b) (((a) > (b)) ? (a) : (b))
 73#endif
 74
 75#ifndef min
 76    #define min(a, b) (((a) < (b)) ? (a) : (b))
 77#endif
 78
 79#ifndef swap
 80    #define swap(x, y) do { typeof(x) SWAP = x; x = y; y = SWAP; } while (0)
 81#endif
 82
 83#if !(CL_COMPILER || TCC_COMPILER)
 84    #define likely(x)   __builtin_expect(!!(x), 1)
 85    #define unlikely(x) __builtin_expect(!!(x), 0)
 86#else
 87    #define likely(x) x
 88    #define unlikely(x) x
 89#endif
 90
 91// constants section
 92
 93#define MAX_FACTORIAL_64 20
 94#define MAX_FACTORIAL_128 34
 95#define PCC_SQRT_ACCURACY 8
 96#define MAX_POW_10_16 10000U
 97#define POW_OF_MAX_POW_10_16 4
 98#define MAX_POW_10_32 1000000000UL
 99#define POW_OF_MAX_POW_10_32 9
100#define MAX_POW_10_64 10000000000000000000ULL
101#define POW_OF_MAX_POW_10_64 19
102#define MAX_POW_10_128 ((uintmax_t) MAX_POW_10_64 * (uintmax_t) MAX_POW_10_64)
103#define POW_OF_MAX_POW_10_128 38
104
105#ifndef UNITY_END
106#define PROGRAM_TAIL(type, prob) \
107int main(int argc, char const *argv[]) { \
108    printf(type "\n", prob()); \
109    return 0; \
110}
111#else
112#define PROGRAM_TAIL(type, prob)
113#endif