/usr/share/gnu-smalltalk/kernel/MappedColl.st is in gnu-smalltalk-common 3.2.4-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 | "======================================================================
|
| MappedCollection Method Definitions
|
|
======================================================================"
"======================================================================
|
| Copyright 1988,92,94,95,99,2000,2001,2002,2006,2007,2008
| Free Software Foundation, Inc.
| Written by Steve Byrne.
|
| This file is part of the GNU Smalltalk class library.
|
| The GNU Smalltalk class library is free software; you can redistribute it
| and/or modify it under the terms of the GNU Lesser General Public License
| as published by the Free Software Foundation; either version 2.1, or (at
| your option) any later version.
|
| The GNU Smalltalk class library is distributed in the hope that it will be
| useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
| General Public License for more details.
|
| You should have received a copy of the GNU Lesser General Public License
| along with the GNU Smalltalk class library; see the file COPYING.LIB.
| If not, write to the Free Software Foundation, 59 Temple Place - Suite
| 330, Boston, MA 02110-1301, USA.
|
======================================================================"
Collection subclass: MappedCollection [
| domain map |
<category: 'Collections-Keyed'>
<comment: 'I represent collections of objects that are indirectly indexed by names.
There are really two collections involved: domain and a map. The map maps
between external names and indices into domain, which contains the
real association. In order to work properly, the domain must be an instance
of a subclass of SequenceableCollection, and the map must be an instance of
Dictionary, or of a subclass of SequenceableCollection.
As an example of using me, consider implenting a Dictionary whose elements
are indexed. The domain would be a SequenceableCollection with n elements,
the map a Dictionary associating each key to an index in the domain. To
access by key, to perform enumeration, etc. you would ask an instance of me;
to access by index, you would access the domain directly.
Another idea could be to implement row access or column access to a matrix
implemented as a single n*m Array: the Array would be the domain, while the
map would be an Interval.
'>
MappedCollection class >> collection: aCollection map: aMap [
"Answer a new MappedCollection using the given domain (aCollection)
and map"
<category: 'instance creation'>
^self basicNew setCollection: aCollection andMap: aMap
]
MappedCollection class >> new [
"This method should not be used; instead, use #collection:map: to
create MappedCollection."
<category: 'instance creation'>
SystemExceptions.WrongMessageSent signalOn: #new
useInstead: #collection:map:
]
at: key [
"Answer the object at the given key"
<category: 'basic'>
^domain at: (map at: key)
]
atAll: keyCollection [
"Answer a new MappedCollection that only includes the given keys. The new
MappedCollection might use keyCollection or consecutive integers for the
keys, depending on the map's type. Fail if any of them is not found in
the map."
<category: 'basic'>
^self class collection: domain map: (map atAll: keyCollection)
]
at: key put: value [
"Store value at the given key"
<category: 'basic'>
^domain at: (map at: key) put: value
]
domain [
"Answer the receiver's domain"
<category: 'basic'>
^domain
]
map [
"Answer the receiver's map"
<category: 'basic'>
^map
]
size [
"Answer the receiver's size"
<category: 'basic'>
^map size
]
add: anObject [
<category: 'basic'>
self shouldNotImplement
]
contents [
"Answer a bag with the receiver's values"
<category: 'basic'>
| aBag |
aBag := Bag new.
map do: [:value | aBag add: (domain at: value)].
^aBag
]
copyFrom: a to: b [
"Answer a new collection containing all the items in the receiver from the
a-th to the b-th."
<category: 'basic'>
^domain atAll: (map atAll: (a to: b))
]
do: aBlock [
"Evaluate aBlock for each object"
<category: 'basic'>
map do: [:value | aBlock value: (domain at: value)]
]
keys [
"Answer the keys that can be used to access this collection."
<category: 'basic'>
^map keys
]
keysAndValuesDo: aBlock [
"Evaluate aBlock passing two arguments, one being a key that can be used to
access this collection, and the other one being the value."
<category: 'basic'>
map do: [:key | aBlock value: key value: (self at: key)]
]
keysDo: aBlock [
"Evaluate aBlock on the keys that can be used to access this collection."
<category: 'basic'>
map keysDo: aBlock
]
collect: aBlock [
"Answer a Collection with the same keys as the map, where accessing
a key yields the value obtained by passing through aBlock the value
accessible from the key in the receiver. The result need not be
another MappedCollection"
"This is tricky. Optimize the operation in order to perform the
minimal number of evaluation of aBlock"
<category: 'basic'>
^domain size > map size
ifTrue: [map collect: [:key | aBlock value: (self at: key)]]
ifFalse: [self class collection: (domain collect: aBlock) map: map copy]
]
reject: aBlock [
"Answer the objects in the domain for which aBlock returns false"
<category: 'basic'>
| newMap |
newMap := newMap reject: [:key | aBlock value: (self at: key)].
^self class collection: domain map: newMap
]
select: aBlock [
"Answer the objects in the domain for which aBlock returns true"
<category: 'basic'>
| newMap |
newMap := newMap select: [:key | aBlock value: (self at: key)].
^self class collection: domain map: newMap
]
setCollection: aCollection andMap: aMap [
<category: 'private'>
domain := aCollection.
map := aMap
]
species [
<category: 'private'>
^self class
]
]
|