#ifndef _TYPES
#define _TYPES

#include "stdint.h"
#include "stddef.h"

typedef int_fast8_t  i8;
typedef int_fast16_t i16;
typedef int_fast32_t i32;
typedef int_fast64_t i64;
typedef uint_fast8_t  u8;
typedef uint_fast16_t u16;
typedef uint_fast32_t u32;
typedef uint_fast64_t u64;
typedef size_t        usize;

typedef enum Result {
    /* Generic */
    R_Ok = 0,
    R_Err,
    R_NotImplemented,
    /* Values */
    R_Uninitialized,
    R_InvalidValue,
    R_OutOfBounds,
    /* Functions */
    R_InvalidArgument,
    R_NullArgument,
    /* Memory */
    R_OutOfMemory,
    /* Resources */
    R_NotFound,
    R_PermissionDenied,
    R_Unreachable,
    R_Unavailable,
    /* Other */
    R_PRIVATE
} Result;

#if defined(__has_warning)
#  if __has_warning("-Wc99-designator")
#    pragma clang diagnostic ignored "-Wc99-designator"
#  endif
#endif

const static char* Result_TO_STR[R_PRIVATE+1] = {
    [R_Ok]               = "Ok",
    [R_Err]              = "Error",
    [R_NotImplemented]   = "Not implemented",
    [R_Uninitialized]    = "Uninitialized",
    [R_InvalidValue]     = "Invalid value",
    [R_OutOfBounds]      = "Out of bounds",
    [R_InvalidArgument]  = "Invalid argument",
    [R_NullArgument]     = "NULL argument",
    [R_OutOfMemory]      = "Out of memory",
    [R_NotFound]         = "Not found",
    [R_PermissionDenied] = "Permission denied",
    [R_Unreachable]      = "Not reachable",
    [R_Unavailable]      = "Not available",
    [R_PRIVATE]          = "Unknown",
};

#define RETURN_NOTOK(x) { Result r = x; if (R_Ok != r) return r; }
#define PRINT_NOTOK(x) { Result r = x; if (R_Ok != r) fprintf(stderr, "%s:%d %s() Error: %s (%d)\n", __FILE__, __LINE__, __func__, Result_TO_STR[r], r); }

#define   B(x) ((x) * 8)
#define KiB(x) ((x) * 1024)
#define MiB(x) ((x) * 1048576)
#define GiB(x) ((x) * 1073741824)

#endif /* _TYPES */
