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