Mercurial > hg > Others > Rakudo
comparison src/core.c/SetHash.pm6 @ 0:c341f82e7ad7 default tip
Rakudo branch in cr.ie.u-ryukyu.ac.jp
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 26 Dec 2019 16:50:27 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c341f82e7ad7 |
---|---|
1 my class SetHash does Setty { | |
2 | |
3 method ^parameterize(Mu \base, Mu \type) { | |
4 Rakudo::Internals.PARAMETERIZE-KEYOF(base,type) | |
5 } | |
6 | |
7 #--- selector methods | |
8 | |
9 multi method grab(SetHash:D:) { | |
10 nqp::if( | |
11 $!elems, | |
12 nqp::stmts( | |
13 (my $object := nqp::iterval( | |
14 my $iter := Rakudo::QuantHash.ROLL($!elems) | |
15 )), | |
16 nqp::deletekey($!elems,nqp::iterkey_s($iter)), | |
17 $object | |
18 ), | |
19 Nil | |
20 ) | |
21 } | |
22 multi method grab(SetHash:D: Callable:D $calculate) { | |
23 self.grab($calculate(self.elems)) | |
24 } | |
25 multi method grab(SetHash:D: Whatever) { | |
26 self.grab(Inf) | |
27 } | |
28 | |
29 my class Grab does Rakudo::QuantHash::Pairs { | |
30 method pull-one() is raw { | |
31 nqp::if( | |
32 nqp::elems($!picked), | |
33 nqp::stmts( | |
34 (my \object := nqp::atkey( | |
35 $!elems, | |
36 (my \key := nqp::pop_s($!picked)) | |
37 )), | |
38 nqp::deletekey($!elems,key), | |
39 object | |
40 ), | |
41 IterationEnd | |
42 ) | |
43 } | |
44 } | |
45 multi method grab(SetHash:D: $count) { Seq.new(Grab.new($!elems,$count)) } | |
46 | |
47 multi method grabpairs(SetHash:D:) { | |
48 Pair.new(self.grab,True) | |
49 } | |
50 multi method grabpairs(SetHash:D: Callable:D $calculate) { | |
51 self.grabpairs($calculate(self.elems)) | |
52 } | |
53 multi method grabpairs(SetHash:D: Whatever) { | |
54 self.grabpairs(Inf) | |
55 } | |
56 | |
57 my class GrabPairs does Rakudo::QuantHash::Pairs { | |
58 method pull-one() is raw { | |
59 nqp::if( | |
60 nqp::elems($!picked), | |
61 nqp::stmts( | |
62 (my \object := nqp::atkey( | |
63 $!elems, | |
64 (my \key := nqp::pop_s($!picked)) | |
65 )), | |
66 nqp::deletekey($!elems,key), | |
67 Pair.new(object,True) | |
68 ), | |
69 IterationEnd | |
70 ) | |
71 } | |
72 } | |
73 multi method grabpairs(SetHash:D: $count) { | |
74 Seq.new(GrabPairs.new($!elems,$count)) | |
75 } | |
76 | |
77 #--- iterator methods | |
78 | |
79 sub proxy(str $key, Mu \elems) is raw { | |
80 # We are only sure that the key exists when the Proxy | |
81 # is made, but we cannot be sure of its existence when | |
82 # either the FETCH or STORE block is executed. So we | |
83 # still need to check for existence, and handle the case | |
84 # where we need to (re-create) the key and value. The | |
85 # logic is therefore basically the same as in AT-KEY, | |
86 # except for tests for allocated storage and .WHICH | |
87 # processing. | |
88 nqp::stmts( | |
89 # save object for potential recreation | |
90 (my $object := nqp::atkey(elems,$key)), | |
91 | |
92 Proxy.new( | |
93 FETCH => { | |
94 nqp::hllbool(nqp::existskey(elems,$key)) | |
95 }, | |
96 STORE => -> $, $value { | |
97 nqp::stmts( | |
98 nqp::if( | |
99 $value, | |
100 nqp::bindkey(elems,$key,$object), | |
101 nqp::deletekey(elems,$key) | |
102 ), | |
103 $value.Bool | |
104 ) | |
105 } | |
106 ) | |
107 ) | |
108 } | |
109 | |
110 my class Iterate does Rakudo::Iterator::Mappy { | |
111 method !SET-SELF(\elems) { | |
112 nqp::bind($!hash,elems); | |
113 nqp::bind($!iter,Rakudo::Internals.ITERATIONSET2LISTITER(elems)); | |
114 self | |
115 } | |
116 method pull-one() { | |
117 nqp::if( | |
118 $!iter, | |
119 Pair.new( | |
120 nqp::atkey($!hash,(my $key := nqp::shift($!iter))), | |
121 proxy($key,$!hash) | |
122 ), | |
123 IterationEnd | |
124 ) | |
125 } | |
126 } | |
127 method iterator(SetHash:D:) { Iterate.new($!elems) } | |
128 | |
129 my class KV does Rakudo::QuantHash::Quanty-kv { | |
130 method !SET-SELF(Mu \elems) { | |
131 nqp::bind($!elems,elems); | |
132 nqp::bind($!iter,Rakudo::Internals.ITERATIONSET2LISTITER(elems)); | |
133 self | |
134 } | |
135 method pull-one() is raw { | |
136 nqp::if( | |
137 $!on, | |
138 nqp::stmts( | |
139 (my $proxy := proxy($!on,$!elems)), | |
140 ($!on = ""), | |
141 $proxy | |
142 ), | |
143 nqp::if( | |
144 $!iter, | |
145 nqp::atkey($!elems,$!on = nqp::shift($!iter)), | |
146 IterationEnd | |
147 ) | |
148 ) | |
149 } | |
150 method skip-one() { # the one provided by the role interferes | |
151 nqp::not_i(nqp::eqaddr(self.pull-one,IterationEnd)) | |
152 } | |
153 method push-all(\target --> IterationEnd) { | |
154 nqp::while( | |
155 $!iter, | |
156 nqp::stmts( # doesn't sink | |
157 target.push(nqp::atkey($!elems,nqp::shift($!iter))), | |
158 target.push(True) | |
159 ) | |
160 ) | |
161 } | |
162 } | |
163 multi method kv(SetHash:D:) { Seq.new(KV.new($!elems)) } | |
164 | |
165 my class Values does Rakudo::Iterator::Mappy { | |
166 method !SET-SELF(\elems) { | |
167 nqp::bind($!hash,elems); | |
168 nqp::bind($!iter,Rakudo::Internals.ITERATIONSET2LISTITER(elems)); | |
169 self | |
170 } | |
171 method pull-one() is rw { | |
172 nqp::if( | |
173 $!iter, | |
174 proxy(nqp::shift($!iter),$!hash), | |
175 IterationEnd | |
176 ) | |
177 } | |
178 } | |
179 multi method values(SetHash:D:) { Seq.new(Values.new($!elems)) } | |
180 | |
181 #--- coercion methods | |
182 multi method Set(SetHash:D: :$view) { | |
183 nqp::if( | |
184 $!elems && nqp::elems($!elems), | |
185 nqp::create(Set).SET-SELF(nqp::if($view,$!elems,nqp::clone($!elems))), | |
186 nqp::create(Set) | |
187 ) | |
188 } | |
189 multi method SetHash(SetHash:D:) { self } | |
190 method clone() { | |
191 nqp::if( | |
192 $!elems && nqp::elems($!elems), | |
193 nqp::create(self).SET-SELF(nqp::clone($!elems)), | |
194 nqp::create(self) | |
195 ) | |
196 } | |
197 | |
198 multi method Setty(SetHash:U:) { SetHash } | |
199 multi method Setty(SetHash:D:) { self } | |
200 multi method Baggy(SetHash:U:) { BagHash } | |
201 multi method Baggy(SetHash:D:) { self.BagHash } | |
202 multi method Mixy (SetHash:U:) { MixHash } | |
203 multi method Mixy (SetHash:D:) { self.MixHash } | |
204 | |
205 #--- interface methods | |
206 multi method STORE(SetHash:D: *@pairs --> SetHash:D) { | |
207 nqp::if( | |
208 (my \iterator := @pairs.iterator).is-lazy, | |
209 Failure.new(X::Cannot::Lazy.new(:action<initialize>,:what(self.^name))), | |
210 self.SET-SELF( | |
211 Rakudo::QuantHash.ADD-PAIRS-TO-SET( | |
212 nqp::create(Rakudo::Internals::IterationSet),iterator,self.keyof | |
213 ) | |
214 ) | |
215 ) | |
216 } | |
217 multi method STORE(SetHash:D: \objects, \bools --> SetHash:D) { | |
218 my \iterobjs := objects.iterator; | |
219 my \iterbools := bools.iterator; | |
220 nqp::bindattr( | |
221 self,SetHash,'$!elems',nqp::create(Rakudo::Internals::IterationSet) | |
222 ); | |
223 nqp::until( | |
224 nqp::eqaddr((my \object := iterobjs.pull-one),IterationEnd), | |
225 nqp::if( | |
226 iterbools.pull-one, | |
227 nqp::bindkey($!elems,object.WHICH,nqp::decont(object)) | |
228 ) | |
229 ); | |
230 self | |
231 } | |
232 | |
233 multi method AT-KEY(SetHash:D: \k --> Bool:D) is raw { | |
234 Proxy.new( | |
235 FETCH => { | |
236 nqp::hllbool($!elems ?? nqp::existskey($!elems,k.WHICH) !! 0) | |
237 }, | |
238 STORE => -> $, $value { | |
239 nqp::stmts( | |
240 nqp::if( | |
241 $value, | |
242 nqp::stmts( | |
243 nqp::unless( | |
244 $!elems, | |
245 nqp::bindattr(self,::?CLASS,'$!elems', | |
246 nqp::create(Rakudo::Internals::IterationSet)) | |
247 ), | |
248 Rakudo::QuantHash.BIND-TO-TYPED-SET( | |
249 $!elems, nqp::decont(k), self.keyof | |
250 ) | |
251 ), | |
252 $!elems && nqp::deletekey($!elems,k.WHICH) | |
253 ), | |
254 $value.Bool | |
255 ) | |
256 } | |
257 ) | |
258 } | |
259 | |
260 multi method DELETE-KEY(SetHash:D: \k --> Bool:D) { | |
261 nqp::hllbool( | |
262 nqp::if( | |
263 $!elems && nqp::existskey($!elems,(my $which := k.WHICH)), | |
264 nqp::stmts( | |
265 nqp::deletekey($!elems,$which), | |
266 1 | |
267 ), | |
268 0 | |
269 ) | |
270 ) | |
271 } | |
272 } | |
273 | |
274 # vim: ft=perl6 expandtab sw=4 |