-
-
Notifications
You must be signed in to change notification settings - Fork 373
/
EnumMap.pm
110 lines (96 loc) · 3.04 KB
/
EnumMap.pm
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
109
my class EnumMap does Associative {
# declared in BOOTSTRAP.pm:
# has $!storage; # Parrot Hash PMC of key->value mappings
multi method Bool(EnumMap:D:) {
nqp::p6bool(pir::defined($!storage) ?? nqp::elems($!storage) !! 0)
}
method elems(EnumMap:D:) {
pir::defined($!storage) ?? nqp::p6box_i(nqp::elems($!storage)) !! 0
}
multi method ACCEPTS(EnumMap:D: Any $topic) {
so self.exists($topic.any);
}
multi method ACCEPTS(EnumMap:D: Cool:D $topic) {
so self.exists($topic);
}
proto method exists(|$) {*}
multi method exists(EnumMap:D: Str:D \$key) {
nqp::p6bool(
pir::defined($!storage)
&& nqp::existskey($!storage, nqp::unbox_s($key))
)
}
multi method exists(EnumMap:D: \$key) {
nqp::p6bool(
pir::defined($!storage)
&& nqp::existskey($!storage, nqp::unbox_s($key.Stringy))
)
}
multi method perl(EnumMap:D:) {
'EnumMap.new('
~ self.keys.map({ .perl ~ ', ' ~ self.at_key($_).perl ~ ', '}).join
~ ')';
}
method iterator() { self.pairs.iterator }
method list() { self.pairs }
method keys() { self.pairs.map( { $_.key } ) }
method kv() { self.pairs.map( { $_.kv } ) }
method values() { self.pairs.map( { $_.value } ) }
method pairs() {
return unless pir::defined($!storage);
gather {
my Mu $iter := nqp::iterator($!storage);
my Mu $pair;
while $iter {
$pair := nqp::shift($iter);
take Pair.new(:key($pair.key), :value($pair.value));
}
Nil
}
}
method invert() {
gather {
my Mu $iter := nqp::iterator($!storage);
my Mu $pair;
while $iter {
$pair := nqp::shift($iter);
take Pair.new(:key($pair.value), :value($pair.key));
}
Nil
}
}
method at_key($key is copy) is rw {
$key = $key.Str;
self.exists($key)
?? nqp::atkey($!storage, nqp::unbox_s($key))
!! Any
}
method STORE_AT_KEY(Str \$key, Mu \$value) is rw {
pir::defined($!storage) ||
nqp::bindattr(self, EnumMap, '$!storage', pir::new__Ps('Hash'));
pir::set__1QsP($!storage, nqp::unbox_s($key), $value)
}
method Capture() {
my $cap := nqp::create(Capture);
nqp::bindattr($cap, Capture, '$!hash', $!storage);
$cap
}
method FLATTENABLE_LIST() { nqp::list() }
method FLATTENABLE_HASH() {
pir::defined($!storage) ||
nqp::bindattr(self, EnumMap, '$!storage', nqp::hash());
$!storage
}
method fmt($format = "%s\t\%s", $sep = "\n") {
self.pairs.fmt($format, $sep);
}
}
multi sub infix:<eqv>(EnumMap $a, EnumMap $b) {
if +$a != +$b { return Bool::False }
for $a.kv -> $k, $v {
unless $b.exists($k) && $b{$k} eqv $v {
return Bool::False;
}
}
Bool::True;
}