Add cmp_void operators.

This commit is contained in:
jun 2025-01-05 00:42:11 +01:00
parent 9e0da64cb4
commit 73eb83484a
4 changed files with 62 additions and 33 deletions

View File

@ -46,8 +46,6 @@ static inline int guf_heap_cstr_cmp(const guf_heap_cstr *a, const guf_heap_cstr
return strcmp(*a, *b);
}
static inline GUF_OBJ_OPS_DEFINE_CMP_INVERSE(guf_heap_cstr, guf_heap_cstr_cmp, guf_heap_cstr_cmp_inv)
static inline bool guf_heap_cstr_eq(const guf_heap_cstr *a, const guf_heap_cstr *b)
{
GUF_ASSERT_RELEASE(a && b);
@ -55,13 +53,17 @@ static inline bool guf_heap_cstr_eq(const guf_heap_cstr *a, const guf_heap_cstr
return 0 == strcmp(*a, *b);
}
static guf_heap_cstr_ops guf_heap_cstr_operations = {
static inline GUF_OBJ_OPS_DEFINE_CMP_VOID(guf_heap_cstr, guf_heap_cstr_cmp)
static inline GUF_OBJ_OPS_DEFINE_CMP_VOID_INV(guf_heap_cstr, guf_heap_cstr_cmp)
static guf_heap_cstr_ops_type guf_heap_cstr_ops = {
.copy_init = guf_heap_cstr_cpy_init,
.move_init = guf_heap_cstr_move_init,
.free = guf_heap_cstr_free,
.eq = guf_heap_cstr_eq,
.cmp = guf_heap_cstr_cmp,
.cmp_inv = guf_heap_cstr_cmp_inv,
.eq = guf_heap_cstr_eq
.cmp_void = guf_heap_cstr_cmp_void,
.cmp_void_inv = guf_heap_cstr_cmp_void_inv
};
static inline int guf_const_cstr_cmp(const guf_const_cstr *a, const guf_const_cstr *b)
@ -71,8 +73,6 @@ static inline int guf_const_cstr_cmp(const guf_const_cstr *a, const guf_const_cs
return strcmp(*a, *b);
}
static inline GUF_OBJ_OPS_DEFINE_CMP_INVERSE(guf_const_cstr, guf_const_cstr_cmp, guf_const_cstr_cmp_inv)
static inline bool guf_const_cstr_eq(const guf_const_cstr *a, const guf_const_cstr *b)
{
GUF_ASSERT_RELEASE(a && b);
@ -80,13 +80,17 @@ static inline bool guf_const_cstr_eq(const guf_const_cstr *a, const guf_const_cs
return 0 == strcmp(*a, *b);
}
static guf_const_cstr_ops guf_const_cstr_operations = {
static inline GUF_OBJ_OPS_DEFINE_CMP_VOID(guf_const_cstr, guf_const_cstr_cmp)
static inline GUF_OBJ_OPS_DEFINE_CMP_VOID_INV(guf_const_cstr, guf_const_cstr_cmp)
static guf_const_cstr_ops_type guf_const_cstr_ops = {
.copy_init = NULL,
.move_init = NULL,
.free = NULL,
.eq = guf_const_cstr_eq,
.cmp = guf_const_cstr_cmp,
.cmp_inv = guf_const_cstr_cmp_inv,
.eq = guf_const_cstr_eq
.cmp_void = guf_const_cstr_cmp_void,
.cmp_void_inv = guf_const_cstr_cmp_void_inv
};
#endif

View File

@ -1,15 +1,24 @@
#include <stddef.h>
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
#include "guf_assert.h"
#include "guf_common.h"
#ifndef GUF_DBUF_H
#define GUF_DBUF_H
#include <stddef.h>
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
#include "guf_assert.h"
#include "guf_common.h"
#define GUF_DBUF_FOREACH(DBUF, ELEM_TYPE, ELEM_PTR_NAME) for (ELEM_TYPE *ELEM_PTR_NAME = (DBUF).data, *end = (DBUF).data ? (DBUF).data + (DBUF).size : NULL; ELEM_PTR_NAME != end; ++ELEM_PTR_NAME)
#endif
/*
Template parameters:
dbuf_type<GUF_CNT_T, GUF_CNT_T_OPS = value_type_ops, GUF_CNT_NAME = GUFCAT(dbuf_, GUF_CNT_T), GUF_DBUF_INITIAL_CAP = 8>
- GUF_CNT_T: The value type stored in the container.
- GUF_CNT_T_OPS: The operations struct (cf. guf_obj.h) of the container (default: empty operations struct corresponding to a basic value type such as int)
- GUF_CNT_NAME: The typename of the resulting container (default: dbuf_GUF_CNT_T)
- GUF_DBUF_INITIAL_CAP: The capacity used for the first allocation if the container got initialised with a capacity of zero (default: 8)
*/
// Used for the first growth if dbuf->capacity is zero.
#ifndef GUF_DBUF_INITIAL_CAP
#define GUF_DBUF_INITIAL_CAP 8
@ -20,17 +29,15 @@
#endif
#ifndef GUF_CNT_NAME
#error "Undefined container template GUF_CONTAINER_T"
#define GUF_CNT_NAME GUF_CAT(dbuf_, GUF_CNT_T)
#endif
#ifndef GUF_CNT_T_OPS
#define GUF_OBJ_TYPE GUF_CNT_T
// #define GUF_OBJ_OPS_TYPENAME GUFCAT(GUF_CNT_T, _ops)
#include "guf_obj.h"
#define GUF_CNT_T_OPS GUF_OBJ_OPS_EMPTY(GUFCAT(GUF_CNT_T, _ops))
#define GUF_CNT_T_OPS GUF_OBJ_OPS_EMPTY(GUFCAT(GUF_CNT_T, _ops_type))
#endif
#define GUF_CNT_T_OPS_CPY GUFCAT(GUFCAT(GUF_CNT_T, _ops), _cpy)
#define GUF_CNT_T_OPS_CPY GUFCAT(GUFCAT(GUF_CNT_T, _ops_type), _cpy)
typedef struct GUF_CNT_NAME {
GUF_CNT_T *data;
@ -349,6 +356,7 @@ static inline GUFCAT(GUF_CNT_NAME, _iter) GUFCAT(GUF_CNT_NAME, _end)(const GUF_C
}
#undef GUF_DBUF_INITIAL_CAP
#undef GUF_CNT_T
#undef GUF_CNT_T_OPS
#undef GUF_CNT_T_OPS_CPY

View File

@ -1,19 +1,35 @@
#include <string.h>
#include "guf_common.h"
#ifndef GUF_OBJ_H
#define GUF_OBJ_H
#define GUF_OBJ_OPS_DEFINE_CMP_INVERSE(obj_type, cmp_fn, cmp_inverted_name) int cmp_inverted_name(const obj_type *a, const obj_type *b) {return -cmp_fn(a, b);}
#define GUF_OBJ_OPS_VALUE_TYPE(obj_ops_type, eq, cmp, cmp_inv) (obj_ops_type){.copy_init = NULL, .move_init = NULL, .free = NULL, .eq = eq, .cmp = cmp, .cmp_inv = cmp_inv}
#define GUF_OBJ_OPS_EMPTY(obj_ops_type) (obj_ops_type){.copy_init = NULL, .move_init = NULL, .free = NULL, .eq = NULL, .cmp = NULL, .cmp_inv = NULL}
#include <string.h>
#include "guf_common.h"
// #define GUF_OBJ_OPS_VALUE_TYPE(obj_ops_type, eq, cmp, cmp_void, cmp_void_inv) (obj_ops_type){.copy_init = NULL, .move_init = NULL, .free = NULL, .eq = eq, .cmp = cmp, .cmp_void = cmp_void, .cmp_void_inv = cmp_void_inv}
#define GUF_OBJ_OPS_EMPTY(obj_ops_type) (obj_ops_type){.copy_init = NULL, .move_init = NULL, .free = NULL, .eq = NULL, .cmp = NULL, .cmp_void = NULL, .cmp_void_inv = NULL}
#define GUF_OBJ_OPS_DEFINE_CMP_VOID(obj_type, cmp_fn) int GUFCAT(cmp_fn, _void)(const void *a, const void *b) {return cmp_fn((const obj_type*)a, (const obj_type*)b);}
#define GUF_OBJ_OPS_DEFINE_CMP_VOID_INV(obj_type, cmp_fn) int GUFCAT(cmp_fn, _void_inv)(const void *a, const void *b) {return -cmp_fn((const obj_type*)a, (const obj_type*)b);}
// #define GUF_OBJ_OPS_DEFINE_CMP_INVERSE(obj_type, cmp_fn) int GUFCAT(cmp_fn, _inv)(const obj_type *a, const obj_type *b) {return -cmp_fn(a, b);}
// #define GUF_OBJ_OPS_DEFINE_COPY_INIT_VOID(obj_type, copy_init_fn) void *GUFCAT(copy_init_fn, _void)(void *dst, const void *src) {return copy_init_fn((obj_type*)dst, (const obj_type*)src);}
// #define GUF_OBJ_OPS_DEFINE_MOVE_INIT_VOID(obj_type, move_init_fn) void *GUFCAT(move_init_fn, _void)(void *dst, const void *src) {return move_init_fn((obj_type*)dst, (const obj_type*)src);}
// #define GUF_OBJ_OPS_DEFINE_FREE_VOID(obj_type, free_fn) void GUFCAT(free_fn, _void)(void *a) {free_fn((obj_type*)a);}
// #define GUF_OBJ_OPS_DEFINE_EQ_VOID(obj_type, eq_fn) int GUFCAT(eq_fn, _void)(const void *a, const void *b) {return eq_fn((const obj_type*)a, (const obj_type*)b);}
#endif
/*
Required template parameters:
- GUF_OBJ_TYPE: The value type of the object for which to define the operations struct.
Optional temlate parameters:
- GUF_OBJ_OPS_TYPENAME: The typename of the operations struct for the object (default: GUFCAT(GUF_OBJ_TYPE, _ops))
*/
#ifndef GUF_OBJ_TYPE
#error "GUF_OBJ_TYPE not set"
#endif
#ifndef GUF_OBJ_OPS_TYPENAME
#define GUF_OBJ_OPS_TYPENAME GUFCAT(GUF_OBJ_TYPE, _ops)
#define GUF_OBJ_OPS_TYPENAME GUFCAT(GUF_OBJ_TYPE, _ops_type)
#endif
typedef struct GUF_OBJ_OPS_TYPENAME {
@ -22,7 +38,8 @@ typedef struct GUF_OBJ_OPS_TYPENAME {
void (*free)(GUF_OBJ_TYPE *obj);
bool (*eq)(const GUF_OBJ_TYPE *a, const GUF_OBJ_TYPE *b);
int (*cmp)(const GUF_OBJ_TYPE *a, const GUF_OBJ_TYPE *b);
int (*cmp_inv)(const GUF_OBJ_TYPE *a, const GUF_OBJ_TYPE *b); // Define with GUF_OBJ_OPS_DEFINE_CMP_REVERSE.
int (*cmp_void)(const void *a, const void *b);
int (*cmp_void_inv)(const void *a, const void *b);
} GUF_OBJ_OPS_TYPENAME;
static inline GUF_OBJ_TYPE *GUFCAT(GUF_OBJ_OPS_TYPENAME, _cpy) (GUF_OBJ_TYPE *dst, GUF_OBJ_TYPE *src, const GUF_OBJ_OPS_TYPENAME *ops, guf_obj_cpy_opt cpy_opt)

View File

@ -10,12 +10,12 @@
#define GUF_CNT_NAME dbuf_const_cstr
#define GUF_CNT_T guf_const_cstr
#define GUF_CNT_T_OPS guf_const_cstr_operations
#define GUF_CNT_T_OPS guf_const_cstr_ops
#include "guf_dbuf.h"
#define GUF_CNT_NAME dbuf_heap_cstr
#define GUF_CNT_T guf_heap_cstr
#define GUF_CNT_T_OPS guf_heap_cstr_operations
#define GUF_CNT_T_OPS guf_heap_cstr_ops
#include "guf_dbuf.h"
typedef struct guf_test {