-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdynamic.h
More file actions
96 lines (76 loc) · 3.09 KB
/
dynamic.h
File metadata and controls
96 lines (76 loc) · 3.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#ifndef DYNAMIC_H_INCLUDED
#define DYNAMIC_H_INCLUDED
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
void* ptr;
long size;
} buff_t;
#define template_buff_ptr_size(func, obj, ptr, size) func(obj, ((buff_t){(void*)ptr, size}))
#define template_buff_ptr(func, obj, ptr) template_buff_ptr_size(func, obj, ptr, sizeof(*ptr))
#define template_buff_var(func, obj, var) template_buff_ptr_size(func, obj, &var, sizeof(var))
#define template_buff_type_val(func, obj, type, val) template_buff_ptr_size(func, obj, &(type){val}, sizeof(type))
static buff_t impl_buff_push_buff_impl(buff_t dest, buff_t src)
{
buff_t buff = {0};
buff.size = dest.size + src.size;
buff.ptr = realloc(dest.ptr, buff.size);
memcpy(buff.ptr + dest.size, src.ptr, src.size);
return buff;
}
///begin user interface
#define buff_push_buff(dest, src) dest = impl_buff_push_buff_impl(dest, src)
#define buff_push_ptr_size(dest, ptr, size) template_buff_ptr_size(buff_push_buff, dest, ptr, size)
#define buff_push_ptr(dest, ptr) template_buff_ptr(buff_push_buff, dest, ptr)
#define buff_push_var(dest, var) template_buff_var(buff_push_buff, dest, var)
#define buff_push_type_val(dest, type, val) template_buff_type_val(buff_push_buff, dest, type, val)
///end user interface
typedef struct
{
buff_t buff;
long head;
long tail;
} queue_t;
static void impl_queue_push_buff_impl(queue_t* dest, buff_t src)
{
const long old_tail = dest->tail;
const long new_index = old_tail + src.size;
const long new_index_wrapped = (new_index < dest->buff.size) ? new_index : 0;
if(new_index_wrapped != dest->head)
{
memcpy(dest->buff.ptr + old_tail, src.ptr, src.size);
dest->tail = new_index_wrapped;
}
else
{
buff_push_buff(dest->buff, src);
dest->head = new_index;
}
}
static bool impl_queue_pop_buff_impl(queue_t* src, buff_t dest)
{
const long old_head = src->head;
const bool retval = (old_head != src->tail);
if(retval)
{
const long new_index = old_head + dest.size;
const long new_index_wrapped = (new_index < src->buff.size) ? new_index : 0;
memcpy(dest.ptr, src->buff.ptr + old_head, dest.size);
src->head = new_index_wrapped;
}
return retval;
}
///begin user interface
#define queue_push_buff(dest, src) impl_queue_push_buff_impl(&dest, src)
#define queue_push_ptr_size(dest, ptr, size) template_buff_ptr_size(queue_push_buff, dest, ptr, size)
#define queue_push_ptr(dest, ptr) template_buff_ptr(queue_push_buff, dest, ptr)
#define queue_push_var(dest, var) template_buff_var(queue_push_buff, dest, var)
#define queue_push_type_val(dest, type, val) template_buff_type_val(queue_push_buff, dest, type, val)
#define queue_pop_buff(src, dest) impl_queue_pop_buff_impl(&src, dest)
#define queue_pop_ptr_size(src, ptr, size) template_buff_ptr_size(queue_pop_buff, src, ptr, size)
#define queue_pop_ptr(src, ptr) template_buff_ptr(queue_pop_buff, src, ptr)
#define queue_pop_var(src, var) template_buff_var(queue_pop_buff, src, var)
///end user interface
#endif // DYNAMIC_H_INCLUDED