Enumerable.vala 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. namespace Invercargill {
  2. public abstract class Enumerable<T> {
  3. public abstract Tracker<T> get_tracker();
  4. // Returns false if iteration was interrupted
  5. // Returns true if iteration reached natural end
  6. public virtual bool iterate_if(PredicateDelegate<T> handler) {
  7. var tracker = get_tracker();
  8. while(tracker.has_next()) {
  9. if(!handler(tracker.get_next())) {
  10. return false;
  11. }
  12. }
  13. return true;
  14. }
  15. public virtual void iterate(ItemDelegate<T> handler) {
  16. iterate_if(i => {
  17. handler(i);
  18. return true;
  19. });
  20. }
  21. public virtual Sequence<T> to_sequence() {
  22. var sequence = new Sequence<T>();
  23. iterate(i => sequence.add(i));
  24. return sequence;
  25. }
  26. public virtual Gee.Collection<T> to_collection() {
  27. var collection = new Gee.LinkedList<T>();
  28. iterate(i => collection.add(i));
  29. return collection;
  30. }
  31. public virtual Gee.Iterable<T> as_iterable() {
  32. return new GeeIterable<T>(this);
  33. }
  34. public virtual T[] to_array() {
  35. return to_collection().to_array();
  36. }
  37. public virtual int count() {
  38. var count = 0;
  39. iterate(i => count++);
  40. return count;
  41. }
  42. public virtual bool any(PredicateDelegate<T> predicate) {
  43. var result = false;
  44. iterate_if(i => {
  45. if(predicate(i)) {
  46. result = true;
  47. return false;
  48. }
  49. return true;
  50. });
  51. return result;
  52. }
  53. public virtual bool all(PredicateDelegate<T> predicate) {
  54. return !any(i => !predicate(i));
  55. }
  56. public virtual bool no(PredicateDelegate<T> predicate) {
  57. return all(i => !predicate(i));
  58. }
  59. public virtual Enumerable<T> where(owned PredicateDelegate<T> predicate) {
  60. return new FilterQuery<T>(this, (owned)predicate);
  61. }
  62. public virtual Enumerable<Tout> select<Tout>(owned TransformDelegate<T, Tout> transform) {
  63. return new TransformQuery<T, Tout>(this, (owned)transform);
  64. }
  65. public virtual Enumerable<Tout> select_many<Tout>(owned TransformDelegate<T, Enumerable<Tout>> transform) {
  66. return new MergeQuery<Tout>(select((owned)transform));
  67. }
  68. public virtual Enumerable<T> sort(owned CompareDelegate<T> compare) {
  69. return new SortQuery<T>(this, (owned)compare);
  70. }
  71. public virtual Enumerable<T> concat(Enumerable<T> other) {
  72. return new ConcatEnumerable<T>(this, other);
  73. }
  74. public virtual Enumerable<T> take(int count) {
  75. return new TakeQuery<T>(this, count);
  76. }
  77. public virtual Enumerable<T> skip(int count) {
  78. return new SkipQuery<T>(this, count);
  79. }
  80. public virtual Tout aggrigate<Tout>(Tout initial, AggrigateDelegate<Tout, T> aggrigate_func) {
  81. var aggrigate = initial;
  82. iterate(i => {
  83. aggrigate = aggrigate_func(aggrigate, i);
  84. });
  85. return aggrigate;
  86. }
  87. public virtual bool contains(T item) {
  88. return any(i => i == item);
  89. }
  90. public virtual Enumerable<Pair<T, Tother>> pair<Tother>(Enumerable<Tother> other) {
  91. return new PairEnumerable<T, Tother>(this, other);
  92. }
  93. public virtual Enumerable<T> zip(Enumerable<T> other) {
  94. return new ZipperEnumerable<T>(this, other);
  95. }
  96. public virtual Enumerable<Tout> fork<Tout>(owned TransformDelegate<T, Tout> fork1, owned TransformDelegate<T, Tout> fork2) {
  97. var seq = to_sequence();
  98. return seq.select<Tout>((owned)fork1).zip(seq.select<Tout>((owned)fork2));
  99. }
  100. public virtual Enumerable<Tout> fork_many<Tout>(owned TransformDelegate<T, Enumerable<Tout>> fork1, owned TransformDelegate<T, Enumerable<Tout>> fork2) {
  101. return new MergeQuery<Tout>(fork((owned)fork1, (owned)fork2));
  102. }
  103. public virtual bool matches(Enumerable<T> other, EqualityDelegate<T> equals) {
  104. return pair(other).all(p => equals(p.value1, p.value2));
  105. }
  106. public virtual Enumerable<T> with(T item) {
  107. var seq = new Sequence<T>();
  108. seq.add(item);
  109. return concat(seq);
  110. }
  111. public virtual T first() throws SequenceError {
  112. var tracker = get_tracker();
  113. if(tracker.has_next()) {
  114. return tracker.get_next();
  115. }
  116. throw new SequenceError.NO_ELEMENTS("The sequence contains no elements");
  117. }
  118. public virtual T? first_or_default() {
  119. var tracker = get_tracker();
  120. if(tracker.has_next()) {
  121. return tracker.get_next();
  122. }
  123. return null;
  124. }
  125. public virtual T single() throws SequenceError {
  126. var tracker = get_tracker();
  127. if(tracker.has_next()) {
  128. var item = tracker.get_next();
  129. if(tracker.has_next()) {
  130. throw new SequenceError.MULTUPLE_ELEMENTS("The sequence contains more than one element");
  131. }
  132. return item;
  133. }
  134. throw new SequenceError.NO_ELEMENTS("The sequence contains no elements");
  135. }
  136. public virtual T single_or_default() throws SequenceError {
  137. var tracker = get_tracker();
  138. if(tracker.has_next()) {
  139. var item = tracker.get_next();
  140. if(tracker.has_next()) {
  141. throw new SequenceError.MULTUPLE_ELEMENTS("The sequence contains more than one element");
  142. }
  143. return item;
  144. }
  145. return null;
  146. }
  147. public virtual string to_string(TransformDelegate<T, string> stringifier, string seperator = "") {
  148. bool is_first = false;
  149. return aggrigate<string>("", (s, v) => {
  150. if(is_first) {
  151. is_first = true;
  152. return stringifier(v);
  153. }
  154. return s + seperator + stringifier(v);
  155. });
  156. }
  157. }
  158. }