| Filename | /Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Type/Tiny/Enum.pm |
| Statements | Executed 2493 statements in 3.75ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 126 | 2 | 1 | 604µs | 614µs | Type::Tiny::Enum::_Trie::_regexp (recurses: max depth 12, inclusive time 2.58ms) |
| 37 | 4 | 3 | 317µs | 483µs | Type::Tiny::Enum::inline_check |
| 19 | 1 | 1 | 124µs | 124µs | Type::Tiny::Enum::_Trie::add |
| 4 | 1 | 1 | 118µs | 271µs | Type::Tiny::Enum::new |
| 44 | 1 | 1 | 81µs | 112µs | Type::Tiny::Enum::parent |
| 4 | 1 | 1 | 76µs | 817µs | Type::Tiny::Enum::_Trie::handle |
| 41 | 2 | 1 | 76µs | 897µs | Type::Tiny::Enum::_regexp |
| 41 | 2 | 1 | 73µs | 73µs | Type::Tiny::Enum::_xs_encoding |
| 41 | 2 | 1 | 50µs | 50µs | Type::Tiny::Enum::unique_values |
| 4 | 1 | 1 | 39µs | 1.57ms | Type::Tiny::Enum::_build_compiled_check |
| 21 | 6 | 3 | 34µs | 34µs | Type::Tiny::Enum::can_be_inlined |
| 1 | 1 | 1 | 25µs | 25µs | Type::Tiny::Enum::BEGIN@3 |
| 22 | 1 | 1 | 19µs | 19µs | Type::Tiny::Enum::has_parent |
| 107 | 1 | 1 | 10µs | 10µs | Type::Tiny::Enum::_Trie::CORE:sort (opcode) |
| 1 | 1 | 1 | 9µs | 14µs | Type::Tiny::Enum::BEGIN@16 |
| 4 | 1 | 1 | 8µs | 8µs | Type::Tiny::Enum::CORE:sort (opcode) |
| 1 | 1 | 1 | 6µs | 8µs | Type::Tiny::Enum::BEGIN@4 |
| 1 | 1 | 1 | 5µs | 14µs | Type::Tiny::Enum::BEGIN@54 |
| 1 | 1 | 1 | 3µs | 28µs | Type::Tiny::Enum::BEGIN@5 |
| 4 | 1 | 1 | 3µs | 3µs | Type::Tiny::Enum::_Trie::new |
| 1 | 1 | 1 | 2µs | 2µs | Type::Tiny::Enum::BEGIN@17 |
| 1 | 1 | 1 | 2µs | 2µs | Type::Tiny::Enum::BEGIN@7 |
| 4 | 1 | 1 | 1µs | 1µs | Type::Tiny::Enum::_is_null_constraint |
| 0 | 0 | 0 | 0s | 0s | Type::Tiny::Enum::__ANON__[:185] |
| 0 | 0 | 0 | 0s | 0s | Type::Tiny::Enum::__ANON__[:21] |
| 0 | 0 | 0 | 0s | 0s | Type::Tiny::Enum::__ANON__[:315] |
| 0 | 0 | 0 | 0s | 0s | Type::Tiny::Enum::__ANON__[:316] |
| 0 | 0 | 0 | 0s | 0s | Type::Tiny::Enum::__ANON__[:396] |
| 0 | 0 | 0 | 0s | 0s | Type::Tiny::Enum::__ANON__[:79] |
| 0 | 0 | 0 | 0s | 0s | Type::Tiny::Enum::__ANON__[:81] |
| 0 | 0 | 0 | 0s | 0s | Type::Tiny::Enum::_build_constraint |
| 0 | 0 | 0 | 0s | 0s | Type::Tiny::Enum::_build_display_name |
| 0 | 0 | 0 | 0s | 0s | Type::Tiny::Enum::_croak |
| 0 | 0 | 0 | 0s | 0s | Type::Tiny::Enum::_enum_order_hash |
| 0 | 0 | 0 | 0s | 0s | Type::Tiny::Enum::_exporter_fail |
| 0 | 0 | 0 | 0s | 0s | Type::Tiny::Enum::_instantiate_moose_type |
| 0 | 0 | 0 | 0s | 0s | Type::Tiny::Enum::as_regexp |
| 0 | 0 | 0 | 0s | 0s | Type::Tiny::Enum::closest_match |
| 0 | 0 | 0 | 0s | 0s | Type::Tiny::Enum::constraint |
| 0 | 0 | 0 | 0s | 0s | Type::Tiny::Enum::exportables |
| 0 | 0 | 0 | 0s | 0s | Type::Tiny::Enum::has_sorter |
| 0 | 0 | 0 | 0s | 0s | Type::Tiny::Enum::is_word_safe |
| 0 | 0 | 0 | 0s | 0s | Type::Tiny::Enum::new_intersection |
| 0 | 0 | 0 | 0s | 0s | Type::Tiny::Enum::new_union |
| 0 | 0 | 0 | 0s | 0s | Type::Tiny::Enum::sorter |
| 0 | 0 | 0 | 0s | 0s | Type::Tiny::Enum::validate_explain |
| 0 | 0 | 0 | 0s | 0s | Type::Tiny::Enum::values |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | package Type::Tiny::Enum; | ||||
| 2 | |||||
| 3 | 2 | 38µs | 1 | 25µs | # spent 25µs within Type::Tiny::Enum::BEGIN@3 which was called:
# once (25µs+0s) by Types::Standard::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard.pm:1059] at line 3 # spent 25µs making 1 call to Type::Tiny::Enum::BEGIN@3 |
| 4 | 2 | 21µs | 2 | 10µs | # spent 8µs (6+2) within Type::Tiny::Enum::BEGIN@4 which was called:
# once (6µs+2µs) by Types::Standard::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard.pm:1059] at line 4 # spent 8µs making 1 call to Type::Tiny::Enum::BEGIN@4
# spent 2µs making 1 call to strict::import |
| 5 | 2 | 25µs | 2 | 53µs | # spent 28µs (3+25) within Type::Tiny::Enum::BEGIN@5 which was called:
# once (3µs+25µs) by Types::Standard::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard.pm:1059] at line 5 # spent 28µs making 1 call to Type::Tiny::Enum::BEGIN@5
# spent 25µ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 | ||||
| 8 | 1 | 1µs | $Type::Tiny::Enum::AUTHORITY = 'cpan:TOBYINK'; | ||
| 9 | 1 | 2µs | $Type::Tiny::Enum::VERSION = '2.000001'; | ||
| 10 | 1 | 42µs | 1 | 2µs | } # spent 2µs making 1 call to Type::Tiny::Enum::BEGIN@7 |
| 11 | |||||
| 12 | 1 | 1µs | $Type::Tiny::Enum::VERSION =~ tr/_//d; | ||
| 13 | |||||
| 14 | sub _croak ($;@) { require Error::TypeTiny; goto \&Error::TypeTiny::croak } | ||||
| 15 | |||||
| 16 | 3 | 23µs | 2 | 19µs | # spent 14µs (9+5) within Type::Tiny::Enum::BEGIN@16 which was called:
# once (9µs+5µs) by Types::Standard::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard.pm:1059] at line 16 # spent 14µs making 1 call to Type::Tiny::Enum::BEGIN@16
# spent 5µs making 1 call to UNIVERSAL::VERSION |
| 17 | 2 | 146µs | 1 | 2µ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 # spent 2µs making 1 call to Type::Tiny::Enum::BEGIN@17 |
| 18 | 1 | 8µs | our @ISA = qw( Type::Tiny Exporter::Tiny ); | ||
| 19 | |||||
| 20 | __PACKAGE__->_install_overloads( | ||||
| 21 | q[@{}] => sub { shift->values }, | ||||
| 22 | 1 | 5µs | 1 | 15µs | ); # spent 15µs making 1 call to Type::Tiny::_install_overloads |
| 23 | |||||
| 24 | sub _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 271µs (118+153) within Type::Tiny::Enum::new which was called 4 times, avg 68µs/call:
# 4 times (118µs+153µ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 68µs/call | ||||
| 40 | 4 | 2µs | my $proto = shift; | ||
| 41 | |||||
| 42 | 4 | 5µs | my %opts = ( @_ == 1 ) ? %{ $_[0] } : @_; | ||
| 43 | _croak | ||||
| 44 | "Enum type constraints cannot have a parent constraint passed to the constructor" | ||||
| 45 | 4 | 3µs | if exists $opts{parent}; | ||
| 46 | _croak | ||||
| 47 | "Enum type constraints cannot have a constraint coderef passed to the constructor" | ||||
| 48 | 4 | 0s | if exists $opts{constraint}; | ||
| 49 | _croak | ||||
| 50 | "Enum type constraints cannot have a inlining coderef passed to the constructor" | ||||
| 51 | 4 | 2µs | if exists $opts{inlined}; | ||
| 52 | 4 | 0s | _croak "Need to supply list of values" unless exists $opts{values}; | ||
| 53 | |||||
| 54 | 2 | 1.74ms | 2 | 23µs | # spent 14µs (5+9) within Type::Tiny::Enum::BEGIN@54 which was called:
# once (5µs+9µs) by Types::Standard::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard.pm:1059] at line 54 # spent 14µs making 1 call to Type::Tiny::Enum::BEGIN@54
# spent 9µs making 1 call to warnings::unimport |
| 55 | $opts{values} = [ | ||||
| 56 | map "$_", | ||||
| 57 | 4 | 14µs | @{ ref $opts{values} eq 'ARRAY' ? $opts{values} : [ $opts{values} ] } | ||
| 58 | ]; | ||||
| 59 | |||||
| 60 | 4 | 1µs | my %tmp; | ||
| 61 | 4 | 17µs | undef $tmp{$_} for @{ $opts{values} }; | ||
| 62 | 4 | 27µs | 4 | 8µs | $opts{unique_values} = [ sort keys %tmp ]; # spent 8µs making 4 calls to Type::Tiny::Enum::CORE:sort, avg 2µs/call |
| 63 | |||||
| 64 | 4 | 6µs | 4 | 7µs | my $xs_encoding = _xs_encoding( $opts{unique_values} ); # spent 7µs making 4 calls to Type::Tiny::Enum::_xs_encoding, avg 2µs/call |
| 65 | 4 | 1µ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 | |||||
| 70 | 4 | 25µ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 | |||||
| 84 | 4 | 19µs | 4 | 138µs | return $proto->SUPER::new( %opts ); # spent 138µs making 4 calls to Type::Tiny::new, avg 34µs/call |
| 85 | } #/ sub new | ||||
| 86 | |||||
| 87 | sub 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 | |||||
| 95 | sub 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 | |||||
| 104 | sub values { $_[0]{values} } | ||||
| 105 | 41 | 86µs | sub unique_values { $_[0]{unique_values} } | ||
| 106 | sub constraint { $_[0]{constraint} ||= $_[0]->_build_constraint } | ||||
| 107 | |||||
| 108 | 4 | 8µs | # spent 1µs within Type::Tiny::Enum::_is_null_constraint which was called 4 times, avg 250ns/call:
# 4 times (1µs+0s) by Type::Tiny::_build_compiled_check at line 532 of Type/Tiny.pm, avg 250ns/call | ||
| 109 | |||||
| 110 | sub _build_display_name { | ||||
| 111 | my $self = shift; | ||||
| 112 | sprintf( "Enum[%s]", join q[,], @{ $self->unique_values } ); | ||||
| 113 | } | ||||
| 114 | |||||
| 115 | sub is_word_safe { | ||||
| 116 | my $self = shift; | ||||
| 117 | return not grep /\W/, @{ $self->unique_values }; | ||||
| 118 | } | ||||
| 119 | |||||
| 120 | sub 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 | { | ||||
| 147 | 1 | 0s | 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 | sub _xs_encoding { | ||||
| 155 | 41 | 10µs | my $unique_values = shift; | ||
| 156 | |||||
| 157 | 41 | 67µ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 | { | ||||
| 178 | 2 | 0s | 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 | { | ||||
| 192 | 2 | 0s | my %cached; | ||
| 193 | |||||
| 194 | # spent 1.57ms (39µs+1.53) within Type::Tiny::Enum::_build_compiled_check which was called 4 times, avg 392µs/call:
# 4 times (39µs+1.53ms) by Type::Tiny::compiled_check at line 437 of Type/Tiny.pm, avg 392µs/call | ||||
| 195 | 4 | 1µs | my $self = shift; | ||
| 196 | 4 | 5µs | 4 | 843µs | my $regexp = $self->_regexp; # spent 843µs making 4 calls to Type::Tiny::Enum::_regexp, avg 211µs/call |
| 197 | 4 | 3µs | return $cached{$regexp} if $cached{$regexp}; | ||
| 198 | 4 | 12µs | 4 | 682µs | my $coderef = ( $cached{$regexp} = $self->SUPER::_build_compiled_check( @_ ) ); # spent 682µs making 4 calls to Type::Tiny::_build_compiled_check, avg 170µs/call |
| 199 | 4 | 10µs | 4 | 2µs | Scalar::Util::weaken( $cached{$regexp} ); # spent 2µs making 4 calls to Scalar::Util::weaken, avg 500ns/call |
| 200 | 4 | 7µs | return $coderef; | ||
| 201 | } | ||||
| 202 | } | ||||
| 203 | |||||
| 204 | 1 | 0s | sub _regexp { | ||
| 205 | 41 | 12µs | my $self = shift; | ||
| 206 | 41 | 84µs | 8 | 821µs | $self->{_regexp} ||= 'Type::Tiny::Enum::_Trie'->handle( $self->unique_values ); # spent 817µs making 4 calls to Type::Tiny::Enum::_Trie::handle, avg 204µs/call
# spent 4µs making 4 calls to Type::Tiny::Enum::unique_values, avg 1µs/call |
| 207 | } | ||||
| 208 | |||||
| 209 | sub 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 34µs within Type::Tiny::Enum::can_be_inlined which was called 21 times, avg 2µs/call:
# 9 times (22µs+0s) by Type::Tiny::inline_assert at line 915 of Type/Tiny.pm, avg 2µs/call
# 4 times (4µ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 (4µs+0s) by Types::Standard::Dict::__inline_generator at line 117 of Types/Standard/Dict.pm, avg 2µ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
# once (1µs+0s) by Types::Standard::Dict::__coercion_generator at line 256 of Types/Standard/Dict.pm | ||||
| 223 | 21 | 41µs | !!1; | ||
| 224 | } | ||||
| 225 | |||||
| 226 | # spent 483µs (317+166) within Type::Tiny::Enum::inline_check which was called 37 times, avg 13µs/call:
# 16 times (118µs+51µ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 11µs/call
# 9 times (98µs+65µs) by Type::Tiny::inline_assert at line 915 of Type/Tiny.pm, avg 18µs/call
# 8 times (72µs+41µ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 14µs/call
# 4 times (29µs+9µs) by Type::Tiny::_build_compiled_check at line 537 of Type/Tiny.pm, avg 10µs/call | ||||
| 227 | 37 | 7µs | my $self = shift; | ||
| 228 | |||||
| 229 | 37 | 8µs | my $xsub; | ||
| 230 | 37 | 114µs | 74 | 112µs | if ( my $xs_encoding = _xs_encoding( $self->unique_values ) ) { # spent 66µs making 37 calls to Type::Tiny::Enum::_xs_encoding, avg 2µs/call
# spent 46µ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 | |||||
| 235 | 37 | 47µs | 37 | 54µs | my $regexp = $self->_regexp; # spent 54µs making 37 calls to Type::Tiny::Enum::_regexp, avg 1µs/call |
| 236 | 37 | 41µ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 | |||||
| 241 | 37 | 11µs | return "do { $Type::Tiny::SafePackage $code }" | ||
| 242 | if $Type::Tiny::AvoidCallbacks; | ||||
| 243 | 37 | 59µs | return $code; | ||
| 244 | } #/ sub inline_check | ||||
| 245 | |||||
| 246 | sub _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 19µs within Type::Tiny::Enum::has_parent which was called 22 times, avg 864ns/call:
# 22 times (19µs+0s) by Type::Tiny::is_strictly_subtype_of at line 697 of Type/Tiny.pm, avg 864ns/call | ||||
| 258 | 22 | 28µs | !!1; | ||
| 259 | } | ||||
| 260 | |||||
| 261 | # spent 112µs (81+31) within Type::Tiny::Enum::parent which was called 44 times, avg 3µs/call:
# 44 times (81µs+31µs) by Type::Tiny::is_strictly_subtype_of at line 698 of Type/Tiny.pm, avg 3µs/call | ||||
| 262 | 44 | 18µs | require Types::Standard; | ||
| 263 | 44 | 72µs | 44 | 31µs | Types::Standard::Str(); # spent 31µs making 44 calls to Types::Standard::Str, avg 705ns/call |
| 264 | } | ||||
| 265 | |||||
| 266 | sub 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 | |||||
| 296 | sub has_sorter { | ||||
| 297 | !!1; | ||||
| 298 | } | ||||
| 299 | |||||
| 300 | sub _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 | |||||
| 311 | sub 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 | |||||
| 320 | 1 | 0s | my $canon; | ||
| 321 | |||||
| 322 | sub 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 | |||||
| 370 | push @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; | ||||
| 396 | 1 | 2µs | }; | ||
| 397 | |||||
| 398 | package # stolen from Regexp::Trie | ||||
| 399 | Type::Tiny::Enum::_Trie; | ||||
| 400 | 4 | 9µs | # spent 3µs within Type::Tiny::Enum::_Trie::new which was called 4 times, avg 750ns/call:
# 4 times (3µs+0s) by Type::Tiny::Enum::_Trie::handle at line 444, avg 750ns/call | ||
| 401 | |||||
| 402 | # spent 124µs within Type::Tiny::Enum::_Trie::add which was called 19 times, avg 7µs/call:
# 19 times (124µs+0s) by Type::Tiny::Enum::_Trie::handle at line 445, avg 7µs/call | ||||
| 403 | 19 | 3µs | my $self = shift; | ||
| 404 | 19 | 2µs | my $str = shift; | ||
| 405 | 19 | 1µs | my $ref = $self; | ||
| 406 | 19 | 36µs | for my $char ( split //, $str ) { | ||
| 407 | 137 | 41µs | $ref->{$char} ||= {}; | ||
| 408 | 137 | 30µs | $ref = $ref->{$char}; | ||
| 409 | } | ||||
| 410 | 19 | 5µs | $ref->{''} = 1; # { '' => 1 } as terminator | ||
| 411 | 19 | 18µs | $self; | ||
| 412 | } #/ sub add | ||||
| 413 | |||||
| 414 | sub _regexp { | ||||
| 415 | 126 | 12µs | my $self = shift; | ||
| 416 | 126 | 35µs | return if $self->{''} and scalar keys %$self == 1; # terminator | ||
| 417 | 107 | 9µs | my ( @alt, @cc ); | ||
| 418 | 107 | 8µs | my $q = 0; | ||
| 419 | 107 | 141µs | 107 | 10µs | for my $char ( sort keys %$self ) { # spent 10µs making 107 calls to Type::Tiny::Enum::_Trie::CORE:sort, avg 93ns/call |
| 420 | 122 | 19µs | my $qchar = quotemeta $char; | ||
| 421 | 122 | 171µs | 122 | 0s | if ( ref $self->{$char} ) { # spent 2.58ms making 122 calls to Type::Tiny::Enum::_Trie::_regexp, avg 21µs/call, recursion: max depth 12, sum of overlapping time 2.58ms |
| 422 | if ( defined( my $recurse = _regexp( $self->{$char} ) ) ) { | ||||
| 423 | push @alt, $qchar . $recurse; | ||||
| 424 | } | ||||
| 425 | else { | ||||
| 426 | 19 | 8µs | push @cc, $qchar; | ||
| 427 | } | ||||
| 428 | } | ||||
| 429 | else { | ||||
| 430 | $q = 1; | ||||
| 431 | } | ||||
| 432 | } #/ for my $char ( sort keys...) | ||||
| 433 | 107 | 11µs | my $cconly = !@alt; | ||
| 434 | 107 | 14µs | @cc and push @alt, @cc == 1 ? $cc[0] : '[' . join( '', @cc ) . ']'; | ||
| 435 | 107 | 37µs | my $result = @alt == 1 ? $alt[0] : '(?:' . join( '|', @alt ) . ')'; | ||
| 436 | 107 | 10µs | $q and $result = $cconly ? "$result?" : "(?:$result)?"; | ||
| 437 | 107 | 145µs | return $result; | ||
| 438 | } #/ sub _regexp | ||||
| 439 | |||||
| 440 | # spent 817µs (76+741) within Type::Tiny::Enum::_Trie::handle which was called 4 times, avg 204µs/call:
# 4 times (76µs+741µs) by Type::Tiny::Enum::_regexp at line 206, avg 204µs/call | ||||
| 441 | 4 | 1µs | my $class = shift; | ||
| 442 | 4 | 1µs | my ( $vals ) = @_; | ||
| 443 | 4 | 1µs | return '(?!)' unless @$vals; | ||
| 444 | 4 | 8µs | 4 | 3µs | my $self = $class->new; # spent 3µs making 4 calls to Type::Tiny::Enum::_Trie::new, avg 750ns/call |
| 445 | 4 | 13µs | 19 | 124µs | $self->add( $_ ) for @$vals; # spent 124µs making 19 calls to Type::Tiny::Enum::_Trie::add, avg 7µs/call |
| 446 | 4 | 31µs | 4 | 614µs | $self->_regexp; # spent 614µs making 4 calls to Type::Tiny::Enum::_Trie::_regexp, avg 154µs/call |
| 447 | } | ||||
| 448 | |||||
| 449 | 1 | 6µs | 1; | ||
| 450 | |||||
| 451 | __END__ | ||||
# spent 8µs within Type::Tiny::Enum::CORE:sort which was called 4 times, avg 2µs/call:
# 4 times (8µs+0s) by Type::Tiny::Enum::new at line 62, avg 2µs/call | |||||
# spent 10µs within Type::Tiny::Enum::_Trie::CORE:sort which was called 107 times, avg 93ns/call:
# 107 times (10µs+0s) by Type::Tiny::Enum::_Trie::_regexp at line 419, avg 93ns/call |