Skip to content

Commit

Permalink
WIP Generic header
Browse files Browse the repository at this point in the history
  • Loading branch information
P-p-H-d committed Nov 1, 2023
1 parent f7f5db6 commit 1d003fb
Show file tree
Hide file tree
Showing 3 changed files with 244 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ PACKAGE=m_lib-$(VERSION)
VERSION=0.7.1

# Define the contain of the distribution tarball
HEADER=m-algo.h m-array.h m-atomic.h m-bitset.h m-bptree.h m-buffer.h m-c-mempool.h m-concurrent.h m-core.h m-deque.h m-dict.h m-funcobj.h m-genint.h m-i-list.h m-i-shared.h m-list.h m-mempool.h m-thread.h m-mutex.h m-prioqueue.h m-rbtree.h m-serial-bin.h m-serial-json.h m-shared.h m-snapshot.h m-string.h m-tree.h m-try.h m-tuple.h m-variant.h m-worker.h
HEADER=m-algo.h m-array.h m-atomic.h m-bitset.h m-bptree.h m-buffer.h m-c-mempool.h m-concurrent.h m-core.h m-deque.h m-dict.h m-funcobj.h m-generic.h m-genint.h m-i-list.h m-i-shared.h m-list.h m-mempool.h m-thread.h m-mutex.h m-prioqueue.h m-rbtree.h m-serial-bin.h m-serial-json.h m-shared.h m-snapshot.h m-string.h m-tree.h m-try.h m-tuple.h m-variant.h m-worker.h
DOC1=LICENSE README.md
DOC2=doc/API.txt doc/Container.html doc/Container.ods doc/depend.png doc/DEV.md doc/ISSUES.org doc/oplist.odp doc/oplist.png
EXAMPLE=example/ex11-algo01.c example/ex11-algo02.c example/ex11-json01.c example/ex11-section.c example/ex-algo02.c example/ex-algo03.c example/ex-algo04.c example/ex-array00.c example/ex-array01.c example/ex-array02.c example/ex-array03.c example/ex-array04.c example/ex-array05.c example/ex-bptree01.c example/ex-buffer01.c example/ex-dict01.c example/ex-dict02.c example/ex-dict03.c example/ex-dict04.c example/ex-grep01.c example/ex-list01.c example/ex-mph.c example/ex-multi01.c example/ex11-multi02.c example/ex-multi03.c example/ex-multi04.c example/ex-multi05.c example/ex-rbtree01.c example/ex11-algo02.json example/ex11-json01.json example/Makefile example/ex-defer01.c example/ex-string01.c example/ex-string02.c example/ex-astar.c example/ex-string03.c example/ex11-tstc.c example/ex-no-stdio.c example/ex11-count-lines.c example/ex11-json-net.c example/ex11-rbtree02.c
Expand Down
119 changes: 119 additions & 0 deletions m-generic.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
* M*LIB - Generic module
*
* Copyright (c) 2017-2023, Patrick Pelissier
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* + Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* + Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef MSTARLIB_GENERIC_H
#define MSTARLIB_GENERIC_H

#include "m-core.h"

/* 3 levels of indirection are neeeded:
* One level is the organisation.
* One level is the component of the organisation.
* One level is the oplist within the component of the organisation
Return the list of unevaled oplist that are registered accorss all organisations, all components.
MLIB Organisation is the default organisation and is always registered
Usage Domain: Nb organizations * Nb components * Nb oplists < M_MAX_NB_ARGUMENT
*/
#define M_G3N_REGISTERED_ITEMS() \
M_CROSS_MAP( M_G3N_IS_PRESENT3, ( comp M_CROSS_MAP(M_G3N_IS_PRESENT2, (MLIB M_MAP(M_G3N_IS_PRESENT, M_SEQ(1, 50))), ( M_SEQ(1, 50) ) ) ), ( M_SEQ(1, 50) ) )

