Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #if !defined(RLT_H)
- #define RLT_H
- #include <stdint.h>
- #include <stddef.h>
- #include <assert.h>
- #include <stdlib.h>
- // NOTE(rohan): typedefs
- typedef int8_t s8;
- typedef int16_t s16;
- typedef int32_t s32;
- typedef int64_t s64;
- typedef uint8_t u8;
- typedef uint16_t u16;
- typedef uint32_t u32;
- typedef uint64_t u64;
- typedef s32 b32;
- typedef float f32;
- typedef double f64;
- typedef size_t usize;
- typedef uintptr_t uptr;
- typedef intptr_t sptr;
- // NOTE(rohan): constants
- #define RLT_VERSION 1
- #define M_PI 3.14159265358979323846f
- // NOTE(rohan): min and max
- #define rlt_min(a,b) ((a) < (b) ? (a) : (b))
- #define rlt_max(a,b) ((a) > (b) ? (a) : (b))
- // NOTE(rohan): lerp and unlerp
- #define rlt_lerp(a,b,t) ((a) + (t) * (float) ((b)-(a)))
- #define rlt_unlerp(a,b,t) (((t) - (a)) / (float) ((b) - (a)))
- // NOTE(rohan): clamp
- #define rlt_clamp(x,xmin,xmax) ((x) < (xmin) ? (xmin) : (x) > (xmax) ? (xmax) : (x))
- // NOTE(rohan): degrees and radians
- #define deg2rad(a) ((a)*(M_PI / 180))
- #define rad2deg(a) ((a)*(180 / M_PI))
- // NOTE(rohan): helper macros
- #define swap(TYPE,a,b) \
- do { TYPE rlt__t; rlt__t = (a); (a) = (b); (b) = rlt__t; } while (0)
- // NOTE(rohan): API function prototypes
- #ifdef __cplusplus
- #define EXTERN_C extern "C" {
- #define EXTERN_C_END }
- #else
- #define EXTERN_C
- #define EXTERN_C_END
- #endif
- #ifdef RLT_STATIC
- #define RLTDEF static
- #else
- #define RLTDEF extern
- #endif
- // NOTE(rohan): stretchy buffers
- typedef struct BufHdr
- {
- usize len;
- usize cap;
- char buf[0];
- } BufHdr;
- #define buf__hdr(b) ((BufHdr *)((char *)b - offsetof(BufHdr, buf)))
- #define buf__fits(b, n) (buf_len(b) + (n) <= buf_cap(b))
- #define buf__fit(b, n) (buf__fits(b, n) ? 0 : ((b) = buf__grow((b), buf_len(b) + (n), sizeof(*(b)))))
- #define buf_len(b) ((b) ? buf__hdr(b)->len : 0)
- #define buf_cap(b) ((b) ? buf__hdr(b)->cap : 0)
- #define buf_push(b, x) (buf__fit(b, 1), (b)[buf_len(b)] = (x), buf__hdr(b)->len++)
- #define buf_free(b) ((b) ? free(buf__hdr(b)) : 0)
- EXTERN_C
- RLTDEF void *buf__grow(const void *buf, usize new_len, usize elem_size);
- EXTERN_C_END
- // NOTE(rohan): quick sort
- #define RLT_(prefix, name) rlt__##prefix##name
- #define rlt_declare_sort(FUNCNAME, TYPE) \
- void FUNCNAME(TYPE *p, int n)
- #define rlt_define_sort(FUNCNAME, TYPE, COMPARE) \
- rlt__define_sort(void, FUNCNAME, TYPE, COMPARE)
- #define rlt_define_sort_static(FUNCNAME, TYPE, COMPARE) \
- rlt__define_sort(static void, FUNCNAME, TYPE, COMPARE)
- #define rlt__define_sort(MODE, FUNCNAME, TYPE, COMPARE) \
- \
- static void RLT_(FUNCNAME, _insertsort)(TYPE *p, int n) \
- { \
- int i, j; \
- for (i = 1; i < n; ++i) \
- { \
- TYPE t = p[i], *a = &t; \
- j = i; \
- while (j > 0) \
- { \
- TYPE *b = &p[j - 1]; \
- int c = COMPARE; \
- if (!c) break; \
- p[j] = p[j - 1]; \
- --j; \
- } \
- \
- if (i != j) \
- p[j] = t; \
- } \
- } \
- \
- static void RLT_(FUNCNAME, _quicksort)(TYPE *p, int n) \
- { \
- /* threshhold for transitioning to insertion sort */ \
- while (n > 12) \
- { \
- TYPE *a, *b, t; \
- int c01, c12, c, m, i, j; \
- \
- /* compute median of three */ \
- m = n >> 1; \
- a = &p[0]; \
- b = &p[m]; \
- c = COMPARE; \
- c01 = c; \
- a = &p[m]; \
- b = &p[n-1]; \
- c = COMPARE; \
- c12 = c; \
- /* if 0 >= mid >= end, or 0 < mid < end, then use mid */ \
- if (c01 != c12) \
- { \
- /* otherwise, we'll need to swap something to middle */ \
- int z; \
- a = &p[0]; \
- b = &p[n - 1]; \
- c = COMPARE; \
- z = (c == c12) ? 0 : n - 1; \
- t = p[z]; \
- p[z] = p[m]; \
- p[m] = t; \
- } \
- /* now p[m] is the median-of-three */ \
- /* swap it to the beginning so it won't move around */ \
- t = p[0]; \
- p[0] = p[m]; \
- p[m] = t; \
- \
- /* partition loop */ \
- i= 1; \
- j= n - 1; \
- for(;;) \
- { \
- b = &p[0]; \
- for (;;++i) \
- { \
- a= &p[i]; \
- c = COMPARE; \
- if (!c) break; \
- } \
- a = &p[0]; \
- for (;;--j) \
- { \
- b= &p[j]; \
- c = COMPARE; \
- if (!c) break; \
- } \
- /* make sure we haven't crossed */ \
- if (i >= j) break; \
- t = p[i]; \
- p[i] = p[j]; \
- p[j] = t; \
- \
- ++i; \
- --j; \
- } \
- /* recurse on smaller side, iterate on larger */ \
- if (j < (n - i)) \
- { \
- RLT_(FUNCNAME,_quicksort)(p, j); \
- p = p + i; \
- n = n - i; \
- } \
- else \
- { \
- RLT_(FUNCNAME,_quicksort)(p+i, n-i); \
- n = j; \
- } \
- } \
- } \
- MODE FUNCNAME(TYPE *p, int n) \
- { \
- RLT_(FUNCNAME, _quicksort)(p, n); \
- RLT_(FUNCNAME, _insertsort)(p, n); \
- } \
- #endif
- // NOTE(rohan): start of implementation code
- // NOTE(rohan): stretchy buffer
- #ifdef RLT_IMPLEMENTATION
- void *buf__grow(const void *buf, usize new_len, usize elem_size)
- {
- usize new_cap = rlt_max(1 + 2 * buf_cap(buf), new_len);
- assert(new_len <= new_cap);
- usize new_size = offsetof(BufHdr, buf) + (new_cap * elem_size);
- BufHdr *new_hdr;
- if (buf)
- {
- new_hdr = realloc(buf__hdr(buf), new_size);
- }
- else
- {
- new_hdr = malloc(new_size);
- new_hdr->len = 0;
- }
- new_hdr->cap = new_cap;
- return new_hdr->buf;
- }
- #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement