1. # This file implements the following set operators:
  2. # (.) set multiplication (ASCII)
  3. # ⊍ set multiplication
  4. proto sub infix:<(.)>(|) is pure {*}
  5. multi sub infix:<(.)>() { bag() }
  6. multi sub infix:<(.)>(Bag:D $a) { $a }
  7. multi sub infix:<(.)>(Mix:D $a) { $a }
  8. multi sub infix:<(.)>(MixHash:D $a) { $a.Mix }
  9. multi sub infix:<(.)>(Any $a) { $a.Bag }
  10. multi sub infix:<(.)>(Setty:D $a, Setty:D $b) {
  11. nqp::if(
  12. (my $elems := $a.Bag.RAW-HASH) && nqp::elems($elems),
  13. nqp::create(Bag).SET-SELF(
  14. Rakudo::QuantHash.MULTIPLY-SET-TO-BAG($elems,$b.RAW-HASH),
  15. ),
  16. bag()
  17. )
  18. }
  19. multi sub infix:<(.)>(Mixy:D $a, Mixy:D $b) {
  20. nqp::if(
  21. (my $elems := Rakudo::QuantHash.BAGGY-CLONE-RAW($a.RAW-HASH))
  22. && nqp::elems($elems),
  23. nqp::stmts(
  24. Rakudo::QuantHash.MULTIPLY-MIX-TO-MIX($elems,$b.RAW-HASH),
  25. nqp::create(Mix).SET-SELF($elems)
  26. ),
  27. mix()
  28. )
  29. }
  30. multi sub infix:<(.)>(Mixy:D $a, Baggy:D $b) { infix:<(.)>($a, $b.Mix) }
  31. multi sub infix:<(.)>(Mixy:D $a, Any $b) { infix:<(.)>($a, $b.Mix) }
  32. multi sub infix:<(.)>(Baggy:D $a, Mixy:D $b) { infix:<(.)>($a.Mix, $b) }
  33. multi sub infix:<(.)>(Any $a, Mixy:D $b) { infix:<(.)>($a.Mix, $b) }
  34. multi sub infix:<(.)>(Baggy:D $a, Baggy:D $b) {
  35. nqp::if(
  36. (my $elems := Rakudo::QuantHash.BAGGY-CLONE-RAW($a.RAW-HASH))
  37. && nqp::elems($elems),
  38. nqp::create(Bag).SET-SELF(
  39. Rakudo::QuantHash.MULTIPLY-BAG-TO-BAG($elems,$b.RAW-HASH),
  40. ),
  41. bag()
  42. )
  43. }
  44. multi sub infix:<(.)>(Any $, Failure:D $b) { $b.throw }
  45. multi sub infix:<(.)>(Failure:D $a, Any $) { $a.throw }
  46. multi sub infix:<(.)>(Any $a, Any $b) { infix:<(.)>($a.Bag,$b.Bag) }
  47. multi sub infix:<(.)>(**@p) {
  48. my $result = @p.shift;
  49. $result = $result (.) @p.shift while @p;
  50. $result
  51. }
  52. # U+228D MULTISET MULTIPLICATION
  53. my constant &infix:<⊍> := &infix:<(.)>;