Factorization of check of index

So that it can be reused for other modules.
This commit is contained in:
Patrick Pelissier committed 2020-06-05 20:30:07 +02:00
1 parent b897027021
commit 8216ef0f7b
2 files changed
+42 -30

No files matched your search

+15 -25
View File
@@ -126,16 +126,6 @@
assert (a->size == 0 || a->ptr != NULL); \ assert (a->size == 0 || a->ptr != NULL); \
} while (0) } while (0)
/* Define a check on an index compare to its maximum.
* The index is supposed to be unsigned.
* Can be overiden by user if it needs to keep access under control
* even on release mode */
#ifndef ARRAY_CHECK_INDEX
#define ARRAY_CHECK_INDEX(index, max) do { \
assert(index < max); \
} while (0)
#endif
/* Deferred evaluation for the array definition, /* Deferred evaluation for the array definition,
so that all arguments are evaluated before further expansion */ so that all arguments are evaluated before further expansion */
#define ARRAYI_DEF_P1(arg) ARRAYI_DEF_P2 arg #define ARRAYI_DEF_P1(arg) ARRAYI_DEF_P2 arg
@@ -267,7 +257,7 @@
{ \ { \
ARRAYI_CONTRACT(v); \ ARRAYI_CONTRACT(v); \
assert(v->size > 0 && v->ptr != NULL); \ assert(v->size > 0 && v->ptr != NULL); \
ARRAY_CHECK_INDEX(i, v->size); \ M_ASSERT_INDEX(i, v->size); \
M_CALL_SET(oplist, v->ptr[i], x); \ M_CALL_SET(oplist, v->ptr[i], x); \
} \ } \
\ \
@@ -276,7 +266,7 @@
{ \ { \
ARRAYI_CONTRACT(v); \ ARRAYI_CONTRACT(v); \
assert(v->ptr != NULL); \ assert(v->ptr != NULL); \
ARRAY_CHECK_INDEX(0, v->size); \ M_ASSERT_INDEX(0, v->size); \
return M_CONST_CAST(type, &v->ptr[v->size-1]); \ return M_CONST_CAST(type, &v->ptr[v->size-1]); \
} \ } \
\ \
@@ -343,7 +333,7 @@
M_C(name, _push_at)(array_t v, size_t key, type const x) \ M_C(name, _push_at)(array_t v, size_t key, type const x) \
{ \ { \
ARRAYI_CONTRACT(v); \ ARRAYI_CONTRACT(v); \
ARRAY_CHECK_INDEX(key, v->size+1); \ M_ASSERT_INDEX(key, v->size+1); \
if (M_UNLIKELY (v->size >= v->alloc) ) { \ if (M_UNLIKELY (v->size >= v->alloc) ) { \
assert(v->size == v->alloc); \ assert(v->size == v->alloc); \
size_t alloc = M_CALL_INC_ALLOC(oplist, v->alloc); \ size_t alloc = M_CALL_INC_ALLOC(oplist, v->alloc); \
@@ -460,7 +450,7 @@
{ \ { \
ARRAYI_CONTRACT(v); \ ARRAYI_CONTRACT(v); \
assert (v->ptr != NULL); \ assert (v->ptr != NULL); \
ARRAY_CHECK_INDEX(0, v->size); \ M_ASSERT_INDEX(0, v->size); \
v->size--; \ v->size--; \
if (dest) { \ if (dest) { \
M_DO_MOVE (oplist, *dest, v->ptr[v->size]); \ M_DO_MOVE (oplist, *dest, v->ptr[v->size]); \
@@ -475,7 +465,7 @@
{ \ { \
ARRAYI_CONTRACT(v); \ ARRAYI_CONTRACT(v); \
assert (v->ptr != NULL); \ assert (v->ptr != NULL); \
ARRAY_CHECK_INDEX(0, v->size); \ M_ASSERT_INDEX(0, v->size); \
assert (dest != NULL); \ assert (dest != NULL); \
v->size--; \ v->size--; \
M_DO_INIT_MOVE (oplist, *dest, v->ptr[v->size]); \ M_DO_INIT_MOVE (oplist, *dest, v->ptr[v->size]); \
@@ -488,7 +478,7 @@
{ \ { \
ARRAYI_CONTRACT(v); \ ARRAYI_CONTRACT(v); \
assert (v == pos->array); \ assert (v == pos->array); \
ARRAY_CHECK_INDEX(pos->index, v->size+1); \ M_ASSERT_INDEX(pos->index, v->size+1); \
M_C(name, _resize)(v, pos->index); \ M_C(name, _resize)(v, pos->index); \
} \ } \
, /* No INIT */ ) \ , /* No INIT */ ) \
@@ -519,7 +509,7 @@
{ \ { \
ARRAYI_CONTRACT(v); \ ARRAYI_CONTRACT(v); \
assert (v->size > 0 && v->ptr != NULL); \ assert (v->size > 0 && v->ptr != NULL); \
ARRAY_CHECK_INDEX(i, v->size); \ M_ASSERT_INDEX(i, v->size); \
if (dest) \ if (dest) \
M_DO_MOVE (oplist, *dest, v->ptr[i]); \ M_DO_MOVE (oplist, *dest, v->ptr[i]); \
else \ else \
@@ -543,7 +533,7 @@
M_C(name, _insert_v)(array_t v, size_t i, size_t num) \ M_C(name, _insert_v)(array_t v, size_t i, size_t num) \
{ \ { \
ARRAYI_CONTRACT(v); \ ARRAYI_CONTRACT(v); \
ARRAY_CHECK_INDEX(i, v->size+1); \ M_ASSERT_INDEX(i, v->size+1); \
size_t size = v->size + num; \ size_t size = v->size + num; \
/* Test for overflow of variable size */ \ /* Test for overflow of variable size */ \
if (M_UNLIKELY (size <= v->size)) { \ if (M_UNLIKELY (size <= v->size)) { \
@@ -580,8 +570,8 @@
{ \ { \
ARRAYI_CONTRACT(v); \ ARRAYI_CONTRACT(v); \
assert(i < j && v->ptr != NULL); \ assert(i < j && v->ptr != NULL); \
ARRAY_CHECK_INDEX(i, v->size); \ M_ASSERT_INDEX(i, v->size); \
ARRAY_CHECK_INDEX(j, v->size+1); \ M_ASSERT_INDEX(j, v->size+1); \
for(size_t k = i ; k < j; k++) \ for(size_t k = i ; k < j; k++) \
M_CALL_CLEAR(oplist, v->ptr[k]); \ M_CALL_CLEAR(oplist, v->ptr[k]); \
memmove(&v->ptr[i], &v->ptr[j], sizeof(type)*(v->size - j) ); \ memmove(&v->ptr[i], &v->ptr[j], sizeof(type)*(v->size - j) ); \
@@ -612,8 +602,8 @@
{ \ { \
ARRAYI_CONTRACT(v); \ ARRAYI_CONTRACT(v); \
assert(v->ptr != NULL); \ assert(v->ptr != NULL); \
ARRAY_CHECK_INDEX(i, v->size); \ M_ASSERT_INDEX(i, v->size); \
ARRAY_CHECK_INDEX(j, v->size); \ M_ASSERT_INDEX(j, v->size); \
type tmp; \ type tmp; \
M_DO_INIT_MOVE(oplist, tmp, v->ptr[i]); \ M_DO_INIT_MOVE(oplist, tmp, v->ptr[i]); \
M_DO_INIT_MOVE(oplist, v->ptr[i], v->ptr[j]); \ M_DO_INIT_MOVE(oplist, v->ptr[i], v->ptr[j]); \
@@ -626,7 +616,7 @@
{ \ { \
ARRAYI_CONTRACT(v); \ ARRAYI_CONTRACT(v); \
assert (v->ptr != NULL); \ assert (v->ptr != NULL); \
ARRAY_CHECK_INDEX(i, v->size); \ M_ASSERT_INDEX(i, v->size); \
return &v->ptr[i]; \ return &v->ptr[i]; \
} \ } \
\ \
@@ -635,7 +625,7 @@
{ \ { \
ARRAYI_CONTRACT(v); \ ARRAYI_CONTRACT(v); \
assert (v->ptr != NULL); \ assert (v->ptr != NULL); \
ARRAY_CHECK_INDEX(i, v->size); \ M_ASSERT_INDEX(i, v->size); \
return M_CONST_CAST(type, &v->ptr[i]); \ return M_CONST_CAST(type, &v->ptr[i]); \
} \ } \
\ \
@@ -643,7 +633,7 @@
M_C(name, _front)(const array_t v) \ M_C(name, _front)(const array_t v) \
{ \ { \
ARRAYI_CONTRACT(v); \ ARRAYI_CONTRACT(v); \
ARRAY_CHECK_INDEX(0, v->size); \ M_ASSERT_INDEX(0, v->size); \
return M_C(name, _cget)(v, 0); \ return M_C(name, _cget)(v, 0); \
} \ } \
\ \
+27 -5
View File
@@ -2692,7 +2692,11 @@ m_core_hash (const void *str, size_t length)
of invalid implicit cast, whereas they won't if there is an of invalid implicit cast, whereas they won't if there is an
explicit cast) */ explicit cast) */
/* Define allocators for object */ /* Define allocators for object:
* void *M_MEMORY_ALLOC(type): Return a pointer to a new object of type 'type'
* It returns NULL in case of memory allocation failure.
* void M_MEMORY_DEL(ptr): Free the object associated to the pointer.
*/
#ifndef M_MEMORY_ALLOC #ifndef M_MEMORY_ALLOC
#ifdef __cplusplus #ifdef __cplusplus
# include <cstdlib> # include <cstdlib>
@@ -2704,7 +2708,13 @@ m_core_hash (const void *str, size_t length)
#endif #endif
#endif #endif
/* Define allocators for array */ /* Define allocators for array
* void *M_MEMORY_REALLOC(type, ptr, n): Return a pointer to a new array of 'n' object of type 'type'
* If ptr is NULL, it creates a new array.
* If ptr is not null, it reallocates the given array to the new size.
* It returns NULL in case of memory allocation failure.
* void M_MEMORY_FREE(ptr): Free the object associated to the array.
*/
#ifndef M_MEMORY_REALLOC #ifndef M_MEMORY_REALLOC
#ifdef __cplusplus #ifdef __cplusplus
# include <cstdlib> # include <cstdlib>
@@ -2717,8 +2727,9 @@ m_core_hash (const void *str, size_t length)
#endif #endif
#endif #endif
/* Basic ERROR handling macros. /* This macro is called on memory allocation failure.
Note: Can be overloaded by user code to * By default, it aborts the program execution.
* NOTE: Can be overloaded by user code.
*/ */
#ifndef M_MEMORY_FULL #ifndef M_MEMORY_FULL
#define M_MEMORY_FULL(size) do { \ #define M_MEMORY_FULL(size) do { \
@@ -2744,10 +2755,21 @@ m_core_hash (const void *str, size_t length)
#endif #endif
/* Define an assertion check on an index, compared to its maximum.
* The index is supposed to be unsigned.
* NOTE: Can be overiden by user if it needs to keep access under control
* even on release mode */
#ifndef M_ASSERT_INDEX
#define M_ASSERT_INDEX(index, max) do { \
assert(index < max); \
} while (0)
#endif
/* Terminate the compilation of the current unit with an error message. /* Terminate the compilation of the current unit with an error message.
The error is classidied as error The error is classidied as error
with an optional message detailling the error. with an optional message detailling the error.
Either use C11 to get a proper message, or at least a good hint in C99 Either use C11 to get a proper message, or at least a good hint in C99.
error shall be a C name, msg a string. error shall be a C name, msg a string.
Quite usefull to terminate with a proper error message rather than Quite usefull to terminate with a proper error message rather than
a garbage of error due to incorrect code generation in the methods a garbage of error due to incorrect code generation in the methods