Mercurial > projects > ldc
comparison tango/tango/util/collection/iterator/InterleavingIterator.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: InterleavingIterator.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.InterleavingIterator; | |
16 | |
17 private import tango.core.Exception; | |
18 | |
19 private import tango.util.collection.model.Iterator; | |
20 | |
21 /** | |
22 * | |
23 * InterleavingIterators allow you to combine the elements | |
24 * of two different enumerations as if they were one enumeration | |
25 * before they are seen by their `consumers'. | |
26 * This sometimes allows you to avoid having to use a | |
27 * Collection object to temporarily combine two sets of Collection elements() | |
28 * that need to be collected together for common processing. | |
29 * <P> | |
30 * The elements are revealed (via get()) in a purely | |
31 * interleaved fashion, alternating between the first and second | |
32 * enumerations unless one of them has been exhausted, in which case | |
33 * all remaining elements of the other are revealed until it too is | |
34 * exhausted. | |
35 * <P> | |
36 * InterleavingIterators work as wrappers around other Iterators. | |
37 * To build one, you need two existing Iterators. | |
38 * For example, if you want to process together the elements of | |
39 * two Collections a and b, you could write something of the form: | |
40 * <PRE> | |
41 * Iterator items = InterleavingIterator(a.elements(), b.elements()); | |
42 * while (items.more()) | |
43 * doSomethingWith(items.get()); | |
44 * </PRE> | |
45 * | |
46 author: Doug Lea | |
47 * @version 0.93 | |
48 * | |
49 * <P> For an introduction to this package see <A HREF="index.html"> Overview </A>. | |
50 * | |
51 **/ | |
52 | |
53 | |
54 public class InterleavingIterator(T) : Iterator!(T) | |
55 { | |
56 | |
57 /** | |
58 * The first source; nulled out once it is exhausted | |
59 **/ | |
60 | |
61 private Iterator!(T) fst_; | |
62 | |
63 /** | |
64 * The second source; nulled out once it is exhausted | |
65 **/ | |
66 | |
67 private Iterator!(T) snd_; | |
68 | |
69 /** | |
70 * The source currently being used | |
71 **/ | |
72 | |
73 private Iterator!(T) current_; | |
74 | |
75 | |
76 | |
77 /** | |
78 * Make an enumeration interleaving elements from fst and snd | |
79 **/ | |
80 | |
81 public this (Iterator!(T) fst, Iterator!(T) snd) | |
82 { | |
83 fst_ = fst; | |
84 snd_ = snd; | |
85 current_ = snd_; // flip will reset to fst (if it can) | |
86 flip(); | |
87 } | |
88 | |
89 /** | |
90 * Implements java.util.Iterator.more | |
91 **/ | |
92 public final bool more() | |
93 { | |
94 return current_ !is null; | |
95 } | |
96 | |
97 /** | |
98 * Implements java.util.Iterator.get. | |
99 **/ | |
100 public final T get() | |
101 { | |
102 if (current_ is null) | |
103 throw new NoSuchElementException("exhausted iterator"); | |
104 else | |
105 { | |
106 // following line may also throw ex, but there's nothing | |
107 // reasonable to do except propagate | |
108 auto result = current_.get(); | |
109 flip(); | |
110 return result; | |
111 } | |
112 } | |
113 | |
114 | |
115 int opApply (int delegate (inout T value) dg) | |
116 { | |
117 int result; | |
118 | |
119 while (current_) | |
120 { | |
121 auto value = get(); | |
122 if ((result = dg(value)) != 0) | |
123 break; | |
124 } | |
125 return result; | |
126 } | |
127 | |
128 /** | |
129 * Alternate sources | |
130 **/ | |
131 | |
132 private final void flip() | |
133 { | |
134 if (current_ is fst_) | |
135 { | |
136 if (snd_ !is null && !snd_.more()) | |
137 snd_ = null; | |
138 if (snd_ !is null) | |
139 current_ = snd_; | |
140 else | |
141 { | |
142 if (fst_ !is null && !fst_.more()) | |
143 fst_ = null; | |
144 current_ = fst_; | |
145 } | |
146 } | |
147 else | |
148 { | |
149 if (fst_ !is null && !fst_.more()) | |
150 fst_ = null; | |
151 if (fst_ !is null) | |
152 current_ = fst_; | |
153 else | |
154 { | |
155 if (snd_ !is null && !snd_.more()) | |
156 snd_ = null; | |
157 current_ = snd_; | |
158 } | |
159 } | |
160 } | |
161 | |
162 | |
163 } | |
164 |