Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b1b99cb224 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,2 +0,0 @@
|
|||||||
.cache
|
|
||||||
build
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
[binaries]
|
|
||||||
c = 'clang-19'
|
|
||||||
c_ld = 'lld-19'
|
|
||||||
cpp = 'clang++-19'
|
|
||||||
cpp_ld = 'lld-19'
|
|
||||||
|
|
||||||
[properties]
|
|
||||||
c_args = ['-DEV_CC_CLANG=1','-fcolor-diagnostics', '-fansi-escape-codes', '-fms-extensions']
|
|
||||||
|
|
||||||
[cmake]
|
|
||||||
CMAKE_C_COMPILER = 'clang-19'
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
[binaries]
|
|
||||||
c = 'clang.exe'
|
|
||||||
c_ld = 'lld'
|
|
||||||
cpp = 'clang++.exe'
|
|
||||||
cpp_ld = 'lld'
|
|
||||||
|
|
||||||
[properties]
|
|
||||||
c_args = ['-DEV_CC_CLANG=1','-fcolor-diagnostics', '-fansi-escape-codes']
|
|
||||||
|
|
||||||
[cmake]
|
|
||||||
CMAKE_C_COMPILER = 'clang.exe'
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
#define EV_LOG_IMPLEMENTATION
|
|
||||||
#include "../ev_log.h"
|
|
||||||
@@ -23,17 +23,12 @@ evstring_readFile(
|
|||||||
#ifdef EV_HELPERS_IMPLEMENTATION
|
#ifdef EV_HELPERS_IMPLEMENTATION
|
||||||
#undef EV_HELPERS_IMPLEMENTATION
|
#undef EV_HELPERS_IMPLEMENTATION
|
||||||
|
|
||||||
|
|
||||||
evstring
|
evstring
|
||||||
evstring_readFile(
|
evstring_readFile(
|
||||||
evstring filePath)
|
evstring filePath)
|
||||||
{
|
{
|
||||||
FILE* f = NULL;
|
FILE* f = fopen(filePath, "rb");
|
||||||
#if EV_OS_WINDOWS
|
if(f == NULL) return EV_INVALID(evstring);
|
||||||
if(fopen_s(&f,filePath,"rb")) return EV_INVALID(evstring);
|
|
||||||
#else
|
|
||||||
f = fopen(filePath, "rb");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
fseek(f, 0, SEEK_END);
|
fseek(f, 0, SEEK_END);
|
||||||
u32 buflen = ftell(f);
|
u32 buflen = ftell(f);
|
||||||
|
|||||||
202
ev_log.h
202
ev_log.h
@@ -1,202 +0,0 @@
|
|||||||
#ifndef EV_HEADERS_LOG_H
|
|
||||||
#define EV_HEADERS_LOG_H
|
|
||||||
|
|
||||||
#define EV_LOG_USE_COLOR
|
|
||||||
|
|
||||||
#include "ev_internal.h"
|
|
||||||
|
|
||||||
#include "stdarg.h"
|
|
||||||
#include "stdbool.h"
|
|
||||||
#include "stdio.h"
|
|
||||||
#include "time.h"
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
va_list ap;
|
|
||||||
const char* fmt;
|
|
||||||
const char* file;
|
|
||||||
struct tm* time;
|
|
||||||
void* udata;
|
|
||||||
int line;
|
|
||||||
int level;
|
|
||||||
} ev_log_event_t;
|
|
||||||
|
|
||||||
typedef void (*ev_log_log_fn)(ev_log_event_t* ev);
|
|
||||||
typedef void (*ev_log_lock_fn)(bool lock, void* udata);
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
EV_LOG_TRACE,
|
|
||||||
EV_LOG_DEBUG,
|
|
||||||
EV_LOG_INFO ,
|
|
||||||
EV_LOG_WARN ,
|
|
||||||
EV_LOG_ERROR,
|
|
||||||
EV_LOG_FATAL,
|
|
||||||
} ev_log_level;
|
|
||||||
|
|
||||||
#define ev_log_trace(...) ev_log(EV_LOG_TRACE, __FILE__, __LINE__, __VA_ARGS__)
|
|
||||||
#define ev_log_debug(...) ev_log(EV_LOG_DEBUG, __FILE__, __LINE__, __VA_ARGS__)
|
|
||||||
#define ev_log_info(...) ev_log(EV_LOG_INFO , __FILE__, __LINE__, __VA_ARGS__)
|
|
||||||
#define ev_log_warn(...) ev_log(EV_LOG_WARN , __FILE__, __LINE__, __VA_ARGS__)
|
|
||||||
#define ev_log_error(...) ev_log(EV_LOG_ERROR, __FILE__, __LINE__, __VA_ARGS__)
|
|
||||||
#define ev_log_fatal(...) ev_log(EV_LOG_FATAL, __FILE__, __LINE__, __VA_ARGS__)
|
|
||||||
|
|
||||||
const char* ev_log_level_string(ev_log_level level);
|
|
||||||
void ev_log_set_lock(ev_log_lock_fn fn, void* udata);
|
|
||||||
void ev_log_set_level(ev_log_level level);
|
|
||||||
void ev_log_set_quiet(bool enable);
|
|
||||||
i32 ev_log_add_callback(ev_log_log_fn fn, void* udata, ev_log_level level);
|
|
||||||
i32 ev_log_add_fp(FILE *fp, ev_log_level level);
|
|
||||||
|
|
||||||
void ev_log(ev_log_level level, const char* file, u32 line, const char* fmt, ...);
|
|
||||||
|
|
||||||
#ifdef EV_LOG_IMPLEMENTATION
|
|
||||||
#undef EV_LOG_IMPLEMENTATION
|
|
||||||
|
|
||||||
#define MAX_CALLBACKS 32
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
ev_log_log_fn fn;
|
|
||||||
void* udata;
|
|
||||||
ev_log_level level;
|
|
||||||
} ev_log_callback_t;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
void* udata;
|
|
||||||
ev_log_lock_fn lock;
|
|
||||||
ev_log_level level;
|
|
||||||
bool quiet;
|
|
||||||
ev_log_callback_t callbacks[MAX_CALLBACKS];
|
|
||||||
} G;
|
|
||||||
|
|
||||||
static const char* level_strings[] = {
|
|
||||||
"TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char* level_colors[] = {
|
|
||||||
"\x1b[94m", "\x1b[36m", "\x1b[32m", "\x1b[33m", "\x1b[31m", "\x1b[35m"
|
|
||||||
};
|
|
||||||
|
|
||||||
static void ev_log_stdout_callback(ev_log_event_t* ev)
|
|
||||||
{
|
|
||||||
char buf[16];
|
|
||||||
buf[strftime(buf, sizeof(buf), "%H:%M:%S", ev->time)] = '\0';
|
|
||||||
#ifdef EV_LOG_USE_COLOR
|
|
||||||
fprintf(
|
|
||||||
ev->udata, "%s %s%-5s\x1b[0m \x1b[90m%s:%d:\x1b[0m ",
|
|
||||||
buf, level_colors[ev->level], level_strings[ev->level],
|
|
||||||
ev->file, ev->line);
|
|
||||||
#else
|
|
||||||
fprintf(
|
|
||||||
ev->udata, "%s %-5s %s:%d: ",
|
|
||||||
buf, level_strings[ev->level], ev->file, ev->line);
|
|
||||||
#endif
|
|
||||||
vfprintf(ev->udata, ev->fmt, ev->ap);
|
|
||||||
fprintf(ev->udata, "\n");
|
|
||||||
fflush(ev->udata);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ev_log_file_callback(ev_log_event_t* ev)
|
|
||||||
{
|
|
||||||
char buf[64];
|
|
||||||
buf[strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", ev->time)] = '\0';
|
|
||||||
fprintf(
|
|
||||||
ev->udata, "%s %-5s %s:%d: ",
|
|
||||||
buf, level_strings[ev->level], ev->file, ev->line);
|
|
||||||
vfprintf(ev->udata, ev->fmt, ev->ap);
|
|
||||||
fprintf(ev->udata, "\n");
|
|
||||||
fflush(ev->udata);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void lock(void)
|
|
||||||
{
|
|
||||||
if(G.lock)
|
|
||||||
G.lock(true, G.udata);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void unlock(void)
|
|
||||||
{
|
|
||||||
if(G.lock)
|
|
||||||
G.lock(false, G.udata);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* ev_log_level_string(ev_log_level level)
|
|
||||||
{
|
|
||||||
return level_strings[level];
|
|
||||||
}
|
|
||||||
|
|
||||||
void ev_log_set_lock(ev_log_lock_fn fn, void* udata)
|
|
||||||
{
|
|
||||||
G.lock = fn;
|
|
||||||
G.udata = udata;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ev_log_set_level(ev_log_level level)
|
|
||||||
{
|
|
||||||
G.level = level;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ev_log_set_quiet(bool enable)
|
|
||||||
{
|
|
||||||
G.quiet = enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
i32 ev_log_add_callback(ev_log_log_fn fn, void* udata, ev_log_level level)
|
|
||||||
{
|
|
||||||
for (i32 i = 0; i < MAX_CALLBACKS; i++) {
|
|
||||||
if (!G.callbacks[i].fn) {
|
|
||||||
G.callbacks[i] = (ev_log_callback_t) { fn, udata, level };
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
i32 log_add_fp(FILE *fp, ev_log_level level)
|
|
||||||
{
|
|
||||||
return ev_log_add_callback(ev_log_file_callback, fp, level);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void init_event(ev_log_event_t* ev, void* udata)
|
|
||||||
{
|
|
||||||
if (!ev->time) {
|
|
||||||
time_t t = time(NULL);
|
|
||||||
ev->time = localtime(&t);
|
|
||||||
}
|
|
||||||
ev->udata = udata;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ev_log(ev_log_level level, const char* file, u32 line, const char* fmt, ...)
|
|
||||||
{
|
|
||||||
ev_log_event_t ev = {
|
|
||||||
.fmt = fmt,
|
|
||||||
.file = file,
|
|
||||||
.line = line,
|
|
||||||
.level = level,
|
|
||||||
};
|
|
||||||
|
|
||||||
lock();
|
|
||||||
|
|
||||||
if (!G.quiet && level >= G.level) {
|
|
||||||
init_event(&ev, stderr);
|
|
||||||
va_start(ev.ap, fmt);
|
|
||||||
ev_log_stdout_callback(&ev);
|
|
||||||
va_end(ev.ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i32 i = 0; i < MAX_CALLBACKS && G.callbacks[i].fn; i++) {
|
|
||||||
ev_log_callback_t* cb = &G.callbacks[i];
|
|
||||||
if (level >= cb->level) {
|
|
||||||
init_event(&ev, cb->udata);
|
|
||||||
va_start(ev.ap, fmt);
|
|
||||||
cb->fn(&ev);
|
|
||||||
va_end(ev.ap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
248
ev_map.h
Normal file
248
ev_map.h
Normal file
@@ -0,0 +1,248 @@
|
|||||||
|
/*!
|
||||||
|
* \file ev_map.h
|
||||||
|
*/
|
||||||
|
#ifndef EV_MAP_HEADER
|
||||||
|
#define EV_MAP_HEADER
|
||||||
|
#include "ev_internal.h"
|
||||||
|
#include "ev_types.h"
|
||||||
|
#include "ev_numeric.h"
|
||||||
|
#include "ev_vec.h"
|
||||||
|
|
||||||
|
#define EV_MAP_MAGIC (0x65765F6D61705F74)
|
||||||
|
|
||||||
|
#if defined(EV_MAP_SHARED)
|
||||||
|
# if defined (EV_MAP_IMPL)
|
||||||
|
# define EV_MAP_API EV_EXPORT
|
||||||
|
# else
|
||||||
|
# define EV_MAP_API EV_IMPORT
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define EV_MAP_API
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef EV_MAP_INIT_CAP
|
||||||
|
/*!
|
||||||
|
* \brief Initial capacity that is first reserved when a map is initialized
|
||||||
|
*/
|
||||||
|
#define EV_MAP_INIT_CAP 32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef EV_MAP_GROWTH_RATE
|
||||||
|
/*!
|
||||||
|
* \brief Rate at which a map grows whenever a resize is needed
|
||||||
|
*/
|
||||||
|
#define EV_MAP_GROWTH_RATE 3 / 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u64 _magic;
|
||||||
|
u64 length;
|
||||||
|
u64 capacity;
|
||||||
|
u64 seed;
|
||||||
|
EvTypeData keyTypeData;
|
||||||
|
EvTypeData valTypeData;
|
||||||
|
ev_vec_t keys;
|
||||||
|
ev_vec_t vals;
|
||||||
|
} ev_map_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
EV_MAP_ERR_NONE = 0,
|
||||||
|
EV_MAP_ERR_OOM = 1
|
||||||
|
} ev_map_error_t;
|
||||||
|
TYPEDATA_GEN(ev_map_error_t, DEFAULT(EV_MAP_ERR_NONE));
|
||||||
|
|
||||||
|
#if defined(EV_MAP_SHORTNAMES)
|
||||||
|
# define map_t ev_map_t
|
||||||
|
|
||||||
|
# define map_error_t ev_map_error_t
|
||||||
|
|
||||||
|
# define map(K,V) ev_map(K,V)
|
||||||
|
|
||||||
|
# define map_init ev_map_init
|
||||||
|
/* # define vec_iter_begin ev_vec_iter_begin */
|
||||||
|
/* # define vec_iter_end ev_vec_iter_end */
|
||||||
|
/* # define vec_iter_next ev_vec_iter_next */
|
||||||
|
/* # define vec_fini ev_vec_fini */
|
||||||
|
/* # define vec_push ev_vec_push */
|
||||||
|
/* # define vec_append ev_vec_append */
|
||||||
|
/* # define vec_last ev_vec_last */
|
||||||
|
/* # define vec_len ev_vec_len */
|
||||||
|
/* # define vec_capacity ev_vec_capacity */
|
||||||
|
/* # define vec_clear ev_vec_clear */
|
||||||
|
/* # define vec_setlen ev_vec_setlen */
|
||||||
|
/* # define vec_setcapacity ev_vec_setcapacity */
|
||||||
|
/* # define vec_grow ev_vec_grow */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief For the sake of readability
|
||||||
|
* \details Sample usage:
|
||||||
|
* ```
|
||||||
|
* ev_map(int,int) v = ev_map_init(int,int);
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
#define ev_map(K,V) struct { \
|
||||||
|
u64 _magic; \
|
||||||
|
u64 length; \
|
||||||
|
u64 capacity; \
|
||||||
|
u64 seed; \
|
||||||
|
EvTypeData keyTypeData; \
|
||||||
|
EvTypeData valTypeData; \
|
||||||
|
ev_vec(K) keys; \
|
||||||
|
ev_vec(V) vals; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \param typeData The EvTypeData for the element that the vector will contain
|
||||||
|
*
|
||||||
|
* \returns A vector object
|
||||||
|
*/
|
||||||
|
EV_MAP_API ev_map_t*
|
||||||
|
ev_map_init_impl(
|
||||||
|
EvTypeData keyTypeData,
|
||||||
|
EvTypeData valTypeData);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Syntactic sugar for `ev_map_init_impl()`
|
||||||
|
* \details Sample usage:
|
||||||
|
* ```
|
||||||
|
* ev_map_init(i32,i64); // ev_map_init_impl(TypeData(i32),TypeData(i64));
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
#define ev_map_init(K,V) (void*)ev_map_init_impl(TypeData(K), TypeData(V))
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Syntactic sugar for `ev_vec_push_impl()` that allows multiple pushed in the same statement.
|
||||||
|
* \details Sample usage:
|
||||||
|
* ```
|
||||||
|
* ev_vec_t v;
|
||||||
|
* i32 x = 1;
|
||||||
|
* i32 y = 2;
|
||||||
|
* ev_vec_push(&v, &x); // ev_vec_push_impl(&v, &x);
|
||||||
|
* ev_vec_push(&v, &x, &y); // ev_vec_push_impl(&v, &x); ev_vec_push_impl(&v, &y);
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* *Note* This is possibly replaceable with a variadic function.
|
||||||
|
*/
|
||||||
|
#define ev_map_add(m, ...) \
|
||||||
|
EV_FOREACH_UDATA(__ev_map_internal_add, m, __VA_ARGS__);
|
||||||
|
#define __ev_map_internal_add(m, entry) ev_map_add_impl((ev_map_t*)m, EV_HEAD entry, EV_TAIL entry);
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief A function that destroys a vector object. If the element type has a
|
||||||
|
* destructor function, then this function is called on every element before
|
||||||
|
* all reserved memory is freed.
|
||||||
|
*
|
||||||
|
* *Note*: For stack-allocated vectors (`svec`), destructors are called for
|
||||||
|
* elements but no memory is freed.
|
||||||
|
*
|
||||||
|
* \param v A pointer to the vector that is being destroyed
|
||||||
|
*/
|
||||||
|
EV_MAP_API void
|
||||||
|
ev_map_fini(
|
||||||
|
ev_map_t* m);
|
||||||
|
|
||||||
|
EV_MAP_API void
|
||||||
|
ev_map_add_impl(
|
||||||
|
ev_map_t* m,
|
||||||
|
void* key,
|
||||||
|
void* val
|
||||||
|
);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Calls the free operation (if exists) on every entry, then sets
|
||||||
|
* the length to 0.
|
||||||
|
*
|
||||||
|
* \param v A pointer to the map object
|
||||||
|
*
|
||||||
|
* \returns 0 on success
|
||||||
|
*/
|
||||||
|
EV_MAP_API u32
|
||||||
|
ev_map_clear(
|
||||||
|
ev_map_t* m);
|
||||||
|
|
||||||
|
TYPEDATA_GEN(
|
||||||
|
ev_map_t,
|
||||||
|
INVALID(
|
||||||
|
._magic = ~0ULL
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
#define EV_MAP_IMPLEMENTATION
|
||||||
|
|
||||||
|
#ifdef EV_MAP_IMPLEMENTATION
|
||||||
|
#undef EV_MAP_IMPLEMENTATION
|
||||||
|
|
||||||
|
#ifdef EV_MAP_API_CHECK
|
||||||
|
#define EV_VEC_CHECK(x) do { x; } while (0)
|
||||||
|
#else
|
||||||
|
#define EV_MAP_CHECK(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
ev_map_t*
|
||||||
|
ev_map_init_impl(
|
||||||
|
EvTypeData keyTypeData,
|
||||||
|
EvTypeData valTypeData)
|
||||||
|
{
|
||||||
|
ev_map_t* m = malloc(sizeof(ev_map_t));
|
||||||
|
if(!m) return &EV_INVALID(ev_map_t);
|
||||||
|
|
||||||
|
m->_magic = EV_MAP_MAGIC;
|
||||||
|
m->keyTypeData = keyTypeData;
|
||||||
|
m->valTypeData = valTypeData;
|
||||||
|
m->keys = ev_vec_init_impl(keyTypeData, EV_DEFAULT(ev_vec_overrides_t));
|
||||||
|
m->vals = ev_vec_init_impl(valTypeData, EV_DEFAULT(ev_vec_overrides_t));
|
||||||
|
|
||||||
|
m->length = 0;
|
||||||
|
|
||||||
|
assert(ev_vec_capacity(&m->keys) == ev_vec_capacity(&m->vals));
|
||||||
|
|
||||||
|
m->capacity = ev_vec_capacity(&m->keys);
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ev_map_fini(
|
||||||
|
ev_map_t* m)
|
||||||
|
{
|
||||||
|
ev_vec_fini(&m->keys);
|
||||||
|
ev_vec_fini(&m->vals);
|
||||||
|
free(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64
|
||||||
|
_ev_map_hash(
|
||||||
|
ev_map_t* m,
|
||||||
|
void* key)
|
||||||
|
{
|
||||||
|
u64 clipMask = 0xFFFFFFFFFFFF;
|
||||||
|
if(m->keyTypeData.hash_fn != NULL)
|
||||||
|
return m->keyTypeData.hash_fn(key, m->seed) & clipMask;
|
||||||
|
return ev_hash_murmur3(key, m->keyTypeData.size, m->seed) & clipMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ev_map_add_impl(
|
||||||
|
ev_map_t* m,
|
||||||
|
void* key,
|
||||||
|
void* val)
|
||||||
|
{
|
||||||
|
u64 hash = _ev_map_hash(m, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32
|
||||||
|
ev_map_clear(
|
||||||
|
ev_map_t* m)
|
||||||
|
{
|
||||||
|
m->length = 0;
|
||||||
|
return ev_vec_clear(m->keys) | ev_vec_clear(m->vals);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
11
ev_numeric.h
11
ev_numeric.h
@@ -97,15 +97,4 @@ static const struct Float64Data Float64 =
|
|||||||
.EPS = 2.2204460492503131e-016
|
.EPS = 2.2204460492503131e-016
|
||||||
};
|
};
|
||||||
|
|
||||||
#if !EV_OS_WINDOWS
|
|
||||||
#define max(a,b) \
|
|
||||||
({ __typeof__(a) _a = (a); \
|
|
||||||
__typeof__(b) _b = (b); \
|
|
||||||
_a > _b ? _a : _b; })
|
|
||||||
#define min(a,b) \
|
|
||||||
({ __typeof__(a) _a = (a); \
|
|
||||||
__typeof__(b) _b = (b); \
|
|
||||||
_a < _b ? _a : _b; })
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // EV_HEADERS_NUMERIC_H
|
#endif // EV_HEADERS_NUMERIC_H
|
||||||
|
|||||||
14
ev_str.h
14
ev_str.h
@@ -197,20 +197,8 @@ DEFINE_EQUAL_FUNCTION(evstring, Default)
|
|||||||
return evstring_cmp(*(evstring*)self, *(evstring*)other) == 0;
|
return evstring_cmp(*(evstring*)self, *(evstring*)other) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_COPY_FUNCTION(evstring, Default)
|
|
||||||
{
|
|
||||||
*(evstring*)dst = evstring_newFromStr(*src);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_FREE_FUNCTION(evstring, Default)
|
|
||||||
{
|
|
||||||
evstring_free(*self);
|
|
||||||
}
|
|
||||||
|
|
||||||
TYPEDATA_GEN(evstring,
|
TYPEDATA_GEN(evstring,
|
||||||
EQUAL(Default),
|
EQUAL(Default)
|
||||||
COPY(Default),
|
|
||||||
FREE(Default)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
14
ev_types.h
14
ev_types.h
@@ -30,12 +30,12 @@ typedef struct {
|
|||||||
void *invalid_val;
|
void *invalid_val;
|
||||||
} EvTypeData;
|
} EvTypeData;
|
||||||
|
|
||||||
#define COPY_FUNCTION(T ,name) EV_CAT(EV_CAT(EV_CAT(EV_COPY_FUNCTION_ ,T),_),name)
|
#define COPY_FUNCTION(T,name) EV_CATN(EV_COPY_FUNCTION_,T,_,name)
|
||||||
#define FREE_FUNCTION(T ,name) EV_CAT(EV_CAT(EV_CAT(EV_FREE_FUNCTION_ ,T),_),name)
|
#define FREE_FUNCTION(T,name) EV_CATN(EV_FREE_FUNCTION_,T,_,name)
|
||||||
#define HASH_FUNCTION(T ,name) EV_CAT(EV_CAT(EV_CAT(EV_HASH_FUNCTION_ ,T),_),name)
|
#define HASH_FUNCTION(T,name) EV_CATN(EV_HASH_FUNCTION_,T,_,name)
|
||||||
#define EQUAL_FUNCTION(T ,name) EV_CAT(EV_CAT(EV_CAT(EV_EQUAL_FUNCTION_ ,T),_),name)
|
#define EQUAL_FUNCTION(T,name) EV_CATN(EV_EQUAL_FUNCTION_,T,_,name)
|
||||||
#define TOSTR_FUNCTION(T ,name) EV_CAT(EV_CAT(EV_CAT(EV_TOSTR_FUNCTION_ ,T),_),name)
|
#define TOSTR_FUNCTION(T,name) EV_CATN(EV_TOSTR_FUNCTION_,T,_,name)
|
||||||
#define TOSTRLEN_FUNCTION(T,name) EV_CAT(EV_CAT(EV_CAT(EV_TOSTRLEN_FUNCTION_,T),_),name)
|
#define TOSTRLEN_FUNCTION(T,name) EV_CATN(EV_TOSTRLEN_FUNCTION_,T,_,name)
|
||||||
|
|
||||||
#define DEFINE_COPY_FUNCTION(T,name) static inline void COPY_FUNCTION(T,name)(T *dst, T *src)
|
#define DEFINE_COPY_FUNCTION(T,name) static inline void COPY_FUNCTION(T,name)(T *dst, T *src)
|
||||||
#define DEFINE_DEFAULT_COPY_FUNCTION(T) \
|
#define DEFINE_DEFAULT_COPY_FUNCTION(T) \
|
||||||
@@ -94,7 +94,7 @@ typedef struct {
|
|||||||
EV_WARNING_POP(); \
|
EV_WARNING_POP(); \
|
||||||
EV_UNUSED static T EV_OVERRIDE_VAR(T)
|
EV_UNUSED static T EV_OVERRIDE_VAR(T)
|
||||||
|
|
||||||
#define __EV_STRUCT_METHOD_DEF(T, ...) EV_CAT(EV_CAT(__EV_,EV_HEAD __VA_ARGS__),_FN)(T, EV_TAIL __VA_ARGS__)
|
#define __EV_STRUCT_METHOD_DEF(T, ...) EV_CATN(__EV_,EV_HEAD __VA_ARGS__,_FN)(T, EV_TAIL __VA_ARGS__)
|
||||||
|
|
||||||
#define COPY(...) (COPY , __VA_ARGS__)
|
#define COPY(...) (COPY , __VA_ARGS__)
|
||||||
#define FREE(...) (FREE , __VA_ARGS__)
|
#define FREE(...) (FREE , __VA_ARGS__)
|
||||||
|
|||||||
162
ev_vec.h
162
ev_vec.h
@@ -6,10 +6,6 @@
|
|||||||
#include "ev_types.h"
|
#include "ev_types.h"
|
||||||
#include "ev_numeric.h"
|
#include "ev_numeric.h"
|
||||||
|
|
||||||
#if !EV_OS_WINDOWS
|
|
||||||
#include <string.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(EV_VEC_SHARED)
|
#if defined(EV_VEC_SHARED)
|
||||||
# if defined (EV_VEC_IMPL)
|
# if defined (EV_VEC_IMPL)
|
||||||
# define EV_VEC_API EV_EXPORT
|
# define EV_VEC_API EV_EXPORT
|
||||||
@@ -103,12 +99,8 @@ TYPEDATA_GEN(ev_vec_overrides_t);
|
|||||||
*/
|
*/
|
||||||
#define ev_svec(T) T*
|
#define ev_svec(T) T*
|
||||||
|
|
||||||
#define EV_VEC_MAGIC (0x65765F7665635F74)
|
|
||||||
|
|
||||||
//! Metadata that is stored with a vector. Unique to each vector.
|
//! Metadata that is stored with a vector. Unique to each vector.
|
||||||
struct ev_vec_meta_t {
|
struct ev_vec_meta_t {
|
||||||
u64 _magic;
|
|
||||||
|
|
||||||
//! The number of elements in the vector.
|
//! The number of elements in the vector.
|
||||||
u64 length;
|
u64 length;
|
||||||
//! The maximum length of the vector before it needs to be resized.
|
//! The maximum length of the vector before it needs to be resized.
|
||||||
@@ -148,19 +140,15 @@ ev_vec_init_impl(
|
|||||||
|
|
||||||
static struct ev_vec_meta_t *__svec_interm_md;
|
static struct ev_vec_meta_t *__svec_interm_md;
|
||||||
#define __ev_svec_init_impl(T, len, cap, ...) ( \
|
#define __ev_svec_init_impl(T, len, cap, ...) ( \
|
||||||
EV_WARNING_PUSH() \
|
__svec_interm_md = (u8[sizeof(T)*cap + sizeof(struct ev_vec_meta_t)]){}, \
|
||||||
EV_WARNING_DISABLE_CLANG("unsequenced") \
|
|
||||||
__svec_interm_md = (void*)(u8[sizeof(T)*cap + sizeof(struct ev_vec_meta_t)]){}, \
|
|
||||||
*__svec_interm_md = (struct ev_vec_meta_t){ \
|
*__svec_interm_md = (struct ev_vec_meta_t){ \
|
||||||
._magic = EV_VEC_MAGIC, \
|
|
||||||
.length = len, \
|
.length = len, \
|
||||||
.capacity = cap, \
|
.capacity = cap, \
|
||||||
.typeData = TypeData(T), \
|
.typeData = TypeData(T), \
|
||||||
.allocationType = EV_VEC_ALLOCATION_TYPE_STACK, \
|
.allocationType = EV_VEC_ALLOCATION_TYPE_STACK, \
|
||||||
}, \
|
}, \
|
||||||
EV_VA_OPT(__VA_ARGS__)(memcpy(&__svec_interm_md[1], (T[])__VA_ARGS__, sizeof((T[])__VA_ARGS__)),) \
|
EV_VA_OPT(__VA_ARGS__)(memcpy(&__svec_interm_md[1], (T[])__VA_ARGS__, sizeof((T[])__VA_ARGS__)),) \
|
||||||
(void*)&(__svec_interm_md[1]) \
|
&(__svec_interm_md[1]) \
|
||||||
EV_WARNING_POP() \
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -181,46 +169,46 @@ static struct ev_vec_meta_t *__svec_interm_md;
|
|||||||
#define __ev_vec_internal_push(v, var) ev_vec_push_impl((ev_vec_t*)v, var);
|
#define __ev_vec_internal_push(v, var) ev_vec_push_impl((ev_vec_t*)v, var);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \param vec_p A pointer to the vector that we want an iterator for
|
* \param v A pointer to the vector that we want an iterator for
|
||||||
*
|
*
|
||||||
* \returns A pointer to the first element in a vector
|
* \returns A pointer to the first element in a vector
|
||||||
*/
|
*/
|
||||||
EV_VEC_API void *
|
EV_VEC_API void *
|
||||||
ev_vec_iter_begin(
|
ev_vec_iter_begin(
|
||||||
const void* vec_p);
|
const ev_vec_t* v);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \param vec_p A pointer to the vector that we want an iterator for
|
* \param v A pointer to the vector that we want an iterator for
|
||||||
*
|
*
|
||||||
* \returns A pointer to the memory block right after the last element in the vector
|
* \returns A pointer to the memory block right after the last element in the vector
|
||||||
*/
|
*/
|
||||||
EV_VEC_API void *
|
EV_VEC_API void *
|
||||||
ev_vec_iter_end(
|
ev_vec_iter_end(
|
||||||
const void* vec_p);
|
const ev_vec_t* v);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief A function that increments an iterator to make it point to the next
|
* \brief A function that increments an iterator to make it point to the next
|
||||||
* element in the vector
|
* element in the vector
|
||||||
*
|
*
|
||||||
* \param vec_p A pointer to the vector that is being iterated over
|
* \param v A pointer to the vector that is being iterated over
|
||||||
* \param iter Reference to the iterator that is being incremented
|
* \param iter Reference to the iterator that is being incremented
|
||||||
*/
|
*/
|
||||||
EV_VEC_API void
|
EV_VEC_API void
|
||||||
ev_vec_iter_next(
|
ev_vec_iter_next(
|
||||||
const void* vec_p,
|
const ev_vec_t* v,
|
||||||
void **iter);
|
void **iter);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief A function that looks for the index of `val` in `v`
|
* \brief A function that looks for the index of `val` in `v`
|
||||||
*
|
*
|
||||||
* \param vec_p A pointer to the vector that is being iterated over
|
* \param v A pointer to the vector that is being iterated over
|
||||||
* \param val A pointer to the object that will be compared with vector elements
|
* \param val A pointer to the object that will be compared with vector elements
|
||||||
*
|
*
|
||||||
* \returns If found, index of element in vector. Otherwise, -1.
|
* \returns If found, index of element in vector. Otherwise, -1.
|
||||||
*/
|
*/
|
||||||
EV_VEC_API i32
|
EV_VEC_API i32
|
||||||
ev_vec_find(
|
ev_vec_find(
|
||||||
const void* vec_p,
|
const ev_vec_t* v,
|
||||||
void* val);
|
void* val);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -231,11 +219,11 @@ ev_vec_find(
|
|||||||
* *Note*: For stack-allocated vectors (`svec`), destructors are called for
|
* *Note*: For stack-allocated vectors (`svec`), destructors are called for
|
||||||
* elements but no memory is freed.
|
* elements but no memory is freed.
|
||||||
*
|
*
|
||||||
* \param vec_p A pointer to the vector that is being destroyed
|
* \param v A pointer to the vector that is being destroyed
|
||||||
*/
|
*/
|
||||||
EV_VEC_API void
|
EV_VEC_API void
|
||||||
ev_vec_fini(
|
ev_vec_fini(
|
||||||
void* vec_p);
|
ev_vec_t* v);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief A function that copies a value to the end of a vector. If the element
|
* \brief A function that copies a value to the end of a vector. If the element
|
||||||
@@ -247,7 +235,7 @@ ev_vec_fini(
|
|||||||
* For `svec`, as long as the capacity is more than the current size, a push
|
* For `svec`, as long as the capacity is more than the current size, a push
|
||||||
* operation is permitted. Otherwise, the operation is treated as an OOM.
|
* operation is permitted. Otherwise, the operation is treated as an OOM.
|
||||||
*
|
*
|
||||||
* \param vec_p Reference to the vector object
|
* \param v Reference to the vector object
|
||||||
* \param val A pointer to the element that is to be copied to the end of the
|
* \param val A pointer to the element that is to be copied to the end of the
|
||||||
* vector
|
* vector
|
||||||
*
|
*
|
||||||
@@ -256,7 +244,7 @@ ev_vec_fini(
|
|||||||
*/
|
*/
|
||||||
EV_VEC_API int
|
EV_VEC_API int
|
||||||
ev_vec_push_impl(
|
ev_vec_push_impl(
|
||||||
void* vec_p,
|
ev_vec_t *v,
|
||||||
void *val);
|
void *val);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -272,7 +260,7 @@ ev_vec_push_impl(
|
|||||||
* operation. If a deep copy is needed, individually pushing the elements of
|
* operation. If a deep copy is needed, individually pushing the elements of
|
||||||
* the array is the way to go.
|
* the array is the way to go.
|
||||||
*
|
*
|
||||||
* \param vec_p Reference to the vector object
|
* \param v Reference to the vector object
|
||||||
* \param arr A pointer to the array that is to be copied to the end of the
|
* \param arr A pointer to the array that is to be copied to the end of the
|
||||||
* vector
|
* vector
|
||||||
* \param size Number of elements in the array
|
* \param size Number of elements in the array
|
||||||
@@ -282,28 +270,17 @@ ev_vec_push_impl(
|
|||||||
*/
|
*/
|
||||||
EV_VEC_API u32
|
EV_VEC_API u32
|
||||||
ev_vec_append(
|
ev_vec_append(
|
||||||
void* vec_p,
|
ev_vec_t *v,
|
||||||
void **arr,
|
void **arr,
|
||||||
u64 size);
|
u64 size);
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief A function that duplicates the passed vector into a new one and returns it.
|
|
||||||
*
|
|
||||||
* \param vec_p Reference to the vector object
|
|
||||||
*
|
|
||||||
* \returns The newly created vector.
|
|
||||||
*/
|
|
||||||
EV_VEC_API ev_vec_t
|
|
||||||
ev_vec_dup(
|
|
||||||
const void* vec_p);
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief A function that copies the value at the end of a vector and removes
|
* \brief A function that copies the value at the end of a vector and removes
|
||||||
* it from the vector. If a copy function was passed while initializing the
|
* it from the vector. If a copy function was passed while initializing the
|
||||||
* vector, then this function is used. Otherwise, memcpy is used with a length
|
* vector, then this function is used. Otherwise, memcpy is used with a length
|
||||||
* of `vec_meta.elemsize`
|
* of `vec_meta.elemsize`
|
||||||
*
|
*
|
||||||
* \param vec_p Reference to the vector object
|
* \param v Reference to the vector object
|
||||||
* \param out A pointer to the memory block at which the popped element will be
|
* \param out A pointer to the memory block at which the popped element will be
|
||||||
* copied. If NULL is passed, then the element is destructed. Otherwise, the
|
* copied. If NULL is passed, then the element is destructed. Otherwise, the
|
||||||
* element is copied to `out` and the receiving code is responsible for its
|
* element is copied to `out` and the receiving code is responsible for its
|
||||||
@@ -314,54 +291,54 @@ ev_vec_dup(
|
|||||||
*/
|
*/
|
||||||
EV_VEC_API ev_vec_error_t
|
EV_VEC_API ev_vec_error_t
|
||||||
ev_vec_pop(
|
ev_vec_pop(
|
||||||
void* vec_p,
|
ev_vec_t *v,
|
||||||
void *out);
|
void *out);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief A function that returns the last element in the vector.
|
* \brief A function that returns the last element in the vector.
|
||||||
*
|
*
|
||||||
* \param vec_p A pointer to the vector object
|
* \param v A pointer to the vector object
|
||||||
*
|
*
|
||||||
* \returns Pointer to the last element in the vector. NULL if the vector is
|
* \returns Pointer to the last element in the vector. NULL if the vector is
|
||||||
* empty.
|
* empty.
|
||||||
*/
|
*/
|
||||||
EV_VEC_API void *
|
EV_VEC_API void *
|
||||||
ev_vec_last(
|
ev_vec_last(
|
||||||
const void* v);
|
const ev_vec_t* v);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief A function that returns the length of a vector
|
* \brief A function that returns the length of a vector
|
||||||
*
|
*
|
||||||
* \param vec_p A pointer to the vector object
|
* \param v A pointer to the vector object
|
||||||
*
|
*
|
||||||
* \returns Current length of the vector
|
* \returns Current length of the vector
|
||||||
*/
|
*/
|
||||||
EV_VEC_API u64
|
EV_VEC_API u64
|
||||||
ev_vec_len(
|
ev_vec_len(
|
||||||
void* vec_p);
|
const ev_vec_t* v);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief A function that returns the capacity of a vector
|
* \brief A function that returns the capacity of a vector
|
||||||
*
|
*
|
||||||
* \param vec_p A pointer to the vector object
|
* \param v A pointer to the vector object
|
||||||
*
|
*
|
||||||
* \returns Current capacity of the vector
|
* \returns Current capacity of the vector
|
||||||
*/
|
*/
|
||||||
EV_VEC_API u64
|
EV_VEC_API u64
|
||||||
ev_vec_capacity(
|
ev_vec_capacity(
|
||||||
const void* vec_p);
|
const ev_vec_t* v);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Calls the free operation (if exists) on every element, then sets
|
* \brief Calls the free operation (if exists) on every element, then sets
|
||||||
* the length to 0.
|
* the length to 0.
|
||||||
*
|
*
|
||||||
* \param vec_p A pointer to the vector object
|
* \param v A pointer to the vector object
|
||||||
*
|
*
|
||||||
* \returns 0 on success
|
* \returns 0 on success
|
||||||
*/
|
*/
|
||||||
EV_VEC_API u32
|
EV_VEC_API u32
|
||||||
ev_vec_clear(
|
ev_vec_clear(
|
||||||
const void* vec_p);
|
const ev_vec_t* v);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Sets the length of the vector to `len`.
|
* \brief Sets the length of the vector to `len`.
|
||||||
@@ -373,20 +350,20 @@ ev_vec_clear(
|
|||||||
* For `svec`, if the `len` is more than the already allocated capacity, it is
|
* For `svec`, if the `len` is more than the already allocated capacity, it is
|
||||||
* treated as an OOM.
|
* treated as an OOM.
|
||||||
*
|
*
|
||||||
* \param vec_p Reference to the vector object
|
* \param v Reference to the vector object
|
||||||
* \param len The desired new length
|
* \param len The desired new length
|
||||||
*
|
*
|
||||||
* \returns `VEC_ERR_NONE` on success
|
* \returns `VEC_ERR_NONE` on success
|
||||||
*/
|
*/
|
||||||
EV_VEC_API ev_vec_error_t
|
EV_VEC_API ev_vec_error_t
|
||||||
ev_vec_setlen(
|
ev_vec_setlen(
|
||||||
void* vec_p,
|
ev_vec_t *v,
|
||||||
u64 len);
|
u64 len);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Sets the capacity of the vector to `cap`.
|
* \brief Sets the capacity of the vector to `cap`.
|
||||||
*
|
*
|
||||||
* \param vec_p Reference to the vector object
|
* \param v Reference to the vector object
|
||||||
* \param cap The desired new capacity
|
* \param cap The desired new capacity
|
||||||
*
|
*
|
||||||
* For stack-allocated vectors, `VEC_ERR_OOM` is returned
|
* For stack-allocated vectors, `VEC_ERR_OOM` is returned
|
||||||
@@ -395,26 +372,25 @@ ev_vec_setlen(
|
|||||||
*/
|
*/
|
||||||
EV_VEC_API ev_vec_error_t
|
EV_VEC_API ev_vec_error_t
|
||||||
ev_vec_setcapacity(
|
ev_vec_setcapacity(
|
||||||
void* vec_p,
|
ev_vec_t *v,
|
||||||
u64 cap);
|
u64 cap);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Grows the vector's capacity by a factor of `VEC_GROWTH_RATE`
|
* \brief Grows the vector's capacity by a factor of `VEC_GROWTH_RATE`
|
||||||
*
|
*
|
||||||
* \param vec_p Reference to the vector object
|
* \param Reference to the vector object
|
||||||
*
|
*
|
||||||
* \returns `VEC_ERR_NONE` on success
|
* \returns `VEC_ERR_NONE` on success
|
||||||
*/
|
*/
|
||||||
EV_VEC_API ev_vec_error_t
|
EV_VEC_API ev_vec_error_t
|
||||||
ev_vec_grow(
|
ev_vec_grow(
|
||||||
void* vec_p);
|
ev_vec_t *v);
|
||||||
|
|
||||||
static const ev_vec_t EV_VEC_EMPTY =
|
static const ev_vec_t EV_VEC_EMPTY =
|
||||||
(ev_vec(i32))&((struct {
|
(ev_vec(i32))&((struct {
|
||||||
struct ev_vec_meta_t meta;
|
struct ev_vec_meta_t meta;
|
||||||
EV_ALIGNAS(EV_ALIGNOF(i32)) i32 data[0];
|
EV_ALIGNAS(EV_ALIGNOF(i32)) i32 data[0];
|
||||||
}) {
|
}) {
|
||||||
.meta._magic = EV_VEC_MAGIC,
|
|
||||||
.meta.length = 0,
|
.meta.length = 0,
|
||||||
.meta.capacity = 0,
|
.meta.capacity = 0,
|
||||||
.meta.typeData = TypeData(i32),
|
.meta.typeData = TypeData(i32),
|
||||||
@@ -436,7 +412,6 @@ TYPEDATA_GEN(
|
|||||||
#ifdef EV_VEC_IMPLEMENTATION
|
#ifdef EV_VEC_IMPLEMENTATION
|
||||||
#undef EV_VEC_IMPLEMENTATION
|
#undef EV_VEC_IMPLEMENTATION
|
||||||
|
|
||||||
|
|
||||||
#ifdef EV_VEC_API_CHECK
|
#ifdef EV_VEC_API_CHECK
|
||||||
#define EV_VEC_CHECK(x) do { x; } while (0)
|
#define EV_VEC_CHECK(x) do { x; } while (0)
|
||||||
#else
|
#else
|
||||||
@@ -450,8 +425,7 @@ TYPEDATA_GEN(
|
|||||||
((struct ev_vec_meta_t *)v) - 1
|
((struct ev_vec_meta_t *)v) - 1
|
||||||
|
|
||||||
#define __ev_vec_getmeta(v) \
|
#define __ev_vec_getmeta(v) \
|
||||||
struct ev_vec_meta_t *metadata = ((struct ev_vec_meta_t *)(v)) - 1; \
|
struct ev_vec_meta_t *metadata = ((struct ev_vec_meta_t *)(v)) - 1;
|
||||||
assert(metadata->_magic == EV_VEC_MAGIC);
|
|
||||||
|
|
||||||
#define __ev_vec_syncmeta(v) \
|
#define __ev_vec_syncmeta(v) \
|
||||||
metadata = ((struct ev_vec_meta_t *)(v)) - 1;
|
metadata = ((struct ev_vec_meta_t *)(v)) - 1;
|
||||||
@@ -476,7 +450,6 @@ ev_vec_init_impl(
|
|||||||
|
|
||||||
struct ev_vec_meta_t *metadata = (struct ev_vec_meta_t *)v;
|
struct ev_vec_meta_t *metadata = (struct ev_vec_meta_t *)v;
|
||||||
*metadata = (struct ev_vec_meta_t){
|
*metadata = (struct ev_vec_meta_t){
|
||||||
._magic = EV_VEC_MAGIC,
|
|
||||||
.length = 0,
|
.length = 0,
|
||||||
.capacity = EV_VEC_INIT_CAP,
|
.capacity = EV_VEC_INIT_CAP,
|
||||||
.allocationType = EV_VEC_ALLOCATION_TYPE_HEAP,
|
.allocationType = EV_VEC_ALLOCATION_TYPE_HEAP,
|
||||||
@@ -488,10 +461,9 @@ ev_vec_init_impl(
|
|||||||
|
|
||||||
i32
|
i32
|
||||||
ev_vec_find(
|
ev_vec_find(
|
||||||
const void* vec_p,
|
const ev_vec_t* v,
|
||||||
void *val)
|
void *val)
|
||||||
{
|
{
|
||||||
ev_vec_t* v = (ev_vec_t*)vec_p;
|
|
||||||
__ev_vec_getmeta(*v)
|
__ev_vec_getmeta(*v)
|
||||||
if(metadata->typeData.equal_fn) {
|
if(metadata->typeData.equal_fn) {
|
||||||
for (void *elem = ev_vec_iter_begin(v); elem != ev_vec_iter_end(v); ev_vec_iter_next(v, &elem)) {
|
for (void *elem = ev_vec_iter_begin(v); elem != ev_vec_iter_end(v); ev_vec_iter_next(v, &elem)) {
|
||||||
@@ -514,9 +486,8 @@ ev_vec_find(
|
|||||||
|
|
||||||
void
|
void
|
||||||
ev_vec_fini(
|
ev_vec_fini(
|
||||||
void* vec_p)
|
ev_vec_t* v)
|
||||||
{
|
{
|
||||||
ev_vec_t* v = (ev_vec_t*)vec_p;
|
|
||||||
__ev_vec_getmeta(*v)
|
__ev_vec_getmeta(*v)
|
||||||
|
|
||||||
if (metadata->typeData.free_fn) {
|
if (metadata->typeData.free_fn) {
|
||||||
@@ -534,10 +505,9 @@ ev_vec_fini(
|
|||||||
|
|
||||||
int
|
int
|
||||||
ev_vec_push_impl(
|
ev_vec_push_impl(
|
||||||
void* vec_p,
|
ev_vec_t *v,
|
||||||
void *val)
|
void *val)
|
||||||
{
|
{
|
||||||
ev_vec_t* v = (ev_vec_t*)vec_p;
|
|
||||||
__ev_vec_getmeta(*v)
|
__ev_vec_getmeta(*v)
|
||||||
|
|
||||||
if (metadata->length == metadata->capacity) {
|
if (metadata->length == metadata->capacity) {
|
||||||
@@ -561,16 +531,15 @@ ev_vec_push_impl(
|
|||||||
|
|
||||||
void *
|
void *
|
||||||
ev_vec_iter_begin(
|
ev_vec_iter_begin(
|
||||||
const void* vec_p)
|
const ev_vec_t* v)
|
||||||
{
|
{
|
||||||
return *(void**)vec_p;
|
return *v;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
ev_vec_iter_end(
|
ev_vec_iter_end(
|
||||||
const void* vec_p)
|
const ev_vec_t* v)
|
||||||
{
|
{
|
||||||
ev_vec_t* v = (ev_vec_t*)vec_p;
|
|
||||||
__ev_vec_getmeta(*v)
|
__ev_vec_getmeta(*v)
|
||||||
|
|
||||||
return ((char *)*v) + (metadata->typeData.size * metadata->length);
|
return ((char *)*v) + (metadata->typeData.size * metadata->length);
|
||||||
@@ -578,21 +547,19 @@ ev_vec_iter_end(
|
|||||||
|
|
||||||
void
|
void
|
||||||
ev_vec_iter_next(
|
ev_vec_iter_next(
|
||||||
const void* vec_p,
|
const ev_vec_t* v,
|
||||||
void **iter)
|
void **iter)
|
||||||
{
|
{
|
||||||
ev_vec_t* v = (ev_vec_t*)vec_p;
|
|
||||||
__ev_vec_getmeta(*v)
|
__ev_vec_getmeta(*v)
|
||||||
*iter = ((char*)*iter) + metadata->typeData.size;
|
*iter = ((char*)*iter) + metadata->typeData.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
EV_VEC_API u32
|
EV_VEC_API u32
|
||||||
ev_vec_append(
|
ev_vec_append(
|
||||||
void* vec_p,
|
ev_vec_t *v,
|
||||||
void **arr,
|
void **arr,
|
||||||
u64 size)
|
u64 size)
|
||||||
{
|
{
|
||||||
ev_vec_t* v = (ev_vec_t*)vec_p;
|
|
||||||
__ev_vec_getmeta(*v)
|
__ev_vec_getmeta(*v)
|
||||||
size_t old_len = metadata->length;
|
size_t old_len = metadata->length;
|
||||||
size_t req_len = old_len + size;
|
size_t req_len = old_len + size;
|
||||||
@@ -609,35 +576,11 @@ ev_vec_append(
|
|||||||
return (int)old_len;
|
return (int)old_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
EV_VEC_API ev_vec_t
|
|
||||||
ev_vec_dup(
|
|
||||||
const void* vec_p)
|
|
||||||
{
|
|
||||||
ev_vec_t v_orig = *(ev_vec_t*)vec_p;
|
|
||||||
__ev_vec_getmeta(v_orig)
|
|
||||||
ev_vec_t v_new = ev_vec_init_impl(metadata->typeData, (ev_vec_overrides_t){0});
|
|
||||||
ev_vec_setcapacity(&v_new, metadata->length);
|
|
||||||
|
|
||||||
if(metadata->typeData.copy_fn)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < metadata->length; i++)
|
|
||||||
ev_vec_push_impl(&v_new, (u8*)v_orig + (metadata->typeData.size * i));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ev_vec_setlen(&v_new, metadata->length);
|
|
||||||
memcpy(v_new, v_orig, metadata->length * metadata->typeData.size);
|
|
||||||
}
|
|
||||||
|
|
||||||
return v_new;
|
|
||||||
}
|
|
||||||
|
|
||||||
ev_vec_error_t
|
ev_vec_error_t
|
||||||
ev_vec_pop(
|
ev_vec_pop(
|
||||||
void* vec_p,
|
ev_vec_t *v,
|
||||||
void *out)
|
void *out)
|
||||||
{
|
{
|
||||||
ev_vec_t* v = (ev_vec_t*)vec_p;
|
|
||||||
__ev_vec_getmeta(*v)
|
__ev_vec_getmeta(*v)
|
||||||
|
|
||||||
if(out != NULL) {
|
if(out != NULL) {
|
||||||
@@ -661,9 +604,8 @@ ev_vec_pop(
|
|||||||
|
|
||||||
void *
|
void *
|
||||||
ev_vec_last(
|
ev_vec_last(
|
||||||
const void* vec_p)
|
const ev_vec_t* v)
|
||||||
{
|
{
|
||||||
ev_vec_t* v = (ev_vec_t*)vec_p;
|
|
||||||
__ev_vec_getmeta(*v)
|
__ev_vec_getmeta(*v)
|
||||||
|
|
||||||
if(metadata->length == 0) {
|
if(metadata->length == 0) {
|
||||||
@@ -675,27 +617,24 @@ ev_vec_last(
|
|||||||
|
|
||||||
u64
|
u64
|
||||||
ev_vec_len(
|
ev_vec_len(
|
||||||
void* vec_p)
|
const ev_vec_t* v)
|
||||||
{
|
{
|
||||||
ev_vec_t* v = (ev_vec_t*)vec_p;
|
|
||||||
__ev_vec_getmeta(*v)
|
__ev_vec_getmeta(*v)
|
||||||
return metadata->length;
|
return metadata->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64
|
u64
|
||||||
ev_vec_capacity(
|
ev_vec_capacity(
|
||||||
const void* vec_p)
|
const ev_vec_t* v)
|
||||||
{
|
{
|
||||||
ev_vec_t* v = (ev_vec_t*)vec_p;
|
|
||||||
__ev_vec_getmeta(*v)
|
__ev_vec_getmeta(*v)
|
||||||
return metadata->capacity;
|
return metadata->capacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32
|
u32
|
||||||
ev_vec_clear(
|
ev_vec_clear(
|
||||||
const void* vec_p)
|
const ev_vec_t* v)
|
||||||
{
|
{
|
||||||
ev_vec_t* v = (ev_vec_t*)vec_p;
|
|
||||||
__ev_vec_getmeta(*v)
|
__ev_vec_getmeta(*v)
|
||||||
|
|
||||||
if (metadata->typeData.free_fn) {
|
if (metadata->typeData.free_fn) {
|
||||||
@@ -711,10 +650,9 @@ ev_vec_clear(
|
|||||||
|
|
||||||
ev_vec_error_t
|
ev_vec_error_t
|
||||||
ev_vec_setlen(
|
ev_vec_setlen(
|
||||||
void* vec_p,
|
ev_vec_t *v,
|
||||||
u64 len)
|
u64 len)
|
||||||
{
|
{
|
||||||
ev_vec_t* v = (ev_vec_t*)vec_p;
|
|
||||||
__ev_vec_getmeta(*v)
|
__ev_vec_getmeta(*v)
|
||||||
|
|
||||||
while(len > metadata->capacity) {
|
while(len > metadata->capacity) {
|
||||||
@@ -731,10 +669,9 @@ ev_vec_setlen(
|
|||||||
|
|
||||||
ev_vec_error_t
|
ev_vec_error_t
|
||||||
ev_vec_setcapacity(
|
ev_vec_setcapacity(
|
||||||
void* vec_p,
|
ev_vec_t *v,
|
||||||
u64 cap)
|
u64 cap)
|
||||||
{
|
{
|
||||||
ev_vec_t* v = (ev_vec_t*)vec_p;
|
|
||||||
__ev_vec_getmeta(*v)
|
__ev_vec_getmeta(*v)
|
||||||
|
|
||||||
if(metadata->allocationType == EV_VEC_ALLOCATION_TYPE_STACK) {
|
if(metadata->allocationType == EV_VEC_ALLOCATION_TYPE_STACK) {
|
||||||
@@ -764,9 +701,8 @@ ev_vec_setcapacity(
|
|||||||
|
|
||||||
ev_vec_error_t
|
ev_vec_error_t
|
||||||
ev_vec_grow(
|
ev_vec_grow(
|
||||||
void* vec_p)
|
ev_vec_t *v)
|
||||||
{
|
{
|
||||||
ev_vec_t* v = (ev_vec_t*)vec_p;
|
|
||||||
__ev_vec_getmeta(*v)
|
__ev_vec_getmeta(*v)
|
||||||
return ev_vec_setcapacity(v, metadata->capacity * EV_VEC_GROWTH_RATE);
|
return ev_vec_setcapacity(v, metadata->capacity * EV_VEC_GROWTH_RATE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
#define EV_LOG_IMPLEMENTATION
|
|
||||||
#include "ev_log.h"
|
|
||||||
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
ev_log_trace("Trace Log");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
22
map_test.c
Normal file
22
map_test.c
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define EV_MAP_IMPLEMENTATION
|
||||||
|
#include "ev_map.h"
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int x = 10;
|
||||||
|
int y = 100;
|
||||||
|
int x2 = 300;
|
||||||
|
int y2 = 123;
|
||||||
|
|
||||||
|
ev_map(i32, i32)* m = ev_map_init(i32, i32);
|
||||||
|
ev_map_add(m, (&x, &y), (&x2, &y2));
|
||||||
|
|
||||||
|
i32 out;
|
||||||
|
ev_map_get(m, &x, &out);
|
||||||
|
|
||||||
|
ev_map_fini(m);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
4
meson-native-clang
Normal file
4
meson-native-clang
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
[binaries]
|
||||||
|
c = 'clang.exe'
|
||||||
|
c_ld = 'lld'
|
||||||
|
cpp = 'clang++.exe'
|
||||||
@@ -24,32 +24,26 @@ endif
|
|||||||
str_lib = static_library('ev_str', files('buildfiles/ev_str.c'), c_args: evh_c_args)
|
str_lib = static_library('ev_str', files('buildfiles/ev_str.c'), c_args: evh_c_args)
|
||||||
vec_lib = static_library('ev_vec', files('buildfiles/ev_vec.c'), c_args: evh_c_args)
|
vec_lib = static_library('ev_vec', files('buildfiles/ev_vec.c'), c_args: evh_c_args)
|
||||||
helpers_lib = static_library('ev_helpers', files('buildfiles/ev_helpers.c'), c_args: evh_c_args)
|
helpers_lib = static_library('ev_helpers', files('buildfiles/ev_helpers.c'), c_args: evh_c_args)
|
||||||
log_lib = static_library('ev_log', files('buildfiles/ev_log.c'), c_args: evh_c_args)
|
|
||||||
|
|
||||||
str_dep = declare_dependency(link_with: str_lib, include_directories: headers_include)
|
str_dep = declare_dependency(link_with: str_lib, include_directories: headers_include)
|
||||||
vec_dep = declare_dependency(link_with: vec_lib, include_directories: headers_include)
|
vec_dep = declare_dependency(link_with: vec_lib, include_directories: headers_include)
|
||||||
helpers_dep = declare_dependency(link_with: helpers_lib, include_directories: headers_include)
|
helpers_dep = declare_dependency(link_with: helpers_lib, include_directories: headers_include)
|
||||||
log_dep = declare_dependency(link_with: log_lib, include_directories: headers_include)
|
|
||||||
|
|
||||||
headers_dep = declare_dependency(
|
headers_dep = declare_dependency(
|
||||||
dependencies: [
|
dependencies: [
|
||||||
str_dep,
|
str_dep,
|
||||||
vec_dep,
|
vec_dep,
|
||||||
helpers_dep,
|
helpers_dep,
|
||||||
log_dep
|
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
# Tests
|
# Tests
|
||||||
str_test = executable('str_test', 'str_test.c', dependencies: [str_dep], c_args: evh_c_args)
|
str_test = executable('str_test', 'str_test.c', dependencies: [str_dep], c_args: evh_c_args)
|
||||||
test('evstr', str_test)
|
test('evstr', str_test)
|
||||||
log_test = executable('log_test', 'log_test.c', dependencies: [log_dep], c_args: evh_c_args)
|
|
||||||
test('evlog', log_test)
|
|
||||||
|
|
||||||
if meson.version().version_compare('>= 0.54.0')
|
if meson.version().version_compare('>= 0.54.0')
|
||||||
meson.override_dependency('ev_vec', vec_dep)
|
meson.override_dependency('ev_vec', vec_dep)
|
||||||
meson.override_dependency('ev_str', str_dep)
|
meson.override_dependency('ev_str', str_dep)
|
||||||
meson.override_dependency('ev_helpers', helpers_dep)
|
meson.override_dependency('ev_helpers', helpers_dep)
|
||||||
meson.override_dependency('ev_log', log_dep)
|
|
||||||
meson.override_dependency('evol-headers', headers_dep)
|
meson.override_dependency('evol-headers', headers_dep)
|
||||||
endif
|
endif
|
||||||
|
|||||||
Reference in New Issue
Block a user