1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
|
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2003-2010, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
// $Id$
package scala.collection
package mutable
import generic._
import script._
import scala.annotation.migration
/** A template trait for mutable sets of type `mutable.Set[A]`.
* @tparam A the type of the elements of the set
* @tparam This the type of the set itself.
*
* $setnote
*
* @author Martin Odersky
* @version 2.8
* @since 2.8
*
* @define setnote
* @note
* This trait provides most of the operations of a `mutable.Set` independently of its representation.
* It is typically inherited by concrete implementations of sets.
*
* To implement a concrete mutable set, you need to provide implementations
* of the following methods:
* {{{
* def contains(elem: A): Boolean
* def iterator: Iterator[A]
* def += (elem: A): this.type
* def -= (elem: A): this.type</pre>
* }}}
* If you wish that methods like `take`,
* `drop`, `filter` return the same kind of set,
* you should also override:
* {{{
* def empty: This</pre>
* }}}
* It is also good idea to override methods `foreach` and
* `size` for efficiency.
* @define coll mutable set
* @define Coll mutable.Set
*/
trait SetLike[A, +This <: SetLike[A, This] with Set[A]]
extends scala.collection.SetLike[A, This]
with Scriptable[A]
with Builder[A, This]
with Growable[A]
with Shrinkable[A]
with Cloneable[mutable.Set[A]]
{ self =>
/** A common implementation of `newBuilder` for all mutable sets
* in terms of `empty`. Overrides the implementation in `collection.SetLike`
* for better efficiency.
*/
override protected[this] def newBuilder: Builder[A, This] = empty
@migration(2, 8, "Set.map now returns a Set, so it will discard duplicate values.")
override def map[B, That](f: A => B)(implicit bf: CanBuildFrom[This, B, That]): That = super.map(f)(bf)
/** Adds an element to this $coll.
*
* @param elem the element to be added
* @return `true` if the element was not yet present in the set, `false` otherwise.
*/
def add(elem: A): Boolean = {
val r = contains(elem)
this += elem
r
}
/** Removes an element from this set.
*
* @param elem The element to be removed.
* @return `true` if the element was previously present in the set, `false` otherwise.
*/
def remove(elem: A): Boolean = {
val r = contains(elem)
this -= elem
r
}
/** Updates the presence of a single element in this set.
*
* This method allows one to add or remove an element `elem`
* from this set depending on the value of parameter `included`.
* Typically, one would use the following syntax:
* {{{
* set(elem) = true // adds element
* set(elem) = false // removes element
* }}}
*
* @param elem the element to be added or removed
* @param included a flag indicating whether element should be included or excluded.
*/
def update(elem: A, included: Boolean) {
if (included) this += elem else this -= elem
}
// abstract methods from Growable/Shrinkable
/** Adds a single element to the set. */
def +=(elem: A): this.type
def -=(elem: A): this.type
/** Removes all elements from the set for which do not satisfy a predicate.
* @param p the predicate used to test elements. Only elements for
* while `p` returns `true` are retained in the set; all others
* are removed.
*/
def retain(p: A => Boolean): Unit = for (elem <- this.toList) if (!p(elem)) this -= elem
/** Removes all elements from the set. After this operation is completed,
* the set will be empty.
*/
def clear() { foreach(-=) }
override def clone(): This = empty ++= repr
/** The result when this set is used as a builder
* @return the set representation itself.
*/
def result: This = repr
/** Adds a single element to this collection and returns
* the collection itself.
*
* @param elem the element to add.
*/
@migration(2, 8,
"As of 2.8, this operation creates a new set. To add an element as a\n"+
"side effect to an existing set and return that set itself, use +=."
)
override def + (elem: A): This = clone() += elem
/** Adds two or more elements to this collection and returns
* the collection itself.
*
* @param elem1 the first element to add.
* @param elem2 the second element to add.
* @param elems the remaining elements to add.
*/
@migration(2, 8,
"As of 2.8, this operation creates a new set. To add the elements as a\n"+
"side effect to an existing set and return that set itself, use +=."
)
override def + (elem1: A, elem2: A, elems: A*): This =
clone() += elem1 += elem2 ++= elems
/** Adds a number of elements provided by a traversable object and returns
* either the collection itself.
*
* @param iter the iterable object.
*/
@migration(2, 8,
"As of 2.8, this operation creates a new set. To add the elements as a\n"+
"side effect to an existing set and return that set itself, use ++=."
)
override def ++(xs: TraversableOnce[A]): This = clone() ++= xs
/** Removes a single element from this collection and returns
* the collection itself.
*
* @param elem the element to remove.
*/
@migration(2, 8,
"As of 2.8, this operation creates a new set. To remove the element as a\n"+
"side effect to an existing set and return that set itself, use -=."
)
override def -(elem: A): This = clone() -= elem
/** Removes two or more elements from this collection and returns
* the collection itself.
*
* @param elem1 the first element to remove.
* @param elem2 the second element to remove.
* @param elems the remaining elements to remove.
*/
@migration(2, 8,
"As of 2.8, this operation creates a new set. To remove the elements as a\n"+
"side effect to an existing set and return that set itself, use -=."
)
override def -(elem1: A, elem2: A, elems: A*): This =
clone() -= elem1 -= elem2 --= elems
/** Removes a number of elements provided by a Traversable object and returns
* the collection itself.
*
* @param iter the Traversable object.
*/
@migration(2, 8,
"As of 2.8, this operation creates a new set. To remove the elements as a\n"+
"side effect to an existing set and return that set itself, use --=."
)
override def --(xs: TraversableOnce[A]): This = clone() --= xs
/** Send a message to this scriptable object.
*
* @param cmd the message to send.
* @throws `Predef.UnsupportedOperationException`
* if the message was not understood.
*/
def <<(cmd: Message[A]): Unit = cmd match {
case Include(_, x) => this += x
case Remove(_, x) => this -= x
case Reset() => clear
case s: Script[_] => s.iterator foreach <<
case _ => throw new UnsupportedOperationException("message " + cmd + " not understood")
}
}
|