diff --git a/README.md b/README.md index e5cb3c76..a5a3f8c2 100644 --- a/README.md +++ b/README.md @@ -4434,6 +4434,18 @@ Initialize the shared pointer 'shared' to the same object than the one pointed by 'src' (sharing ownership). This function is thread safe from 'src' point of view. +##### void name\_init\_with\[suffix\](shared\_t shared, args...) + +Initialize the shared pointer 'shared' to the new object initilized with args. +The provided arguments shall therefore match one of the constructor provided +by the EMPLACE\_TYPE operator. +There is one generated method per suffix defined in the EMPLACE\_TYPE operator, +and the 'suffix' in the generated method name corresponds to the suffix defined in +in the EMPLACE\_TYPE operator (it can be empty). +This method is created only if the EMPLACE\_TYPE operator is provided. +See emplace chapter for more details. +It is equivalent to the C++ make\_shared. + ##### bool name\_NULL\_p(const shared\_t shared) Return true if shared doesn't reference any object (i.e. is the NULL pointer). diff --git a/m-shared.h b/m-shared.h index 3b216e89..54bddee6 100644 --- a/m-shared.h +++ b/m-shared.h @@ -1,5 +1,5 @@ /* - * M*LIB - SHARED Module + * M*LIB - SHARED Pointer Module * * Copyright (c) 2017-2023, Patrick Pelissier * All rights reserved. @@ -166,6 +166,7 @@ M_INLINE int m_shar3d_integer_cref(int *p) { return *p; } M_SHAR3D_PTR_DEF_TYPE(name, type, oplist, cpt_oplist, shared_t) \ M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \ M_SHAR3D_PTR_DEF_CORE(name, type, oplist, cpt_oplist, shared_t) \ + M_EMPLACE_QUEUE_DEF(name, cpt_oplist, M_F(name, _init_with), oplist, M_SHAR3D_PTR_DEF_EMPLACE) /* Define the types */ #define M_SHAR3D_PTR_DEF_TYPE(name, type, oplist, cpt_oplist, shared_t) \ @@ -180,6 +181,7 @@ M_INLINE int m_shar3d_integer_cref(int *p) { return *p; } \ /* Internal type for oplist */ \ typedef shared_t M_F(name, _ct); \ + typedef type M_F(name, _subtype_ct); \ \ typedef struct M_F(name, combine_s) { \ type data; \ @@ -361,6 +363,30 @@ M_INLINE int m_shar3d_integer_cref(int *p) { return *p; } return data; \ } \ +/* Definition of the emplace_back function for arrays */ +#define M_SHAR3D_PTR_DEF_EMPLACE(name, cpt_oplist, function_name, oplist, init_func, exp_emplace_type) \ + M_INLINE void \ + function_name(M_F(name, _ct) shared \ + M_EMPLACE_LIST_TYPE_VAR(a, exp_emplace_type) ) \ + { \ + /* NOTE: Alloc 1 struct with both structures. */ \ + struct M_F(name, combine_s) *p = \ + M_CALL_NEW(oplist, struct M_F(name, combine_s)); \ + if (M_UNLIKELY_NOMEM (p == NULL)) { \ + M_MEMORY_FULL(sizeof(struct M_F(name, combine_s))); \ + return; \ + } \ + struct M_F(name, _s) *ptr = &p->ptr; \ + M_F(name, _subtype_ct) *data = &p->data; \ + M_EMPLACE_CALL_FUNC(a, init_func, oplist, *data, exp_emplace_type); \ + ptr->data = data; \ + M_CALL_INIT_SET(cpt_oplist, &ptr->cpt, 1); \ + ptr->combineAlloc = true; \ + *shared = ptr; \ + M_SHAR3D_CONTRACT(shared, cpt_oplist); \ + } \ + + /********************************** INTERNAL *********************************/ @@ -407,6 +433,7 @@ M_INLINE int m_shar3d_integer_cref(int *p) { return *p; } \ /* Internal Types for oplist */ \ typedef shared_t M_F(name, _ct); \ + typedef type M_F(name, _subtype_ct); \ /* Define the core functions */ #define M_SHAR3D_RESOURCE_DEF_CORE(name, type, oplist, shared_t, it_t) \ diff --git a/tests/test-mshared.c b/tests/test-mshared.c index 3093e8eb..fcd995bd 100644 --- a/tests/test-mshared.c +++ b/tests/test-mshared.c @@ -135,6 +135,15 @@ static void test2(void) shared_int_clear(p1); } +static void test_emplace(void) +{ + shared_mpz_t z; + + shared_mpz_init_with_ui(z, 23); + assert ( (*shared_mpz_ref(z))->ptr[0] == 23); + shared_mpz_clear(z); +} + #define MAX_RESSOURCE 10 static void test_ressource(int n) @@ -223,6 +232,7 @@ int main(void) { test1(); test2(); + test_emplace(); for(int i = 1; i < MAX_RESSOURCE; i++) { test_ressource(i); }