Skip to content

Commit

Permalink
more PAIR stuff
Browse files Browse the repository at this point in the history
include it at the right position. we need to have A already
to set default methods.
  • Loading branch information
rurban committed Feb 21, 2024
1 parent 8d1ec96 commit 6f90e79
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 33 deletions.
21 changes: 12 additions & 9 deletions ctl/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,28 @@
#error "Template struct type T undefined for <ctl/map.h>"
#endif

// TODO C++17: emplace, try_emplace, extract, merge
// TODO C++17: emplace, try_emplace, extract, merge, pair

#include <ctl/ctl.h>

#define CTL_MAP
#define HOLD
#define C map
#define set map
#define _set _map
#include <ctl/set.h>
#define A JOIN(map, JOIN(T, T_VALUE))

#include <ctl/pair.h>
#include <ctl/set.h>

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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
49 changes: 36 additions & 13 deletions ctl/pair.h
Original file line number Diff line number Diff line change
@@ -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 <ctl/pair.h>"
#endif
#ifndef A
# error "Template type A undefined for <ctl/pair.h>"
#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
{
Expand All @@ -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 <ctl/bits/integral.h>
#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
7 changes: 6 additions & 1 deletion ctl/set.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
#error "Template type T undefined for <ctl/set.h>"
#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)
Expand All @@ -35,6 +37,9 @@ typedef struct A
int (*equal)(T *, T *);
} A;

#ifdef CTL_MAP
#include <ctl/pair.h>
#endif
#include <ctl/bits/iterator_vtable.h>

typedef struct I
Expand Down
26 changes: 16 additions & 10 deletions ctl/unordered_map.h
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -15,44 +15,50 @@
#define CTL_UMAP
#define HOLD
#define uset umap
#define A JOIN(umap, JOIN(T, T_VALUE))

#include <ctl/unordered_set.h>

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
Expand Down
5 changes: 5 additions & 0 deletions ctl/unordered_set.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -127,6 +129,9 @@ typedef struct A
#endif
} A;

#ifdef CTL_UMAP
#include <ctl/pair.h>
#endif
#include <ctl/bits/iterator_vtable.h>

typedef struct I
Expand Down
6 changes: 6 additions & 0 deletions tests/func/test_integral.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ typedef unsigned char unsigned_char;
#define T_VALUE float
#include <ctl/map.h>

#define POD
typedef char* charp;
#define T charp
#define T_VALUE int
#include <ctl/unordered_map.h>

#define POD
#define T double
#include <ctl/vector.h>
Expand Down

0 comments on commit 6f90e79

Please sign in to comment.