my class Bag does Baggy { has ValueObjAt $!WHICH; has Int $!total; my role KeyOf[::CONSTRAINT] { method keyof() { CONSTRAINT } } method ^parameterize(Mu \base, Mu \type) { my \what := base.^mixin(KeyOf[type]); what.^set_name(base.^name ~ '[' ~ type.^name ~ ']'); what } #--- introspection methods multi method WHICH(Bag:D: --> ValueObjAt:D) { nqp::isconcrete($!WHICH) ?? $!WHICH !! self!WHICH } method !WHICH() { $!WHICH := nqp::box_s( nqp::concat( nqp::if( nqp::eqaddr(self.WHAT,Bag), 'Bag|', nqp::concat(nqp::unbox_s(self.^name), '|') ), nqp::sha1( nqp::join('\0',Rakudo::Sorting.MERGESORT-str( Rakudo::QuantHash.BAGGY-RAW-KEY-VALUES(self) )) ) ), ValueObjAt ) } method total(Bag:D: --> Int:D) { $!total // ($!total := Rakudo::QuantHash.BAG-TOTAL($!elems)) } #--- interface methods multi method STORE(Bag:D: Any:D \keys, :INITIALIZE($)! --> Bag:D) { (my \iterator := keys.iterator).is-lazy ?? self.fail-iterator-cannot-be-lazy('initialize') !! self.SET-SELF(Rakudo::QuantHash.ADD-PAIRS-TO-BAG( nqp::create(Rakudo::Internals::IterationSet),iterator,self.keyof )) } multi method STORE(Bag:D: \objects, \values, :INITIALIZE($)! --> Bag:D) { self.SET-SELF( Rakudo::QuantHash.ADD-OBJECTS-VALUES-TO-BAG( nqp::create(Rakudo::Internals::IterationSet), objects.iterator, values.iterator, self.keyof ) ) } multi method DELETE-KEY(Bag:D: \k) { X::Immutable.new(method => 'DELETE-KEY', typename => self.^name).throw; } #--- selection methods multi method grabpairs(Bag:D: $count?) { X::Immutable.new( method => 'grabpairs', typename => self.^name ).throw; } #--- coercion methods multi method Bag(Bag:D:) { self } multi method BagHash(Bag:D:) { $!elems && nqp::elems($!elems) ?? nqp::create(BagHash).SET-SELF( Rakudo::QuantHash.BAGGY-CLONE($!elems)) !! nqp::create(BagHash) } multi method Mix(Bag:D:) { $!elems && nqp::elems($!elems) ?? nqp::create(Mix).SET-SELF($!elems) !! mix() } multi method MixHash(Bag:D:) { $!elems && nqp::elems($!elems) ?? nqp::create(MixHash).SET-SELF( Rakudo::QuantHash.BAGGY-CLONE($!elems)) !! nqp::create(MixHash) } multi method Setty(Bag:U:) { Set } multi method Setty(Bag:D:) { self.Set } multi method Baggy(Bag:U:) { Bag } multi method Baggy(Bag:D:) { self } multi method Mixy (Bag:U:) { Mix } multi method Mixy (Bag:D:) { self.Mix } #--- illegal methods proto method classify-list(|) { X::Immutable.new(:method, :typename(self.^name)).throw; } proto method categorize-list(|) { X::Immutable.new(:method, :typename(self.^name)).throw; } } # vim: expandtab shiftwidth=4