-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathitplus_collect.h
76 lines (70 loc) · 4.14 KB
/
itplus_collect.h
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
/**
* @file
* @brief Macros for implementing the `collect` abstraction.
*
* https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.collect
* Note: Rust's `collect` has a polymorphic return type. The `collect` here just turns an iterable into an array.
*/
#ifndef LIB_ITPLUS_COLLECT_H
#define LIB_ITPLUS_COLLECT_H
#include "itplus_foreach.h"
#include "itplus_iterator.h"
#include "itplus_maybe.h"
#include <stdlib.h>
#ifndef ITPLUS_COLLECT_BUFSZ
#define ITPLUS_COLLECT_BUFSZ 64
#endif /* !ITPLUS_COLLECT_BUFSZ */
/**
* @def define_itercollect_func(T, Name)
* @brief Define the `collect` function for an iterable.
*
* The defined function takes in an iterable of type `T`, and turns it into an array. Each element of said array
* is of type `T`. Nothing is implicitly cloned. The same values from the iterable are assigned to the array.
*
* This defined function will consume the given iterable.
*
* # Example
*
* @code
* // Defines a function with the signature- `int* collect_int(Iterable(int) x, size_t* len)`
* define_itercollect_func(int, collect_int)
* @endcode
*
* Usage of the defined function-
*
* @code
* size_t arrlen = 0;
* // Collect `it` (of type `Iterable(int)`) into an array
* int* intarr = collect_int(it, &arrlen);
* @endcode
*
* @param T The type of value the `Iterable`, for which this is being implemented, yields.
* @param Name Name to define the function as.
*
* @note The returned array must be freed.
* @note If `T` is a pointer, it needs to be typedef-ed into a type that does not contain the `*`. Only alphanumerics.
* @note An #Iterator(T) for the given `T` **must** also exist.
*/
#define define_itercollect_func(T, Name) \
T* Name(Iterable(T) it, size_t* len) \
{ \
size_t size = ITPLUS_COLLECT_BUFSZ; \
*len = 0; \
T* arr = malloc(size * sizeof(*arr)); \
if (arr == NULL) { \
return NULL; \
} \
foreach (T, x, it) { \
if (*len == size) { \
T* temp = realloc(arr, (size *= 2) * sizeof(*arr)); \
if (temp == NULL) { \
free(arr); \
return NULL; \
} \
arr = temp; \
} \
arr[(*len)++] = x; \
} \
return arr; \
}
#endif /* !LIB_ITPLUS_COLLECT_H */