summaryrefslogtreecommitdiffhomepage
path: root/docs/cset_api.md
blob: 287f763603ec07fe1ebe17792b183454a6f9366b (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
# 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_tag       // alternative typename: cmap_{i_tag}. i_tag defaults to i_val
#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_ssize      // default int32_t. If defined, table expand 2x (else 1.5x)
#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

bool                cset_X_empty(const cset_X* self);
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
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);

int                 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)
        {
            second = c_make(cset_str, {"red", "green", "blue"});

            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
```