132
|
1 /*******************************************************************************
|
|
2
|
|
3 File: MapCollection.d
|
|
4
|
|
5 Originally written by Doug Lea and released into the public domain.
|
|
6 Thanks for the assistance and support of Sun Microsystems Labs, Agorics
|
|
7 Inc, Loral, and everyone contributing, testing, and using this code.
|
|
8
|
|
9 History:
|
|
10 Date Who What
|
|
11 13Oct95 dl Create
|
|
12 28jan97 dl make class public
|
|
13 14Dec06 kb adapted for Tango usage
|
|
14
|
|
15 ********************************************************************************/
|
|
16
|
|
17 module tango.util.collection.impl.MapCollection;
|
|
18
|
|
19 private import tango.core.Exception;
|
|
20
|
|
21 private import tango.util.collection.impl.Collection;
|
|
22
|
|
23 private import tango.util.collection.model.Map,
|
|
24 tango.util.collection.model.View,
|
|
25 tango.util.collection.model.MapView,
|
|
26 tango.util.collection.model.Iterator,
|
|
27 tango.util.collection.model.SortedKeys;
|
|
28
|
|
29
|
|
30 /*******************************************************************************
|
|
31
|
|
32 MapCollection extends Collection to provide default implementations of
|
|
33 some Map operations.
|
|
34
|
|
35 author: Doug Lea
|
|
36 @version 0.93
|
|
37
|
|
38 <P> For an introduction to this package see <A HREF="index.html"
|
|
39 > Overview </A>.
|
|
40
|
|
41 ********************************************************************************/
|
|
42
|
|
43 public abstract class MapCollection(K, T) : Collection!(T), Map!(K, T)
|
|
44 {
|
|
45 alias MapView!(K, T) MapViewT;
|
|
46 alias Collection!(T).remove remove;
|
|
47 alias Collection!(T).removeAll removeAll;
|
|
48
|
|
49
|
|
50 /***********************************************************************
|
|
51
|
|
52 Initialize at version 0, an empty count, and null screener
|
|
53
|
|
54 ************************************************************************/
|
|
55
|
|
56 protected this ()
|
|
57 {
|
|
58 super();
|
|
59 }
|
|
60
|
|
61 /***********************************************************************
|
|
62
|
|
63 Initialize at version 0, an empty count, and supplied screener
|
|
64
|
|
65 ************************************************************************/
|
|
66
|
|
67 protected this (Predicate screener)
|
|
68 {
|
|
69 super(screener);
|
|
70 }
|
|
71
|
|
72 /***********************************************************************
|
|
73
|
|
74 Implements tango.util.collection.Map.allowsKey.
|
|
75 Default key-screen. Just checks for null.
|
|
76
|
|
77 See_Also: tango.util.collection.Map.allowsKey
|
|
78
|
|
79 ************************************************************************/
|
|
80
|
|
81 public final bool allowsKey(K key)
|
|
82 {
|
|
83 return (key !is K.init);
|
|
84 }
|
|
85
|
|
86 protected final bool isValidKey(K key)
|
|
87 {
|
|
88 static if (is (K : Object))
|
|
89 {
|
|
90 if (key is null)
|
|
91 return false;
|
|
92 }
|
|
93 return true;
|
|
94 }
|
|
95
|
|
96 /***********************************************************************
|
|
97
|
|
98 Principal method to throw a IllegalElementException for keys
|
|
99
|
|
100 ************************************************************************/
|
|
101
|
|
102 protected final void checkKey(K key)
|
|
103 {
|
|
104 if (!isValidKey(key))
|
|
105 {
|
|
106 throw new IllegalElementException("Attempt to include invalid key _in Collection");
|
|
107 }
|
|
108 }
|
|
109
|
|
110 /***********************************************************************
|
|
111
|
|
112 Implements tango.util.collection.impl.MapCollection.MapCollection.opIndexAssign
|
|
113 Just calls add(key, element).
|
|
114
|
|
115 See_Also: tango.util.collection.impl.MapCollection.MapCollection.add
|
|
116
|
|
117 ************************************************************************/
|
|
118
|
|
119 public final void opIndexAssign (T element, K key)
|
|
120 {
|
|
121 add (key, element);
|
|
122 }
|
|
123
|
|
124 /***********************************************************************
|
|
125
|
|
126 Implements tango.util.collection.impl.Collection.Collection.matches
|
|
127 Time complexity: O(n).
|
|
128 Default implementation. Fairly sleazy approach.
|
|
129 (Defensible only when you remember that it is just a default impl.)
|
|
130 It tries to cast to one of the known collection interface types
|
|
131 and then applies the corresponding comparison rules.
|
|
132 This suffices for all currently supported collection types,
|
|
133 but must be overridden if you define new Collection subinterfaces
|
|
134 and/or implementations.
|
|
135
|
|
136 See_Also: tango.util.collection.impl.Collection.Collection.matches
|
|
137
|
|
138 ************************************************************************/
|
|
139
|
|
140 public override bool matches(View!(T) other)
|
|
141 {
|
|
142 if (other is null)
|
|
143 {}
|
|
144 else
|
|
145 if (other is this)
|
|
146 return true;
|
|
147 else
|
|
148 {
|
|
149 auto tmp = cast (MapViewT) other;
|
|
150 if (tmp)
|
|
151 if (cast(SortedKeys!(K, T)) this)
|
|
152 return sameOrderedPairs(this, tmp);
|
|
153 else
|
|
154 return samePairs(this, tmp);
|
|
155 }
|
|
156 return false;
|
|
157 }
|
|
158
|
|
159
|
|
160 public final static bool samePairs(MapViewT s, MapViewT t)
|
|
161 {
|
|
162 if (s.size !is t.size)
|
|
163 return false;
|
|
164
|
|
165 try { // set up to return false on collection exceptions
|
|
166 foreach (key, value; t.keys)
|
|
167 if (! s.containsPair (key, value))
|
|
168 return false;
|
|
169 } catch (NoSuchElementException ex)
|
|
170 {
|
|
171 return false;
|
|
172 }
|
|
173 return true;
|
|
174 }
|
|
175
|
|
176 public final static bool sameOrderedPairs(MapViewT s, MapViewT t)
|
|
177 {
|
|
178 if (s.size !is t.size)
|
|
179 return false;
|
|
180
|
|
181 auto ss = s.keys();
|
|
182 try { // set up to return false on collection exceptions
|
|
183 foreach (key, value; t.keys)
|
|
184 {
|
|
185 K sk;
|
|
186 auto sv = ss.get (sk);
|
|
187 if (sk != key || sv != value)
|
|
188 return false;
|
|
189 }
|
|
190 } catch (NoSuchElementException ex)
|
|
191 {
|
|
192 return false;
|
|
193 }
|
|
194 return true;
|
|
195 }
|
|
196
|
|
197
|
|
198 // Object methods
|
|
199
|
|
200 /***********************************************************************
|
|
201
|
|
202 Implements tango.util.collection.impl.Collection.Collection.removeAll
|
|
203 See_Also: tango.util.collection.impl.Collection.Collection.removeAll
|
|
204
|
|
205 Has to be here rather than in the superclass to satisfy
|
|
206 D interface idioms
|
|
207
|
|
208 ************************************************************************/
|
|
209
|
|
210 public void removeAll (Iterator!(T) e)
|
|
211 {
|
|
212 while (e.more)
|
|
213 removeAll (e.get);
|
|
214 }
|
|
215
|
|
216 /***********************************************************************
|
|
217
|
|
218 Implements tango.util.collection.impl.Collection.Collection.removeElements
|
|
219 See_Also: tango.util.collection.impl.Collection.Collection.removeElements
|
|
220
|
|
221 Has to be here rather than in the superclass to satisfy
|
|
222 D interface idioms
|
|
223
|
|
224 ************************************************************************/
|
|
225
|
|
226 public void remove (Iterator!(T) e)
|
|
227 {
|
|
228 while (e.more)
|
|
229 remove (e.get);
|
|
230 }
|
|
231 }
|
|
232
|