Mercurial > hg > Others > Rakudo
view 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 |
line wrap: on
line source
my class SetHash does Setty { method ^parameterize(Mu \base, Mu \type) { Rakudo::Internals.PARAMETERIZE-KEYOF(base,type) } #--- selector methods multi method grab(SetHash:D:) { nqp::if( $!elems, nqp::stmts( (my $object := nqp::iterval( my $iter := Rakudo::QuantHash.ROLL($!elems) )), nqp::deletekey($!elems,nqp::iterkey_s($iter)), $object ), Nil ) } multi method grab(SetHash:D: Callable:D $calculate) { self.grab($calculate(self.elems)) } multi method grab(SetHash:D: Whatever) { self.grab(Inf) } my class Grab does Rakudo::QuantHash::Pairs { method pull-one() is raw { nqp::if( nqp::elems($!picked), nqp::stmts( (my \object := nqp::atkey( $!elems, (my \key := nqp::pop_s($!picked)) )), nqp::deletekey($!elems,key), object ), IterationEnd ) } } multi method grab(SetHash:D: $count) { Seq.new(Grab.new($!elems,$count)) } multi method grabpairs(SetHash:D:) { Pair.new(self.grab,True) } multi method grabpairs(SetHash:D: Callable:D $calculate) { self.grabpairs($calculate(self.elems)) } multi method grabpairs(SetHash:D: Whatever) { self.grabpairs(Inf) } my class GrabPairs does Rakudo::QuantHash::Pairs { method pull-one() is raw { nqp::if( nqp::elems($!picked), nqp::stmts( (my \object := nqp::atkey( $!elems, (my \key := nqp::pop_s($!picked)) )), nqp::deletekey($!elems,key), Pair.new(object,True) ), IterationEnd ) } } multi method grabpairs(SetHash:D: $count) { Seq.new(GrabPairs.new($!elems,$count)) } #--- iterator methods sub proxy(str $key, Mu \elems) is raw { # We are only sure that the key exists when the Proxy # is made, but we cannot be sure of its existence when # either the FETCH or STORE block is executed. So we # still need to check for existence, and handle the case # where we need to (re-create) the key and value. The # logic is therefore basically the same as in AT-KEY, # except for tests for allocated storage and .WHICH # processing. nqp::stmts( # save object for potential recreation (my $object := nqp::atkey(elems,$key)), Proxy.new( FETCH => { nqp::hllbool(nqp::existskey(elems,$key)) }, STORE => -> $, $value { nqp::stmts( nqp::if( $value, nqp::bindkey(elems,$key,$object), nqp::deletekey(elems,$key) ), $value.Bool ) } ) ) } my class Iterate does Rakudo::Iterator::Mappy { method !SET-SELF(\elems) { nqp::bind($!hash,elems); nqp::bind($!iter,Rakudo::Internals.ITERATIONSET2LISTITER(elems)); self } method pull-one() { nqp::if( $!iter, Pair.new( nqp::atkey($!hash,(my $key := nqp::shift($!iter))), proxy($key,$!hash) ), IterationEnd ) } } method iterator(SetHash:D:) { Iterate.new($!elems) } my class KV does Rakudo::QuantHash::Quanty-kv { method !SET-SELF(Mu \elems) { nqp::bind($!elems,elems); nqp::bind($!iter,Rakudo::Internals.ITERATIONSET2LISTITER(elems)); self } method pull-one() is raw { nqp::if( $!on, nqp::stmts( (my $proxy := proxy($!on,$!elems)), ($!on = ""), $proxy ), nqp::if( $!iter, nqp::atkey($!elems,$!on = nqp::shift($!iter)), IterationEnd ) ) } method skip-one() { # the one provided by the role interferes nqp::not_i(nqp::eqaddr(self.pull-one,IterationEnd)) } method push-all(\target --> IterationEnd) { nqp::while( $!iter, nqp::stmts( # doesn't sink target.push(nqp::atkey($!elems,nqp::shift($!iter))), target.push(True) ) ) } } multi method kv(SetHash:D:) { Seq.new(KV.new($!elems)) } my class Values does Rakudo::Iterator::Mappy { method !SET-SELF(\elems) { nqp::bind($!hash,elems); nqp::bind($!iter,Rakudo::Internals.ITERATIONSET2LISTITER(elems)); self } method pull-one() is rw { nqp::if( $!iter, proxy(nqp::shift($!iter),$!hash), IterationEnd ) } } multi method values(SetHash:D:) { Seq.new(Values.new($!elems)) } #--- coercion methods multi method Set(SetHash:D: :$view) { nqp::if( $!elems && nqp::elems($!elems), nqp::create(Set).SET-SELF(nqp::if($view,$!elems,nqp::clone($!elems))), nqp::create(Set) ) } multi method SetHash(SetHash:D:) { self } method clone() { nqp::if( $!elems && nqp::elems($!elems), nqp::create(self).SET-SELF(nqp::clone($!elems)), nqp::create(self) ) } multi method Setty(SetHash:U:) { SetHash } multi method Setty(SetHash:D:) { self } multi method Baggy(SetHash:U:) { BagHash } multi method Baggy(SetHash:D:) { self.BagHash } multi method Mixy (SetHash:U:) { MixHash } multi method Mixy (SetHash:D:) { self.MixHash } #--- interface methods multi method STORE(SetHash:D: *@pairs --> SetHash:D) { nqp::if( (my \iterator := @pairs.iterator).is-lazy, Failure.new(X::Cannot::Lazy.new(:action<initialize>,:what(self.^name))), self.SET-SELF( Rakudo::QuantHash.ADD-PAIRS-TO-SET( nqp::create(Rakudo::Internals::IterationSet),iterator,self.keyof ) ) ) } multi method STORE(SetHash:D: \objects, \bools --> SetHash:D) { my \iterobjs := objects.iterator; my \iterbools := bools.iterator; nqp::bindattr( self,SetHash,'$!elems',nqp::create(Rakudo::Internals::IterationSet) ); nqp::until( nqp::eqaddr((my \object := iterobjs.pull-one),IterationEnd), nqp::if( iterbools.pull-one, nqp::bindkey($!elems,object.WHICH,nqp::decont(object)) ) ); self } multi method AT-KEY(SetHash:D: \k --> Bool:D) is raw { Proxy.new( FETCH => { nqp::hllbool($!elems ?? nqp::existskey($!elems,k.WHICH) !! 0) }, STORE => -> $, $value { nqp::stmts( nqp::if( $value, nqp::stmts( nqp::unless( $!elems, nqp::bindattr(self,::?CLASS,'$!elems', nqp::create(Rakudo::Internals::IterationSet)) ), Rakudo::QuantHash.BIND-TO-TYPED-SET( $!elems, nqp::decont(k), self.keyof ) ), $!elems && nqp::deletekey($!elems,k.WHICH) ), $value.Bool ) } ) } multi method DELETE-KEY(SetHash:D: \k --> Bool:D) { nqp::hllbool( nqp::if( $!elems && nqp::existskey($!elems,(my $which := k.WHICH)), nqp::stmts( nqp::deletekey($!elems,$which), 1 ), 0 ) ) } } # vim: ft=perl6 expandtab sw=4