aboutsummaryrefslogtreecommitdiff
path: root/Mammoth/Couscous/mammoth/internal/util/Iterables.cs
blob: 6a4d8bbde27bc42a9944ca6ee7ca25d3d3bcfaa0 (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
130
131
132
133
using System.Collections.Generic;
using System.Linq;
using Mammoth.Couscous.java.lang;
using Mammoth.Couscous.java.util;
using Mammoth.Couscous.java.util.function;

namespace Mammoth.Couscous.org.zwobble.mammoth.@internal.util
{
	internal static class Iterables
	{
		internal static Optional<T> getFirst<T>(Iterable<T> iterable) {
			var iterator = iterable.iterator();
			if (iterator.hasNext()) {
				return Optional.of(iterator.next());
			} else {
				return Optional.empty<T>();
			}
		}
		
		internal static T getFirst<T>(Iterable<T> iterable, T defaultValue) {
			var iterator = iterable.iterator();
			if (iterator.hasNext()) {
				return iterator.next();
			} else {
				return defaultValue;
			}
		}
		
		internal static Optional<T> tryGetLast<T>(Iterable<T> iterable) where T : class {
			var hasElement = false;
			T last = null;
			var iterator = iterable.iterator();
			while (iterator.hasNext()) {
				hasElement = true;
				last = iterator.next();
			}
			if (hasElement) {
				return Optional.of(last);
			} else {
				return Optional.empty<T>();
			}
		}
		
		internal static Optional<T> tryFind<T>(Iterable<T> iterable, Predicate<T> predicate) {
			var iterator = iterable.iterator();
			while (iterator.hasNext()) {
				T value = iterator.next();
				if (predicate.test(value)) {
					return new Some<T>(value);
				}
			}
			return None<T>.Instance;
		}
		
		internal static OptionalInt findIndex<T>(Iterable<T> iterable, Predicate<T> predicate) {
			var iterator = iterable.iterator();
			int index = 0;
			while (iterator.hasNext()) {
				T value = iterator.next();
				if (predicate.test(value)) {
					return new SomeInt(index);
				}
				index++;
			}
			return NoneInt.Instance;
		}
		
		internal static Iterable<T> lazyFilter<T>(Iterable<T> iterable, Predicate<T> predicate) {
			var enumerable = FromJava.IterableToEnumerable(iterable).Where(predicate.test);
			return ToJava.EnumerableToIterable(enumerable);
		}
		
		internal static Iterable<U> lazyFilter<T, U>(Iterable<T> iterable, System.Type type) {
			var enumerable = FromJava.IterableToEnumerable(iterable).OfType<U>();
			return ToJava.EnumerableToIterable(enumerable);
		}
		
		internal static Iterable<U> lazyMap<T, U>(Iterable<T> iterable, Function<T, U> function) {
            var enumerable = FromJava.IterableToEnumerable(iterable)
                .Select(function.apply);
			return ToJava.EnumerableToIterable(enumerable);
		}
		
		internal static Iterable<U> lazyFlatMap<T, U>(Iterable<T> iterable, Function<T, Iterable<U>> function) {
            var enumerable = FromJava.IterableToEnumerable(iterable)
                .SelectMany(element => FromJava.IterableToEnumerable(function.apply(element)));
			return ToJava.EnumerableToIterable(enumerable);
		}
		
		internal static Iterable<T> lazyConcat<T>(Iterable<T> first, Iterable<T> second) {
            var enumerable = FromJava.IterableToEnumerable(first)
				.Concat(FromJava.IterableToEnumerable(second));
			return ToJava.EnumerableToIterable(enumerable);
		}
		
		internal static Iterable<int> intRange(int start, int end) {
			return new IntRange(start, end);
		}
		
		private class IntRange : Iterable<int> {
			private readonly int _start;
			private readonly int _end;
			
			internal IntRange(int start, int end) {
				_start = start;
				_end = end;
			}
			
			public Iterator<int> iterator() {
				return new IntRangeIterator(_start, _end);
			}
		}
		
		private class IntRangeIterator : Iterator<int> {
			private int _next;
			private readonly int _end;
			
			internal IntRangeIterator(int start, int end) {
				_next = start;
				_end = end;
			}
			
			public bool hasNext() {
				return _next < _end;
			}
			
			public int next() {
				return _next++;
			}
		}
	}
}