#define M_G3N_IS_PRESENT(num) \
M_IF(M_PARENTHESIS_P(M_C(M_GENERIC_ORG_, num)() ))(M_DEFERRED_COMMA M_ID M_C(M_GENERIC_ORG_, num)(), )

#define M_G3N_IS_PRESENT2(el1, num) \
M_IF(M_PARENTHESIS_P(M_C4(M_GENERIC_ORG_, el1, _COMP_, num)()))(M_DEFERRED_COMMA M_APPLY(M_C3, el1, _COMP_, M_ID M_C4(M_GENERIC_ORG_, el1, _COMP_, num)()), )

#define M_G3N_IS_PRESENT3(el1, num) \
M_IF(M_OPLIST_P(M_C4(M_GENERIC_ORG_, el1, _OPLIST_, num)()))(M_DEFERRED_COMMA M_C4(M_GENERIC_ORG_, el1, _OPLIST_, num), )

// Dummy unused structure. Just to fill in default case of the _Generic
struct m_g3neric_dummys;

// Call the OPERATOR call of the oplist registered to the variable 'x'
// which takes one argument.
#define M_G3N_CALL_1(call, x) \
_Generic( ((void)0, (x)), \
M_MAP2(M_G3N_CALL_1_func, (call, x) M_G3N_REGISTERED_ITEMS() ) \
struct m_g3neric_dummys *: /* cannot happen */ (void)0)
#define M_G3N_CALL_1_func(x, oplist) \
M_G3N_CALL_1_func_expand(M_GET_GENTYPE oplist(), M_PAIR_1 x, M_PAIR_2 x, oplist)
#define M_G3N_CALL_1_func_expand(gentype, call, x, oplist) \
gentype: call(oplist(), M_AS_TYPE(gentype, x)),

// Call the OPERATOR call of the oplist registered to the variable 'x'
// which takes two argument (type, type)
#define M_G3N_CALL_2(call, x, y) \
_Generic( ((void)0, (x)), \
M_MAP2(M_G3N_CALL_2_func, (call, x, y) M_G3N_REGISTERED_ITEMS() ) \
struct m_g3neric_dummys *: /* cannot happen */ (void) 0)
#define M_G3N_CALL_2_func(x, oplist) \
M_G3N_CALL_2_func_expand(M_GET_GENTYPE oplist(), M_TRIPLE_1 x, M_TRIPLE_2 x, M_TRIPLE_3 x, oplist)
#define M_G3N_CALL_2_func_expand(gentype, call, x, y, oplist) \
gentype: call(oplist(), M_AS_TYPE(gentype, x), M_AS_TYPE(gentype, y)),

// Call the OPERATOR call of the oplist registered to the variable 'x'
// which takes two argument (type, subtype)
#define M_G3N_CALL_2t(call, x, y) \
_Generic( ((void)0, (x)), \
M_MAP2(M_G3N_CALL_2t_func, (call, x, y) M_G3N_REGISTERED_ITEMS() ) \
struct m_g3neric_dummys *: /* cannot happen */ (void) 0)
#define M_G3N_CALL_2t_func(x, oplist) \
M_G3N_CALL_2t_func_expand(M_GET_GENTYPE oplist(), \
M_IF_METHOD(GENTYPE, M_GET_OPLIST oplist())(M_GET_GENTYPE M_GET_OPLIST oplist(), M_GET_SUBTYPE oplist()), \
M_TRIPLE_1 x, M_TRIPLE_2 x, M_TRIPLE_3 x, oplist)
#define M_G3N_CALL_2t_func_expand(gentype, basictype, call, x, y, oplist) \
gentype: call(oplist(), M_AS_TYPE(gentype, x), M_AS_TYPE(basictype, y)),


