1. my class Set does Setty {
  2. has $!WHICH;
  3. method SET-SELF(\elems) {
  4. nqp::if(
  5. nqp::elems(elems),
  6. nqp::stmts(
  7. nqp::bindattr(self,::?CLASS,'$!elems',elems),
  8. self
  9. ),
  10. set()
  11. )
  12. }
  13. multi method new(Set:_:) {
  14. nqp::if(
  15. nqp::eqaddr(self.WHAT,Set),
  16. set(),
  17. nqp::create(self)
  18. )
  19. }
  20. multi method WHICH (Set:D:) {
  21. nqp::if(
  22. nqp::attrinited(self,Set,'$!WHICH'),
  23. $!WHICH,
  24. $!WHICH := nqp::if(
  25. nqp::istype(self.WHAT,Set),
  26. 'Set|',
  27. nqp::concat(self.^name,'|')
  28. ) ~ nqp::sha1(
  29. nqp::join('\0',Rakudo::Sorting.MERGESORT-str(self.raw_keys))
  30. )
  31. )
  32. }
  33. method iterator(Set:D:) {
  34. class :: does Rakudo::Iterator::Mappy {
  35. method pull-one() {
  36. nqp::if(
  37. $!iter,
  38. Pair.new(nqp::iterval(nqp::shift($!iter)),True),
  39. IterationEnd
  40. )
  41. }
  42. }.new(self.hll_hash)
  43. }
  44. multi method kv(Set:D:) {
  45. Seq.new(class :: does Rakudo::Iterator::Mappy {
  46. has int $!on-value;
  47. method pull-one() is raw {
  48. nqp::if(
  49. $!on-value,
  50. nqp::stmts(
  51. ($!on-value = 0),
  52. True,
  53. ),
  54. nqp::if(
  55. $!iter,
  56. nqp::stmts(
  57. ($!on-value = 1),
  58. nqp::iterval(nqp::shift($!iter))
  59. ),
  60. IterationEnd
  61. )
  62. )
  63. }
  64. method skip-one() {
  65. nqp::if(
  66. $!on-value,
  67. nqp::not_i($!on-value = 0), # skipped a value
  68. nqp::if(
  69. $!iter, # if false, we didn't skip
  70. nqp::stmts( # skipped a key
  71. nqp::shift($!iter),
  72. ($!on-value = 1)
  73. )
  74. )
  75. )
  76. }
  77. method count-only() {
  78. nqp::p6box_i(
  79. nqp::add_i(nqp::elems($!storage),nqp::elems($!storage))
  80. )
  81. }
  82. }.new(self.hll_hash))
  83. }
  84. multi method values(Set:D:) { True xx self.total }
  85. multi method grab(Set:D: $count?) {
  86. X::Immutable.new( method => 'grab', typename => self.^name ).throw;
  87. }
  88. multi method grabpairs(Set:D $count?) {
  89. X::Immutable.new( method => 'grabpairs', typename => self.^name ).throw;
  90. }
  91. multi method Set(Set:D:) { self }
  92. multi method SetHash(Set:D:) {
  93. nqp::if(
  94. $!elems,
  95. nqp::p6bindattrinvres(
  96. nqp::create(SetHash),SetHash,'$!elems',$!elems.clone
  97. ),
  98. nqp::create(SetHash)
  99. )
  100. }
  101. method clone() { nqp::clone(self) }
  102. multi method AT-KEY(Set:D: \k --> Bool:D) {
  103. nqp::p6bool($!elems && nqp::existskey($!elems,k.WHICH))
  104. }
  105. multi method ASSIGN-KEY(Set:D: \k,\v) {
  106. X::Assignment::RO.new(value => self).throw;
  107. }
  108. multi method DELETE-KEY(Set:D: \k) {
  109. X::Immutable.new(method => 'DELETE-KEY', typename => self.^name).throw;
  110. }
  111. }