advent-of-code

Solutions for Advent of Code.
git clone git://git.amin.space/advent-of-code.git
Log | Files | Refs | LICENSE

am_base.h (2749B)


      1 #ifndef AM_BASE_H
      2 #define AM_BASE_H
      3 
      4 #if __STDC_VERSION__ < 201112L
      5 # error "C11 or greater required."
      6 #endif
      7 
      8 // context
      9 // https://sourceforge.net/p/predef/wiki/Home/
     10 #if defined(__clang__)
     11 # define COMPILER_CLANG 1
     12 #elif defined (__GNUC__)
     13 # define COMPILER_GCC 1
     14 #else
     15 # error "Unsupported compiler."
     16 #endif
     17 
     18 #if !defined(COMPILER_CLANG)
     19 # define COMPILER_CLANG 0
     20 #endif
     21 #if !defined(COMPILER_GCC)
     22 # define COMPILER_GCC 0
     23 #endif
     24 
     25 #if defined (__linux__)
     26 # define OPERATING_SYSTEM_LINUX 1
     27 #elif defined(_WIN32)
     28 # define OPERATING_SYSTEM_WINDOWS 1
     29 #else
     30 # error "Unsupported OS."
     31 #endif
     32 
     33 #if !defined(OPERATING_SYSTEM_LINUX)
     34 # define OPERATING_SYSTEM_LINUX 0
     35 #endif
     36 #if !defined(OPERATING_SYSTEM_WINDOWS)
     37 # define OPERATING_SYSTEM_WINDOWS 0
     38 #endif
     39 
     40 // compiler builtins
     41 #if COMPILER_CLANG || COMPILER_GCC
     42 # ifndef __has_builtin
     43 #  define __has_builtin(x) 0
     44 # endif
     45 #endif
     46 
     47 #define IMPLEMENTATION_UNSIGNED_CHAR (CHAR_MIN == 0)
     48 
     49 // freestanding headers
     50 #include <float.h>
     51 #include <limits.h>
     52 #include <stdalign.h>
     53 #include <stdarg.h>
     54 #include <stdbool.h>
     55 #include <stddef.h>
     56 #include <stdint.h>
     57 #include <stdnoreturn.h>
     58 
     59 // preprocessor improvement
     60 #define AM__STRINGIFY(S) #S
     61 #define AM__GLUE(A, B) A##B
     62 #define AM_STRINGIFY(S) AM__STRINGIFY(S)
     63 #define AM_GLUE(A, B) AM__GLUE((A), (B))
     64 
     65 // assert
     66 #define static_assert(expr) _Static_assert((expr), "")
     67 
     68 #if !defined(AM_ENABLE_ASSERT)
     69 # define AM_ENABLE_ASSERT 0
     70 #endif
     71 
     72 #if AM_ENABLE_ASSERT
     73 # if !defined(AM_ASSERT_FAIL)
     74 #  if __has_builtin(__builtin_trap)
     75 #   define AM_ASSERT_FAIL(expr, file, line, func) __builtin_trap()
     76 #  else
     77 #   error "Must define implementation of AM_ASSERT_FAIL(expr, file, line, func)."
     78 #  endif
     79 # endif
     80 # define assert(x) ((void)((x) || (AM_ASSERT_FAIL(AM_STRINGIFY(x), __FILE__, __LINE__, __func__),0)))
     81 #else
     82 # define assert(c) ((void)0)
     83 #endif
     84 
     85 #define AM_UNREACHABLE assert(false && "Unreachable code reached")
     86 
     87 // utility macros
     88 #define ALIGN_UP_POW_2(x, p) (((x) + (p) - 1) & ~((p) - (1)))
     89 #define ALIGN_DOWN_POW_2(x, p) ((x) & ~((p) - 1))
     90 #define ARRAY_COUNT(a) (sizeof(a)/sizeof(*(a)))
     91 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
     92 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
     93 #define CLAMP(a, x, b) (((x) < (a)) ? (a) : (((b) < (x)) ? (b) : (x)))
     94 #define CLAMP_TOP(a, b) MIN((a), (b))
     95 #define CLAMP_BOT(a, b) MAX((a), (b))
     96 #define UNUSED(p) (void)(p)
     97 
     98 // basic types
     99 typedef int8_t   s8;
    100 typedef int16_t  s16;
    101 typedef int32_t  s32;
    102 typedef int64_t  s64;
    103 typedef uint8_t  u8;
    104 typedef uint16_t u16;
    105 typedef uint32_t u32;
    106 typedef uint64_t u64;
    107 typedef size_t   usz;
    108 typedef float    f32;
    109 typedef double   f64;
    110 
    111 #define global        static
    112 #define local_persist static
    113 #define internal      static
    114 
    115 // sanity checks
    116 static_assert(CHAR_BIT == 8);
    117 
    118 #endif // AM_BASE_H