Mercurial > projects > ldc
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 |