// Define generic functions
// TODO: m_ prefix?
#define init(x) M_G3N_CALL_1(M_CALL_INIT, x)
#define init_set(x, y) M_G3N_CALL_2(M_CALL_INIT_SET, x, y)
#define set(x, y) M_G3N_CALL_2(M_CALL_SET, x, y)
#define clear(x) M_G3N_CALL_1(M_CALL_CLEAR, x)
#define init_move(x, y) M_G3N_CALL_2(M_CALL_INIT_MOVE, x, y)
#define push(x, y) M_G3N_CALL_2t(M_CALL_PUSH, x, y)


/* User code has to register oplists :
#define M_GENERIC_ORG_2() (USER)
#define M_GENERIC_ORG_USER_COMP_1() (CORE)
#define M_GENERIC_ORG_USER_COMP_CORE_OPLIST_6() FLT1
#define M_GENERIC_ORG_USER_COMP_CORE_OPLIST_7() STR1
*/

// Don't need to register M*LIB organisation as it is the default one
//#define M_GENERIC_ORG_1() (MLIB)

// TODO: Register CORE component
// TODO: Register oplist to CORE component (m-string ? serial ?)
// TODO: Add GENTYPE to all types
//#define M_GENERIC_ORG_MLIB_COMP_1() (CORE)
//#define M_GENERIC_ORG_MLIB_COMP_CORE_OPLIST_1() STR1
//#define M_GENERIC_ORG_MLIB_COMP_CORE_OPLIST_5() FLT1



#endif
124 changes: 124 additions & 0 deletions tests/test-mgeneric.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* Copyright (c) 2017-2023, Patrick Pelissier
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* + Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* + Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <stdbool.h>
#include <assert.h>
#include "coverage.h"

#include "m-string.h"
#include "m-generic.h"

// Serial json is not supported for standard types if not C11
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L

static void h(string_t x)
{
string_set_str(x, "TEST STRING");
}

const string_t gx;


/*
init(x)
init_set(x,y)
set(x,y)
clear(x)
init_move(x,y)
init_with(x, ...)
swap(x,y)
reset(x)
bool empty_p(x)
size_t get_size(x)
size_t hash(x)
bool equal(x, y)
int cmp(x,y)
add(x, y)
sub(x, y)
mul(x, y)
div(x, y)
T* get(x, key)
set(x, key, value)
T *safe_get(x, key)
erase(x, key)
push(x, y)
pop(x, y)
...
pas de pb
pb for iterator through "each":
FIXME: uses of C23 typeof + extensions ?
*/

#define STR1 M_OPEXTEND(STRING_OPLIST, GENTYPE(struct m_string_s *))
#define FLT1 (GENTYPE(float), TYPE(float), INIT(M_INIT_DEFAULT))

//#define M_GENERIC_ORG_MLIB_COMP_1() (CORE)
//#define M_GENERIC_ORG_MLIB_COMP_CORE_OPLIST_1() STR1
//#define M_GENERIC_ORG_MLIB_COMP_CORE_OPLIST_5() FLT1

#define M_GENERIC_ORG_2() (USER)
#define M_GENERIC_ORG_USER_COMP_1() (CORE)
#define M_GENERIC_ORG_USER_COMP_CORE_OPLIST_6() FLT1
#define M_GENERIC_ORG_USER_COMP_CORE_OPLIST_7() STR1

// typeof(_Generic(...) ) ?
// GCC/CLANG/TCC: __extension__ __typeof__
// MSVC++: decltype
// C23; typeof

static void test_string(string_t p)
{
string_t s , d;
// ‘_Generic’ selector of type ‘const struct m_string_s *’ is not compatible with any association
//init(gx);

init(s);
h(s);
init_set(d, s);
h(d);
init_set(p, gx);
clear(s);
clear(d);

float f;
init(f);
clear(f);
clear(p);
// clear(gx);
}

int main(void)
{
string_t p;
test_string(p);

exit(0);
}

#else
int main(void)
{
exit(0);
}
#endif

0 comments on commit 1d003fb

Please sign in to comment.