1. my class Bag does Baggy {
  2. has Int $!total;
  3. has $!WHICH;
  4. #--- introspection methods
  5. multi method WHICH(Bag:D:) {
  6. nqp::if(
  7. nqp::attrinited(self,Bag,'$!WHICH'),
  8. $!WHICH,
  9. $!WHICH := ValueObjAt.new('Bag!' ~ nqp::sha1(
  10. nqp::join('\0',Rakudo::Sorting.MERGESORT-str(
  11. Rakudo::QuantHash.BAGGY-RAW-KEY-VALUES(self)
  12. ))
  13. ))
  14. )
  15. }
  16. method total(Bag:D: --> Int:D) {
  17. nqp::if(
  18. nqp::attrinited(self,Bag,'$!total'),
  19. $!total,
  20. $!total := Rakudo::QuantHash.BAG-TOTAL($!elems)
  21. )
  22. }
  23. #--- interface methods
  24. method STORE(*@pairs, :$initialize --> Bag:D) {
  25. nqp::if(
  26. (my $iterator := @pairs.iterator).is-lazy,
  27. Failure.new(X::Cannot::Lazy.new(:action<initialize>,:what(self.^name))),
  28. nqp::if(
  29. $initialize,
  30. self.SET-SELF(
  31. Rakudo::QuantHash.ADD-PAIRS-TO-BAG(
  32. nqp::create(Rakudo::Internals::IterationSet), $iterator
  33. )
  34. ),
  35. X::Assignment::RO.new(value => self).throw
  36. )
  37. )
  38. }
  39. multi method DELETE-KEY(Bag:D: \k) {
  40. X::Immutable.new(method => 'DELETE-KEY', typename => self.^name).throw;
  41. }
  42. #--- selection methods
  43. multi method grabpairs(Bag:D: $count?) {
  44. X::Immutable.new( method => 'grabpairs', typename => self.^name ).throw;
  45. }
  46. #--- coercion methods
  47. multi method Bag(Bag:D:) { self }
  48. multi method BagHash(Bag:D) {
  49. nqp::if(
  50. $!elems && nqp::elems($!elems),
  51. nqp::create(BagHash).SET-SELF(Rakudo::QuantHash.BAGGY-CLONE($!elems)),
  52. nqp::create(BagHash)
  53. )
  54. }
  55. multi method Mix(Bag:D:) {
  56. nqp::if(
  57. $!elems && nqp::elems($!elems),
  58. nqp::create(Mix).SET-SELF($!elems),
  59. mix()
  60. )
  61. }
  62. multi method MixHash(Bag:D) {
  63. nqp::if(
  64. $!elems && nqp::elems($!elems),
  65. nqp::create(MixHash).SET-SELF(Rakudo::QuantHash.BAGGY-CLONE($!elems)),
  66. nqp::create(MixHash)
  67. )
  68. }
  69. method clone() {
  70. nqp::if(
  71. $!elems && nqp::elems($!elems),
  72. nqp::clone(self),
  73. bag()
  74. )
  75. }
  76. #--- illegal methods
  77. proto method classify-list(|) {
  78. X::Immutable.new(:method<classify-list>, :typename(self.^name)).throw;
  79. }
  80. proto method categorize-list(|) {
  81. X::Immutable.new(:method<categorize-list>, :typename(self.^name)).throw;
  82. }
  83. }