Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: fa7fca745c
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 109 lines (92 sloc) 3.864 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
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 ($thing) { X::Set::Coerce.new(:$thing).throw }

    multi method Str(Any:D $ : --> Str) { ~%!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);
}

my class KeySet 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) && %!elems{$a} }
    method Bool { %!elems.Bool }
    method Numeric { %!elems.Numeric }
    method hash { %!elems.hash }
    method at_key($k) {
        Proxy.new(FETCH => { %!elems.exists($k) ?? True !! False },
                  STORE => -> $, $value { if $value { %!elems{$k} = True } else { %!elems.delete($k) }});
    }
    method exists_key($k) { self.exists($k) }
    method delete_key($k) { %!elems.delete($k) }

    # Constructor
    method new(*@args --> KeySet) {
        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) { }

    multi method Str(Any:D $ : --> Str) { ~%!elems.keys }
    multi method gist(Any:D $ : --> Str) { "keyset({ %!elems.keys».gist.join(', ') })" }
    multi method perl(Any:D $ : --> Str) { 'KeySet.new(' ~ 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) }
}
Something went wrong with that request. Please try again.