aboutsummaryrefslogtreecommitdiff
path: root/Mammoth/Couscous/mammoth/internal/util/Lists.cs
blob: 4601b282f21e61bd4406a3faa4639cde55ab28e8 (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
using Mammoth.Couscous.java.lang;
using Mammoth.Couscous.java.util;
using Mammoth.Couscous.java.util.function;
using System.Linq;

namespace Mammoth.Couscous.org.zwobble.mammoth.@internal.util {
    internal static class Lists {
        internal static List<T> list<T>(params T[] values) {
            return ToJava.ListToList(values);
        }
        
        internal static List<T> toList<T>(Iterable<T> iterable) {
            return ToJava.ListToList(FromJava.IterableToEnumerable(iterable).ToList());
        }
        
        internal static List<T> eagerFilter<T>(Iterable<T> iterable, Predicate<T> function) {
            var result = FromJava.IterableToEnumerable(iterable)
                .Where(function.test)
                .ToList();
            return ToJava.ListToList(result);
        }
        
        internal static List<U> eagerMap<T, U>(Iterable<T> iterable, Function<T, U> function) {
            var result = FromJava.IterableToEnumerable(iterable)
                .Select(function.apply)
                .ToList();
            return ToJava.ListToList(result);
        }
        
        internal static List<U> eagerMapWithIndex<T, U>(Iterable<T> iterable, BiFunction<int, T, U> function) {
            var result = FromJava.IterableToEnumerable(iterable)
                .Select((value, index) => function.apply(index, value))
                .ToList();
            return ToJava.ListToList(result);
        }
        
        internal static List<U> eagerFlatMap<T, U>(Iterable<T> iterable, Function<T, Iterable<U>> function) {
            var result = FromJava.IterableToEnumerable(iterable)
                .SelectMany(element => FromJava.IterableToEnumerable(function.apply(element)))
                .ToList();
            return ToJava.ListToList(result);
        }
        
        internal static List<T> cons<T>(T head, Iterable<T> tail) {
            var result = new T[] { head }
				.Concat(FromJava.IterableToEnumerable(tail))
                .ToList();
			return ToJava.ListToList(result);
        }
        
        internal static List<T> eagerConcat<T>(Iterable<T> first, Iterable<T> second) {
            var result = FromJava.IterableToEnumerable(first)
				.Concat(FromJava.IterableToEnumerable(second))
                .ToList();
			return ToJava.ListToList(result);
        }
        
        internal static List<T> eagerConcat<T>(Iterable<T> first, Iterable<T> second, Iterable<T> third) {
            var result = FromJava.IterableToEnumerable(first)
				.Concat(FromJava.IterableToEnumerable(second))
                .Concat(FromJava.IterableToEnumerable(third))
                .ToList();
			return ToJava.ListToList(result);
        }
        
        internal static List<T> orderedBy<T, R>(Iterable<T> iterable, Function<T, R> getKey) {
            var result = FromJava.IterableToEnumerable(iterable)
                .OrderBy(getKey.apply)
                .ToList();
            return ToJava.ListToList(result);
        }
        
        internal static Optional<T> tryGetFirst<T>(List<T> list) {
            if (list.isEmpty()) {
                return None<T>.Instance;
            } else {
                return new Some<T>(list.get(0));
            }
        }
        
        internal static Optional<T> tryGetLast<T>(List<T> list) {
            if (list.isEmpty()) {
                return None<T>.Instance;
            } else {
                return new Some<T>(list.get(list.size() - 1));
            }
        }
        
        internal static Iterable<T> reversed<T>(List<T> list) {
            return new ReversedList<T>(list);
        }
        
        private class ReversedList<T> : Iterable<T> {
            private readonly List<T> _list;
            
            internal ReversedList(List<T> list) {
                _list = list;
            }
            
            public Iterator<T> iterator() {
                return new ReverseIterator<T>(_list);
            }
        }
        
        private class ReverseIterator<T> : Iterator<T> {
            private readonly List<T> _list;
            private int _nextIndex;
            
            internal ReverseIterator(List<T> list) {
                _list = list;
                _nextIndex = _list.size() - 1;
            }
            
            public bool hasNext() {
                return _nextIndex >= 0;
            }
            
            public T next() {
                if (hasNext()) {
                    return _list.get(_nextIndex--);
                } else {
                    throw new NoSuchElementException();
                }
            }
        }
    }
}