#pragma once
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <unistd.h>
#include <stdint.h>
#include <errno.h>
#include <string.h>


#define LOG(fmt, ...) fprintf(stderr, fmt "\n", ##__VA_ARGS__)
#define LOG_ERRNO(fmt, ...) LOG(fmt " - %d: %s", ##__VA_ARGS__, errno, strerror(errno))

#ifdef NDEBUG
    #define INLINE inline __attribute__((always_inline))
    #undef DEBUG
#else
    #define INLINE inline
    #define DEBUG 1
#endif

#define INIT_EARLY __attribute__((init_priority(101)))

#define likely(x)   __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#define unless(x) if (unlikely(!(x)))

#define MIN(a,b) ((a)<(b)?(a):(b))
#define MAX(a,b) ((a)>(b)?(a):(b))
#define MIN3(a,b,c) (MIN((a),MIN((b),(c))))
#define MAX3(a,b,c) (MAX((a),MAX((b),(c))))
#define MIN4(a,b,c,d) MIN(MIN((a),(b)),MIN((c),(d)))
#define MAX4(a,b,c,d) MAX(MAX((a),(b)),MAX((c),(d)))
#define MIN8(a,b,c,d,e,f,g,h) MIN(MIN4((a),(b),(c),(d)),MIN4((e),(f),(g),(h)))
#define MAX8(a,b,c,d,e,f,g,h) MAX(MAX4((a),(b),(c),(d)),MAX4((e),(f),(g),(h)))

#define GETORSET(var, fun) ((var)?:((var)=(fun)))

char* file_read(const char*, size_t&);

typedef struct {
    typedef struct { // might want union and type flag instead
        const char* name;
        int i;
        float d;
    } val_t;
    val_t ao_len;
    val_t ao_lin;
    val_t ao_os;
    val_t ao_fac;
    val_t alight_samples;
    val_t supersample;
} config_t;
extern config_t config;