← Index
NYTProf Performance Profile   « line view »
For ../prof.pl
  Run on Wed Dec 14 15:33:55 2022
Reported on Wed Dec 14 15:40:04 2022

Filename/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Type/Tiny/Enum.pm
StatementsExecuted 2380 statements in 5.25ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
11821888µs909µsType::Tiny::Enum::_Trie::::_regexpType::Tiny::Enum::_Trie::_regexp (recurses: max depth 12, inclusive time 4.33ms)
3743513µs714µsType::Tiny::Enum::::inline_check Type::Tiny::Enum::inline_check
1811172µs172µsType::Tiny::Enum::_Trie::::addType::Tiny::Enum::_Trie::add
4411133µs181µsType::Tiny::Enum::::parent Type::Tiny::Enum::parent
411106µs314µsType::Tiny::Enum::::new Type::Tiny::Enum::new
41197µs1.18msType::Tiny::Enum::_Trie::::handleType::Tiny::Enum::_Trie::handle
412195µs95µsType::Tiny::Enum::::_xs_encoding Type::Tiny::Enum::_xs_encoding
412183µs1.27msType::Tiny::Enum::::_regexp Type::Tiny::Enum::_regexp
412156µs56µsType::Tiny::Enum::::unique_values Type::Tiny::Enum::unique_values
41154µs2.30msType::Tiny::Enum::::_build_compiled_check Type::Tiny::Enum::_build_compiled_check
216352µs52µsType::Tiny::Enum::::can_be_inlined Type::Tiny::Enum::can_be_inlined
11132µs32µsType::Tiny::Enum::::BEGIN@3 Type::Tiny::Enum::BEGIN@3
221126µs26µsType::Tiny::Enum::::has_parent Type::Tiny::Enum::has_parent
1001121µs21µsType::Tiny::Enum::_Trie::::CORE:sortType::Tiny::Enum::_Trie::CORE:sort (opcode)
11116µs25µsType::Tiny::Enum::::BEGIN@4 Type::Tiny::Enum::BEGIN@4
11113µs22µsType::Tiny::Enum::::BEGIN@16 Type::Tiny::Enum::BEGIN@16
41112µs12µsType::Tiny::Enum::::CORE:sort Type::Tiny::Enum::CORE:sort (opcode)
1118µs39µsType::Tiny::Enum::::BEGIN@5 Type::Tiny::Enum::BEGIN@5
1118µs25µsType::Tiny::Enum::::BEGIN@54 Type::Tiny::Enum::BEGIN@54
4118µs8µsType::Tiny::Enum::::_is_null_constraint Type::Tiny::Enum::_is_null_constraint
4116µs6µsType::Tiny::Enum::_Trie::::newType::Tiny::Enum::_Trie::new
1113µs3µsType::Tiny::Enum::::BEGIN@17 Type::Tiny::Enum::BEGIN@17
1112µs2µsType::Tiny::Enum::::BEGIN@7 Type::Tiny::Enum::BEGIN@7
0000s0sType::Tiny::Enum::::__ANON__[:185] Type::Tiny::Enum::__ANON__[:185]
0000s0sType::Tiny::Enum::::__ANON__[:21] Type::Tiny::Enum::__ANON__[:21]
0000s0sType::Tiny::Enum::::__ANON__[:315] Type::Tiny::Enum::__ANON__[:315]
0000s0sType::Tiny::Enum::::__ANON__[:316] Type::Tiny::Enum::__ANON__[:316]
0000s0sType::Tiny::Enum::::__ANON__[:396] Type::Tiny::Enum::__ANON__[:396]
0000s0sType::Tiny::Enum::::__ANON__[:79] Type::Tiny::Enum::__ANON__[:79]
0000s0sType::Tiny::Enum::::__ANON__[:81] Type::Tiny::Enum::__ANON__[:81]
0000s0sType::Tiny::Enum::::_build_constraint Type::Tiny::Enum::_build_constraint
0000s0sType::Tiny::Enum::::_build_display_name Type::Tiny::Enum::_build_display_name
0000s0sType::Tiny::Enum::::_croak Type::Tiny::Enum::_croak
0000s0sType::Tiny::Enum::::_enum_order_hash Type::Tiny::Enum::_enum_order_hash
0000s0sType::Tiny::Enum::::_exporter_fail Type::Tiny::Enum::_exporter_fail
0000s0sType::Tiny::Enum::::_instantiate_moose_type Type::Tiny::Enum::_instantiate_moose_type
0000s0sType::Tiny::Enum::::as_regexp Type::Tiny::Enum::as_regexp
0000s0sType::Tiny::Enum::::closest_match Type::Tiny::Enum::closest_match
0000s0sType::Tiny::Enum::::constraint Type::Tiny::Enum::constraint
0000s0sType::Tiny::Enum::::exportables Type::Tiny::Enum::exportables
0000s0sType::Tiny::Enum::::has_sorter Type::Tiny::Enum::has_sorter
0000s0sType::Tiny::Enum::::is_word_safe Type::Tiny::Enum::is_word_safe
0000s0sType::Tiny::Enum::::new_intersection Type::Tiny::Enum::new_intersection
0000s0sType::Tiny::Enum::::new_union Type::Tiny::Enum::new_union
0000s0sType::Tiny::Enum::::sorter Type::Tiny::Enum::sorter
0000s0sType::Tiny::Enum::::validate_explain Type::Tiny::Enum::validate_explain
0000s0sType::Tiny::Enum::::values Type::Tiny::Enum::values
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1package Type::Tiny::Enum;
2
32117µs132µs
# spent 32µs within Type::Tiny::Enum::BEGIN@3 which was called: # once (32µs+0s) by Types::Standard::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard.pm:1059] at line 3
use 5.008001;
# spent 32µs making 1 call to Type::Tiny::Enum::BEGIN@3
4246µs234µs
# spent 25µs (16+9) within Type::Tiny::Enum::BEGIN@4 which was called: # once (16µs+9µs) by Types::Standard::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard.pm:1059] at line 4
use strict;
# spent 25µs making 1 call to Type::Tiny::Enum::BEGIN@4 # spent 9µs making 1 call to strict::import
5241µs270µs
# spent 39µs (8+31) within Type::Tiny::Enum::BEGIN@5 which was called: # once (8µs+31µs) by Types::Standard::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard.pm:1059] at line 5
use warnings;
# spent 39µs making 1 call to Type::Tiny::Enum::BEGIN@5 # spent 31µs making 1 call to warnings::import
6
7
# spent 2µs within Type::Tiny::Enum::BEGIN@7 which was called: # once (2µs+0s) by Types::Standard::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard.pm:1059] at line 10
BEGIN {
810s $Type::Tiny::Enum::AUTHORITY = 'cpan:TOBYINK';
913µs $Type::Tiny::Enum::VERSION = '2.000001';
10165µs12µs}
# spent 2µs making 1 call to Type::Tiny::Enum::BEGIN@7
11
1211µs$Type::Tiny::Enum::VERSION =~ tr/_//d;
13
14sub _croak ($;@) { require Error::TypeTiny; goto \&Error::TypeTiny::croak }
15
16335µs231µs
# spent 22µs (13+9) within Type::Tiny::Enum::BEGIN@16 which was called: # once (13µs+9µs) by Types::Standard::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard.pm:1059] at line 16
use Exporter::Tiny 1.004001 ();
# spent 22µs making 1 call to Type::Tiny::Enum::BEGIN@16 # spent 9µs making 1 call to UNIVERSAL::VERSION
172223µs13µs
# spent 3µs within Type::Tiny::Enum::BEGIN@17 which was called: # once (3µs+0s) by Types::Standard::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard.pm:1059] at line 17
use Type::Tiny ();
# spent 3µs making 1 call to Type::Tiny::Enum::BEGIN@17
18112µsour @ISA = qw( Type::Tiny Exporter::Tiny );
19
20__PACKAGE__->_install_overloads(
21 q[@{}] => sub { shift->values },
2217µs121µs);
# spent 21µs making 1 call to Type::Tiny::_install_overloads
23
24sub _exporter_fail {
25 my ( $class, $type_name, $values, $globals ) = @_;
26 my $caller = $globals->{into};
27 my $type = $class->new(
28 name => $type_name,
29 values => [ @$values ],
30 coercion => 1,
31 );
32 $INC{'Type/Registry.pm'}
33 ? 'Type::Registry'->for_class( $caller )->add_type( $type, $type_name )
34 : ( $Type::Registry::DELAYED{$caller}{$type_name} = $type )
35 unless( ref($caller) or $caller eq '-lexical' or $globals->{'lexical'} );
36 return map +( $_->{name} => $_->{code} ), @{ $type->exportables };
37}
38
39
# spent 314µs (106+208) within Type::Tiny::Enum::new which was called 4 times, avg 78µs/call: # 4 times (106µs+208µs) by Types::Standard::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard.pm:1059] at line 1054 of Types/Standard.pm, avg 78µs/call
sub new {
4041µs my $proto = shift;
41
4248µs my %opts = ( @_ == 1 ) ? %{ $_[0] } : @_;
43 _croak
44 "Enum type constraints cannot have a parent constraint passed to the constructor"
4542µs if exists $opts{parent};
46 _croak
47 "Enum type constraints cannot have a constraint coderef passed to the constructor"
4842µs if exists $opts{constraint};
49 _croak
50 "Enum type constraints cannot have a inlining coderef passed to the constructor"
5140s if exists $opts{inlined};
5241µs _croak "Need to supply list of values" unless exists $opts{values};
53
5422.23ms242µs
# spent 25µs (8+17) within Type::Tiny::Enum::BEGIN@54 which was called: # once (8µs+17µs) by Types::Standard::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard.pm:1059] at line 54
no warnings 'uninitialized';
# spent 25µs making 1 call to Type::Tiny::Enum::BEGIN@54 # spent 17µs making 1 call to warnings::unimport
55 $opts{values} = [
56 map "$_",
57418µs @{ ref $opts{values} eq 'ARRAY' ? $opts{values} : [ $opts{values} ] }
58 ];
59
6041µs my %tmp;
61415µs undef $tmp{$_} for @{ $opts{values} };
62430µs412µs $opts{unique_values} = [ sort keys %tmp ];
# spent 12µs making 4 calls to Type::Tiny::Enum::CORE:sort, avg 3µs/call
63
6447µs44µs my $xs_encoding = _xs_encoding( $opts{unique_values} );
# spent 4µs making 4 calls to Type::Tiny::Enum::_xs_encoding, avg 1µs/call
6542µs if ( defined $xs_encoding ) {
66 my $xsub = Type::Tiny::XS::get_coderef_for( $xs_encoding );
67 $opts{compiled_type_constraint} = $xsub if $xsub;
68 }
69
7041µs if ( defined $opts{coercion} and !ref $opts{coercion} and 1 eq $opts{coercion} )
71 {
72 delete $opts{coercion};
73 $opts{_build_coercion} = sub {
74 require Types::Standard;
75 my $c = shift;
76 my $t = $c->type_constraint;
77 $c->add_type_coercions(
78 Types::Standard::Str(),
79 sub { $t->closest_match( @_ ? $_[0] : $_ ) }
80 );
81 };
82 } #/ if ( defined $opts{coercion...})
83
84424µs4192µs return $proto->SUPER::new( %opts );
# spent 192µs making 4 calls to Type::Tiny::new, avg 48µs/call
85} #/ sub new
86
87sub new_union {
88 my $proto = shift;
89 my %opts = ( @_ == 1 ) ? %{ $_[0] } : @_;
90 my @types = @{ delete $opts{type_constraints} };
91 my @values = map @$_, @types;
92 $proto->new( %opts, values => \@values );
93}
94
95sub new_intersection {
96 my $proto = shift;
97 my %opts = ( @_ == 1 ) ? %{ $_[0] } : @_;
98 my @types = @{ delete $opts{type_constraints} };
99 my %values; ++$values{$_} for map @$_, @types;
100 my @values = sort grep $values{$_}==@types, keys %values;
101 $proto->new( %opts, values => \@values );
102}
103
104sub values { $_[0]{values} }
10541163µs
# spent 56µs within Type::Tiny::Enum::unique_values which was called 41 times, avg 1µs/call: # 37 times (53µs+0s) by Type::Tiny::Enum::inline_check at line 230, avg 1µs/call # 4 times (3µs+0s) by Type::Tiny::Enum::_regexp at line 206, avg 750ns/call
sub unique_values { $_[0]{unique_values} }
106sub constraint { $_[0]{constraint} ||= $_[0]->_build_constraint }
107
10847µs
# spent 8µs within Type::Tiny::Enum::_is_null_constraint which was called 4 times, avg 2µs/call: # 4 times (8µs+0s) by Type::Tiny::_build_compiled_check at line 532 of Type/Tiny.pm, avg 2µs/call
sub _is_null_constraint { 0 }
109
110sub _build_display_name {
111 my $self = shift;
112 sprintf( "Enum[%s]", join q[,], @{ $self->unique_values } );
113}
114
115sub is_word_safe {
116 my $self = shift;
117 return not grep /\W/, @{ $self->unique_values };
118}
119
120sub exportables {
121 my ( $self, $base_name ) = @_;
122 if ( not $self->is_anon ) {
123 $base_name ||= $self->name;
124 }
125
126 my $exportables = $self->SUPER::exportables( $base_name );
127
128 if ( $self->is_word_safe ) {
129 require Eval::TypeTiny;
130 require B;
131 for my $value ( @{ $self->unique_values } ) {
132 push @$exportables, {
133 name => uc( sprintf '%s_%s', $base_name, $value ),
134 tags => [ 'constants' ],
135 code => Eval::TypeTiny::eval_closure(
136 source => sprintf( 'sub () { %s }', B::perlstring($value) ),
137 environment => {},
138 ),
139 };
140 }
141 }
142
143 return $exportables;
144}
145
146{
14710s my $new_xs;
148
149 #
150 # Note the fallback code for older Type::Tiny::XS cannot be tested as
151 # part of the coverage tests because they use the latest Type::Tiny::XS.
152 #
153
154
# spent 95µs within Type::Tiny::Enum::_xs_encoding which was called 41 times, avg 2µs/call: # 37 times (91µs+0s) by Type::Tiny::Enum::inline_check at line 230, avg 2µs/call # 4 times (4µs+0s) by Type::Tiny::Enum::new at line 64, avg 1µs/call
sub _xs_encoding {
1554124µs my $unique_values = shift;
156
15741101µs return undef unless Type::Tiny::_USE_XS;
158
159 return undef if @$unique_values > 50; # RT 121957
160
161 $new_xs = eval { Type::Tiny::XS->VERSION( "0.020" ); 1 } ? 1 : 0
162 unless defined $new_xs;
163 if ( $new_xs ) {
164 require B;
165 return sprintf(
166 "Enum[%s]",
167 join( ",", map B::perlstring( $_ ), @$unique_values )
168 );
169 }
170 else { # uncoverable statement
171 return undef if grep /\W/, @$unique_values; # uncoverable statement
172 return sprintf( "Enum[%s]", join( ",", @$unique_values ) ); # uncoverable statement
173 } # uncoverable statement
174 } #/ sub _xs_encoding
175}
176
177{
17820s my %cached;
179
180 sub _build_constraint {
181 my $self = shift;
182
183 my $regexp = $self->_regexp;
184 return $cached{$regexp} if $cached{$regexp};
185 my $coderef = ( $cached{$regexp} = sub { defined and m{\A(?:$regexp)\z} } );
186 Scalar::Util::weaken( $cached{$regexp} );
187 return $coderef;
188 }
189}
190
191{
19221µs my %cached;
193
194
# spent 2.30ms (54µs+2.25) within Type::Tiny::Enum::_build_compiled_check which was called 4 times, avg 576µs/call: # 4 times (54µs+2.25ms) by Type::Tiny::compiled_check at line 437 of Type/Tiny.pm, avg 576µs/call
sub _build_compiled_check {
19541µs my $self = shift;
19645µs41.21ms my $regexp = $self->_regexp;
# spent 1.21ms making 4 calls to Type::Tiny::Enum::_regexp, avg 303µs/call
19744µs return $cached{$regexp} if $cached{$regexp};
198417µs41.03ms my $coderef = ( $cached{$regexp} = $self->SUPER::_build_compiled_check( @_ ) );
# spent 1.03ms making 4 calls to Type::Tiny::_build_compiled_check, avg 258µs/call
199415µs45µs Scalar::Util::weaken( $cached{$regexp} );
# spent 5µs making 4 calls to Scalar::Util::weaken, avg 1µs/call
20049µs return $coderef;
201 }
202}
203
20410s
# spent 1.27ms (83µs+1.19) within Type::Tiny::Enum::_regexp which was called 41 times, avg 31µs/call: # 37 times (57µs+0s) by Type::Tiny::Enum::inline_check at line 235, avg 2µs/call # 4 times (26µs+1.19ms) by Type::Tiny::Enum::_build_compiled_check at line 196, avg 303µs/call
sub _regexp {
2054113µs my $self = shift;
20641107µs81.19ms $self->{_regexp} ||= 'Type::Tiny::Enum::_Trie'->handle( $self->unique_values );
# spent 1.18ms making 4 calls to Type::Tiny::Enum::_Trie::handle, avg 296µs/call # spent 3µs making 4 calls to Type::Tiny::Enum::unique_values, avg 750ns/call
207}
208
209sub as_regexp {
210 my $self = shift;
211
212 my $flags = @_ ? $_[0] : '';
213 unless ( defined $flags and $flags =~ /^[i]*$/ ) {
214 _croak(
215 "Unknown regexp flags: '$flags'; only 'i' currently accepted; stopped" );
216 }
217
218 my $regexp = $self->_regexp;
219 $flags ? qr/\A(?:$regexp)\z/i : qr/\A(?:$regexp)\z/;
220} #/ sub as_regexp
221
222
# spent 52µs within Type::Tiny::Enum::can_be_inlined which was called 21 times, avg 2µs/call: # 9 times (41µs+0s) by Type::Tiny::inline_assert at line 915 of Type/Tiny.pm, avg 5µs/call # 4 times (5µs+0s) by Type::Tiny::_build_compiled_check at line 537 of Type/Tiny.pm, avg 1µs/call # 3 times (1µs+0s) by Type::Tiny::_overload_coderef at line 203 of Type/Tiny.pm, avg 333ns/call # 2 times (3µs+0s) by Types::Standard::Dict::__inline_generator at line 117 of Types/Standard/Dict.pm, avg 2µs/call # 2 times (1µs+0s) by Types::Standard::Tuple::__inline_generator at line 103 of Types/Standard/Tuple.pm, avg 500ns/call # once (1µs+0s) by Types::Standard::Dict::__coercion_generator at line 256 of Types/Standard/Dict.pm
sub can_be_inlined {
2232153µs !!1;
224}
225
226
# spent 714µs (513+201) within Type::Tiny::Enum::inline_check which was called 37 times, avg 19µs/call: # 16 times (217µs+89µs) by Types::Standard::Dict::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard/Dict.pm:161] at line 156 of Types/Standard/Dict.pm, avg 19µs/call # 9 times (126µs+58µs) by Type::Tiny::inline_assert at line 915 of Type/Tiny.pm, avg 20µs/call # 8 times (124µs+34µs) by Types::Standard::Tuple::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard/Tuple.pm:164] at line 157 of Types/Standard/Tuple.pm, avg 20µs/call # 4 times (46µs+20µs) by Type::Tiny::_build_compiled_check at line 537 of Type/Tiny.pm, avg 16µs/call
sub inline_check {
227378µs my $self = shift;
228
2293710µs my $xsub;
23037143µs74144µs if ( my $xs_encoding = _xs_encoding( $self->unique_values ) ) {
# spent 91µs making 37 calls to Type::Tiny::Enum::_xs_encoding, avg 2µs/call # spent 53µs making 37 calls to Type::Tiny::Enum::unique_values, avg 1µs/call
231 $xsub = Type::Tiny::XS::get_subname_for( $xs_encoding );
232 return "$xsub\($_[0]\)" if $xsub && !$Type::Tiny::AvoidCallbacks;
233 }
234
2353768µs3757µs my $regexp = $self->_regexp;
# spent 57µs making 37 calls to Type::Tiny::Enum::_regexp, avg 2µs/call
2363756µs my $code =
237 $_[0] eq '$_'
238 ? "(defined and !ref and m{\\A(?:$regexp)\\z})"
239 : "(defined($_[0]) and !ref($_[0]) and $_[0] =~ m{\\A(?:$regexp)\\z})";
240
2413712µs return "do { $Type::Tiny::SafePackage $code }"
242 if $Type::Tiny::AvoidCallbacks;
24337146µs return $code;
244} #/ sub inline_check
245
246sub _instantiate_moose_type {
247 my $self = shift;
248 my %opts = @_;
249 delete $opts{parent};
250 delete $opts{constraint};
251 delete $opts{inlined};
252 require Moose::Meta::TypeConstraint::Enum;
253 return "Moose::Meta::TypeConstraint::Enum"
254 ->new( %opts, values => $self->values );
255} #/ sub _instantiate_moose_type
256
257
# spent 26µs within Type::Tiny::Enum::has_parent which was called 22 times, avg 1µs/call: # 22 times (26µs+0s) by Type::Tiny::is_strictly_subtype_of at line 697 of Type/Tiny.pm, avg 1µs/call
sub has_parent {
2582250µs !!1;
259}
260
261
# spent 181µs (133+48) within Type::Tiny::Enum::parent which was called 44 times, avg 4µs/call: # 44 times (133µs+48µs) by Type::Tiny::is_strictly_subtype_of at line 698 of Type/Tiny.pm, avg 4µs/call
sub parent {
2624435µs require Types::Standard;
26344112µs4448µs Types::Standard::Str();
# spent 48µs making 44 calls to Types::Standard::Str, avg 1µs/call
264}
265
266sub validate_explain {
267 my $self = shift;
268 my ( $value, $varname ) = @_;
269 $varname = '$_' unless defined $varname;
270
271 return undef if $self->check( $value );
272
273 require Type::Utils;
274 !defined( $value )
275 ? [
276 sprintf(
277 '"%s" requires that the value is defined',
278 $self,
279 ),
280 ]
281 : @$self < 13 ? [
282 sprintf(
283 '"%s" requires that the value is equal to %s',
284 $self,
285 Type::Utils::english_list( \"or", map B::perlstring( $_ ), @$self ),
286 ),
287 ]
288 : [
289 sprintf(
290 '"%s" requires that the value is one of an enumerated list of strings',
291 $self,
292 ),
293 ];
294} #/ sub validate_explain
295
296sub has_sorter {
297 !!1;
298}
299
300sub _enum_order_hash {
301 my $self = shift;
302 my %hash;
303 my $i = 0;
304 for my $value ( @{ $self->values } ) {
305 next if exists $hash{$value};
306 $hash{$value} = $i++;
307 }
308 return %hash;
309} #/ sub _enum_order_hash
310
311sub sorter {
312 my $self = shift;
313 my %hash = $self->_enum_order_hash;
314 return [
315 sub { $_[0] <=> $_[1] },
316 sub { exists( $hash{ $_[0] } ) ? $hash{ $_[0] } : 2_100_000_000 },
317 ];
318}
319
32010smy $canon;
321
322sub closest_match {
323 require Types::Standard;
324
325 my ( $self, $given ) = ( shift, @_ );
326
327 return unless Types::Standard::is_Str $given;
328
329 return $given if $self->check( $given );
330
331 $canon ||= eval(
332 $] lt '5.016'
333 ? q< sub { ( my $var = lc($_[0]) ) =~ s/(^\s+)|(\s+$)//g; $var } >
334 : q< sub { CORE::fc($_[0]) =~ s/(^\s+)|(\s+$)//gr; } >
335 );
336
337 $self->{_lookups} ||= do {
338 my %lookups;
339 for ( @{ $self->values } ) {
340 my $key = $canon->( $_ );
341 next if exists $lookups{$key};
342 $lookups{$key} = $_;
343 }
344 \%lookups;
345 };
346
347 my $cgiven = $canon->( $given );
348 return $self->{_lookups}{$cgiven}
349 if $self->{_lookups}{$cgiven};
350
351 my $best;
352 VALUE: for my $possible ( @{ $self->values } ) {
353 my $stem = substr( $possible, 0, length $cgiven );
354 if ( $cgiven eq $canon->( $stem ) ) {
355 if ( defined( $best ) and length( $best ) >= length( $possible ) ) {
356 next VALUE;
357 }
358 $best = $possible;
359 }
360 }
361
362 return $best if defined $best;
363
364 return $self->values->[$given]
365 if Types::Standard::is_Int $given;
366
367 return $given;
368} #/ sub closest_match
369
370push @Type::Tiny::CMP, sub {
371 my $A = shift->find_constraining_type;
372 my $B = shift->find_constraining_type;
373 return Type::Tiny::CMP_UNKNOWN
374 unless $A->isa( __PACKAGE__ ) && $B->isa( __PACKAGE__ );
375
376 my %seen;
377 for my $word ( @{ $A->unique_values } ) {
378 $seen{$word} += 1;
379 }
380 for my $word ( @{ $B->unique_values } ) {
381 $seen{$word} += 2;
382 }
383
384 my $values = join( '', CORE::values %seen );
385 if ( $values =~ /^3*$/ ) {
386 return Type::Tiny::CMP_EQUIVALENT;
387 }
388 elsif ( $values !~ /2/ ) {
389 return Type::Tiny::CMP_SUPERTYPE;
390 }
391 elsif ( $values !~ /1/ ) {
392 return Type::Tiny::CMP_SUBTYPE;
393 }
394
395 return Type::Tiny::CMP_UNKNOWN;
39612µs};
397
398package # stolen from Regexp::Trie
399 Type::Tiny::Enum::_Trie;
400411µs
# spent 6µs within Type::Tiny::Enum::_Trie::new which was called 4 times, avg 2µs/call: # 4 times (6µs+0s) by Type::Tiny::Enum::_Trie::handle at line 444, avg 2µs/call
sub new { bless {} => shift }
401
402
# spent 172µs within Type::Tiny::Enum::_Trie::add which was called 18 times, avg 10µs/call: # 18 times (172µs+0s) by Type::Tiny::Enum::_Trie::handle at line 445, avg 10µs/call
sub add {
403184µs my $self = shift;
404183µs my $str = shift;
405184µs my $ref = $self;
4061845µs for my $char ( split //, $str ) {
40712865µs $ref->{$char} ||= {};
40812835µs $ref = $ref->{$char};
409 }
410188µs $ref->{''} = 1; # { '' => 1 } as terminator
4111826µs $self;
412} #/ sub add
413
414
# spent 909µs (888+21) within Type::Tiny::Enum::_Trie::_regexp which was called 118 times, avg 8µs/call: # 114 times (811µs+-811µs) by Type::Tiny::Enum::_Trie::_regexp at line 421, avg 0s/call # 4 times (77µs+832µs) by Type::Tiny::Enum::_Trie::handle at line 446, avg 227µs/call
sub _regexp {
41511812µs my $self = shift;
41611861µs return if $self->{''} and scalar keys %$self == 1; # terminator
41710010µs my ( @alt, @cc );
41810014µs my $q = 0;
419100257µs10021µs for my $char ( sort keys %$self ) {
# spent 21µs making 100 calls to Type::Tiny::Enum::_Trie::CORE:sort, avg 210ns/call
42011422µs my $qchar = quotemeta $char;
421114216µs1140s if ( ref $self->{$char} ) {
# spent 4.33ms making 114 calls to Type::Tiny::Enum::_Trie::_regexp, avg 38µs/call, recursion: max depth 12, sum of overlapping time 4.33ms
422 if ( defined( my $recurse = _regexp( $self->{$char} ) ) ) {
423 push @alt, $qchar . $recurse;
424 }
425 else {
426189µs push @cc, $qchar;
427 }
428 }
429 else {
430 $q = 1;
431 }
432 } #/ for my $char ( sort keys...)
43310020µs my $cconly = !@alt;
43410016µs @cc and push @alt, @cc == 1 ? $cc[0] : '[' . join( '', @cc ) . ']';
43510071µs my $result = @alt == 1 ? $alt[0] : '(?:' . join( '|', @alt ) . ')';
43610013µs $q and $result = $cconly ? "$result?" : "(?:$result)?";
437100192µs return $result;
438} #/ sub _regexp
439
440
# spent 1.18ms (97µs+1.09) within Type::Tiny::Enum::_Trie::handle which was called 4 times, avg 296µs/call: # 4 times (97µs+1.09ms) by Type::Tiny::Enum::_regexp at line 206, avg 296µs/call
sub handle {
44141µs my $class = shift;
44242µs my ( $vals ) = @_;
44340s return '(?!)' unless @$vals;
44444µs46µs my $self = $class->new;
# spent 6µs making 4 calls to Type::Tiny::Enum::_Trie::new, avg 2µs/call
445417µs18172µs $self->add( $_ ) for @$vals;
# spent 172µs making 18 calls to Type::Tiny::Enum::_Trie::add, avg 10µs/call
446451µs4909µs $self->_regexp;
# spent 909µs making 4 calls to Type::Tiny::Enum::_Trie::_regexp, avg 227µs/call
447}
448
44917µs1;
450
451__END__
 
# spent 12µs within Type::Tiny::Enum::CORE:sort which was called 4 times, avg 3µs/call: # 4 times (12µs+0s) by Type::Tiny::Enum::new at line 62, avg 3µs/call
sub Type::Tiny::Enum::CORE:sort; # opcode
# spent 21µs within Type::Tiny::Enum::_Trie::CORE:sort which was called 100 times, avg 210ns/call: # 100 times (21µs+0s) by Type::Tiny::Enum::_Trie::_regexp at line 419, avg 210ns/call
sub Type::Tiny::Enum::_Trie::CORE:sort; # opcode