C Container Collection (CCC)
Loading...
Searching...
No Matches
impl_doubly_linked_list.h
1#ifndef CCC_IMPL_DOUBLY_LINKED_LIST_H
2#define CCC_IMPL_DOUBLY_LINKED_LIST_H
3
5#include <assert.h>
6#include <stddef.h>
9#include "../types.h"
10
11/* NOLINTBEGIN(readability-identifier-naming) */
12
14typedef struct ccc_dll_elem_
15{
16 struct ccc_dll_elem_ *n_;
17 struct ccc_dll_elem_ *p_;
18} ccc_dll_elem_;
19
21struct ccc_dll_
22{
23 struct ccc_dll_elem_ sentinel_;
24 size_t elem_sz_;
25 size_t dll_elem_offset_;
26 size_t sz_;
27 ccc_alloc_fn *alloc_;
28 ccc_cmp_fn *cmp_;
29 void *aux_;
30};
31
32/*======================= Private Interface ===========================*/
33
35void ccc_impl_dll_push_back(struct ccc_dll_ *, struct ccc_dll_elem_ *);
37void ccc_impl_dll_push_front(struct ccc_dll_ *, struct ccc_dll_elem_ *);
39struct ccc_dll_elem_ *ccc_impl_dll_elem_in(struct ccc_dll_ const *,
40 void const *user_struct);
41
42/*======================= Macro Implementations =======================*/
43
45#define ccc_impl_dll_init(dll_name, struct_name, dll_elem_field, cmp_fn, \
46 alloc_fn, aux_data) \
47 { \
48 .sentinel_.n_ = &(dll_name).sentinel_, \
49 .sentinel_.p_ = &(dll_name).sentinel_, \
50 .elem_sz_ = sizeof(struct_name), \
51 .dll_elem_offset_ = offsetof(struct_name, dll_elem_field), \
52 .sz_ = 0, \
53 .alloc_ = (alloc_fn), \
54 .cmp_ = (cmp_fn), \
55 .aux_ = (aux_data), \
56 }
57
59#define ccc_impl_dll_emplace_back(dll_ptr, struct_initializer...) \
60 (__extension__({ \
61 typeof(struct_initializer) *dll_res_ = NULL; \
62 struct ccc_dll_ *dll_ = (dll_ptr); \
63 if (dll_) \
64 { \
65 if (dll_->alloc_) \
66 { \
67 dll_res_ = dll_->alloc_(NULL, dll_->elem_sz_, dll_->aux_); \
68 if (dll_res_) \
69 { \
70 *dll_res_ = (typeof(*dll_res_))struct_initializer; \
71 ccc_impl_dll_push_back( \
72 dll_, ccc_impl_dll_elem_in(dll_, dll_res_)); \
73 } \
74 } \
75 } \
76 dll_res_; \
77 }))
78
80#define ccc_impl_dll_emplace_front(dll_ptr, struct_initializer...) \
81 (__extension__({ \
82 typeof(struct_initializer) *dll_res_; \
83 struct ccc_dll_ *dll_ = (dll_ptr); \
84 assert(sizeof(*dll_res_) == dll_->elem_sz_); \
85 if (!dll_->alloc_) \
86 { \
87 dll_res_ = NULL; \
88 } \
89 else \
90 { \
91 dll_res_ = dll_->alloc_(NULL, dll_->elem_sz_, dll_->aux_); \
92 if (dll_res_) \
93 { \
94 *dll_res_ = struct_initializer; \
95 ccc_impl_dll_push_front(dll_, \
96 ccc_impl_dll_elem_in(dll_, dll_res_)); \
97 } \
98 } \
99 dll_res_; \
100 }))
101
102/* NOLINTEND(readability-identifier-naming) */
103
104#endif /* CCC_IMPL_DOUBLY_LINKED_LIST_H */
ccc_threeway_cmp ccc_cmp_fn(ccc_cmp)
A callback function for comparing two elements in a container.
Definition: types.h:291
void * ccc_alloc_fn(void *ptr, size_t size, void *aux)
An allocation function at the core of all containers.
Definition: types.h:283