summaryrefslogtreecommitdiff
path: root/functional.c
blob: c1577bd5289c44d0c5e33101f9fdbf9a19ded190 (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
#include "functional.h"

void func_map(Functional* f) {
  f->args.i = 0;
  f->args.offset = 0;
  while (f->args.i < f->args.n) {
    f->map(&f->args);
    f->args.i++;
  }
}

void func_filterGeneric(Functional* f,
                        void (*shiftLeft)(FunctionalArgs* args)) {
  bool shouldMutate = shiftLeft != NULL;
  int nInCollection = 0;
  for (f->args.i = 0; f->args.i < f->args.n; f->args.i++) {
    bool shouldInclude = f->filter(&f->args);
    if (shouldInclude) {
      f->args.offset = f->args.i - nInCollection;
      if (!shouldMutate) {
        f->map(&f->args);
      }
      nInCollection++;
    } else {
      if (shouldMutate) {
        shiftLeft(&f->args);
      }
    }
  }
  f->args.n = nInCollection;
}

void func_filter(Functional* f) {
  func_filterGeneric(f, NULL);
}

void func_filterMutate(Functional* f, void (*shiftLeft)(FunctionalArgs* args)) {
  func_filterGeneric(f, shiftLeft);
}

void* func_find(Functional* f) {
  f->args.i = 0;
  while (f->args.i < f->args.n) {
    if (f->filter(&f->args)) {
      return f->derefInput(f->args.i, f->args.arr);
    }
    f->args.i++;
  }
  return NULL;
}