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