Skip to content

Commit

Permalink
WIP: Support user data within container.
Browse files Browse the repository at this point in the history
It is useful for calling methods with another user data argument.
It is mainly useful for custom allocations,
so for now, only custom allocations methods can access the user data.
Port it to array container.
  • Loading branch information
P-p-H-d committed Jan 25, 2024
1 parent d7a2323 commit 55dc524
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 39 deletions.
74 changes: 39 additions & 35 deletions m-array.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
/* FIXME: Do we want to export some methods as they are slow and
are not fit to be used for building other methods (like _it_remove)? */
#define M_ARRA4_OPLIST_P3(name, oplist) \
(INIT(M_F(name, _init)) \
( M_USER_INIT_OPERATOR(name, oplist), \
,M_IF_METHOD2(INIT_SET,SET, oplist)(INIT_SET(M_F(name, _init_set)),) \
,M_IF_METHOD(INIT_SET, oplist)(INIT_WITH(API_1(M_INIT_WITH_VAI)),) \
,M_IF_METHOD2(INIT_SET,SET, oplist)(SET(M_F(name, _set)), ) \
Expand Down Expand Up @@ -173,7 +173,8 @@
M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \
M_ARRA4_DEF_CORE(name, type, oplist, array_t, it_t) \
M_ARRA4_DEF_IO(name, type, oplist, array_t, it_t) \
M_EMPLACE_QUEUE_DEF(name, array_t, M_F(name, _emplace_back), oplist, M_ARRA4_EMPLACE_DEF)
M_EMPLACE_QUEUE_DEF(name, array_t, M_F(name, _emplace_back), oplist, M_ARRA4_EMPLACE_DEF) \
M_USER_DEF_GEN(oplist, name, array_t)

/* Define the types */
#define M_ARRA4_DEF_TYPE(name, type, oplist, array_t, it_t) \
Expand All @@ -183,6 +184,7 @@
size_t size; /* Number of elements in the array */ \
size_t alloc; /* Allocated size for the array base */ \
type *ptr; /* Pointer to the array base */ \
M_USER_FIELD(oplist) \
} array_t[1]; \
\
/* Define an iterator over an array */ \
Expand All @@ -202,10 +204,11 @@
#define M_ARRA4_DEF_CORE(name, type, oplist, array_t, it_t) \
\
M_INLINE void \
M_F(name, _init)(array_t v) \
M_F(name, _init)(array_t v M_USER_PARAM(oplist)) \
{ \
M_ASSERT (v != NULL); \
/* Initially, the array is empty with nothing allocated */ \
M_USER_INIT(oplist, user_data); \
v->size = 0; \
v->alloc = 0; \
v->ptr = NULL; \
Expand Down Expand Up @@ -235,38 +238,38 @@
\
M_IF_METHOD2(INIT_SET, SET, oplist)( \
M_INLINE void \
M_F(name, _set)(array_t d, const array_t s) \
M_F(name, _set)(array_t v, const array_t s) \
{ \
M_ARRA4_CONTRACT(d); \
M_ARRA4_CONTRACT(v); \
M_ARRA4_CONTRACT(s); \
if (M_UNLIKELY (d == s)) return; \
if (s->size > d->alloc) { \
if (M_UNLIKELY (v == s)) return; \
if (s->size > v->alloc) { \
const size_t alloc = s->size; \
type *ptr = M_CALL_REALLOC(oplist, type, d->ptr, alloc); \
type *ptr = M_CALL_REALLOC(oplist, type, v->ptr, alloc); \
if (M_UNLIKELY_NOMEM (ptr == NULL)) { \
M_MEMORY_FULL(sizeof (type) * alloc); \
return ; \
} \
d->ptr = ptr; \
d->alloc = alloc; \
v->ptr = ptr; \
v->alloc = alloc; \
} \
size_t i; \
size_t step1 = M_MIN(s->size, d->size); \
size_t step1 = M_MIN(s->size, v->size); \
for(i = 0; i < step1; i++) \
M_CALL_SET(oplist, d->ptr[i], s->ptr[i]); \
M_CALL_SET(oplist, v->ptr[i], s->ptr[i]); \
for( ; i < s->size; i++) \
M_CALL_INIT_SET(oplist, d->ptr[i], s->ptr[i]); \
for( ; i < d->size; i++) \
M_CALL_CLEAR(oplist, d->ptr[i]); \
d->size = s->size; \
M_ARRA4_CONTRACT(d); \
M_CALL_INIT_SET(oplist, v->ptr[i], s->ptr[i]); \
for( ; i < v->size; i++) \
M_CALL_CLEAR(oplist, v->ptr[i]); \
v->size = s->size; \
M_ARRA4_CONTRACT(v); \
} \
\
M_INLINE void \
M_F(name, _init_set)(array_t d, const array_t s) \
{ \
M_ASSERT (d != s); \
M_F(name, _init)(d); \
M_F(name, _init)(d M_USER_CALL(oplist, M_USER_DATA(s))); \
M_F(name, _set)(d, s); \
} \
, /* No SET & INIT_SET */) \
Expand All @@ -276,10 +279,11 @@
{ \
M_ASSERT (d != s); \
M_ARRA4_CONTRACT(s); \
M_USER_INIT(opl, M_USER_DATA(s)); \
d->size = s->size; \
d->alloc = s->alloc; \
d->ptr = s->ptr; \
/* Robustness */ \
/* Robustness: invalid representation of an array */ \
s->alloc = 1; \
s->ptr = NULL; \
M_ARRA4_CONTRACT(d); \
Expand Down Expand Up @@ -886,17 +890,17 @@
} \
\
M_INLINE void \
M_F(name, _special_stable_sort)(array_t l) \
M_F(name, _special_stable_sort)(array_t v) \
{ \
if (M_UNLIKELY (l->size < 2)) \
if (M_UNLIKELY (v->size < 2)) \
return; \
/* NOTE: if size is <= 4, no need to perform an allocation */ \
type *temp = M_CALL_REALLOC(oplist, type, NULL, l->size); \
type *temp = M_CALL_REALLOC(oplist, type, NULL, v->size); \
if (M_UNLIKELY_NOMEM (temp == NULL)) { \
M_MEMORY_FULL(sizeof (type) * l->size); \
M_MEMORY_FULL(sizeof (type) * v->size); \
return ; \
} \
M_C3(m_arra4_,name,_stable_sort_noalloc)(l->ptr, l->size, temp); \
M_C3(m_arra4_,name,_stable_sort_noalloc)(v->ptr, v->size, temp); \
M_CALL_FREE(oplist, temp); \
} \
,) /* IF SWAP & SET methods */ \
Expand Down Expand Up @@ -937,31 +941,31 @@
, /* no HASH */ ) \
\
M_INLINE void \
M_F(name, _splice)(array_t a1, array_t a2) \
M_F(name, _splice)(array_t v, array_t a2) \
{ \
M_ARRA4_CONTRACT(a1); \
M_ARRA4_CONTRACT(v); \
M_ARRA4_CONTRACT(a2); \
if (M_LIKELY (a2->size > 0)) { \
size_t newSize = a1->size + a2->size; \
size_t newSize = v->size + a2->size; \
/* To overflow newSize, we need to a1 and a2 a little bit above \
SIZE_MAX/2, which is not possible in the classic memory model as we \
should have exhausted all memory before reaching such sizes. */ \
M_ASSERT_INDEX(a1->size, newSize); \
if (newSize > a1->alloc) { \
type *ptr = M_CALL_REALLOC(oplist, type, a1->ptr, newSize); \
M_ASSERT_INDEX(v->size, newSize); \
if (newSize > v->alloc) { \
type *ptr = M_CALL_REALLOC(oplist, type, v->ptr, newSize); \
if (M_UNLIKELY_NOMEM (ptr == NULL) ) { \
M_MEMORY_FULL(sizeof (type) * newSize); \
} \
a1->ptr = ptr; \
a1->alloc = newSize; \
v->ptr = ptr; \
v->alloc = newSize; \
} \
M_ASSERT(a1->ptr != NULL); \
M_ASSERT(v->ptr != NULL); \
M_ASSERT(a2->ptr != NULL); \
memcpy(&a1->ptr[a1->size], &a2->ptr[0], a2->size * sizeof (type)); \
memcpy(&v->ptr[v->size], &a2->ptr[0], a2->size * sizeof (type)); \
/* a2 is now empty */ \
a2->size = 0; \
/* a1 has been expanded with the items of a2 */ \
a1->size = newSize; \
v->size = newSize; \
} \
} \

Expand Down
Loading

0 comments on commit 55dc524

Please sign in to comment.