1. my class BagHash does Baggy {
  2. #--- interface methods
  3. multi method WHICH(BagHash:D:) { self.Mu::WHICH }
  4. multi method AT-KEY(BagHash: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::getattr(nqp::decont(nqp::atkey($hash,$which)),Pair,'$!value') = $value)
  19. !! nqp::deletekey($hash,$which);
  20. }
  21. elsif $value > 0 {
  22. nqp::bindkey($hash,$which,self!PAIR(k,$value));
  23. }
  24. $value < 0 ?? 0 !! $value;
  25. }
  26. );
  27. }
  28. #--- introspection methods
  29. method Bag(:$view) {
  30. nqp::p6bindattrinvres(
  31. nqp::create(Bag),Bag,'%!elems',
  32. $view ?? %!elems !! %!elems.clone
  33. )
  34. }
  35. method BagHash { self }
  36. method Mix {
  37. nqp::p6bindattrinvres(nqp::create(Mix),Mix,'%!elems',%!elems.clone)
  38. }
  39. method MixHash { MixHash.new-from-pairs(%!elems.values) }
  40. method clone(BagHash:D:) { self.new-from-pairs(self.pairs) }
  41. }