Derive-C
Loading...
Searching...
No Matches
template.h File Reference

Go to the source code of this file.

Data Structures

struct  TRACKED_ENTRY
struct  SELF
 An allocator that prints to stdout when it allocates or frees memory. More...

Macros

#define ENTRIES_VECTOR   NS(NAME, entries)
 For unit tests expected to throw, as C has no unwind, we cannot free allocated memory. This macro wraps the allocator in debug, to allow clearing leaks after an exception.
#define TRACKED_ENTRY   NS(EXPAND(ENTRIES), entry)
#define ITEM   TRACKED_ENTRY
#define ALLOC   stdalloc
#define INTERNAL_NAME   ENTRIES_VECTOR

Functions

static SELF new (ALLOC *alloc)
static ENTRIES_VECTOR const * get_entries (SELF const *self)
static void unleak_and_delete (SELF *self)
static void * calloc (SELF *self, size_t count, size_t size)
static void * malloc (SELF *self, size_t size)
static void * realloc (SELF *self, void *ptr, size_t size)
static void free (SELF *self, void *ptr)
static void debug (SELF const *self, dc_debug_fmt fmt, FILE *stream)
 DC_TRAIT_ALLOC (SELF)

Macro Definition Documentation

◆ ALLOC

#define ALLOC   stdalloc

Definition at line 64 of file template.h.

◆ ENTRIES_VECTOR

#define ENTRIES_VECTOR   NS(NAME, entries)

For unit tests expected to throw, as C has no unwind, we cannot free allocated memory. This macro wraps the allocator in debug, to allow clearing leaks after an exception.

In release, it is a no-op / pass through.

As this is entirely C, we do not get the niceties of a C++ RAII allocator guard shebang. However, this is usable inside unit tests written in C.

Definition at line 48 of file template.h.

◆ INTERNAL_NAME

#define INTERNAL_NAME   ENTRIES_VECTOR

Definition at line 65 of file template.h.

◆ ITEM

#define ITEM   TRACKED_ENTRY

Definition at line 63 of file template.h.

◆ TRACKED_ENTRY

#define TRACKED_ENTRY   NS(EXPAND(ENTRIES), entry)

Definition at line 49 of file template.h.

Function Documentation

◆ calloc()

void * calloc ( SELF * self,
size_t count,
size_t size )
static

Definition at line 97 of file template.h.

97 {
98 DC_ASSUME(self);
99 void* ptr = NS(ALLOC, calloc)(self->alloc, count, size);
100 if (ptr) {
102 .ptr = ptr,
103 .freed = false,
104 });
105 }
106 return ptr;
107}
static void * calloc(SELF *self, size_t count, size_t size)
Definition template.h:34
#define ALLOC
Definition template.h:64
#define TRACKED_ENTRY
Definition template.h:49
#define ENTRIES_VECTOR
For unit tests expected to throw, as C has no unwind, we cannot free allocated memory....
Definition template.h:48
static INDEX_TYPE size(SELF const *self)
Definition template.h:252
static ITEM * push(SELF *self, ITEM item)
Definition template.h:216
#define NS(pre, post)
Definition namespace.h:4
#define DC_ASSUME(expr,...)
Definition panic.h:56
ENTRIES_VECTOR entries
Definition template.h:72
ALLOC * alloc
Definition template.h:71

◆ DC_TRAIT_ALLOC()

DC_TRAIT_ALLOC ( SELF )

◆ debug()

void debug ( SELF const * self,
dc_debug_fmt fmt,
FILE * stream )
static

Definition at line 145 of file template.h.

145 {
146 fprintf(stream, STRINGIFY(SELF) " @%p {", self);
147 fmt = dc_debug_fmt_scope_begin(fmt);
148 dc_debug_fmt_print(fmt, stream, "base: " STRINGIFY(ALLOC) "@%p,\n", self->alloc);
149 NS(ENTRIES_VECTOR, debug)(&self->entries, fmt, stream);
150 fmt = dc_debug_fmt_scope_end(fmt);
151 dc_debug_fmt_print(fmt, stream, "}");
152}
static void debug(SELF const *self, dc_debug_fmt fmt, FILE *stream)
Definition template.h:62
dc_debug_fmt dc_debug_fmt_scope_end(dc_debug_fmt fmt)
Definition fmt.h:39
dc_debug_fmt dc_debug_fmt_scope_begin(dc_debug_fmt fmt)
Definition fmt.h:33
static void dc_debug_fmt_print(dc_debug_fmt fmt, FILE *stream, const char *format,...)
Definition fmt.h:22
#define STRINGIFY(MACRO)
Definition namespace.h:7
#define SELF
Definition def.h:52
static FILE * stream(SELF *self)
Opens a file for.
Definition template.h:107

◆ free()

void free ( SELF * self,
void * ptr )
static

Definition at line 127 of file template.h.

127 {
128 DC_ASSUME(ptr);
129 DC_ASSUME(self);
130
131 NS(ENTRIES_VECTOR, iter) iter = NS(ENTRIES_VECTOR, get_iter)(&self->entries);
132 TRACKED_ENTRY* entry;
133
134 while ((entry = NS(ENTRIES_VECTOR, iter_next)(&iter))) {
135 if (entry->ptr == ptr) {
136 DC_ASSUME(!entry->freed);
137 entry->freed = true;
138 break;
139 }
140 }
141
142 NS(ALLOC, free)(self->alloc, ptr);
143}
static void free(SELF *self, void *ptr)
Definition template.h:56
static ITER get_iter(SELF *self)
Definition template.h:370
bool freed
Definition template.h:53
void * ptr
Definition template.h:52

◆ get_entries()

ENTRIES_VECTOR const * get_entries ( SELF const * self)
static

Definition at line 79 of file template.h.

79 {
80 DC_ASSUME(self);
81 return &self->entries;
82}

◆ malloc()

void * malloc ( SELF * self,
size_t size )
static

Definition at line 109 of file template.h.

109 {
110 DC_ASSUME(self);
111 void* ptr = NS(ALLOC, malloc)(self->alloc, size);
112 if (ptr) {
114 .ptr = ptr,
115 .freed = false,
116 });
117 }
118 return ptr;
119}
static void * malloc(SELF *self, size_t size)
Definition template.h:23

◆ new()

SELF new ( ALLOC * alloc)
static

Definition at line 75 of file template.h.

75 {
76 return (SELF){.alloc = alloc, .entries = NS(ENTRIES_VECTOR, new)(stdalloc_get())};
77}

◆ realloc()

void * realloc ( SELF * self,
void * ptr,
size_t size )
static

Definition at line 121 of file template.h.

121 {
122 DC_ASSUME(self);
123 DC_ASSUME(ptr);
124 return NS(ALLOC, realloc)(self->alloc, ptr, size);
125}
static void * realloc(SELF *self, void *ptr, size_t size)
Definition template.h:45

◆ unleak_and_delete()

void unleak_and_delete ( SELF * self)
static

Definition at line 84 of file template.h.

84 {
85 NS(ENTRIES_VECTOR, iter) iter = NS(ENTRIES_VECTOR, get_iter)(&self->entries);
86 TRACKED_ENTRY* entry;
87
88 while ((entry = NS(ENTRIES_VECTOR, iter_next)(&iter))) {
89 if (!entry->freed) {
90 NS(ALLOC, free)(self->alloc, entry->ptr);
91 }
92 }
93
94 NS(ENTRIES_VECTOR, delete)(&self->entries);
95}