← Index
NYTProf Performance Profile   « line view »
For ../prof.pl
  Run on Wed Dec 14 16:10:05 2022
Reported on Wed Dec 14 16:12:58 2022

Filename/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Type/Tiny/Enum.pm
StatementsExecuted 2493 statements in 4.48ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
12621917µs942µsType::Tiny::Enum::_Trie::::_regexpType::Tiny::Enum::_Trie::_regexp (recurses: max depth 12, inclusive time 3.40ms)
3743345µs515µsType::Tiny::Enum::::inline_check Type::Tiny::Enum::inline_check
1911174µs174µsType::Tiny::Enum::_Trie::::addType::Tiny::Enum::_Trie::add
4411118µs154µsType::Tiny::Enum::::parent Type::Tiny::Enum::parent
411107µs312µsType::Tiny::Enum::::new Type::Tiny::Enum::new
411103µs1.23msType::Tiny::Enum::_Trie::::handleType::Tiny::Enum::_Trie::handle
412183µs1.31msType::Tiny::Enum::::_regexp Type::Tiny::Enum::_regexp
41177µs2.40msType::Tiny::Enum::::_build_compiled_check Type::Tiny::Enum::_build_compiled_check
412165µs65µsType::Tiny::Enum::::_xs_encoding Type::Tiny::Enum::_xs_encoding
412159µs59µsType::Tiny::Enum::::unique_values Type::Tiny::Enum::unique_values
11131µs31µsType::Tiny::Enum::::BEGIN@3 Type::Tiny::Enum::BEGIN@3
1071125µs25µsType::Tiny::Enum::_Trie::::CORE:sortType::Tiny::Enum::_Trie::CORE:sort (opcode)
221125µs25µsType::Tiny::Enum::::has_parent Type::Tiny::Enum::has_parent
216320µs20µsType::Tiny::Enum::::can_be_inlined Type::Tiny::Enum::can_be_inlined
11116µs18µsType::Tiny::Enum::::BEGIN@4 Type::Tiny::Enum::BEGIN@4
41112µs12µsType::Tiny::Enum::::CORE:sort Type::Tiny::Enum::CORE:sort (opcode)
11110µs15µsType::Tiny::Enum::::BEGIN@16 Type::Tiny::Enum::BEGIN@16
4117µs7µsType::Tiny::Enum::_Trie::::newType::Tiny::Enum::_Trie::new
1116µs30µsType::Tiny::Enum::::BEGIN@5 Type::Tiny::Enum::BEGIN@5
4116µs6µsType::Tiny::Enum::::_is_null_constraint Type::Tiny::Enum::_is_null_constraint
1114µs18µsType::Tiny::Enum::::BEGIN@54 Type::Tiny::Enum::BEGIN@54
1112µs2µ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
3270µs131µs
# spent 31µs within Type::Tiny::Enum::BEGIN@3 which was called: # once (31µ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 31µs making 1 call to Type::Tiny::Enum::BEGIN@3
4227µs220µs
# spent 18µs (16+2) within Type::Tiny::Enum::BEGIN@4 which was called: # once (16µs+2µs) by Types::Standard::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard.pm:1059] at line 4
use strict;
# spent 18µs making 1 call to Type::Tiny::Enum::BEGIN@4 # spent 2µs making 1 call to strict::import
5225µs254µs
# spent 30µs (6+24) within Type::Tiny::Enum::BEGIN@5 which was called: # once (6µs+24µs) by Types::Standard::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard.pm:1059] at line 5
use warnings;
# spent 30µs making 1 call to Type::Tiny::Enum::BEGIN@5 # spent 24µ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';
10151µs12µs}
# spent 2µs making 1 call to Type::Tiny::Enum::BEGIN@7
11
1212µs$Type::Tiny::Enum::VERSION =~ tr/_//d;
13
14sub _croak ($;@) { require Error::TypeTiny; goto \&Error::TypeTiny::croak }
15
16324µs220µs
# spent 15µs (10+5) within Type::Tiny::Enum::BEGIN@16 which was called: # once (10µs+5µ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 15µs making 1 call to Type::Tiny::Enum::BEGIN@16 # spent 5µs making 1 call to UNIVERSAL::VERSION
172151µs12µs
# spent 2µs within Type::Tiny::Enum::BEGIN@17 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 17
use Type::Tiny ();
# spent 2µs making 1 call to Type::Tiny::Enum::BEGIN@17
18111µsour @ISA = qw( Type::Tiny Exporter::Tiny );
19
20__PACKAGE__->_install_overloads(
21 q[@{}] => sub { shift->values },
2216µs116µs);
# spent 16µ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 312µs (107+205) within Type::Tiny::Enum::new which was called 4 times, avg 78µs/call: # 4 times (107µs+205µ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 {
4040s my $proto = shift;
41
42410µs my %opts = ( @_ == 1 ) ? %{ $_[0] } : @_;
43 _croak
44 "Enum type constraints cannot have a parent constraint passed to the constructor"
4543µs if exists $opts{parent};
46 _croak
47 "Enum type constraints cannot have a constraint coderef passed to the constructor"
4840s if exists $opts{constraint};
49 _croak
50 "Enum type constraints cannot have a inlining coderef passed to the constructor"
5141µs if exists $opts{inlined};
5241µs _croak "Need to supply list of values" unless exists $opts{values};
53
5421.84ms232µs
# spent 18µs (4+14) within Type::Tiny::Enum::BEGIN@54 which was called: # once (4µs+14µ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 18µs making 1 call to Type::Tiny::Enum::BEGIN@54 # spent 14µ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
6040s my %tmp;
61416µs undef $tmp{$_} for @{ $opts{values} };
62429µ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
7042µ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
84421µs4189µs return $proto->SUPER::new( %opts );
# spent 189µs making 4 calls to Type::Tiny::new, avg 47µ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} }
1054189µs
# spent 59µs within Type::Tiny::Enum::unique_values which was called 41 times, avg 1µs/call: # 37 times (56µs+0s) by Type::Tiny::Enum::inline_check at line 230, avg 2µ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
108411µs
# spent 6µs within Type::Tiny::Enum::_is_null_constraint which was called 4 times, avg 2µs/call: # 4 times (6µ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 65µs within Type::Tiny::Enum::_xs_encoding which was called 41 times, avg 2µs/call: # 37 times (61µ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 {
1554110µs my $unique_values = shift;
156
1574174µ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{
19220s my %cached;
193
194
# spent 2.40ms (77µs+2.32) within Type::Tiny::Enum::_build_compiled_check which was called 4 times, avg 600µs/call: # 4 times (77µs+2.32ms) by Type::Tiny::compiled_check at line 437 of Type/Tiny.pm, avg 600µs/call
sub _build_compiled_check {
19540s my $self = shift;
19649µs41.26ms my $regexp = $self->_regexp;
# spent 1.26ms making 4 calls to Type::Tiny::Enum::_regexp, avg 315µs/call
19743µs return $cached{$regexp} if $cached{$regexp};
198421µs41.05ms my $coderef = ( $cached{$regexp} = $self->SUPER::_build_compiled_check( @_ ) );
# spent 1.05ms making 4 calls to Type::Tiny::_build_compiled_check, avg 263µs/call
199422µs412µs Scalar::Util::weaken( $cached{$regexp} );
# spent 12µs making 4 calls to Scalar::Util::weaken, avg 3µs/call
200441µs return $coderef;
201 }
202}
203
20410s
# spent 1.31ms (83µs+1.23) within Type::Tiny::Enum::_regexp which was called 41 times, avg 32µs/call: # 37 times (53µs+0s) by Type::Tiny::Enum::inline_check at line 235, avg 1µs/call # 4 times (30µs+1.23ms) by Type::Tiny::Enum::_build_compiled_check at line 196, avg 315µs/call
sub _regexp {
2054111µs my $self = shift;
20641101µs81.23ms $self->{_regexp} ||= 'Type::Tiny::Enum::_Trie'->handle( $self->unique_values );
# spent 1.23ms making 4 calls to Type::Tiny::Enum::_Trie::handle, avg 306µ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 20µs within Type::Tiny::Enum::can_be_inlined which was called 21 times, avg 952ns/call: # 9 times (8µs+0s) by Type::Tiny::inline_assert at line 915 of Type/Tiny.pm, avg 889ns/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 (3µs+0s) by Type::Tiny::_overload_coderef at line 203 of Type/Tiny.pm, avg 1µs/call # 2 times (2µs+0s) by Types::Standard::Tuple::__inline_generator at line 103 of Types/Standard/Tuple.pm, avg 1µs/call # 2 times (2µs+0s) by Types::Standard::Dict::__inline_generator at line 117 of Types/Standard/Dict.pm, avg 1µs/call # once (0s+0s) by Types::Standard::Dict::__coercion_generator at line 256 of Types/Standard/Dict.pm
sub can_be_inlined {
2232150µs !!1;
224}
225
226
# spent 515µs (345+170) within Type::Tiny::Enum::inline_check which was called 37 times, avg 14µs/call: # 16 times (151µs+69µ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 14µs/call # 9 times (63µs+34µs) by Type::Tiny::inline_assert at line 915 of Type/Tiny.pm, avg 11µs/call # 8 times (84µs+45µ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 16µs/call # 4 times (47µs+22µs) by Type::Tiny::_build_compiled_check at line 537 of Type/Tiny.pm, avg 17µs/call
sub inline_check {
227377µs my $self = shift;
228
229375µs my $xsub;
23037103µs74117µs if ( my $xs_encoding = _xs_encoding( $self->unique_values ) ) {
# spent 61µs making 37 calls to Type::Tiny::Enum::_xs_encoding, avg 2µs/call # spent 56µs making 37 calls to Type::Tiny::Enum::unique_values, avg 2µs/call
231 $xsub = Type::Tiny::XS::get_subname_for( $xs_encoding );
232 return "$xsub\($_[0]\)" if $xsub && !$Type::Tiny::AvoidCallbacks;
233 }
234
2353749µs3753µs my $regexp = $self->_regexp;
# spent 53µs making 37 calls to Type::Tiny::Enum::_regexp, avg 1µs/call
2363755µ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
241377µs return "do { $Type::Tiny::SafePackage $code }"
242 if $Type::Tiny::AvoidCallbacks;
2433770µ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 25µs within Type::Tiny::Enum::has_parent which was called 22 times, avg 1µs/call: # 22 times (25µs+0s) by Type::Tiny::is_strictly_subtype_of at line 697 of Type/Tiny.pm, avg 1µs/call
sub has_parent {
2582249µs !!1;
259}
260
261
# spent 154µs (118+36) within Type::Tiny::Enum::parent which was called 44 times, avg 4µs/call: # 44 times (118µs+36µs) by Type::Tiny::is_strictly_subtype_of at line 698 of Type/Tiny.pm, avg 4µs/call
sub parent {
2624426µs require Types::Standard;
26344101µs4436µs Types::Standard::Str();
# spent 36µs making 44 calls to Types::Standard::Str, avg 818ns/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;
39611µs};
397
398package # stolen from Regexp::Trie
399 Type::Tiny::Enum::_Trie;
40049µs
# spent 7µs within Type::Tiny::Enum::_Trie::new which was called 4 times, avg 2µs/call: # 4 times (7µs+0s) by Type::Tiny::Enum::_Trie::handle at line 444, avg 2µs/call
sub new { bless {} => shift }
401
402
# spent 174µs within Type::Tiny::Enum::_Trie::add which was called 19 times, avg 9µs/call: # 19 times (174µs+0s) by Type::Tiny::Enum::_Trie::handle at line 445, avg 9µs/call
sub add {
403195µs my $self = shift;
404192µs my $str = shift;
405192µs my $ref = $self;
4061944µs for my $char ( split //, $str ) {
40713768µs $ref->{$char} ||= {};
40813736µs $ref = $ref->{$char};
409 }
4101911µs $ref->{''} = 1; # { '' => 1 } as terminator
4111928µs $self;
412} #/ sub add
413
414
# spent 942µs (917+25) within Type::Tiny::Enum::_Trie::_regexp which was called 126 times, avg 7µs/call: # 122 times (792µs+-792µs) by Type::Tiny::Enum::_Trie::_regexp at line 421, avg 0s/call # 4 times (125µs+817µs) by Type::Tiny::Enum::_Trie::handle at line 446, avg 236µs/call
sub _regexp {
41512613µs my $self = shift;
41612654µs return if $self->{''} and scalar keys %$self == 1; # terminator
41710719µs my ( @alt, @cc );
41810714µs my $q = 0;
419107199µs10725µs for my $char ( sort keys %$self ) {
# spent 25µs making 107 calls to Type::Tiny::Enum::_Trie::CORE:sort, avg 234ns/call
42012221µs my $qchar = quotemeta $char;
421122244µs1220s if ( ref $self->{$char} ) {
# spent 3.40ms making 122 calls to Type::Tiny::Enum::_Trie::_regexp, avg 28µs/call, recursion: max depth 12, sum of overlapping time 3.40ms
422 if ( defined( my $recurse = _regexp( $self->{$char} ) ) ) {
423 push @alt, $qchar . $recurse;
424 }
425 else {
4261911µs push @cc, $qchar;
427 }
428 }
429 else {
430 $q = 1;
431 }
432 } #/ for my $char ( sort keys...)
43310720µs my $cconly = !@alt;
43410725µs @cc and push @alt, @cc == 1 ? $cc[0] : '[' . join( '', @cc ) . ']';
43510780µs my $result = @alt == 1 ? $alt[0] : '(?:' . join( '|', @alt ) . ')';
43610710µs $q and $result = $cconly ? "$result?" : "(?:$result)?";
437107235µs return $result;
438} #/ sub _regexp
439
440
# spent 1.23ms (103µs+1.12) within Type::Tiny::Enum::_Trie::handle which was called 4 times, avg 306µs/call: # 4 times (103µs+1.12ms) by Type::Tiny::Enum::_regexp at line 206, avg 306µs/call
sub handle {
44143µs my $class = shift;
44242µs my ( $vals ) = @_;
44341µs return '(?!)' unless @$vals;
44446µs47µs my $self = $class->new;
# spent 7µs making 4 calls to Type::Tiny::Enum::_Trie::new, avg 2µs/call
445417µs19174µs $self->add( $_ ) for @$vals;
# spent 174µs making 19 calls to Type::Tiny::Enum::_Trie::add, avg 9µs/call
446455µs4942µs $self->_regexp;
# spent 942µs making 4 calls to Type::Tiny::Enum::_Trie::_regexp, avg 236µs/call
447}
448
44915µ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 25µs within Type::Tiny::Enum::_Trie::CORE:sort which was called 107 times, avg 234ns/call: # 107 times (25µs+0s) by Type::Tiny::Enum::_Trie::_regexp at line 419, avg 234ns/call
sub Type::Tiny::Enum::_Trie::CORE:sort; # opcode