Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Port Set from niecza
  • Loading branch information
Tadeusz Sośnierz committed Mar 1, 2012
1 parent d4e8e41 commit bc82980
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 1 deletion.
61 changes: 61 additions & 0 deletions src/core/Set.pm
@@ -0,0 +1,61 @@
my class Set is Iterable does Associative {
has %!elems;

method keys { %!elems.keys }
method values { %!elems.values }
method elems returns Int { %!elems.elems }
method exists($a) returns Bool { %!elems.exists($a) }
method Bool { %!elems.Bool }
method Numeric { %!elems.Numeric }
method hash { %!elems.hash }
method at_key($k) { ?(%!elems{$k} // False) }
method exists_key($k) { self.exists($k) }

# Constructor
method new(*@args --> Set) {
my %e;
sub register-arg($arg) {
given $arg {
when Pair { %e{.key} = True; }
when Set | KeySet { for .keys -> $key { %e{$key} = True; } }
when Associative { for .pairs -> $p { register-arg($p); } }
when Positional { for .list -> $p { register-arg($p); } }
default { %e{$_} = True; }
}
}

for @args {
register-arg($_);
}
self.bless(*, :elems(%e));
}

submethod BUILD (:%!elems) { }

# Coercions to and from
method postcircumfix:<( )> ($s --> Set) { to-set($s) }
multi to-set (Set $set --> Set) { $set }
multi to-set (KeySet $set --> Set) { Set.new: $set }
multi to-set (Bag $bag --> Set) { Set.new: $bag }
multi to-set (KeyBag $bag --> Set) { Set.new: $bag }
multi to-set (@elems --> Set) { Set.new: @elems }
multi to-set ([*@elems] --> Set) { Set.new: @elems }
multi to-set (%elems --> Set) { Set.new: %elems.keys }
multi to-set ($elem --> Set) { die "Cannot coerce $elem.perl() to a Set; use set($elem.perl()) to create a one-element set" }

multi method Str(Any:D $ : --> Str) { "set(< %!elems.keys() >)" }
multi method gist(Any:D $ : --> Str) { "set({ %!elems.keys».gist.join(', ') })"
}
multi method perl(Any:D $ : --> Str) { 'set(' ~ join(', ', map { .perl }, %!elems.keys) ~ ')' }

method iterator() { %!elems.keys.iterator }
method list() { %!elems.keys }
method pick($count = 1) { %!elems.keys.pick($count) }
method roll($count = 1) { %!elems.keys.roll($count) }

# TODO: WHICH will require the capability for >1 pointer in ObjAt
}

sub set(*@args) {
Set.new(@args);
}
3 changes: 2 additions & 1 deletion src/core/stubs.pm
Expand Up @@ -5,7 +5,8 @@
# in the end.
my class Whatever { ... }
my class Bag is Iterable does Associative { }
my class Set is Iterable does Associative { }
my class KeyBag is Iterable does Associative { }
my class KeySet is Iterable does Associative { }
my class KeyHash is Iterable does Associative { }
my class Seq is List does Positional { }
my class Exception { ... }
Expand Down
1 change: 1 addition & 0 deletions tools/build/Makefile.in
Expand Up @@ -221,6 +221,7 @@ CORE_SOURCES = \
src/core/Temporal.pm \
src/core/EXPORTHOW.pm \
src/core/Pod.pm \
src/core/Set.pm \
src/core/ObjAt.pm \
src/core/operators.pm \
src/core/metaops.pm \
Expand Down

0 comments on commit bc82980

Please sign in to comment.