-
Notifications
You must be signed in to change notification settings - Fork 5
/
vector.self
157 lines (133 loc) · 4.53 KB
/
vector.self
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
"
Copyright (c) 2022, sin-ack <[email protected]>
SPDX-License-Identifier: GPL-3.0-only
"
std traits _AddSlots: (|
vector = (|
mutable* = std mixins mutableCollection.
indexable* = std mixins indexableCollection.
removable* = std mixins removableCollection.
implicitKeyInsertable* = std mixins implicitKeyInsertableCollection.
parent* = std traits collection.
copy = (
clone
; items: items copy
).
copyRemoveAll = (
clone
; items: std array copy
; size: 0.
).
"Trait & mixin requirements"
at: key = (
(private isWithinBounds: key) ifFalse: [ _Error: 'key out of bounds' ].
items at: key
).
at: key Put: item = (
[| p = private |
(p isWithinBounds: key) ifFalse: [ _Error: 'key out of bounds' ].
p at: key PutWithoutBoundsCheck: item.
] value.
self
).
remove: index IfAbsent: blk = (
[| p = private |
(p isWithinBounds: index) ifFalse: [^ blk value].
p removeIndex: index.
] value.
self
).
add: item = (
[| p = private |
p ensureSpaceForOneMore.
p at: size PutWithoutBoundsCheck: item.
size: size succ.
] value.
self
).
shift = (| value |
value: at: 0.
remove: 0.
value
).
capacity = (items size).
shrinkToFit = (private resizeTo: size. self).
asString = (| s |
s: '['.
each: [| :v. :i |
i > 0 ifTrue: [ s: s, ', ' ].
s: s, v asString.
].
s, ']'.
).
sort = (sortKey: [| :v | v]).
"Naive quicksort implementation."
sortKey: keyBlock = (| pivot |
size < 2 ifTrue: [ ^ self ].
private quickSortFrom: 0 Until: size KeyBlock: keyBlock.
self
).
reverse = (| p |
p: private.
firstKey to: (lastKey - firstKey) / 2 Do: [| :k |
p swap: k With: lastKey - k.
].
self
).
copyFrom: start = (copyFrom: start To: size).
copyFrom: start To: end = (| new |
new: copyRemoveAll.
start to: end Do: [| :i | new add: at: i ].
new
).
private = (|
prototype = (|
receiver* <- nil.
resizeTo: c = (
items: items copySize: c.
).
grow = (resizeTo: (2 ** capacity succ bitLength; max: 4)).
ensureSpaceForOneMore = (capacity = size ifTrue: [ grow ]).
at: index PutWithoutBoundsCheck: value = (
items at: index Put: value.
).
isWithinBounds: index = ((index >= firstKey) && [index <= lastKey]).
removeIndex: index = (
index to: size prec Do: [| :i |
at: i PutWithoutBoundsCheck: at: i + 1.
].
size: size prec.
at: size PutWithoutBoundsCheck: nil.
).
quickSortFrom: start Until: end KeyBlock: keyBlock = (| pivot. pivotKey. pivotIndex. |
(start >= end) || [start < 0] ifTrue: [ ^ nil ].
pivot: at: end prec.
pivotKey: keyBlock value: pivot.
pivotIndex: start prec.
start to: end prec Do: [| :i |
(keyBlock value: at: i) <= pivotKey ifTrue: [
pivotIndex: pivotIndex succ.
swap: pivotIndex With: i.
]
].
pivotIndex: pivotIndex succ.
swap: pivotIndex With: end prec.
quickSortFrom: start Until: pivotIndex KeyBlock: keyBlock.
quickSortFrom: pivotIndex succ Until: end KeyBlock: keyBlock.
).
swap: a With: b = (| temp |
temp: at: a.
at: a Put: at: b.
at: b Put: temp.
).
|).
| prototype clone; receiver: self).
|).
|).
std _AddSlots: (|
vector = (|
parent* = std traits vector.
items <- std array.
size <- 0.
|).
|)