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