1. my class MixHash does Mixy {
  2. #--- interface methods
  3. multi method WHICH(MixHash:D:) { self.Mu::WHICH }
  4. multi method AT-KEY(MixHash:D: \k) is raw {
  5. Proxy.new(
  6. FETCH => {
  7. my $hash := nqp::getattr(%!elems,Map,'$!storage');
  8. my str $which = nqp::unbox_s(k.WHICH);
  9. nqp::existskey($hash,$which)
  10. ?? nqp::getattr(nqp::decont(nqp::atkey($hash,$which)),Pair,'$!value')
  11. !! 0
  12. },
  13. STORE => -> $, $value is copy {
  14. my $hash := nqp::getattr(%!elems,Map,'$!storage');
  15. my str $which = nqp::unbox_s(k.WHICH);
  16. if nqp::existskey($hash,$which) {
  17. $value == 0
  18. ?? nqp::deletekey($hash,$which)
  19. !! (nqp::getattr(nqp::decont(nqp::atkey($hash,$which)),Pair,'$!value') = $value);
  20. }
  21. elsif $value {
  22. nqp::bindkey($hash,$which,self!PAIR(k,$value));
  23. }
  24. $value;
  25. }
  26. );
  27. }
  28. #--- coercion methods
  29. method Mix(:$view) {
  30. nqp::p6bindattrinvres(
  31. nqp::create(Mix),Mix,'%!elems',
  32. $view ?? %!elems !! %!elems.clone
  33. )
  34. }
  35. method MixHash { self }
  36. method Bag { Bag.new-from-pairs(%!elems.values.grep(*.value > 0).map({.key => .value.Int})) }
  37. method BagHash { BagHash.new-from-pairs(%!elems.values.grep(*.value > 0).map({.key => .value.Int})) }
  38. method clone(MixHash:D:) { self.new-from-pairs(self.pairs) }
  39. }