From ee9e16852fb206ad0809d3e17f789befdcab968c Mon Sep 17 00:00:00 2001 From: Reini Urban Date: Thu, 25 Mar 2021 09:49:49 +0100 Subject: [PATCH] more PAIR stuff include it at the right position. we need to have A already to set default methods. --- ctl/map.h | 21 +++++++++------- ctl/pair.h | 49 +++++++++++++++++++++++++++---------- ctl/set.h | 7 +++++- ctl/unordered_map.h | 26 ++++++++++++-------- ctl/unordered_set.h | 5 ++++ tests/func/test_integral.cc | 6 +++++ 6 files changed, 81 insertions(+), 33 deletions(-) diff --git a/ctl/map.h b/ctl/map.h index 319fbe1d..4cb1ca76 100644 --- a/ctl/map.h +++ b/ctl/map.h @@ -5,28 +5,28 @@ #error "Template struct type T undefined for " #endif -// TODO C++17: emplace, try_emplace, extract, merge +// TODO C++17: emplace, try_emplace, extract, merge, pair #include #define CTL_MAP #define HOLD -#define C map #define set map #define _set _map -#include +#define A JOIN(map, JOIN(T, T_VALUE)) -#include +#include -static inline I JOIN(A, insert_or_assign)(A *self, T key) +static inline I JOIN(A, insert_or_assign)(A *self, T key, T_VALUE value) { - B *insert = JOIN(B, init)(key, 0); + PAIR pair = JOIN(PAIR, make_pair)(key, value); + B *insert = JOIN(B, init)(pair, 0); if (self->root) { B *node = self->root; while (1) { - int diff = self->compare(&key, &node->value); + int diff = self->compare(&key, &((PAIR)node->value).first); if (diff == 0) { JOIN(A, free_node)(self, node); @@ -68,13 +68,14 @@ static inline I JOIN(A, insert_or_assign)(A *self, T key) static inline I JOIN(A, insert_or_assign_found)(A *self, T key, int *foundp) { - B *insert = JOIN(B, init)(key, 0); + PAIR pair = JOIN(PAIR, make_pair)(key, value); + B *insert = JOIN(B, init)(pair, 0); if (self->root) { B *node = self->root; while (1) { - int diff = self->compare(&key, &node->value); + int diff = self->compare(&key, &((PAIR)node->value).first); if (diff == 0) { JOIN(A, free_node)(self, node); @@ -119,8 +120,10 @@ static inline I JOIN(A, insert_or_assign_found)(A *self, T key, int *foundp) #undef _set #undef set #undef T +#undef T_VALUE #undef A #undef B #undef I #undef GI +#undef PAIR #undef CTL_MAP diff --git a/ctl/pair.h b/ctl/pair.h index 2b72ab45..034a28e0 100644 --- a/ctl/pair.h +++ b/ctl/pair.h @@ -1,18 +1,27 @@ /* pair for map/umap - Should not be included directly, only required by map.h or unordered_map.h. - See MIT LICENSE. */ + Should not be included directly, only required by map or unordered_map + (and friends, like swisstable, hashmap). + pair understands POD, T for the key, and POD_VALUE, T_VALUE for the value. + + SPDX-License-Identifier: MIT */ #ifndef __CTL_PAIR__H__ #define __CTL_PAIR__H__ #ifndef T # error "Template type T undefined for " #endif +#ifndef A +# error "Template type A undefined for " +#endif #ifndef T_VALUE -# define T_VALUE void* +typedef void* voidp; +# define T_VALUE voidp +static inline void voidp_free(T_VALUE* value) { free (*value); } +static inline T_VALUE voidp_copy(T_VALUE* value) { return *value; } #endif -#define CTL_PAIR -#define PAIR JOIN(pair, T) +//#define CTL_PAIR +#define PAIR JOIN(pair, JOIN(T, T_VALUE)) typedef struct PAIR { @@ -21,34 +30,48 @@ typedef struct PAIR void (*free)(T*); T (*copy)(T*); void (*free_value)(T_VALUE*); - T (*copy_value)(T_VALUE*); + T_VALUE (*copy_value)(T_VALUE*); int (*compare)(T*, T*); int (*equal)(T*, T*); } PAIR; +#ifdef A #include +#endif -static inline T_VALUE JOIN(A, implicit_value_copy)(T_VALUE *self) +static inline T_VALUE JOIN(PAIR, implicit_value_copy)(T_VALUE *self) { return *self; } -static inline A -JOIN(A, init)(T key, T_VALUE value) +static inline PAIR +JOIN(PAIR, make_pair)(T key, T_VALUE value) { - static A zero; - A self = zero; + static PAIR zero; + PAIR self = zero; + self.first = key; + self.second = value; + #ifdef POD +# ifdef A self.copy = JOIN(A, implicit_copy); _JOIN(A, _set_default_methods)(&self); +# endif #else self.free = JOIN(T, free); self.copy = JOIN(T, copy); #endif + +#ifdef POD_VALUE self.free_value = free; - self.copy_value = JOIN(A, implicit_value_copy); + self.copy_value = JOIN(PAIR, implicit_value_copy); +#else + self.free_value = JOIN(T_VALUE, free); + self.copy_value = JOIN(T_VALUE, copy); +#endif + return self; } -#undef C +//#undef A #endif diff --git a/ctl/set.h b/ctl/set.h index 8ddce13a..4dfe482b 100644 --- a/ctl/set.h +++ b/ctl/set.h @@ -5,10 +5,12 @@ #error "Template type T undefined for " #endif -// TODO emplace, extract, extract_it +// TODO emplace, extract, extract_it, pair #define CTL_SET +#ifndef A #define A JOIN(set, T) +#endif #define B JOIN(A, node) #define I JOIN(A, it) #define GI JOIN(A, it) @@ -35,6 +37,9 @@ typedef struct A int (*equal)(T *, T *); } A; +#ifdef CTL_MAP +#include +#endif #include typedef struct I diff --git a/ctl/unordered_map.h b/ctl/unordered_map.h index 6d0b0f5f..c2577494 100644 --- a/ctl/unordered_map.h +++ b/ctl/unordered_map.h @@ -1,9 +1,9 @@ /* Same hash table as unordered_set SPDX-License-Identifier: MIT - TODO: add pairs, to handle the extra free for key and value pairs. + But with pairs, to handle the extra free/copy for key and value pairs. - search only the key. for most ops, just not insert/emplace. + Search only the key. For most ops, just not insert/emplace. */ #ifndef T @@ -15,44 +15,50 @@ #define CTL_UMAP #define HOLD #define uset umap +#define A JOIN(umap, JOIN(T, T_VALUE)) #include -static inline I JOIN(A, insert_or_assign)(A *self, T value) +static inline I JOIN(A, insert_or_assign)(A *self, T key, T_VALUE value) { B *node; - if ((node = JOIN(A, find_node)(self, value))) + if ((node = JOIN(A, find_node)(self, key))) { - FREE_VALUE(self, value); + if (self->free) + self->free(&key); return JOIN(I, iter)(self, node); } else { + PAIR pair = JOIN(PAIR, make_pair)(key, value); JOIN(A, _pre_insert_grow)(self); - return JOIN(I, iter)(self, *JOIN(A, push_cached)(self, &value)); + return JOIN(I, iter)(self, *JOIN(A, push_cached)(self, &pair)); } } -static inline I JOIN(A, insert_or_assign_found)(A *self, T value, int *foundp) +static inline I JOIN(A, insert_or_assign_found)(A *self, T key, T_VALUE value, int *foundp) { B *node; - if ((node = JOIN(A, find_node)(self, value))) + if ((node = JOIN(A, find_node)(self, key))) { - FREE_VALUE(self, value); + if (self->free) + self->free(&key); *foundp = 1; return JOIN(I, iter)(self, node); } else { + PAIR pair = JOIN(PAIR, make_pair)(key, value); JOIN(A, _pre_insert_grow)(self); *foundp = 0; - return JOIN(I, iter)(self, *JOIN(A, push_cached)(self, &value)); + return JOIN(I, iter)(self, *JOIN(A, push_cached)(self, &pair)); } } #undef CTL_UMAP #undef uset #undef T +#undef T_VALUE #undef A #undef B #undef I diff --git a/ctl/unordered_set.h b/ctl/unordered_set.h index 5a69fd01..0e01ca63 100644 --- a/ctl/unordered_set.h +++ b/ctl/unordered_set.h @@ -92,7 +92,9 @@ position to the top in each access, such as find and contains, not only insert. #endif #define CTL_USET +#ifndef A #define A JOIN(uset, T) +#endif #define B JOIN(A, node) #define I JOIN(A, it) #define GI JOIN(A, it) @@ -127,6 +129,9 @@ typedef struct A #endif } A; +#ifdef CTL_UMAP +#include +#endif #include typedef struct I diff --git a/tests/func/test_integral.cc b/tests/func/test_integral.cc index 67f80610..754ce9ca 100644 --- a/tests/func/test_integral.cc +++ b/tests/func/test_integral.cc @@ -35,6 +35,12 @@ typedef unsigned char unsigned_char; #define T_VALUE float #include +#define POD +typedef char* charp; +#define T charp +#define T_VALUE int +#include + #define POD #define T double #include