~brenns10/funlisp

ref: 7347d0eca6d0a50799d3048c21f376277e827224 funlisp/src/iter.c -rw-r--r-- 2.2 KiB
7347d0ecStephen Brennan Updates for readthedocs 3 years ago
                                                                                
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
/*
 * iter.c: special iterators
 *
 * Stephen Brennan <stephen@brennan.io>
 */

#include <stdlib.h>
#include <stddef.h>
#include <stdint.h>

#include "iter.h"

void iterator_close_noop(struct iterator *iter)
{
	(void)iter;
}

static bool sv_has_next(struct iterator *iter)
{
	return iter->index == 0;
}

static void *sv_next(struct iterator *iter)
{
	iter->index++;
	return iter->ds;
}

struct iterator iterator_single_value(void *value)
{
	struct iterator it = {
		.ds=value,
		.index=0,
		.has_next=sv_has_next,
		.next=sv_next,
		.close=iterator_close_noop,
	};
	return it;
}

static bool cc_has_next(struct iterator *iter)
{
	struct iterator *its = iter->ds;
	intptr_t max_iterators = (intptr_t) iter->state_ptr;
	bool has_next;

	while (iter->state_int < max_iterators) {
		has_next = its[iter->state_int].has_next(&its[iter->state_int]);
		if (has_next) {
			return true;
		}

		its[iter->state_int].close(&its[iter->state_int]);
		iter->state_int++;
	}

	return false;
}

static void *cc_next(struct iterator *iter)
{
	struct iterator *its = iter->ds;
	void *result = its[iter->state_int].next(&its[iter->state_int]);
	if (result) {
		iter->index++;
	}
	return result;
}

static void cc_close(struct iterator *iter)
{
	free(iter->ds);
}

struct iterator iterator_concat(struct iterator *its, size_t n)
{
	struct iterator it = {
		.ds = its,
		.index = 0,
		.state_int = 0,
		.state_ptr = (void*) n,

		.has_next = cc_has_next,
		.next = cc_next,
		.close = cc_close,
	};
	return it;
}

struct iterator iterator_concat2(struct iterator left, struct iterator right)
{
	struct iterator *arr = calloc(sizeof(struct iterator), 2);
	arr[0] = left;
	arr[1] = right;
	return iterator_concat(arr, 2);
}

struct iterator iterator_concat3(struct iterator a, struct iterator b,
																 struct iterator c)
{
	struct iterator *arr = calloc(sizeof(struct iterator), 3);
	arr[0] = a;
	arr[1] = b;
	arr[2] = c;
	return iterator_concat(arr, 3);
}

static void *empty_next(struct iterator *iter)
{
	(void)iter;
	return NULL;
}

static bool empty_has_next(struct iterator *iter)
{
	(void)iter;
	return false;
}

struct iterator iterator_empty()
{
	struct iterator it = {
		.index=0,
		.next=empty_next,
		.has_next=empty_has_next,
		.close=iterator_close_noop,
	};
	return it;
}