You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Iterators.java 8.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. /* *******************************************************************
  2. * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Eclipse Public License v 2.0
  6. * which accompanies this distribution and is available at
  7. * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
  8. *
  9. * Contributors:
  10. * PARC initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.weaver;
  13. import java.util.HashSet;
  14. import java.util.Iterator;
  15. import java.util.List;
  16. import java.util.NoSuchElementException;
  17. import java.util.Set;
  18. public final class Iterators {
  19. /**
  20. * Private constructor, nobody should ever make one of these
  21. */
  22. private Iterators() {
  23. }
  24. /**
  25. * A getter represents a mapping function from Object to Iterator
  26. */
  27. public interface Getter<A, B> {
  28. Iterator<B> get(A target);
  29. }
  30. /**
  31. * A filter represents a mapping function from Iterator to Iterator
  32. */
  33. public interface Filter<T> {
  34. Iterator<T> filter(Iterator<T> in);
  35. }
  36. /**
  37. * Create a new filter F that, when wrapped around another iterator I, creates a new iterator I' that will return only those
  38. * values of I that have not yet been returned by I', discarding duplicates.
  39. */
  40. public static <T> Filter<T> dupFilter() {
  41. return new Filter<T>() {
  42. final Set<T> seen = new HashSet<>(); // should have weak ptrs?
  43. public Iterator<T> filter(final Iterator<T> in) {
  44. return new Iterator<T>() {
  45. boolean fresh = false;
  46. T peek;
  47. public boolean hasNext() {
  48. if (fresh) {
  49. return true;
  50. }
  51. while (true) {
  52. if (!in.hasNext()) {
  53. return false;
  54. }
  55. peek = in.next();
  56. if (!seen.contains(peek)) {
  57. fresh = true;
  58. return true;
  59. } else {
  60. peek = null; // garbage collection
  61. }
  62. }
  63. }
  64. public T next() {
  65. if (!hasNext()) {
  66. throw new NoSuchElementException();
  67. }
  68. T ret = peek;
  69. seen.add(peek);
  70. peek = null;
  71. fresh = false;
  72. return ret;
  73. }
  74. public void remove() {
  75. throw new UnsupportedOperationException();
  76. }
  77. };
  78. }
  79. };
  80. }
  81. /**
  82. * Creates an iterator that will return the elements of a specified array, in order. Like Arrays.asList(o).iterator(), without
  83. * all that pesky safety.
  84. */
  85. public static <T> Iterator<T> array(final T[] o) {
  86. return new Iterator<T>() {
  87. int i = 0;
  88. int len = (o == null) ? 0 : o.length;
  89. public boolean hasNext() {
  90. return i < len;
  91. }
  92. public T next() {
  93. if (i < len) {
  94. return o[i++];
  95. } else {
  96. throw new NoSuchElementException();
  97. }
  98. }
  99. public void remove() {
  100. throw new UnsupportedOperationException();
  101. }
  102. };
  103. }
  104. public static class ResolvedTypeArrayIterator implements Iterator<ResolvedType> {
  105. private ResolvedType[] array;
  106. private int index;
  107. private int len;
  108. private boolean wantGenerics;
  109. private List<String> alreadySeen; // type signatures
  110. public ResolvedTypeArrayIterator(ResolvedType[] array, List<String> alreadySeen, boolean wantGenerics) {
  111. assert array != null;
  112. this.array = array;
  113. this.wantGenerics = wantGenerics;
  114. this.len = array.length;
  115. this.index = 0;
  116. this.alreadySeen = alreadySeen;
  117. moveToNextNewOne();
  118. }
  119. private void moveToNextNewOne() {
  120. while (index < len) {
  121. ResolvedType interfaceType = array[index];
  122. if (!wantGenerics && interfaceType.isParameterizedOrGenericType()) {
  123. interfaceType = interfaceType.getRawType();
  124. }
  125. String signature = interfaceType.getSignature();
  126. if (!alreadySeen.contains(signature)) {
  127. break;
  128. }
  129. index++;
  130. }
  131. }
  132. public boolean hasNext() {
  133. return index < len;
  134. }
  135. public ResolvedType next() {
  136. if (index < len) {
  137. ResolvedType oo = array[index++];
  138. if (!wantGenerics && (oo.isParameterizedType() || oo.isGenericType())) {
  139. oo = oo.getRawType();
  140. }
  141. alreadySeen.add(oo.getSignature());
  142. moveToNextNewOne();
  143. return oo;
  144. } else {
  145. throw new NoSuchElementException();
  146. }
  147. }
  148. public void remove() {
  149. throw new UnsupportedOperationException();
  150. }
  151. }
  152. public static Iterator<ResolvedType> array(final ResolvedType[] o, final boolean genericsAware) {
  153. return new Iterator<ResolvedType>() {
  154. int i = 0;
  155. int len = (o == null) ? 0 : o.length;
  156. public boolean hasNext() {
  157. return i < len;
  158. }
  159. public ResolvedType next() {
  160. if (i < len) {
  161. ResolvedType oo = o[i++];
  162. if (!genericsAware && (oo.isParameterizedType() || oo.isGenericType())) {
  163. return oo.getRawType();
  164. }
  165. return oo;
  166. } else {
  167. throw new NoSuchElementException();
  168. }
  169. }
  170. public void remove() {
  171. throw new UnsupportedOperationException();
  172. }
  173. };
  174. }
  175. /**
  176. * creates an iterator I based on a base iterator A and a getter G. I returns, in order, forall (i in A), G(i).
  177. */
  178. public static <A, B> Iterator<B> mapOver(final Iterator<A> a, final Getter<A, B> g) {
  179. return new Iterator<B>() {
  180. Iterator<B> delegate = new Iterator<B>() {
  181. public boolean hasNext() {
  182. if (!a.hasNext()) {
  183. return false;
  184. }
  185. A o = a.next();
  186. delegate = append1(g.get(o), this);
  187. return delegate.hasNext();
  188. }
  189. public B next() {
  190. if (!hasNext()) {
  191. throw new UnsupportedOperationException();
  192. }
  193. return delegate.next();
  194. }
  195. public void remove() {
  196. throw new UnsupportedOperationException();
  197. }
  198. };
  199. public boolean hasNext() {
  200. return delegate.hasNext();
  201. }
  202. public B next() {
  203. return delegate.next();
  204. }
  205. public void remove() {
  206. throw new UnsupportedOperationException();
  207. }
  208. };
  209. }
  210. /**
  211. * creates an iterator I based on a base iterator A and a getter G. I returns, in order, forall (i in I) i :: forall (i' in
  212. * g(i)) recur(i', g)
  213. */
  214. public static <A> Iterator<A> recur(final A a, final Getter<A, A> g) {
  215. return new Iterator<A>() {
  216. Iterator<A> delegate = one(a);
  217. public boolean hasNext() {
  218. return delegate.hasNext();
  219. }
  220. public A next() {
  221. A next = delegate.next();
  222. delegate = append(g.get(next), delegate);
  223. return next;
  224. }
  225. public void remove() {
  226. throw new UnsupportedOperationException();
  227. }
  228. };
  229. }
  230. /**
  231. * creates an iterator I based on base iterators A and B. Returns the elements returned by A followed by those returned by B. If
  232. * B is empty, simply returns A, and if A is empty, simply returns B. Do NOT USE if b.hasNext() is not idempotent.
  233. */
  234. public static <T> Iterator<T> append(final Iterator<T> a, final Iterator<T> b) {
  235. if (!b.hasNext()) {
  236. return a;
  237. }
  238. return append1(a, b);
  239. }
  240. /**
  241. * creates an iterator I based on base iterators A and B. Returns the elements returned by A followed by those returned by B. If
  242. * A is empty, simply returns B. Guaranteed not to call B.hasNext() until A is empty.
  243. */
  244. public static <T> Iterator<T> append1(final Iterator<T> a, final Iterator<T> b) {
  245. if (!a.hasNext()) {
  246. return b;
  247. }
  248. return new Iterator<T>() {
  249. public boolean hasNext() {
  250. return a.hasNext() || b.hasNext();
  251. }
  252. public T next() {
  253. if (a.hasNext()) {
  254. return a.next();
  255. }
  256. if (b.hasNext()) {
  257. return b.next();
  258. }
  259. throw new NoSuchElementException();
  260. }
  261. public void remove() {
  262. throw new UnsupportedOperationException();
  263. }
  264. };
  265. }
  266. /**
  267. * creates an iterator I based on a base iterator A and an object O. Returns the elements returned by A, followed by O.
  268. */
  269. public static <T> Iterator<T> snoc(final Iterator<T> first, final T last) {
  270. return new Iterator<T>() {
  271. T last1 = last;
  272. public boolean hasNext() {
  273. return first.hasNext() || last1 != null;
  274. }
  275. public T next() {
  276. if (first.hasNext()) {
  277. return first.next();
  278. } else if (last1 == null) {
  279. throw new NoSuchElementException();
  280. }
  281. T ret = last1;
  282. last1 = null;
  283. return ret;
  284. }
  285. public void remove() {
  286. throw new UnsupportedOperationException();
  287. }
  288. };
  289. }
  290. /**
  291. * creates an iterator I based on an object O. Returns O, once.
  292. */
  293. public static <T> Iterator<T> one(final T it) {
  294. return new Iterator<T>() {
  295. boolean avail = true;
  296. public boolean hasNext() {
  297. return avail;
  298. }
  299. public T next() {
  300. if (!avail) {
  301. throw new NoSuchElementException();
  302. }
  303. avail = false;
  304. return it;
  305. }
  306. public void remove() {
  307. throw new UnsupportedOperationException();
  308. }
  309. };
  310. }
  311. }