Loading...
Searching...
No Matches
Go to the documentation of this file.
11#define CU_RC_NAME(NAME) NAME##_Rc
13#define CU_RC_FN(NAME, SUFFIX) CU_CONCAT(CU_RC_NAME(NAME), SUFFIX)
15#define CU_RC_OPTIONAL_NAME(NAME) CU_CONCAT(CU_RC_NAME(NAME), _Optional)
16#define CU_RC_OPTIONAL_FN(NAME, SUFFIX) \
17 CU_CONCAT(CU_RC_OPTIONAL_NAME(NAME), SUFFIX)
19#define CU_RC_DESTRUCTOR_OPTIONAL_NAME(NAME) \
20 CU_CONCAT(CU_RC_DESTRUCTOR_NAME(NAME), _Optional)
21#define CU_RC_DESTRUCTOR_OPTIONAL_FN(NAME, SUFFIX) \
22 CU_OPTIONAL_FN(CU_RC_DESTRUCTOR_NAME(NAME), SUFFIX)
25#define CU_RC_DESTRUCTOR_NAME(NAME) CU_RC_FN(NAME, _Destructor)
26#define CU_RC_CONTAINER(NAME, T) \
27 typedef void (*CU_RC_DESTRUCTOR_NAME(NAME))(T *); \
28 CU_OPTIONAL_DECL(CU_RC_DESTRUCTOR_NAME(NAME), CU_RC_DESTRUCTOR_NAME(NAME)) \
29 struct CU_RC_FN(NAME, _Container) { \
32 CU_RC_DESTRUCTOR_OPTIONAL_NAME(NAME) destructor; \
36#define CU_RC_RESULT_NAME(NAME) NAME##_Rc_Result
38#define CU_RC_HEADER(NAME, T) \
39 CU_RC_RESULT_NAME(NAME) \
40 CU_RC_FN(NAME, _create)(cu_Allocator alloc, T value, \
41 CU_RC_DESTRUCTOR_OPTIONAL_NAME(NAME) destructor); \
42 CU_RC_OPTIONAL_NAME(NAME) \
43 CU_RC_FN(NAME, _clone)(const CU_RC_NAME(NAME) * rc); \
44 void CU_RC_FN(NAME, _destroy)(CU_RC_NAME(NAME) * rc); \
45 T *CU_RC_FN(NAME, _get)(const CU_RC_NAME(NAME) * rc);
48#define CU_RC_DECL(NAME, T) \
49 CU_RC_CONTAINER(NAME, T) \
51 struct CU_RC_FN(NAME, _Container) * inner; \
54 CU_OPTIONAL_DECL(CU_RC_NAME(NAME), CU_RC_NAME(NAME)) \
55 CU_RESULT_DECL(CU_RC_NAME(NAME), CU_RC_NAME(NAME), cu_Io_Error) \
59#define CU_RC_IMPL(NAME, T) \
60 CU_OPTIONAL_IMPL(CU_RC_NAME(NAME), CU_RC_NAME(NAME)) \
61 CU_OPTIONAL_IMPL(CU_RC_DESTRUCTOR_NAME(NAME), CU_RC_DESTRUCTOR_NAME(NAME)) \
62 CU_RESULT_IMPL(CU_RC_NAME(NAME), CU_RC_NAME(NAME), cu_Io_Error) \
63 CU_RC_RESULT_NAME(NAME) \
64 CU_RC_FN(NAME, _create)(cu_Allocator alloc, T value, \
65 CU_RC_DESTRUCTOR_OPTIONAL_NAME(NAME) destructor) { \
66 cu_IoSlice_Result mem = cu_Allocator_Alloc( \
67 alloc, CU_LAYOUT(struct CU_RC_FN(NAME, _Container))); \
68 if (!cu_IoSlice_Result_is_ok(&mem)) { \
69 return CU_RESULT_FN(CU_RC_NAME(NAME), _error)( \
70 cu_IoSlice_Result_unwrap_error(&mem)); \
72 struct CU_RC_FN(NAME, _Container) *cont = \
73 (struct CU_RC_FN(NAME, _Container) *)cu_IoSlice_Result_unwrap(&mem) \
76 cont->ref_count = 1; \
77 cont->destructor = destructor; \
78 CU_RC_NAME(NAME) rc = {cont, alloc}; \
79 return CU_RESULT_FN(CU_RC_NAME(NAME), _ok)(rc); \
81 CU_RC_OPTIONAL_NAME(NAME) \
82 CU_RC_FN(NAME, _clone)(const CU_RC_NAME(NAME) * rc) { \
83 CU_IF_NULL(rc) { return CU_RC_OPTIONAL_FN(NAME, _none)(); } \
84 CU_IF_NULL(rc->inner) { return CU_RC_OPTIONAL_FN(NAME, _none)(); } \
85 rc->inner->ref_count++; \
86 CU_RC_NAME(NAME) clone = {rc->inner, rc->alloc}; \
87 return CU_RC_OPTIONAL_FN(NAME, _some)(clone); \
89 void CU_RC_FN(NAME, _destroy)(CU_RC_NAME(NAME) * rc) { \
90 CU_IF_NULL(rc) { return; } \
91 if (--rc->inner->ref_count == 0) { \
92 if (CU_RC_DESTRUCTOR_OPTIONAL_FN(NAME, _is_some)( \
93 &rc->inner->destructor)) { \
94 CU_RC_DESTRUCTOR_NAME(NAME) \
95 dtor = CU_RC_DESTRUCTOR_OPTIONAL_FN(NAME, _unwrap)( \
96 &rc->inner->destructor); \
97 dtor(&rc->inner->item); \
100 rc->alloc, cu_Slice_create(rc->inner, sizeof(*rc->inner))); \
104 T *CU_RC_FN(NAME, _get)(const CU_RC_NAME(NAME) * rc) { \
105 CU_IF_NULL(rc) { return NULL; } \
106 CU_IF_NULL(rc->inner) { return NULL; } \
107 return &rc->inner->item; \