comparison tango/tango/util/collection/iterator/FilteringIterator.d @ 132:1700239cab2e trunk

[svn r136] MAJOR UNSTABLE UPDATE!!! Initial commit after moving to Tango instead of Phobos. Lots of bugfixes... This build is not suitable for most things.
author lindquist
date Fri, 11 Jan 2008 17:57:40 +0100
parents
children
comparison
equal deleted inserted replaced
131:5825d48b27d1 132:1700239cab2e
1 /*
2 File: FilteringIterator.d
3
4 Originally written by Doug Lea and released into the public domain.
5 Thanks for the assistance and support of Sun Microsystems Labs, Agorics
6 Inc, Loral, and everyone contributing, testing, and using this code.
7
8 History:
9 Date Who What
10 22Oct95 dl@cs.oswego.edu Created.
11
12 */
13
14
15 module tango.util.collection.iterator.FilteringIterator;
16
17 private import tango.core.Exception;
18
19 private import tango.util.collection.model.Iterator;
20
21 /**
22 *
23 * FilteringIterators allow you to filter out elements from
24 * other enumerations before they are seen by their `consumers'
25 * (i.e., the callers of `get').
26 *
27 * FilteringIterators work as wrappers around other Iterators.
28 * To build one, you need an existing Iterator (perhaps one
29 * from coll.elements(), for some Collection coll), and a Predicate
30 * object (i.e., implementing interface Predicate).
31 * For example, if you want to screen out everything but Panel
32 * objects from a collection coll that might hold things other than Panels,
33 * write something of the form:
34 * ---
35 * Iterator e = coll.elements();
36 * Iterator panels = FilteringIterator(e, IsPanel);
37 * while (panels.more())
38 * doSomethingWith(cast(Panel)(panels.get()));
39 * ---
40 * To use this, you will also need to write a little class of the form:
41 * ---
42 * class IsPanel : Predicate {
43 * bool predicate(Object v) { return ( 0 !is cast(Panel)v; }
44 * }
45 * ---
46 * See_Also: tango.util.collection.Predicate.predicate
47 * author: Doug Lea
48 *
49 **/
50
51 public class FilteringIterator(T) : Iterator!(T)
52 {
53 alias bool delegate(T) Predicate;
54
55 // instance variables
56
57 /**
58 * The enumeration we are wrapping
59 **/
60
61 private Iterator!(T) src_;
62
63 /**
64 * The screening predicate
65 **/
66
67 private Predicate pred_;
68
69 /**
70 * The sense of the predicate. False means to invert
71 **/
72
73 private bool sign_;
74
75 /**
76 * The next element to hand out
77 **/
78
79 private T get_;
80
81 /**
82 * True if we have a next element
83 **/
84
85 private bool haveNext_;
86
87 /**
88 * Make a Filter using src for the elements, and p as the screener,
89 * selecting only those elements of src for which p is true
90 **/
91
92 public this (Iterator!(T) src, Predicate p)
93 {
94 this(src, p, true);
95 }
96
97 /**
98 * Make a Filter using src for the elements, and p as the screener,
99 * selecting only those elements of src for which p.predicate(v) == sense.
100 * A value of true for sense selects only values for which p.predicate
101 * is true. A value of false selects only those for which it is false.
102 **/
103 public this (Iterator!(T) src, Predicate p, bool sense)
104 {
105 src_ = src;
106 pred_ = p;
107 sign_ = sense;
108 findNext();
109 }
110
111 /**
112 * Implements java.util.Iterator.more
113 **/
114
115 public final bool more()
116 {
117 return haveNext_;
118 }
119
120 /**
121 * Implements java.util.Iterator.get.
122 **/
123 public final T get()
124 {
125 if (! haveNext_)
126 throw new NoSuchElementException("exhausted enumeration");
127 else
128 {
129 auto result = get_;
130 findNext();
131 return result;
132 }
133 }
134
135
136 int opApply (int delegate (inout T value) dg)
137 {
138 int result;
139
140 while (haveNext_)
141 {
142 auto value = get();
143 if ((result = dg(value)) != 0)
144 break;
145 }
146 return result;
147 }
148
149
150 /**
151 * Traverse through src_ elements finding one passing predicate
152 **/
153 private final void findNext()
154 {
155 haveNext_ = false;
156
157 for (;;)
158 {
159 if (! src_.more())
160 return ;
161 else
162 {
163 try {
164 auto v = src_.get();
165 if (pred_(v) is sign_)
166 {
167 haveNext_ = true;
168 get_ = v;
169 return;
170 }
171 } catch (NoSuchElementException ex)
172 {
173 return;
174 }
175 }
176 }
177 }
178 }
179