1. my class Set does Setty {
  2. has $!WHICH;
  3. multi method WHICH (Set:D:) {
  4. nqp::if(
  5. nqp::attrinited(self,Set,'$!WHICH'),
  6. $!WHICH,
  7. $!WHICH := nqp::if(
  8. nqp::istype(self.WHAT,Set),
  9. 'Set|',
  10. nqp::concat(self.^name,'|')
  11. ) ~ nqp::sha1(
  12. nqp::join("\0",Rakudo::Sorting.MERGESORT-str(
  13. Rakudo::QuantHash.RAW-KEYS(self)
  14. ))
  15. )
  16. )
  17. }
  18. method iterator(Set:D:) {
  19. class :: does Rakudo::Iterator::Mappy {
  20. method pull-one() {
  21. nqp::if(
  22. $!iter,
  23. Pair.new(nqp::iterval(nqp::shift($!iter)),True),
  24. IterationEnd
  25. )
  26. }
  27. }.new($!elems)
  28. }
  29. multi method kv(Set:D:) {
  30. Seq.new(class :: does Rakudo::QuantHash::Quanty-kv {
  31. method pull-one() is raw {
  32. nqp::if(
  33. $!on,
  34. nqp::stmts(
  35. ($!on = 0),
  36. True,
  37. ),
  38. nqp::if(
  39. $!iter,
  40. nqp::stmts(
  41. ($!on = 1),
  42. nqp::iterval(nqp::shift($!iter))
  43. ),
  44. IterationEnd
  45. )
  46. )
  47. }
  48. method push-all($target --> IterationEnd) {
  49. nqp::while(
  50. $!iter,
  51. nqp::stmts( # doesn't sink
  52. $target.push(nqp::iterval(nqp::shift($!iter))),
  53. $target.push(True)
  54. )
  55. )
  56. }
  57. }.new(self))
  58. }
  59. multi method values(Set:D:) { True xx self.total }
  60. multi method grab(Set:D: $count?) {
  61. X::Immutable.new( method => 'grab', typename => self.^name ).throw;
  62. }
  63. multi method grabpairs(Set:D $count?) {
  64. X::Immutable.new( method => 'grabpairs', typename => self.^name ).throw;
  65. }
  66. #--- coercion methods
  67. multi method Set(Set:D:) { self }
  68. multi method SetHash(Set:D:) {
  69. nqp::if(
  70. $!elems && nqp::elems($!elems),
  71. nqp::p6bindattrinvres(
  72. nqp::create(SetHash),SetHash,'$!elems',nqp::clone($!elems)
  73. ),
  74. nqp::create(SetHash)
  75. )
  76. }
  77. method clone() {
  78. nqp::if(
  79. $!elems && nqp::elems($!elems),
  80. nqp::clone(self),
  81. set()
  82. )
  83. }
  84. #--- interface methods
  85. method STORE(*@pairs, :$initialize --> Set:D) {
  86. nqp::if(
  87. (my $iterator := @pairs.iterator).is-lazy,
  88. Failure.new(X::Cannot::Lazy.new(:action<initialize>,:what(self.^name))),
  89. nqp::if(
  90. $initialize,
  91. self.SET-SELF(
  92. Rakudo::QuantHash.ADD-PAIRS-TO-SET(
  93. nqp::create(Rakudo::Internals::IterationSet), $iterator
  94. )
  95. ),
  96. X::Assignment::RO.new(value => self).throw
  97. )
  98. )
  99. }
  100. multi method AT-KEY(Set:D: \k --> Bool:D) {
  101. nqp::p6bool($!elems && nqp::existskey($!elems,k.WHICH))
  102. }
  103. multi method ASSIGN-KEY(Set:D: \k,\v) {
  104. X::Assignment::RO.new(value => self).throw;
  105. }
  106. multi method DELETE-KEY(Set:D: \k) {
  107. X::Immutable.new(method => 'DELETE-KEY', typename => self.^name).throw;
  108. }
  109. }