// ----------------------------------------------------------------------------- // semantic versioning in a single byte (octal) // - rlyeh, public domain. // // - single octal byte that represents semantic versioning (major.minor.patch). // - allowed range [0000..0377] ( <-> [0..255] decimal ) // - comparison checks only major.minor tuple as per convention. API int semver( int major, int minor, int patch ); API int semvercmp( int v1, int v2 ); #define SEMVER(major,minor,patch) (0100 * (major) + 010 * (minor) + (patch)) #define SEMVERCMP(v1,v2) (((v1) & 0110) - ((v2) & 0110)) #define SEMVERFMT "%03o" // ----------------------------------------------------------------------------- // autorun initializers for C // - rlyeh, public domain // // note: based on code by Joe Lowe (public domain). // note: XIU for C initializers, XCU for C++ initializers, XTU for C deinitializers #ifdef __cplusplus #define AUTORUN \ static void AUTORUN_U(f)(void); \ static const int AUTORUN_J(AUTORUN_U(f),__1) = (AUTORUN_U(f)(), 1); \ static void AUTORUN_U(f)(void) #elif _MSC_VER #define AUTORUN \ static void AUTORUN_U(f)(void); \ static int AUTORUN_J(AUTORUN_U(f),__1) (){ AUTORUN_U(f)(); return 0; } \ __pragma(section(".CRT$XIU", long, read)) \ __declspec(allocate(".CRT$XIU")) \ static int(* AUTORUN_J(AUTORUN_U(f),__2) )() = AUTORUN_J(AUTORUN_U(f),__1); \ static void AUTORUN_U(f)(void) #else #define AUTORUN \ __attribute__((constructor)) \ static void AUTORUN_U(f)(void) #endif // join + unique macro utils #define AUTORUN_j(a, b) a##b #define AUTORUN_J(a, b) AUTORUN_j(a, b) #define AUTORUN_U(x) AUTORUN_J(x, __LINE__) #if 0 // autorun demo void byebye(void) { puts("seen after main()"); } AUTORUN { puts("seen before main()"); } AUTORUN { puts("seen before main() too"); atexit( byebye ); } #endif // ----------------------------------------------------------------------------- // storage types. refer to vec2i/3i, vec2/3/4 if you plan to do math operations typedef struct byte2 { uint8_t x,y; } byte2; typedef struct byte3 { uint8_t x,y,z; } byte3; typedef struct byte4 { uint8_t x,y,z,w; } byte4; typedef struct int2 { int x,y; } int2; typedef struct int3 { int x,y,z; } int3; typedef struct int4 { int x,y,z,w; } int4; typedef struct uint2 { unsigned int x,y; } uint2; typedef struct uint3 { unsigned int x,y,z; } uint3; typedef struct uint4 { unsigned int x,y,z,w; } uint4; typedef struct float2 { float x,y; } float2; typedef struct float3 { float x,y,z; } float3; typedef struct float4 { float x,y,z,w; } float4; typedef struct double2 { double x,y; } double2; typedef struct double3 { double x,y,z; } double3; typedef struct double4 { double x,y,z,w; } double4; #define byte2(x,y) M_CAST(byte2, (uint8_t)(x), (uint8_t)(y) ) #define byte3(x,y,z) M_CAST(byte3, (uint8_t)(x), (uint8_t)(y), (uint8_t)(z) ) #define byte4(x,y,z,w) M_CAST(byte4, (uint8_t)(x), (uint8_t)(y), (uint8_t)(z), (uint8_t)(w) ) #define int2(x,y) M_CAST(int2, (int)(x), (int)(y) ) #define int3(x,y,z) M_CAST(int3, (int)(x), (int)(y), (int)(z) ) #define int4(x,y,z,w) M_CAST(int4, (int)(x), (int)(y), (int)(z), (int)(w) ) #define uint2(x,y) M_CAST(uint2, (unsigned)(x), (unsigned)(y) ) #define uint3(x,y,z) M_CAST(uint3, (unsigned)(x), (unsigned)(y), (unsigned)(z) ) #define uint4(x,y,z,w) M_CAST(uint4, (unsigned)(x), (unsigned)(y), (unsigned)(z), (unsigned)(w) ) #define float2(x,y) M_CAST(float2, (float)(x), (float)(y) ) #define float3(x,y,z) M_CAST(float3, (float)(x), (float)(y), (float)(z) ) #define float4(x,y,z,w) M_CAST(float4, (float)(x), (float)(y), (float)(z), (float)(w) ) #define double2(x,y) M_CAST(double2, (double)(x), (double)(y) ) #define double3(x,y,z) M_CAST(double3, (double)(x), (double)(y), (double)(z) ) #define double4(x,y,z,w) M_CAST(double4, (double)(x), (double)(y), (double)(z), (double)(w) )