};
}
-fold :: (it: Iterator($T), initial_value: R, combine: (T, $R) -> R) -> R {
- for value: it {
- initial_value = combine(value, initial_value);
- }
-
- return initial_value;
-}
-
-to_array :: (it: Iterator($T), allocator := context.allocator) -> [..] T {
- array :: package core.array
-
- arr := array.make(T, allocator=allocator);
- for v: it do array.push(^arr, v);
-
- return arr;
-}
-
#match as_iterator from_array
from_array :: (arr: [] $T) -> Iterator(^T) {
Context :: struct (T: type_expr) {
close = close,
};
}
+
+fold :: #match {}
+@Cleanup // some way to shorten this would be nice
+#match fold macro (it: $T, init: $R, combine: $S) -> #auto where Iterable(T) {
+ fold :: fold
+ return fold(it, init, combine);
+}
+
+#match fold (it: Iterator($T), initial_value: R, combine: (T, $R) -> R) -> R {
+ for value: it {
+ initial_value = combine(value, initial_value);
+ }
+
+ return initial_value;
+}
+
+count :: #match {}
+#match count macro (it: $T, cond: $F) -> #auto where Iterable(T) {
+ count :: count
+ return count(it, cond);
+}
+
+#match count (it: Iterator($T), cond: (T) -> bool) -> i32 {
+ c := 0;
+ for value: it do if cond(value) do c += 1;
+ return c;
+}
+
+some :: #match {}
+#match some macro (it: $T, cond: $F) -> #auto where Iterable(T) {
+ some :: some
+ return some(it, cond);
+}
+
+#match some (it: Iterator($T), cond: (T) -> bool) -> bool {
+ for value: it do if cond(value) do return true;
+ return false;
+}
+
+every :: #match {}
+#match every macro (it: $T, cond: $F) -> #auto where Iterable(T) {
+ every :: every
+ return every(it, cond);
+}
+
+#match every (it: Iterator($T), cond: (T) -> bool) -> bool {
+ for value: it do if !cond(value) do return false;
+ return true;
+}
+
+to_array :: (it: Iterator($T), allocator := context.allocator) -> [..] T {
+ array :: package core.array
+
+ arr := array.make(T, allocator=allocator);
+ for v: it do array.push(^arr, v);
+
+ return arr;
+}
first: ^ListElem(T) = null;
last: ^ListElem(T) = null;
+
+ // "Method" like things
+ free :: free
+ push_end :: push_end
+ push_begin :: push_begin
+ pop_end :: pop_end
+ pop_begin :: pop_begin
+ count :: count
+ at :: at
+ contains :: contains
+ fold :: fold
+ map :: map
+ get_iterator :: get_iterator
}
make :: ($T: type_expr, allocator := context.allocator) -> List(T) {
return .{ allocator = allocator };
}
+free :: (list: ^List($T)) {
+ elem := list.first;
+ while elem != null {
+ to_delete := elem;
+ elem = elem.next;
+ raw_free(list.allocator, elem);
+ }
+}
+
push_end :: (list: ^List($T), x: T) {
new_elem := allocate_elem(list);
new_elem.data = x;
return begin.data;
}
+count :: (list: ^List($T)) -> i32 {
+ c := 0;
+ elem := list.first;
+ while elem != null {
+ c += 1;
+ elem = elem.next;
+ }
+
+ return c;
+}
+
+at :: (list: ^List($T), index: i32) -> ^T {
+ elem := list.first;
+ while elem != null {
+ if index == 0 do return ^elem.data;
+ index -= 1;
+ elem = elem.next;
+ }
+
+ return null;
+}
+
contains :: (list: ^List($T), x: T) -> bool {
elem := list.first;
while elem != null {
return val;
}
-// map :: #match {
-// (list: ^List($T), f: (^T) -> void) {
-// }
-// }
+map :: #match {}
+#match map (list: ^List($T), f: (^T) -> void) {
+ elem := list.first;
+ while elem != null {
+ f(^elem.data);
+ elem = elem.next;
+ }
+}
+
+#match map (list: ^List($T), f: (T) -> $R) -> List(R) {
+ new_list := make(R, allocator=list.allocator);
+ elem := list.first;
+ while elem != null {
+ push_end(new_list, f(elem.data));
+ elem = elem.next;
+ }
+}
+#local iter :: package core.iter
+#match iter.as_iterator get_iterator
get_iterator :: (list: ^List($T)) -> Iterator(T) {
iterator_next :: (list_iter: ^ListIterator($T)) -> (T, bool) {
use package core.intrinsics.onyx { __zero_value }
};
}
-#local
-allocate_elem :: macro (list: ^List($T)) => new(ListElem(T), allocator=list.allocator);
+#local allocate_elem :: macro (list: ^List($T)) => new(ListElem(T), allocator=list.allocator);