1. my class SetHash does Setty {
  2. role SetHashMappy does Rakudo::Iterator::Mappy {
  3. method ISINSET(\key) {
  4. Proxy.new(
  5. FETCH => {
  6. nqp::p6bool(
  7. nqp::existskey(
  8. nqp::getattr(self,::?CLASS,'$!storage'),
  9. key
  10. )
  11. )
  12. },
  13. STORE => -> $, \value {
  14. nqp::stmts(
  15. nqp::unless(
  16. value,
  17. nqp::deletekey(
  18. nqp::getattr(self,::?CLASS,'$!storage'),
  19. key
  20. )
  21. ),
  22. value
  23. )
  24. }
  25. )
  26. }
  27. }
  28. method iterator(SetHash:D:) {
  29. class :: does SetHashMappy {
  30. method pull-one() {
  31. nqp::if(
  32. $!iter,
  33. Pair.new(
  34. nqp::iterval(nqp::shift($!iter)),
  35. self.ISINSET(nqp::iterkey_s($!iter))
  36. ),
  37. IterationEnd
  38. )
  39. }
  40. }.new(%!elems)
  41. }
  42. multi method kv(SetHash:D:) {
  43. Seq.new(class :: does SetHashMappy {
  44. has int $!on-value;
  45. method pull-one() {
  46. nqp::if(
  47. $!on-value,
  48. nqp::stmts(
  49. ($!on-value = 0),
  50. self.ISINSET(nqp::iterkey_s($!iter))
  51. ),
  52. nqp::if(
  53. $!iter,
  54. nqp::stmts(
  55. ($!on-value = 1),
  56. nqp::iterval(nqp::shift($!iter))
  57. ),
  58. IterationEnd
  59. )
  60. )
  61. }
  62. method skip-one() {
  63. nqp::if(
  64. $!on-value,
  65. nqp::not_i($!on-value = 0), # skipped a value
  66. nqp::if(
  67. $!iter, # if false, we didn't skip
  68. nqp::stmts( # skipped a key
  69. nqp::shift($!iter),
  70. ($!on-value = 1)
  71. )
  72. )
  73. )
  74. }
  75. method count-only() {
  76. nqp::p6box_i(
  77. nqp::add_i(nqp::elems($!storage),nqp::elems($!storage))
  78. )
  79. }
  80. }.new(%!elems))
  81. }
  82. multi method values(SetHash:D:) {
  83. Seq.new(class :: does SetHashMappy {
  84. method pull-one() {
  85. nqp::if(
  86. $!iter,
  87. self.ISINSET(nqp::iterkey_s(nqp::shift($!iter))),
  88. IterationEnd
  89. )
  90. }
  91. }.new(%!elems))
  92. }
  93. method clone(SetHash:D:) { self.new-from-pairs(self.pairs) }
  94. method Set(SetHash:D: :$view) {
  95. nqp::p6bindattrinvres(
  96. nqp::create(Set),Set,'%!elems',
  97. $view ?? %!elems !! %!elems.clone
  98. )
  99. }
  100. method SetHash(SetHash:D:) { self }
  101. multi method AT-KEY(SetHash:D: \k --> Bool:D) is raw {
  102. Proxy.new(
  103. FETCH => {
  104. %!elems.EXISTS-KEY(k.WHICH);
  105. },
  106. STORE => -> $, $value {
  107. $value
  108. ?? %!elems.ASSIGN-KEY(k.WHICH,k)
  109. !! %!elems.DELETE-KEY(k.WHICH);
  110. so $value;
  111. });
  112. }
  113. multi method DELETE-KEY(SetHash:D: \k --> Bool:D) {
  114. nqp::if(
  115. %!elems.EXISTS-KEY(my $key := k.WHICH),
  116. nqp::stmts(
  117. %!elems.DELETE-KEY($key),
  118. True
  119. )
  120. )
  121. }
  122. }