summaryrefslogtreecommitdiffhomepage
path: root/docs/cset_api.md
blob: ef4df63bf342048d05578b0334e07102b0599039 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# STC [cset](../include/stc/cset.h): Unordered Set
![Set](pics/set.jpg)

A **cset** is an associative container that contains a set of unique objects of type i_key. Search, insertion, and removal have average constant-time complexity. See the c++ class
[std::unordered_set](https://en.cppreference.com/w/cpp/container/unordered_set) for a functional description.

## Header file and declaration

```c
#define i_type      // container type name (default: cset_{i_key})
#define i_key       // hash key: REQUIRED.
#define i_hash      // hash func: REQUIRED IF i_keyraw is a non-pod type.
#define i_eq        // equality comparison two i_keyraw*: !i_cmp is used if not defined.
#define i_keydrop   // destroy key func - defaults to empty destruct
#define i_keyclone  // REQUIRED IF i_keydrop defined

#define i_keyraw    // convertion "raw" type - defaults to i_key
#define i_keyfrom   // convertion func i_keyraw => i_key - defaults to plain copy
#define i_keyto     // convertion func i_key* => i_keyraw - defaults to plain copy

#define i_size      // default: uint32_t. If defined, table expand 2x (else 1.5x)
#define i_hash_functor // advanced, see examples/functor.c for similar usage.
#define i_eq_functor // advanced, see examples/functor.c for similar usage.
#define i_tag       // alternative typename: cmap_{i_tag}. i_tag defaults to i_val
#include <stc/cset.h>
```
`X` should be replaced by the value of `i_tag` in all of the following documentation.

## Methods

```c
cset_X              cset_X_init(void);
cset_X              cset_X_with_capacity(intptr_t cap);
cset_X              cset_X_clone(cset_x set);

void                cset_X_clear(cset_X* self);
void                cset_X_copy(cset_X* self, const cset_X* other);
float               cset_X_max_load_factor(const cset_X* self);              // default: 0.85
bool                cset_X_reserve(cset_X* self, intptr_t size);
void                cset_X_shrink_to_fit(cset_X* self);
void                cset_X_drop(cset_X* self);                               // destructor

intptr_t            cset_X_size(const cset_X* self);                         // num. of allocated buckets
intptr_t            cset_X_capacity(const cset_X* self);                     // buckets * max_load_factor
bool                cset_X_empty(const cset_X* self);
intptr_t            cset_X_bucket_count(const cset_X* self);

bool                cset_X_contains(const cset_X* self, i_keyraw rkey);
const cset_X_value* cset_X_get(const cset_X* self, i_keyraw rkey);          // return NULL if not found
cset_X_value*       cset_X_get_mut(cset_X* self, i_keyraw rkey);            // mutable get
cset_X_iter         cset_X_find(const cset_X* self, i_keyraw rkey);

cset_X_result       cset_X_insert(cset_X* self, i_key key);
cset_X_result       cset_X_push(cset_X* self, i_key key);                    // alias for insert.
cset_X_result       cset_X_emplace(cset_X* self, i_keyraw rkey);

intptr_t            cset_X_erase(cset_X* self, i_keyraw rkey);               // return 0 or 1
cset_X_iter         cset_X_erase_at(cset_X* self, cset_X_iter it);           // return iter after it
void                cset_X_erase_entry(cset_X* self, cset_X_value* entry);

cset_X_iter         cset_X_begin(const cset_X* self);
cset_X_iter         cset_X_end(const cset_X* self);
void                cset_X_next(cset_X_iter* it);

cset_X_value        cset_X_value_clone(cset_X_value val);
```

## Types

| Type name          | Type definition                                  | Used to represent...        |
|:-------------------|:-------------------------------------------------|:----------------------------|
| `cset_X`           | `struct { ... }`                                 | The cset type               |
| `cset_X_rawkey`    | `i_keyraw`                                       | The raw key type            |
| `cset_X_raw`       | `i_keyraw`                                       | The raw value type          |
| `cset_X_key`       | `i_key`                                          | The key type                |
| `cset_X_value`     | `i_key`                                          | The value                   |
| `cset_X_result`    | `struct { cset_X_value* ref; bool inserted; }`   | Result of insert/emplace    |
| `cset_X_iter`      | `struct { cset_X_value *ref; ... }`              | Iterator type               |

## Example
```c
#include <stc/cstr.h>

#define i_key_str
#include <stc/cset.h>

int main ()
{
    c_AUTO (cset_str, fifth)
    {
        c_AUTO (cset_str, first, second)
        c_AUTO (cset_str, third, fourth)
        {
            c_FORLIST (i, const char*, {"red", "green", "blue"})
                cset_str_emplace(&second, *i.ref);

            c_FORLIST (i, const char*, {"orange", "pink", "yellow"})
                cset_str_emplace(&third, *i.ref);

            cset_str_emplace(&fourth, "potatoes");
            cset_str_emplace(&fourth, "milk");
            cset_str_emplace(&fourth, "flour");

            fifth = cset_str_clone(second);
            c_FOREACH (i, cset_str, third)
                cset_str_emplace(&fifth, cstr_str(i.ref));

            c_FOREACH (i, cset_str, fourth)
                cset_str_emplace(&fifth, cstr_str(i.ref));
        }
        printf("fifth contains:\n\n");
        c_FOREACH (i, cset_str, fifth)
            printf("%s\n", cstr_str(i.ref));
    }
}
```
Output:
```
fifth contains:

red
green
flour
orange
blue
pink
yellow
milk
potatoes
```