File Coverage

blib/lib/Type/Tiny.pm
Criterion Covered Total %
statement 694 758 91.8
branch 348 460 75.6
condition 195 293 66.5
subroutine 208 222 93.6
pod 84 84 100.0
total 1529 1817 84.2


line stmt bran cond sub pod time code
1             package Type::Tiny;
2              
3 272     272   293201 use 5.008001;
  272         1070  
4 272     272   1574 use strict;
  272         589  
  272         6509  
5 272     272   1343 use warnings;
  272         582  
  272         14031  
6              
7             BEGIN {
8 272 50   272   13073 if ( $] < 5.010 ) { require Devel::TypeTiny::Perl58Compat }
  0         0  
9             }
10              
11             BEGIN {
12 272     272   973 $Type::Tiny::AUTHORITY = 'cpan:TOBYINK';
13 272         587 $Type::Tiny::VERSION = '2.002001';
14 272         30789 $Type::Tiny::XS_VERSION = '0.016';
15             }
16              
17             $Type::Tiny::VERSION =~ tr/_//d;
18             $Type::Tiny::XS_VERSION =~ tr/_//d;
19              
20             our @InternalPackages = qw(
21             Devel::TypeTiny::Perl56Compat
22             Devel::TypeTiny::Perl58Compat
23             Error::TypeTiny
24             Error::TypeTiny::Assertion
25             Error::TypeTiny::Compilation
26             Error::TypeTiny::WrongNumberOfParameters
27             Eval::TypeTiny
28             Eval::TypeTiny::CodeAccumulator
29             Eval::TypeTiny::Sandbox
30             Exporter::Tiny
31             Reply::Plugin::TypeTiny
32             Test::TypeTiny
33             Type::Coercion
34             Type::Coercion::FromMoose
35             Type::Coercion::Union
36             Type::Library
37             Type::Params
38             Type::Params::Alternatives
39             Type::Params::Parameter
40             Type::Params::Signature
41             Type::Parser
42             Type::Parser::AstBuilder
43             Type::Parser::Token
44             Type::Parser::TokenStream
45             Type::Registry
46             Types::Common
47             Types::Common::Numeric
48             Types::Common::String
49             Types::Standard
50             Types::Standard::_Stringable
51             Types::Standard::ArrayRef
52             Types::Standard::CycleTuple
53             Types::Standard::Dict
54             Types::Standard::HashRef
55             Types::Standard::Map
56             Types::Standard::ScalarRef
57             Types::Standard::StrMatch
58             Types::Standard::Tied
59             Types::Standard::Tuple
60             Types::TypeTiny
61             Type::Tie
62             Type::Tie::ARRAY
63             Type::Tie::BASE
64             Type::Tie::HASH
65             Type::Tie::SCALAR
66             Type::Tiny
67             Type::Tiny::_DeclaredType
68             Type::Tiny::_HalfOp
69             Type::Tiny::Class
70             Type::Tiny::ConsrtainedObject
71             Type::Tiny::Duck
72             Type::Tiny::Enum
73             Type::Tiny::Intersection
74             Type::Tiny::Role
75             Type::Tiny::Union
76             Type::Utils
77             );
78              
79 272     272   2178 use Scalar::Util qw( blessed );
  272         622  
  272         15301  
80 272     272   73581 use Types::TypeTiny ();
  272         688  
  272         114210  
81              
82             our $SafePackage = sprintf 'package %s;', __PACKAGE__;
83              
84 14     14   2320 sub _croak ($;@) { require Error::TypeTiny; goto \&Error::TypeTiny::croak }
  14         59  
85              
86 40153 50   40153   126778 sub _swap { $_[2] ? @_[ 1, 0 ] : @_[ 0, 1 ] }
87              
88             BEGIN {
89 272     272   1456 my $support_smartmatch = 0+ !!( $] >= 5.010001 );
90 272         18334 eval qq{ sub SUPPORT_SMARTMATCH () { !! $support_smartmatch } };
91            
92 272         2646 my $fixed_precedence = 0+ !!( $] >= 5.014 );
93 272         11525 eval qq{ sub _FIXED_PRECEDENCE () { !! $fixed_precedence } };
94            
95             my $try_xs =
96             exists( $ENV{PERL_TYPE_TINY_XS} ) ? !!$ENV{PERL_TYPE_TINY_XS}
97             : exists( $ENV{PERL_ONLY} ) ? !$ENV{PERL_ONLY}
98 272 50       2462 : 1;
    50          
99            
100 272         591 my $use_xs = 0;
101 272 50       963 $try_xs and eval {
102 272         1703 require Type::Tiny::XS;
103 272         3416 'Type::Tiny::XS'->VERSION( $Type::Tiny::XS_VERSION );
104 272         1062 $use_xs++;
105             };
106            
107             *_USE_XS =
108             $use_xs
109             ? sub () { !!1 }
110 272 50       1209 : sub () { !!0 };
111            
112             *_USE_MOUSE =
113             $try_xs
114 249 50   249   2323 ? sub () { $INC{'Mouse/Util.pm'} and Mouse::Util::MOUSE_XS() }
115 272 50       1417 : sub () { !!0 };
116            
117 272         570 my $strict_mode = 0;
118 272   100     2686 $ENV{$_} && ++$strict_mode for qw(
119             EXTENDED_TESTING
120             AUTHOR_TESTING
121             RELEASE_TESTING
122             PERL_STRICT
123             );
124 272 100       9560 *_STRICT_MODE = $strict_mode ? sub () { !!1 } : sub () { !!0 };
125             } #/ BEGIN
126              
127             {
128              
129             sub _install_overloads {
130 272     272   1830 no strict 'refs';
  272         684  
  272         10258  
131 272     272   1727 no warnings 'redefine', 'once';
  272         679  
  272         3163789  
132            
133             # Coverage is checked on Perl 5.26
134 1720 50   1720   6115 if ( $] < 5.010 ) { # uncoverable statement
135 0         0 require overload; # uncoverable statement
136 0         0 push @_, fallback => 1; # uncoverable statement
137 0         0 goto \&overload::OVERLOAD; # uncoverable statement
138             }
139            
140 1720         3361 my $class = shift;
141 1720     0   4795 *{ $class . '::((' } = sub { };
  1720         9748  
142 1720     0   5191 *{ $class . '::()' } = sub { };
  1720         6095  
143 1720         2852 *{ $class . '::()' } = do { my $x = 1; \$x };
  1720         4066  
  1720         2582  
  1720         2995  
144 1720         4928 while ( @_ ) {
145 6414         9658 my $f = shift;
146 6414 100       11574 *{ $class . '::(' . $f } = ref $_[0] ? shift : do {
  6414         29338  
147 519         1003 my $m = shift;
148 682     682   79621 sub { shift->$m( @_ ) }
149 519         1918 };
150             }
151             } #/ sub _install_overloads
152             }
153              
154             __PACKAGE__->_install_overloads(
155             q("") => sub {
156 42838 50   42838   228787 caller =~ m{^(Moo::HandleMoose|Sub::Quote)}
157             ? $_[0]->_stringify_no_magic
158             : $_[0]->display_name;
159             },
160 40068     40068   107273 q(bool) => sub { 1 },
161             q(&{}) => "_overload_coderef",
162             q(|) => sub {
163 64     64   3844 my @tc = _swap @_;
164 64         114 if ( !_FIXED_PRECEDENCE && $_[2] ) {
165             if ( blessed $tc[0] ) {
166             if ( blessed $tc[0] eq "Type::Tiny::_HalfOp" ) {
167             my $type = $tc[0]->{type};
168             my $param = $tc[0]->{param};
169             my $op = $tc[0]->{op};
170             require Type::Tiny::Union;
171             return "Type::Tiny::_HalfOp"->new(
172             $op,
173             $param,
174             "Type::Tiny::Union"->new_by_overload( type_constraints => [ $type, $tc[1] ] ),
175             );
176             } #/ if ( blessed $tc[0] eq...)
177             } #/ if ( blessed $tc[0] )
178             elsif ( ref $tc[0] eq 'ARRAY' ) {
179             require Type::Tiny::_HalfOp;
180             return "Type::Tiny::_HalfOp"->new( '|', @tc );
181             }
182             } #/ if ( !_FIXED_PRECEDENCE...)
183 64         9873 require Type::Tiny::Union;
184 64         329 return "Type::Tiny::Union"->new_by_overload( type_constraints => \@tc );
185             },
186             q(&) => sub {
187 40059     40059   1761186 my @tc = _swap @_;
188 40059         58463 if ( !_FIXED_PRECEDENCE && $_[2] ) {
189             if ( blessed $tc[0] ) {
190             if ( blessed $tc[0] eq "Type::Tiny::_HalfOp" ) {
191             my $type = $tc[0]->{type};
192             my $param = $tc[0]->{param};
193             my $op = $tc[0]->{op};
194             require Type::Tiny::Intersection;
195             return "Type::Tiny::_HalfOp"->new(
196             $op,
197             $param,
198             "Type::Tiny::Intersection"->new_by_overload( type_constraints => [ $type, $tc[1] ] ),
199             );
200             } #/ if ( blessed $tc[0] eq...)
201             } #/ if ( blessed $tc[0] )
202             elsif ( ref $tc[0] eq 'ARRAY' ) {
203             require Type::Tiny::_HalfOp;
204             return "Type::Tiny::_HalfOp"->new( '&', @tc );
205             }
206             } #/ if ( !_FIXED_PRECEDENCE...)
207 40059         193162 require Type::Tiny::Intersection;
208 40059         135842 "Type::Tiny::Intersection"->new_by_overload( type_constraints => \@tc );
209             },
210 69     69   1338 q(~) => sub { shift->complementary_type },
211 699     699   6600 q(==) => sub { $_[0]->equals( $_[1] ) },
212 1     1   5 q(!=) => sub { not $_[0]->equals( $_[1] ) },
213 8     8   75 q(<) => sub { my $m = $_[0]->can( 'is_subtype_of' ); $m->( _swap @_ ) },
  8         21  
214             q(>) => sub {
215 10     10   89 my $m = $_[0]->can( 'is_subtype_of' );
216 10         31 $m->( reverse _swap @_ );
217             },
218 6     6   50 q(<=) => sub { my $m = $_[0]->can( 'is_a_type_of' ); $m->( _swap @_ ) },
  6         12  
219             q(>=) => sub {
220 6     6   58 my $m = $_[0]->can( 'is_a_type_of' );
221 6         18 $m->( reverse _swap @_ );
222             },
223 27     27   7857 q(eq) => sub { "$_[0]" eq "$_[1]" },
224 0 0   0   0 q(cmp) => sub { $_[2] ? ( "$_[1]" cmp "$_[0]" ) : ( "$_[0]" cmp "$_[1]" ) },
225 1     1   56 q(0+) => sub { $_[0]{uniq} },
226 4 100 50 4   2815 q(/) => sub { ( _STRICT_MODE xor $_[2] ) ? $_[0] : $_[1] },
227             );
228              
229             __PACKAGE__->_install_overloads(
230 3     3   440 q(~~) => sub { $_[0]->check( $_[1] ) },
231             ) if Type::Tiny::SUPPORT_SMARTMATCH;
232              
233             # Would be easy to just return sub { $self->assert_return(@_) }
234             # but try to build a more efficient coderef whenever possible.
235             #
236             sub _overload_coderef {
237 12065     12065   27451 my $self = shift;
238            
239             # Bypass generating a coderef if we've already got the best possible one.
240             #
241 12065 100       37259 return $self->{_overload_coderef} if $self->{_overload_coderef_no_rebuild};
242            
243             # Subclasses of Type::Tiny might override assert_return to do some kind
244             # of interesting thing. In that case, we can't rely on it having identical
245             # behaviour to Type::Tiny::inline_assert.
246             #
247             $self->{_overrides_assert_return} =
248             ( $self->can( 'assert_return' ) != \&assert_return )
249 12046 100       35500 unless exists $self->{_overrides_assert_return};
250            
251 12046 100       37178 if ( $self->{_overrides_assert_return} ) {
    100          
252 1   33     9 $self->{_overload_coderef} ||= do {
253 1         5 Scalar::Util::weaken( my $weak = $self );
254 1     2   5 sub { $weak->assert_return( @_ ) };
  2         13  
255             };
256 1         5 ++$self->{_overload_coderef_no_rebuild};
257             }
258             elsif ( exists( &Sub::Quote::quote_sub ) ) {
259            
260             # Use `=` instead of `||=` because we want to overwrite non-Sub::Quote
261             # coderef if possible.
262 162 100       335 $self->{_overload_coderef} = $self->can_be_inlined
263             ? Sub::Quote::quote_sub(
264             $self->inline_assert( '$_[0]' ),
265             )
266             : Sub::Quote::quote_sub(
267             $self->inline_assert( '$_[0]', '$type' ),
268             { '$type' => \$self },
269             );
270 162         13057 ++$self->{_overload_coderef_no_rebuild};
271             } #/ elsif ( exists( &Sub::Quote::quote_sub...))
272             else {
273 11883         60741 require Eval::TypeTiny;
274 11883 100 66     41352 $self->{_overload_coderef} ||= $self->can_be_inlined
275             ? Eval::TypeTiny::eval_closure(
276             source => sprintf(
277             'sub { %s }', $self->inline_assert( '$_[0]', undef, no_wrapper => 1 )
278             ),
279             description => sprintf( "compiled assertion 'assert_%s'", $self ),
280             )
281             : Eval::TypeTiny::eval_closure(
282             source => sprintf(
283             'sub { %s }', $self->inline_assert( '$_[0]', '$type', no_wrapper => 1 )
284             ),
285             description => sprintf( "compiled assertion 'assert_%s'", $self ),
286             environment => { '$type' => \$self },
287             );
288             } #/ else [ if ( $self->{_overrides_assert_return...})]
289            
290 12046         74171 $self->{_overload_coderef};
291             } #/ sub _overload_coderef
292              
293             our %ALL_TYPES;
294              
295             my $QFS;
296             my $uniq = 1;
297              
298             sub new {
299 92981     92981 1 159610 my $class = shift;
300 92981 50       294290 my %params = ( @_ == 1 ) ? %{ $_[0] } : @_;
  0         0  
301            
302 92981         185257 for ( qw/ name display_name library / ) {
303 278943 100       564898 $params{$_} = $params{$_} . '' if defined $params{$_};
304             }
305            
306 92981         146184 my $level = 0;
307 92981   66     306054 while ( not exists $params{definition_context} and $level < 20 ) {
308 227815   66     389132 our $_TT_GUTS ||= do {
309 261         13709 my $g = join '|', map quotemeta, grep !m{^Types::}, @InternalPackages;
310 261         127196 qr/\A(?:$g)\z/o
311             };
312 227815         393947 my $package = caller $level;
313 227815 100       1122619 if ( $package !~ $_TT_GUTS ) {
314 92981         467260 @{ $params{definition_context} = {} }{ qw/ package file line / } = caller $level;
  92981         363472  
315             }
316 227815         688716 ++$level;
317             }
318            
319 92981 100       175343 if ( exists $params{parent} ) {
320             $params{parent} =
321             ref( $params{parent} ) =~ /^Type::Tiny\b/
322             ? $params{parent}
323 10710 50       42566 : Types::TypeTiny::to_TypeTiny( $params{parent} );
324            
325             _croak "Parent must be an instance of %s", __PACKAGE__
326             unless blessed( $params{parent} )
327 10710 50 33     49317 && $params{parent}->isa( __PACKAGE__ );
328            
329 10710 100 100     30040 if ( $params{parent}->deprecated and not exists $params{deprecated} ) {
330 3         8 $params{deprecated} = 1;
331             }
332             } #/ if ( exists $params{parent...})
333            
334 92981 100 66     321615 if ( exists $params{constraint}
      100        
335             and defined $params{constraint}
336             and not ref $params{constraint} )
337             {
338 77         428 require Eval::TypeTiny;
339 77         164 my $code = $params{constraint};
340 77         416 $params{constraint} = Eval::TypeTiny::eval_closure(
341             source => sprintf( 'sub ($) { %s }', $code ),
342             description => "anonymous check",
343             );
344             $params{inlined} ||= sub {
345 264     264   535 my ( $type ) = @_;
346 264 100       1038 my $inlined = $_ eq '$_' ? "do { $code }" : "do { local \$_ = $_; $code }";
347 264 100       480 $type->has_parent ? ( undef, $inlined ) : $inlined;
348             }
349 77 50 50     452 if ( !exists $params{parent} or $params{parent}->can_be_inlined );
      66        
350             } #/ if ( exists $params{constraint...})
351            
352             # canonicalize to a boolean
353 92981         194152 $params{deprecated} = !!$params{deprecated};
354            
355 92981 100       219103 $params{name} = "__ANON__" unless exists $params{name};
356 92981         161224 $params{uniq} = $uniq++;
357            
358 92981 100       191882 if ( $params{name} ne "__ANON__" ) {
359            
360             # First try a fast ASCII-only expression, but fall back to Unicode
361             $params{name} =~ /^_{0,2}[A-Z][A-Za-z0-9_]+$/sm
362             or eval q( use 5.008; $params{name} =~ /^_{0,2}\p{Lu}[\p{L}0-9_]+$/sm )
363 10971 100 66     56845 or _croak '"%s" is not a valid type name', $params{name};
  1         21  
  1         3  
  1         678  
  1         30  
  1         15  
364             }
365            
366 92980 50 100     194378 if ( exists $params{coercion} and !ref $params{coercion} and $params{coercion} )
      66        
367             {
368             $params{parent}->has_coercion
369 2 50       8 or _croak
370             "coercion => 1 requires type to have a direct parent with a coercion";
371            
372 2         8 $params{coercion} = $params{parent}->coercion->type_coercion_map;
373             }
374            
375 92980 100 100     522678 if ( !exists $params{inlined}
      100        
      100        
      100        
      100        
376             and exists $params{constraint}
377             and ( !exists $params{parent} or $params{parent}->can_be_inlined )
378             and $QFS ||= "Sub::Quote"->can( "quoted_from_sub" ) )
379             {
380 6 100       14 my ( undef, $perlstring, $captures ) = @{ $QFS->( $params{constraint} ) || [] };
  6         21  
381            
382             $params{inlined} = sub {
383 28     28   51 my ( $self, $var ) = @_;
384 28 50       116 my $code = Sub::Quote::inlinify(
385             $perlstring,
386             $var,
387             $var eq q($_) ? '' : "local \$_ = $var;",
388             1,
389             );
390 28 100       546 $code = sprintf( '%s and %s', $self->parent->inline_check( $var ), $code )
391             if $self->has_parent;
392 28         64 return $code;
393             }
394 6 100 100     353 if $perlstring && !$captures;
395             } #/ if ( !exists $params{inlined...})
396            
397 92980         178741 my $self = bless \%params, $class;
398            
399 92980 100       182591 unless ( $params{tmp} ) {
400 92922         199778 my $uniq = $self->{uniq};
401            
402 92922         291334 $ALL_TYPES{$uniq} = $self;
403 92922         291252 Scalar::Util::weaken( $ALL_TYPES{$uniq} );
404            
405 92922         125520 my $tmp = $self;
406 92922         200019 Scalar::Util::weaken( $tmp );
407 92922     0   353304 $Moo::HandleMoose::TYPE_MAP{ $self->_stringify_no_magic } = sub { $tmp };
  0         0  
408             } #/ unless ( $params{tmp} )
409            
410 92980 100       323451 if ( ref( $params{coercion} ) eq q(CODE) ) {
    100          
411 2         12 require Types::Standard;
412 2         5 my $code = delete( $params{coercion} );
413 2         8 $self->{coercion} = $self->_build_coercion;
414 2         29 $self->coercion->add_type_coercions( Types::Standard::Any(), $code );
415             }
416             elsif ( ref( $params{coercion} ) eq q(ARRAY) ) {
417 5         16 my $arr = delete( $params{coercion} );
418 5         16 $self->{coercion} = $self->_build_coercion;
419 5         16 $self->coercion->add_type_coercions( @$arr );
420             }
421            
422             # Documenting this here because it's too weird to be in the pod.
423             # There's a secret attribute called "_build_coercion" which takes a
424             # coderef. If present, then when $type->coercion is lazy built,
425             # the blank Type::Coercion object gets passed to the coderef,
426             # allowing the coderef to manipulate it a little. This is used by
427             # Types::TypeTiny to allow it to build a coercion for the TypeTiny
428             # type constraint without needing to load Type::Coercion yet.
429            
430 92980 100       203991 if ( $params{my_methods} ) {
431 965         5542 require Eval::TypeTiny;
432             Scalar::Util::reftype( $params{my_methods}{$_} ) eq 'CODE'
433             and Eval::TypeTiny::set_subname(
434             sprintf( "%s::my_%s", $self->qualified_name, $_ ),
435             $params{my_methods}{$_},
436 965   66     1786 ) for keys %{ $params{my_methods} };
  965         10216  
437             } #/ if ( $params{my_methods...})
438            
439             # In general, mutating a type constraint after it's been created
440             # is a bad idea and will probably not work. However some places are
441             # especially harmful and can lead to confusing errors, so allow
442             # subclasses to lock down particular keys.
443             #
444             $self->_lockdown( sub {
445 40341     40341   158266 &Internals::SvREADONLY( $_, !!1 ) for @_;
446 92980         390164 } );
447            
448 92980         572058 return $self;
449             } #/ sub new
450              
451       52639     sub _lockdown {}
452              
453             sub DESTROY {
454 81456     81456   283860 my $self = shift;
455 81456         237477 delete( $ALL_TYPES{ $self->{uniq} } );
456 81456         169049 delete( $Moo::HandleMoose::TYPE_MAP{ $self->_stringify_no_magic } );
457 81456         839268 return;
458             }
459              
460             sub _clone {
461 96     96   193 my $self = shift;
462 96         187 my %opts;
463 96         1026 $opts{$_} = $self->{$_} for qw< name display_name message >;
464 96         431 $self->create_child_type( %opts );
465             }
466              
467             sub _stringify_no_magic {
468 174379     174379   1219611 sprintf(
469             '%s=%s(0x%08x)', blessed( $_[0] ), Scalar::Util::reftype( $_[0] ),
470             Scalar::Util::refaddr( $_[0] )
471             );
472             }
473              
474             our $DD;
475              
476             sub _dd {
477 2415 50   2415   6391 @_ = $_ unless @_;
478 2415         4351 my ( $value ) = @_;
479            
480 2415 100       6534 goto $DD if ref( $DD ) eq q(CODE);
481            
482 2413         11561 require B;
483            
484             !defined $value ? 'Undef'
485             : !ref $value ? sprintf( 'Value %s', B::perlstring( $value ) )
486 2413 100       18869 : do {
    100          
487 1494 50       3471 my $N = 0+ ( defined( $DD ) ? $DD : 72 );
488 1494         66759 require Data::Dumper;
489 1494         625643 local $Data::Dumper::Indent = 0;
490 1494         2264 local $Data::Dumper::Useqq = 1;
491 1494         2298 local $Data::Dumper::Terse = 1;
492 1494         2438 local $Data::Dumper::Sortkeys = 1;
493 1494         2122 local $Data::Dumper::Maxdepth = 2;
494 1494         2046 my $str;
495             eval {
496 1494         4282 $str = Data::Dumper::Dumper( $value );
497 1494 100       82478 $str = substr( $str, 0, $N - 12 ) . '...' . substr( $str, -1, 1 )
498             if length( $str ) >= $N;
499 1494         4203 1;
500 1494 50       2362 } or do { $str = 'which cannot be dumped' };
  0         0  
501 1494         14428 "Reference $str";
502             } #/ do
503             } #/ sub _dd
504              
505             sub _loose_to_TypeTiny {
506 29043     29043   45569 my $caller = caller( 1 ); # assumption
507             map +(
508             ref( $_ )
509             ? Types::TypeTiny::to_TypeTiny( $_ )
510 29043 100       73589 : do { require Type::Utils; Type::Utils::dwim_type( $_, for => $caller ) }
  2         580  
  2         7  
511             ), @_;
512             }
513              
514 88753     88753 1 391265 sub name { $_[0]{name} }
515 44304   66 44304 1 211891 sub display_name { $_[0]{display_name} ||= $_[0]->_build_display_name }
516 132982     132982 1 259127 sub parent { $_[0]{parent} }
517 403992   66 403992 1 1449756 sub constraint { $_[0]{constraint} ||= $_[0]->_build_constraint }
518              
519             sub compiled_check {
520 126499   66 126499 1 467342 $_[0]{compiled_type_constraint} ||= $_[0]->_build_compiled_check;
521             }
522 16088   66 16088 1 55758 sub coercion { $_[0]{coercion} ||= $_[0]->_build_coercion }
523 28     28 1 86 sub message { $_[0]{message} }
524 67     67 1 951 sub library { $_[0]{library} }
525 44114     44114 1 120011 sub inlined { $_[0]{inlined} }
526 28086     28086 1 111148 sub deprecated { $_[0]{deprecated} }
527 1000     1000 1 7219 sub constraint_generator { $_[0]{constraint_generator} }
528 1056     1056 1 3393 sub inline_generator { $_[0]{inline_generator} }
529 868   66 868 1 4103 sub name_generator { $_[0]{name_generator} ||= $_[0]->_build_name_generator }
530 190     190 1 833 sub coercion_generator { $_[0]{coercion_generator} }
531 914     914 1 5371 sub parameters { $_[0]{parameters} }
532 0   0 0 1 0 sub moose_type { $_[0]{moose_type} ||= $_[0]->_build_moose_type }
533 0   0 0 1 0 sub mouse_type { $_[0]{mouse_type} ||= $_[0]->_build_mouse_type }
534 101     101 1 454 sub deep_explanation { $_[0]{deep_explanation} }
535 1892   66 1892 1 6693 sub my_methods { $_[0]{my_methods} ||= $_[0]->_build_my_methods }
536 25     25 1 52 sub sorter { $_[0]{sorter} }
537              
538 521429     521429 1 1290857 sub has_parent { exists $_[0]{parent} }
539 0     0 1 0 sub has_library { exists $_[0]{library} }
540 130651     130651 1 423639 sub has_inlined { exists $_[0]{inlined} }
541 12899     12899 1 63042 sub has_constraint_generator { exists $_[0]{constraint_generator} }
542 791     791 1 4108 sub has_inline_generator { exists $_[0]{inline_generator} }
543 1750     1750 1 6378 sub has_coercion_generator { exists $_[0]{coercion_generator} }
544 492     492 1 2132 sub has_parameters { exists $_[0]{parameters} }
545 888     888 1 3373 sub has_message { defined $_[0]{message} }
546 101     101 1 455 sub has_deep_explanation { exists $_[0]{deep_explanation} }
547 74     74 1 174 sub has_sorter { exists $_[0]{sorter} }
548              
549             sub _default_message {
550 860   66 860   3175 $_[0]{_default_message} ||= $_[0]->_build_default_message;
551             }
552              
553             sub has_coercion {
554 25364 100   25364 1 61558 $_[0]->coercion if $_[0]{_build_coercion}; # trigger auto build thing
555 25364 100       108049 $_[0]{coercion} and !!@{ $_[0]{coercion}->type_coercion_map };
  15268         32499  
556             }
557              
558             sub _assert_coercion {
559 636     636   904 my $self = shift;
560 636 100       1890 return $self->coercion if $self->{_build_coercion}; # trigger auto build thing
561             _croak "No coercion for this type constraint"
562             unless $self->has_coercion
563 506 100 66     990 && @{ $self->coercion->type_coercion_map };
  497         1088  
564 497         1088 $self->coercion;
565             }
566              
567             my $null_constraint = sub { !!1 };
568              
569             sub _build_display_name {
570 10894     10894   21483 shift->name;
571             }
572              
573             sub _build_constraint {
574 3959     3959   22499 return $null_constraint;
575             }
576              
577             sub _is_null_constraint {
578 345811     345811   537315 shift->constraint == $null_constraint;
579             }
580              
581             sub _build_coercion {
582 10636     10636   157427 require Type::Coercion;
583 10636         16915 my $self = shift;
584 10636         21158 my %opts = ( type_constraint => $self );
585 10636 100       19293 $opts{display_name} = "to_$self" unless $self->is_anon;
586 10636         39723 my $coercion = "Type::Coercion"->new( %opts );
587 10636 100       25355 $self->{_build_coercion}->( $coercion ) if ref $self->{_build_coercion};
588 10636         32346 $coercion;
589             }
590              
591             sub _build_default_message {
592 175     175   343 my $self = shift;
593 175         432 $self->{is_using_default_message} = 1;
594 64     64   187 return sub { sprintf '%s did not pass type constraint', _dd( $_[0] ) }
595 175 100       484 if "$self" eq "__ANON__";
596 152         630 my $name = "$self";
597             return sub {
598 793     793   2046 sprintf '%s did not pass type constraint "%s"', _dd( $_[0] ), $name;
599 152         1141 };
600             } #/ sub _build_default_message
601              
602             sub _build_name_generator {
603 207     207   495 my $self = shift;
604             return sub {
605 720   33 720   4762 defined && s/[\x00-\x1F]//smg for ( my ( $s, @a ) = @_ );
606 720 100 100     7217 sprintf( '%s[%s]', $s, join q[,], map !defined() ? 'undef' : !ref() && /\W/ ? B::perlstring($_) : $_, @a );
    50          
607 207         1847 };
608             }
609              
610             sub _build_compiled_check {
611 46806     46806   89446 my $self = shift;
612            
613 46806         73261 local our $AvoidCallbacks = 0;
614            
615 46806 100 100     85344 if ( $self->_is_null_constraint and $self->has_parent ) {
616 2986         6882 return $self->parent->compiled_check;
617             }
618            
619 43820         203762 require Eval::TypeTiny;
620 43820 100       101028 return Eval::TypeTiny::eval_closure(
621             source => sprintf( 'sub ($) { %s }', $self->inline_check( '$_[0]' ) ),
622             description => sprintf( "compiled check '%s'", $self ),
623             ) if $self->can_be_inlined;
624            
625 40258         68661 my @constraints;
626 40258 100       67007 push @constraints, $self->parent->compiled_check if $self->has_parent;
627 40258 50       69251 push @constraints, $self->constraint if !$self->_is_null_constraint;
628 40258 50       88793 return $null_constraint unless @constraints;
629            
630             return sub ($) {
631 3482     3482   79944 local $_ = $_[0];
        576      
        575      
        558      
        572      
632 3482         5222 for my $c ( @constraints ) {
633 5914 100       15155 return unless $c->( @_ );
634             }
635 2314         12127 return !!1;
636 40258         227513 };
637             } #/ sub _build_compiled_check
638              
639             sub definition_context {
640 1     1 1 3 my $self = shift;
641             my $found = $self->find_parent(sub {
642 1 50   1   7 ref $_->{definition_context} and exists $_->{definition_context}{file};
643 1         5 });
644 1 50       5 $found ? $found->{definition_context} : {};
645             }
646              
647             sub find_constraining_type {
648 3671     3671 1 4597 my $self = shift;
649 3671 100 100     5407 if ( $self->_is_null_constraint and $self->has_parent ) {
650 716         1363 return $self->parent->find_constraining_type;
651             }
652 2955         5804 $self;
653             }
654              
655             sub type_default {
656 554     554 1 5811 my ( $self, @args ) = @_;
657 554 100       1936 if ( exists $self->{type_default} ) {
658 412 100       1191 if ( @args ) {
659 1         6 my $td = $self->{type_default};
660 1     1   7 return sub { local $_ = \@args; &$td; };
  1         740  
  1         4  
661             }
662 411         2085 return $self->{type_default};
663             }
664 142 100       424 if ( my $parent = $self->parent ) {
665 140 100       416 return $parent->type_default( @args ) if $self->_is_null_constraint;
666             }
667 59         449 return undef;
668             }
669              
670             our @CMP;
671              
672             sub CMP_SUPERTYPE () { -1 }
673             sub CMP_EQUAL () { 0 }
674             sub CMP_EQUIVALENT () { '0E0' }
675             sub CMP_SUBTYPE () { 1 }
676             sub CMP_UNKNOWN () { ''; }
677              
678             # avoid getting mixed up with cmp operator at compile time
679             *cmp = sub {
680 1455     1455   15172 my ( $A, $B ) = _loose_to_TypeTiny( $_[0], $_[1] );
681 1455 50 33     6706 return unless blessed( $A ) && $A->isa( "Type::Tiny" );
682 1455 50 33     5720 return unless blessed( $B ) && $B->isa( "Type::Tiny" );
683 1455         3561 for my $comparator ( @CMP ) {
684 1844         3780 my $result = $comparator->( $A, $B );
685 1844 100       4283 next if $result eq CMP_UNKNOWN;
686 1143 100       2337 if ( $result eq CMP_EQUIVALENT ) {
687 51 100       165 my $prefer = @_ == 3 ? $_[2] : CMP_EQUAL;
688 51         177 return $prefer;
689             }
690 1092         2600 return $result;
691             }
692 312         675 return CMP_UNKNOWN;
693             };
694              
695             push @CMP, sub {
696             my ( $A, $B ) = @_;
697             return CMP_EQUAL
698             if Scalar::Util::refaddr( $A ) == Scalar::Util::refaddr( $B );
699            
700             return CMP_EQUIVALENT
701             if Scalar::Util::refaddr( $A->compiled_check ) ==
702             Scalar::Util::refaddr( $B->compiled_check );
703            
704             my $A_stem = $A->find_constraining_type;
705             my $B_stem = $B->find_constraining_type;
706             return CMP_EQUIVALENT
707             if Scalar::Util::refaddr( $A_stem ) == Scalar::Util::refaddr( $B_stem );
708             return CMP_EQUIVALENT
709             if Scalar::Util::refaddr( $A_stem->compiled_check ) ==
710             Scalar::Util::refaddr( $B_stem->compiled_check );
711            
712             if ( $A_stem->can_be_inlined and $B_stem->can_be_inlined ) {
713             return CMP_EQUIVALENT
714             if $A_stem->inline_check( '$WOLFIE' ) eq $B_stem->inline_check( '$WOLFIE' );
715             }
716            
717             A_IS_SUBTYPE: {
718             my $A_prime = $A_stem;
719             while ( $A_prime->has_parent ) {
720             $A_prime = $A_prime->parent;
721             return CMP_SUBTYPE
722             if Scalar::Util::refaddr( $A_prime ) == Scalar::Util::refaddr( $B_stem );
723             return CMP_SUBTYPE
724             if Scalar::Util::refaddr( $A_prime->compiled_check ) ==
725             Scalar::Util::refaddr( $B_stem->compiled_check );
726             if ( $A_prime->can_be_inlined and $B_stem->can_be_inlined ) {
727             return CMP_SUBTYPE
728             if $A_prime->inline_check( '$WOLFIE' ) eq $B_stem->inline_check( '$WOLFIE' );
729             }
730             } #/ while ( $A_prime->has_parent)
731             } #/ A_IS_SUBTYPE:
732            
733             B_IS_SUBTYPE: {
734             my $B_prime = $B_stem;
735             while ( $B_prime->has_parent ) {
736             $B_prime = $B_prime->parent;
737             return CMP_SUPERTYPE
738             if Scalar::Util::refaddr( $B_prime ) == Scalar::Util::refaddr( $A_stem );
739             return CMP_SUPERTYPE
740             if Scalar::Util::refaddr( $B_prime->compiled_check ) ==
741             Scalar::Util::refaddr( $A_stem->compiled_check );
742             if ( $A_stem->can_be_inlined and $B_prime->can_be_inlined ) {
743             return CMP_SUPERTYPE
744             if $B_prime->inline_check( '$WOLFIE' ) eq $A_stem->inline_check( '$WOLFIE' );
745             }
746             } #/ while ( $B_prime->has_parent)
747             } #/ B_IS_SUBTYPE:
748            
749             return CMP_UNKNOWN;
750             };
751              
752             sub equals {
753 761     761 1 2201 my $result = Type::Tiny::cmp( $_[0], $_[1] );
754 761 50       1599 return unless defined $result;
755 761         3628 $result eq CMP_EQUAL;
756             }
757              
758             sub is_subtype_of {
759 101     101 1 293 my $result = Type::Tiny::cmp( $_[0], $_[1], CMP_SUBTYPE );
760 101 50       247 return unless defined $result;
761 101         479 $result eq CMP_SUBTYPE;
762             }
763              
764             sub is_supertype_of {
765 19     19 1 386 my $result = Type::Tiny::cmp( $_[0], $_[1], CMP_SUBTYPE );
766 19 50       45 return unless defined $result;
767 19         82 $result eq CMP_SUPERTYPE;
768             }
769              
770             sub is_a_type_of {
771 530     530 1 4170 my $result = Type::Tiny::cmp( $_[0], $_[1] );
772 530 50       1220 return unless defined $result;
773 530 100 100     4446 $result eq CMP_SUBTYPE or $result eq CMP_EQUAL or $result eq CMP_EQUIVALENT;
774             }
775              
776             sub strictly_equals {
777 12903     12903 1 20683 my ( $self, $other ) = _loose_to_TypeTiny( @_ );
778 12903 50 33     40982 return unless blessed( $self ) && $self->isa( "Type::Tiny" );
779 12903 50 33     39316 return unless blessed( $other ) && $other->isa( "Type::Tiny" );
780 12903         51331 $self->{uniq} == $other->{uniq};
781             }
782              
783             sub is_strictly_subtype_of {
784 12363     12363 1 20240 my ( $self, $other ) = _loose_to_TypeTiny( @_ );
785 12363 50 33     39527 return unless blessed( $self ) && $self->isa( "Type::Tiny" );
786 12363 50 33     38458 return unless blessed( $other ) && $other->isa( "Type::Tiny" );
787            
788 12363 100       24970 return unless $self->has_parent;
789 10566 100       18545 $self->parent->strictly_equals( $other )
790             or $self->parent->is_strictly_subtype_of( $other );
791             }
792              
793             sub is_strictly_supertype_of {
794 2     2 1 13 my ( $self, $other ) = _loose_to_TypeTiny( @_ );
795 2 50 33     17 return unless blessed( $self ) && $self->isa( "Type::Tiny" );
796 2 50 33     12 return unless blessed( $other ) && $other->isa( "Type::Tiny" );
797            
798 2         6 $other->is_strictly_subtype_of( $self );
799             }
800              
801             sub is_strictly_a_type_of {
802 2320     2320 1 11501 my ( $self, $other ) = _loose_to_TypeTiny( @_ );
803 2320 50 33     9837 return unless blessed( $self ) && $self->isa( "Type::Tiny" );
804 2320 50 33     8613 return unless blessed( $other ) && $other->isa( "Type::Tiny" );
805            
806 2320 50       6035 $self->strictly_equals( $other ) or $self->is_strictly_subtype_of( $other );
807             }
808              
809             sub qualified_name {
810 12008     12008 1 17055 my $self = shift;
811             ( exists $self->{library} and $self->name ne "__ANON__" )
812             ? "$self->{library}::$self->{name}"
813 12008 100 66     32906 : $self->{name};
814             }
815              
816             sub is_anon {
817 34296     34296 1 45911 my $self = shift;
818 34296         54870 $self->name eq "__ANON__";
819             }
820              
821             sub parents {
822 34403     34403 1 43888 my $self = shift;
823 34403 100       51209 return unless $self->has_parent;
824 28647         50278 return ( $self->parent, $self->parent->parents );
825             }
826              
827             sub find_parent {
828 462     462 1 878 my $self = shift;
829 462         837 my ( $test ) = @_;
830            
831 462         1530 local ( $_, $. );
832 462         748 my $type = $self;
833 462         671 my $count = 0;
834 462         1310 while ( $type ) {
835 570 100       1797 if ( $test->( $_ = $type, $. = $count ) ) {
836 459 100       2289 return wantarray ? ( $type, $count ) : $type;
837             }
838             else {
839 111         195 $type = $type->parent;
840 111         252 $count++;
841             }
842             }
843            
844 3         19 return;
845             } #/ sub find_parent
846              
847             sub check {
848 136892     136892 1 240040 my $self = shift;
849 136892   66     618984 ( $self->{compiled_type_constraint} ||= $self->_build_compiled_check )->( @_ );
850             }
851              
852             sub _strict_check {
853 5045     5045   10573 my $self = shift;
854 5045         9709 local $_ = $_[0];
855            
856             my @constraints =
857             reverse
858 18054         28061 map { $_->constraint }
859 5045         12078 grep { not $_->_is_null_constraint } ( $self, $self->parents );
  29854         49114  
860            
861 5045         12124 for my $c ( @constraints ) {
862 13785 100       41633 return unless $c->( @_ );
863             }
864            
865 1351         8804 return !!1;
866             } #/ sub _strict_check
867              
868             sub get_message {
869 888     888 1 1450 my $self = shift;
870 888         1457 local $_ = $_[0];
871 888 100       2238 $self->has_message
872             ? $self->message->( @_ )
873             : $self->_default_message->( @_ );
874             }
875              
876             sub validate {
877 2     2 1 5 my $self = shift;
878            
879             return undef
880 2 50 33     9 if ( $self->{compiled_type_constraint} ||= $self->_build_compiled_check )
881             ->( @_ );
882            
883 2         23 local $_ = $_[0];
884 2         5 return $self->get_message( @_ );
885             } #/ sub validate
886              
887             sub validate_explain {
888 2130     2130 1 4327 my $self = shift;
889 2130         3527 my ( $value, $varname ) = @_;
890 2130 100       3664 $varname = '$_' unless defined $varname;
891            
892 2130 100       3623 return undef if $self->check( $value );
893            
894 1684 100       5532 if ( $self->has_parent ) {
895 1676         2815 my $parent = $self->parent->validate_explain( $value, $varname );
896             return [
897 1676 100       4632 sprintf( '"%s" is a subtype of "%s"', $self, $self->parent ),
898             @$parent
899             ]
900             if $parent;
901             }
902            
903 454 100       1077 my $message = sprintf(
904             '%s%s',
905             $self->get_message( $value ),
906             $varname eq q{$_} ? '' : sprintf( ' (in %s)', $varname ),
907             );
908            
909 454 100 66     1425 if ( $self->is_parameterized and $self->parent->has_deep_explanation ) {
910 101         261 my $deep = $self->parent->deep_explanation->( $self, $value, $varname );
911 101 50       763 return [ $message, @$deep ] if $deep;
912             }
913              
914 353     0   2557 local $SIG{__WARN__} = sub {};
915             return [
916 353         1074 $message,
917             sprintf( '"%s" is defined as: %s', $self, $self->_perlcode )
918             ];
919             } #/ sub validate_explain
920              
921             my $b;
922              
923             sub _perlcode {
924 353     353   580 my $self = shift;
925            
926 353         612 local our $AvoidCallbacks = 1;
927 353 100       771 return $self->inline_check( '$_' )
928             if $self->can_be_inlined;
929            
930 12   66     66 $b ||= do {
931 7         13 local $@;
932 7         46 require B::Deparse;
933 7         401 my $tmp = "B::Deparse"->new;
934 7 50       534 $tmp->ambient_pragmas( strict => "all", warnings => "all" )
935             if $tmp->can( 'ambient_pragmas' );
936 7         35 $tmp;
937             };
938            
939 12         37 my $code = $b->coderef2text( $self->constraint );
940 12         131 $code =~ s/\s+/ /g;
941 12         79 return "sub $code";
942             } #/ sub _perlcode
943              
944             sub assert_valid {
945 81     81 1 5711 my $self = shift;
946            
947             return !!1
948 81 100 66     416 if ( $self->{compiled_type_constraint} ||= $self->_build_compiled_check )
949             ->( @_ );
950            
951 13         109 local $_ = $_[0];
952 13         45 $self->_failed_check( "$self", $_ );
953             } #/ sub assert_valid
954              
955             sub assert_return {
956 115083     115083 1 175292 my $self = shift;
957            
958             return $_[0]
959 115083 100 66     347124 if ( $self->{compiled_type_constraint} ||= $self->_build_compiled_check )
960             ->( @_ );
961            
962 1         9 local $_ = $_[0];
963 1         4 $self->_failed_check( "$self", $_ );
964             } #/ sub assert_return
965              
966             sub can_be_inlined {
967 169359     169359 1 235468 my $self = shift;
968 169359 100 100     277484 return $self->parent->can_be_inlined
969             if $self->has_parent && $self->_is_null_constraint;
970 144772 100 100     266116 return !!1
971             if !$self->has_parent && $self->_is_null_constraint;
972 133026         249554 return $self->has_inlined;
973             }
974              
975             sub inline_check {
976 60278     60278 1 106286 my $self = shift;
977 60278 50       93961 _croak 'Cannot inline type constraint check for "%s"', $self
978             unless $self->can_be_inlined;
979            
980 60278 100 100     102470 return $self->parent->inline_check( @_ )
981             if $self->has_parent && $self->_is_null_constraint;
982 49242 100 100     88283 return '(!!1)'
983             if !$self->has_parent && $self->_is_null_constraint;
984            
985 45374         76965 local $_ = $_[0];
986 45374         87234 my @r = $self->inlined->( $self, @_ );
987 45374 100 66     161006 if ( @r and not defined $r[0] ) {
988 6563 50       12328 _croak 'Inlining type constraint check for "%s" returned undef!', $self
989             unless $self->has_parent;
990 6563         13796 $r[0] = $self->parent->inline_check( @_ );
991             }
992             my $r = join " && " => map {
993 45374 100 100     81224 /[;{}]/ && !/\Ado \{.+\}\z/
  54942         319175  
994             ? "do { $SafePackage $_ }"
995             : "($_)"
996             } @r;
997 45374 100       917053 return @r == 1 ? $r : "($r)";
998             } #/ sub inline_check
999              
1000             sub inline_assert {
1001 10474     10474 1 39323 require B;
1002 10474         16359 my $self = shift;
1003 10474         31421 my ( $varname, $typevarname, %extras ) = @_;
1004            
1005 10474         14585 my $inline_check;
1006 10474 100       17860 if ( $self->can_be_inlined ) {
    100          
1007 10376         23682 $inline_check = sprintf( '(%s)', $self->inline_check( $varname ) );
1008             }
1009             elsif ( $typevarname ) {
1010 97         352 $inline_check = sprintf( '%s->check(%s)', $typevarname, $varname );
1011             }
1012             else {
1013 1         4 _croak 'Cannot inline type constraint check for "%s"', $self;
1014             }
1015            
1016 10473         28804 my $do_wrapper = !delete $extras{no_wrapper};
1017            
1018 10473         14802 my $inline_throw;
1019 10473 100       18068 if ( $typevarname ) {
1020             $inline_throw = sprintf(
1021             'Type::Tiny::_failed_check(%s, %s, %s, %s)',
1022             $typevarname,
1023             B::perlstring( "$self" ),
1024             $varname,
1025             join(
1026 98         315 ',', map +( B::perlstring( $_ ) => B::perlstring( $extras{$_} ) ),
1027             sort keys %extras
1028             ),
1029             );
1030             } #/ if ( $typevarname )
1031             else {
1032             $inline_throw = sprintf(
1033             'Type::Tiny::_failed_check(%s, %s, %s, %s)',
1034             $self->{uniq},
1035             B::perlstring( "$self" ),
1036             $varname,
1037             join(
1038 10375         34885 ',', map +( B::perlstring( $_ ) => B::perlstring( $extras{$_} ) ),
1039             sort keys %extras
1040             ),
1041             );
1042             } #/ else [ if ( $typevarname ) ]
1043            
1044 10473 100       71894 $do_wrapper
1045             ? qq[do { no warnings "void"; $SafePackage $inline_check or $inline_throw; $varname };]
1046             : qq[ no warnings "void"; $SafePackage $inline_check or $inline_throw; $varname ];
1047             } #/ sub inline_assert
1048              
1049             sub _failed_check {
1050 414     414   31469 require Error::TypeTiny::Assertion;
1051            
1052 414         1459 my ( $self, $name, $value, %attrs ) = @_;
1053 414 100 100     2563 $self = $ALL_TYPES{$self} if defined $self && !ref $self;
1054            
1055             my $exception_class =
1056 414   50     1567 delete( $attrs{exception_class} ) || "Error::TypeTiny::Assertion";
1057 414         702 my $callback = delete( $attrs{on_die} );
1058              
1059 414 100       1539 if ( $self ) {
1060 413         1391 return $exception_class->throw_cb(
1061             $callback,
1062             message => $self->get_message( $value ),
1063             type => $self,
1064             value => $value,
1065             %attrs,
1066             );
1067             }
1068             else {
1069 1         7 return $exception_class->throw_cb(
1070             $callback,
1071             message => sprintf( '%s did not pass type constraint "%s"', _dd( $value ), $name ),
1072             value => $value,
1073             %attrs,
1074             );
1075             }
1076             } #/ sub _failed_check
1077              
1078             sub coerce {
1079 564     564 1 57432 my $self = shift;
1080 564         1236 $self->_assert_coercion->coerce( @_ );
1081             }
1082              
1083             sub assert_coerce {
1084 64     64 1 381 my $self = shift;
1085 64         145 $self->_assert_coercion->assert_coerce( @_ );
1086             }
1087              
1088             sub is_parameterizable {
1089 12899     12899 1 27331 shift->has_constraint_generator;
1090             }
1091              
1092             sub is_parameterized {
1093 490     490 1 1545 shift->has_parameters;
1094             }
1095              
1096             {
1097             my %seen;
1098            
1099             sub ____make_key {
1100             #<<<
1101             join ',', map {
1102 1392     1392   2815 Types::TypeTiny::is_TypeTiny( $_ ) ? sprintf( '$Type::Tiny::ALL_TYPES{%s}', defined( $_->{uniq} ) ? $_->{uniq} : '____CANNOT_KEY____' ) :
1103 7 50       101 ref() eq 'ARRAY' ? do { $seen{$_}++ ? '____CANNOT_KEY____' : sprintf( '[%s]', ____make_key( @$_ ) ) } :
1104 18 50       198 ref() eq 'HASH' ? do { $seen{$_}++ ? '____CANNOT_KEY____' : sprintf( '{%s}', ____make_key( do { my %h = %$_; map +( $_, $h{$_} ), sort keys %h; } ) ) } :
  18         55  
  18         103  
1105 3 50       45 ref() eq 'SCALAR' || ref() eq 'REF' ? do { $seen{$_}++ ? '____CANNOT_KEY____' : sprintf( '\\(%s)', ____make_key( $$_ ) ) } :
1106             !defined() ? 'undef' :
1107 3440 50 66     69253 !ref() ? do { require B; B::perlstring( $_ ) } :
  975 100       12045  
  975 100       4970  
    100          
    100          
    100          
    100          
1108             '____CANNOT_KEY____';
1109             } @_;
1110             #>>>
1111             } #/ sub ____make_key
1112             my %param_cache;
1113            
1114             sub parameterize {
1115 1362     1362 1 128993 my $self = shift;
1116            
1117 1362 0       3305 $self->is_parameterizable
    50          
1118             or @_
1119             ? _croak( "Type '%s' does not accept parameters", "$self" )
1120             : return ( $self );
1121            
1122 1362         5588 @_ = map Types::TypeTiny::to_TypeTiny( $_ ), @_;
1123            
1124             # Generate a key for caching parameterized type constraints,
1125             # but only if all the parameters are strings or type constraints.
1126 1362         3089 %seen = ();
1127 1362         3721 my $key = $self->____make_key( @_ );
1128 1362 100       5493 undef( $key ) if $key =~ /____CANNOT_KEY____/;
1129 1362 100 100     7697 return $param_cache{$key} if defined $key && defined $param_cache{$key};
1130            
1131 1000         2003 local $Type::Tiny::parameterize_type = $self;
1132 1000         1757 local $_ = $_[0];
1133 1000         1547 my $P;
1134            
1135 1000         3257 my ( $constraint, $compiled ) = $self->constraint_generator->( @_ );
1136            
1137 959 100       21430 if ( Types::TypeTiny::is_TypeTiny( $constraint ) ) {
1138 168         413 $P = $constraint;
1139             }
1140             else {
1141 791         6054 my %options = (
1142             constraint => $constraint,
1143             display_name => $self->name_generator->( $self, @_ ),
1144             parameters => [@_],
1145             );
1146 791 100       2894 $options{compiled_type_constraint} = $compiled
1147             if $compiled;
1148 791 100       2122 $options{inlined} = $self->inline_generator->( @_ )
1149             if $self->has_inline_generator;
1150             $options{type_default} = $self->{type_default_generator}->( @_ )
1151 791 100       3838 if exists $self->{type_default_generator}; # undocumented
1152             exists $options{$_} && !defined $options{$_} && delete $options{$_}
1153 791   66     9905 for keys %options;
      66        
1154            
1155 791         3303 $P = $self->create_child_type( %options );
1156            
1157 791 100       2857 if ( $self->has_coercion_generator ) {
1158 384         1288 my @args = @_;
1159             $P->{_build_coercion} = sub {
1160 190     190   370 my $coercion = shift;
1161 190         654 my $built = $self->coercion_generator->( $self, $P, @args );
1162 190 100       643 $coercion->add_type_coercions( @{ $built->type_coercion_map } ) if $built;
  111         247  
1163 190         664 $coercion->freeze;
1164 384         2548 };
1165             }
1166             } #/ else [ if ( Types::TypeTiny::is_TypeTiny...)]
1167            
1168 959 100       3148 if ( defined $key ) {
1169 926         2667 $param_cache{$key} = $P;
1170 926         2526 Scalar::Util::weaken( $param_cache{$key} );
1171             }
1172            
1173 959 100       2170 $P->coercion->freeze unless $self->has_coercion_generator;
1174            
1175 959         4160 return $P;
1176             } #/ sub parameterize
1177             }
1178              
1179             sub child_type_class {
1180 1301     1301 1 5536 __PACKAGE__;
1181             }
1182              
1183             sub create_child_type {
1184 1301     1301 1 6594 my $self = shift;
1185 1301         2105 my %moreopts;
1186 1301 100       3773 $moreopts{is_object} = 1 if $self->{is_object};
1187 1301         3327 return $self->child_type_class->new( parent => $self, %moreopts, @_ );
1188             }
1189              
1190             sub complementary_type {
1191 76     76 1 136 my $self = shift;
1192 76   66     326 my $r = ( $self->{complementary_type} ||= $self->_build_complementary_type );
1193             Scalar::Util::weaken( $self->{complementary_type} )
1194 76 100       357 unless Scalar::Util::isweak( $self->{complementary_type} );
1195 76         1227 return $r;
1196             }
1197              
1198             sub _build_complementary_type {
1199 64     64   86 my $self = shift;
1200             my %opts = (
1201 106     106   209 constraint => sub { not $self->check( $_ ) },
1202 64         360 display_name => sprintf( "~%s", $self ),
1203             );
1204 64         186 $opts{display_name} =~ s/^\~{2}//;
1205 292     292   411 $opts{inlined} = sub { shift; "not(" . $self->inline_check( @_ ) . ")" }
  292         587  
1206 64 100       139 if $self->can_be_inlined;
1207             $opts{display_name} = $opts{name} = $self->{complement_name}
1208 64 100       167 if $self->{complement_name};
1209 64         250 return "Type::Tiny"->new( %opts );
1210             } #/ sub _build_complementary_type
1211              
1212             sub _instantiate_moose_type {
1213 0     0   0 my $self = shift;
1214 0         0 my %opts = @_;
1215 0         0 require Moose::Meta::TypeConstraint;
1216 0         0 return "Moose::Meta::TypeConstraint"->new( %opts );
1217             }
1218              
1219             sub _build_moose_type {
1220 0     0   0 my $self = shift;
1221            
1222 0         0 my $r;
1223 0 0       0 if ( $self->{_is_core} ) {
1224 0         0 require Moose::Util::TypeConstraints;
1225 0         0 $r = Moose::Util::TypeConstraints::find_type_constraint( $self->name );
1226 0         0 $r->{"Types::TypeTiny::to_TypeTiny"} = $self;
1227 0         0 Scalar::Util::weaken( $r->{"Types::TypeTiny::to_TypeTiny"} );
1228             }
1229             else {
1230             # Type::Tiny is more flexible than Moose, allowing
1231             # inlined to return a list. So we need to wrap the
1232             # inlined coderef to make sure Moose gets a single
1233             # string.
1234             #
1235             my $wrapped_inlined = sub {
1236 0     0   0 shift;
1237 0         0 $self->inline_check( @_ );
1238 0         0 };
1239            
1240 0         0 my %opts;
1241 0 0 0     0 $opts{name} = $self->qualified_name if $self->has_library && !$self->is_anon;
1242 0 0       0 $opts{parent} = $self->parent->moose_type if $self->has_parent;
1243 0 0       0 $opts{constraint} = $self->constraint unless $self->_is_null_constraint;
1244 0 0       0 $opts{message} = $self->message if $self->has_message;
1245 0 0       0 $opts{inlined} = $wrapped_inlined if $self->has_inlined;
1246            
1247 0         0 $r = $self->_instantiate_moose_type( %opts );
1248 0         0 $r->{"Types::TypeTiny::to_TypeTiny"} = $self;
1249 0         0 $self->{moose_type} = $r; # prevent recursion
1250 0 0       0 $r->coercion( $self->coercion->moose_coercion ) if $self->has_coercion;
1251             } #/ else [ if ( $self->{_is_core})]
1252            
1253 0         0 return $r;
1254             } #/ sub _build_moose_type
1255              
1256             sub _build_mouse_type {
1257 0     0   0 my $self = shift;
1258            
1259 0         0 my %options;
1260 0 0 0     0 $options{name} = $self->qualified_name if $self->has_library && !$self->is_anon;
1261 0 0       0 $options{parent} = $self->parent->mouse_type if $self->has_parent;
1262 0 0       0 $options{constraint} = $self->constraint unless $self->_is_null_constraint;
1263 0 0       0 $options{message} = $self->message if $self->has_message;
1264            
1265 0         0 require Mouse::Meta::TypeConstraint;
1266 0         0 my $r = "Mouse::Meta::TypeConstraint"->new( %options );
1267            
1268 0         0 $self->{mouse_type} = $r; # prevent recursion
1269 0 0       0 $r->_add_type_coercions(
1270             $self->coercion->freeze->_codelike_type_coercion_map( 'mouse_type' ) )
1271             if $self->has_coercion;
1272            
1273 0         0 return $r;
1274             } #/ sub _build_mouse_type
1275              
1276             sub exportables {
1277 11924     11924 1 27304 my ( $self, $base_name, $tag ) = ( shift, @_ ); # $tag is undocumented
1278 11924 100       19895 if ( not $self->is_anon ) {
1279 11923   66     31353 $base_name ||= $self->name;
1280             }
1281 11924   100     47448 $tag ||= 0;
1282              
1283 11924         16975 my @exportables;
1284 11924 50       21921 return \@exportables if ! $base_name;
1285              
1286 11924         59632 require Eval::TypeTiny;
1287              
1288 11924 100 66     59057 push @exportables, {
1289             name => $base_name,
1290             code => Eval::TypeTiny::type_to_coderef( $self ),
1291             tags => [ 'types' ],
1292             } if $tag eq 'types' || !$tag;
1293              
1294 11924 100 100     90058 push @exportables, {
1295             name => sprintf( 'is_%s', $base_name ),
1296             code => $self->compiled_check,
1297             tags => [ 'is' ],
1298             } if $tag eq 'is' || !$tag;
1299              
1300 11924 100 66     70009 push @exportables, {
1301             name => sprintf( 'assert_%s', $base_name ),
1302             code => $self->_overload_coderef,
1303             tags => [ 'assert' ],
1304             } if $tag eq 'assert' || !$tag;
1305              
1306             push @exportables, {
1307             name => sprintf( 'to_%s', $base_name ),
1308             code => $self->has_coercion && $self->coercion->frozen
1309             ? $self->coercion->compiled_coercion
1310 4     4   1537 : sub ($) { $self->coerce( $_[0] ) },
        4      
        8      
        8      
        12      
        12      
        12      
        8      
        8      
        8      
        12      
        8      
        12      
        12      
        8      
        8      
        8      
        12      
        12      
        8      
        8      
        8      
        12      
        12      
        8      
        8      
        8      
        8      
        8      
        8      
        8      
        12      
        8      
        8      
        12      
        12      
        8      
        644      
1311 11924 100 100     90171 tags => [ 'to' ],
    100 100        
1312             } if $tag eq 'to' || !$tag;
1313              
1314 11924         47222 return \@exportables;
1315             }
1316              
1317             sub exportables_by_tag {
1318 521     525 1 1986 my ( $self, $tag, $base_name ) = ( shift, @_ );
1319             my @matched = grep {
1320 521         1298 my $e = $_;
1321 521 50       1141 grep $_ eq $tag, @{ $e->{tags} || [] };
  521         3132  
1322 521         1324 } @{ $self->exportables( $base_name, $tag ) };
  521         1982  
1323 521 100       3722 return @matched if wantarray;
1324 1 50       3 _croak( 'Expected to find one exportable tagged "%s", found %d', $tag, scalar @matched )
1325             unless @matched == 1;
1326 1         13 return $matched[0];
1327             }
1328              
1329             sub _process_coercion_list {
1330 92     92   203 my $self = shift;
1331            
1332 92         173 my @pairs;
1333 92         289 while ( @_ ) {
1334 96         183 my $next = shift;
1335 96 100 66     624 if ( blessed( $next )
    100 100        
    50 66        
1336             and $next->isa( 'Type::Coercion' )
1337             and $next->is_parameterized )
1338             {
1339 7         12 push @pairs => ( @{ $next->_reparameterize( $self )->type_coercion_map } );
  7         24  
1340             }
1341             elsif ( blessed( $next ) and $next->can( 'type_coercion_map' ) ) {
1342             push @pairs => (
1343 9         18 @{ $next->type_coercion_map },
  9         18  
1344             );
1345             }
1346             elsif ( ref( $next ) eq q(ARRAY) ) {
1347 0         0 unshift @_, @$next;
1348             }
1349             else {
1350 80         361 push @pairs => (
1351             Types::TypeTiny::to_TypeTiny( $next ),
1352             shift,
1353             );
1354             }
1355             } #/ while ( @_ )
1356            
1357 92         298 return @pairs;
1358             } #/ sub _process_coercion_list
1359              
1360             sub plus_coercions {
1361 89     89 1 38801 my $self = shift;
1362 89         327 my $new = $self->_clone;
1363             $new->coercion->add_type_coercions(
1364             $self->_process_coercion_list( @_ ),
1365 89         323 @{ $self->coercion->type_coercion_map },
  89         298  
1366             );
1367 89         296 $new->coercion->freeze;
1368 89         370 return $new;
1369             } #/ sub plus_coercions
1370              
1371             sub plus_fallback_coercions {
1372 2     2 1 571 my $self = shift;
1373            
1374 2         6 my $new = $self->_clone;
1375             $new->coercion->add_type_coercions(
1376 2         6 @{ $self->coercion->type_coercion_map },
  2         4  
1377             $self->_process_coercion_list( @_ ),
1378             );
1379 2         5 $new->coercion->freeze;
1380 2         4 return $new;
1381             } #/ sub plus_fallback_coercions
1382              
1383             sub minus_coercions {
1384 1     1 1 637 my $self = shift;
1385            
1386 1         6 my $new = $self->_clone;
1387 1         6 my @not = grep Types::TypeTiny::is_TypeTiny( $_ ),
1388             $self->_process_coercion_list( $new, @_ );
1389            
1390 1         7 my @keep;
1391 1         3 my $c = $self->coercion->type_coercion_map;
1392 1         7 for ( my $i = 0 ; $i <= $#$c ; $i += 2 ) {
1393 4         6 my $keep_this = 1;
1394 4         7 NOT: for my $n ( @not ) {
1395 11 100       26 if ( $c->[$i] == $n ) {
1396 2         4 $keep_this = 0;
1397 2         6 last NOT;
1398             }
1399             }
1400            
1401 4 100       23 push @keep, $c->[$i], $c->[ $i + 1 ] if $keep_this;
1402             } #/ for ( my $i = 0 ; $i <=...)
1403            
1404 1         5 $new->coercion->add_type_coercions( @keep );
1405 1         4 $new->coercion->freeze;
1406 1         3 return $new;
1407             } #/ sub minus_coercions
1408              
1409             sub no_coercions {
1410 4     4 1 1246 my $new = shift->_clone;
1411 4         18 $new->coercion->freeze;
1412 4         16 $new;
1413             }
1414              
1415             sub coercibles {
1416 7     7 1 219 my $self = shift;
1417 7 100       13 $self->has_coercion ? $self->coercion->_source_type_union : $self;
1418             }
1419              
1420             sub isa {
1421 272355     272355 1 752118 my $self = shift;
1422            
1423 272355 0 33     567173 if ( $INC{"Moose.pm"}
      33        
1424             and ref( $self )
1425             and $_[0] =~ /^(?:Class::MOP|MooseX?::Meta)::(.+)$/ )
1426             {
1427 0         0 my $meta = $1;
1428            
1429 0 0       0 return !!1 if $meta eq 'TypeConstraint';
1430 0 0       0 return $self->is_parameterized if $meta eq 'TypeConstraint::Parameterized';
1431 0 0       0 return $self->is_parameterizable if $meta eq 'TypeConstraint::Parameterizable';
1432 0 0       0 return $self->isa( 'Type::Tiny::Union' ) if $meta eq 'TypeConstraint::Union';
1433            
1434 0         0 my $inflate = $self->moose_type;
1435 0         0 return $inflate->isa( @_ );
1436             } #/ if ( $INC{"Moose.pm"} ...)
1437            
1438 272355 0 33     482323 if ( $INC{"Mouse.pm"}
      33        
1439             and ref( $self )
1440             and $_[0] eq 'Mouse::Meta::TypeConstraint' )
1441             {
1442 0         0 return !!1;
1443             }
1444            
1445 272355         1185306 $self->SUPER::isa( @_ );
1446             } #/ sub isa
1447              
1448             sub _build_my_methods {
1449 141     141   1030 return {};
1450             }
1451              
1452             sub _lookup_my_method {
1453 1278     1278   1882 my $self = shift;
1454 1278         2862 my ( $name ) = @_;
1455            
1456 1278 100       2338 if ( $self->my_methods->{$name} ) {
1457 614         1145 return $self->my_methods->{$name};
1458             }
1459            
1460 664 100       1360 if ( $self->has_parent ) {
1461 662         1296 return $self->parent->_lookup_my_method( @_ );
1462             }
1463            
1464 2         9 return;
1465             } #/ sub _lookup_my_method
1466              
1467             my %object_methods = (
1468             with_attribute_values => 1, stringifies_to => 1,
1469             numifies_to => 1
1470             );
1471              
1472             sub can {
1473 77835     77835 1 161384 my $self = shift;
1474            
1475 77835 50 66     176324 return !!0
      33        
1476             if $_[0] eq 'type_parameter'
1477             && blessed( $_[0] )
1478             && $_[0]->has_parameters;
1479            
1480 77835         234381 my $can = $self->SUPER::can( @_ );
1481 77835 100       597621 return $can if $can;
1482            
1483 42080 100       92452 if ( ref( $self ) ) {
1484 42079 50       83994 if ( $INC{"Moose.pm"} ) {
1485 0         0 my $method = $self->moose_type->can( @_ );
1486 0     0   0 return sub { shift->moose_type->$method( @_ ) }
1487 0 0       0 if $method;
1488             }
1489 42079 100       97248 if ( $_[0] =~ /\Amy_(.+)\z/ ) {
1490 4         9 my $method = $self->_lookup_my_method( $1 );
1491 4 100       13 return $method if $method;
1492             }
1493 42077 100 100     101118 if ( $self->{is_object} && $object_methods{ $_[0] } ) {
1494 1         756 require Type::Tiny::ConstrainedObject;
1495 1         14 return Type::Tiny::ConstrainedObject->can( $_[0] );
1496             }
1497 42076         82544 for my $util ( qw/ grep map sort rsort first any all assert_any assert_all / ) {
1498 378540 100       623414 if ( $_[0] eq $util ) {
1499 36   66     153 $self->{'_util'}{$util} ||= eval { $self->_build_util( $util ) };
  36         83  
1500 36 100       149 return unless $self->{'_util'}{$util};
1501 34     0   178 return sub { my $s = shift; $s->{'_util'}{$util}( @_ ) };
  0         0  
  0         0  
1502             }
1503             }
1504             } #/ if ( ref( $self ) )
1505            
1506 42041         249262 return;
1507             } #/ sub can
1508              
1509             sub AUTOLOAD {
1510 685     685   14827 my $self = shift;
1511 685         4236 my ( $m ) = ( our $AUTOLOAD =~ /::(\w+)$/ );
1512 685 50       1966 return if $m eq 'DESTROY';
1513            
1514 685 50       1688 if ( ref( $self ) ) {
1515 685 50       1678 if ( $INC{"Moose.pm"} ) {
1516 0         0 my $method = $self->moose_type->can( $m );
1517 0 0       0 return $self->moose_type->$method( @_ ) if $method;
1518             }
1519 685 100       2358 if ( $m =~ /\Amy_(.+)\z/ ) {
1520 612         1531 my $method = $self->_lookup_my_method( $1 );
1521 612 50       2419 return &$method( $self, @_ ) if $method;
1522             }
1523 73 50 66     238 if ( $self->{is_object} && $object_methods{$m} ) {
1524 3         1187 require Type::Tiny::ConstrainedObject;
1525 3         13 unshift @_, $self;
1526 272     272   3011 no strict 'refs';
  272         709  
  272         409804  
1527 3         8 goto \&{"Type::Tiny::ConstrainedObject::$m"};
  3         25  
1528             }
1529 70         151 for my $util ( qw/ grep map sort rsort first any all assert_any assert_all / ) {
1530 376 100       668 if ( $m eq $util ) {
1531 70   66     926 return ( $self->{'_util'}{$util} ||= $self->_build_util( $util ) )->( @_ );
1532             }
1533             }
1534             } #/ if ( ref( $self ) )
1535            
1536 0   0     0 _croak q[Can't locate object method "%s" via package "%s"], $m,
1537             ref( $self ) || $self;
1538             } #/ sub AUTOLOAD
1539              
1540             sub DOES {
1541 45     45 1 112 my $self = shift;
1542            
1543 45 50 33     202 return !!1
1544             if ref( $self )
1545             && $_[0] =~ m{^ Type::API::Constraint (?: ::Coercible | ::Inlinable )? $}x;
1546 45 50 33     148 return !!1 if !ref( $self ) && $_[0] eq 'Type::API::Constraint::Constructor';
1547            
1548 45 50       334 "UNIVERSAL"->can( "DOES" ) ? $self->SUPER::DOES( @_ ) : $self->isa( @_ );
1549             } #/ sub DOES
1550              
1551             sub _has_xsub {
1552 1     1   520 require B;
1553 1         5 !!B::svref_2object( shift->compiled_check )->XSUB;
1554             }
1555              
1556             sub _build_util {
1557 82     82   182 my ( $self, $func ) = @_;
1558 82         256 Scalar::Util::weaken( my $type = $self );
1559            
1560 82 100 100     659 if ( $func eq 'grep'
      100        
      100        
      100        
      100        
1561             || $func eq 'first'
1562             || $func eq 'any'
1563             || $func eq 'all'
1564             || $func eq 'assert_any'
1565             || $func eq 'assert_all' )
1566             {
1567 43         65 my ( $inline, $compiled );
1568            
1569 43 100       123 if ( $self->can_be_inlined ) {
1570 13         34 $inline = $self->inline_check( '$_' );
1571             }
1572             else {
1573 30         63 $compiled = $self->compiled_check;
1574 30         61 $inline = '$compiled->($_)';
1575             }
1576            
1577 43 100       192 if ( $func eq 'grep' ) {
    100          
    100          
    100          
    100          
    50          
1578 5         592 return eval "sub { grep { $inline } \@_ }";
1579             }
1580             elsif ( $func eq 'first' ) {
1581 5         603 return eval "sub { for (\@_) { return \$_ if ($inline) }; undef; }";
1582             }
1583             elsif ( $func eq 'any' ) {
1584 8         912 return eval "sub { for (\@_) { return !!1 if ($inline) }; !!0; }";
1585             }
1586             elsif ( $func eq 'assert_any' ) {
1587 8         17 my $qname = B::perlstring( $self->name );
1588             return
1589             eval
1590 8         1164 "sub { for (\@_) { return \@_ if ($inline) }; Type::Tiny::_failed_check(\$type, $qname, \@_ ? \$_[-1] : undef); }";
1591             }
1592             elsif ( $func eq 'all' ) {
1593 9         1069 return eval "sub { for (\@_) { return !!0 unless ($inline) }; !!1; }";
1594             }
1595             elsif ( $func eq 'assert_all' ) {
1596 8         16 my $qname = B::perlstring( $self->name );
1597             return
1598             eval
1599 8         1243 "sub { my \$idx = 0; for (\@_) { Type::Tiny::_failed_check(\$type, $qname, \$_, varname => sprintf('\$_[%d]', \$idx)) unless ($inline); ++\$idx }; \@_; }";
1600             }
1601             } #/ if ( $func eq 'grep' ||...)
1602            
1603 39 100       96 if ( $func eq 'map' ) {
1604 8         14 my ( $inline, $compiled );
1605 8         16 my $c = $self->_assert_coercion;
1606            
1607 4 100       11 if ( $c->can_be_inlined ) {
1608 1         5 $inline = $c->inline_coercion( '$_' );
1609             }
1610             else {
1611 3         13 $compiled = $c->compiled_coercion;
1612 3         7 $inline = '$compiled->($_)';
1613             }
1614            
1615 4         425 return eval "sub { map { $inline } \@_ }";
1616             } #/ if ( $func eq 'map' )
1617            
1618 31 100 100     102 if ( $func eq 'sort' || $func eq 'rsort' ) {
1619 29         63 my ( $inline, $compiled );
1620            
1621 29     76   134 my $ptype = $self->find_parent( sub { $_->has_sorter } );
  76         147  
1622 29 100       114 _croak "No sorter for this type constraint" unless $ptype;
1623            
1624 27         86 my $sorter = $ptype->sorter;
1625            
1626             # Schwarzian transformation
1627 27 100       82 if ( ref( $sorter ) eq 'ARRAY' ) {
1628 6         11 my $sort_key;
1629 6         15 ( $sorter, $sort_key ) = @$sorter;
1630            
1631 6 100       21 if ( $func eq 'sort' ) {
    50          
1632             return
1633             eval
1634 4         660 "our (\$a, \$b); sub { map \$_->[0], sort { \$sorter->(\$a->[1],\$b->[1]) } map [\$_,\$sort_key->(\$_)], \@_ }";
1635             }
1636             elsif ( $func eq 'rsort' ) {
1637             return
1638             eval
1639 2         289 "our (\$a, \$b); sub { map \$_->[0], sort { \$sorter->(\$b->[1],\$a->[1]) } map [\$_,\$sort_key->(\$_)], \@_ }";
1640             }
1641             } #/ if ( ref( $sorter ) eq...)
1642            
1643             # Simple sort
1644             else {
1645 21 100       58 if ( $func eq 'sort' ) {
    50          
1646 12         1412 return eval "our (\$a, \$b); sub { sort { \$sorter->(\$a,\$b) } \@_ }";
1647             }
1648             elsif ( $func eq 'rsort' ) {
1649 9         1006 return eval "our (\$a, \$b); sub { sort { \$sorter->(\$b,\$a) } \@_ }";
1650             }
1651             }
1652             } #/ if ( $func eq 'sort' ||...)
1653            
1654 2         23 die "Unknown function: $func";
1655             } #/ sub _build_util
1656              
1657 284     284 1 6653 sub of { shift->parameterize( @_ ) }
1658 138     138 1 49432 sub where { shift->create_child_type( constraint => @_ ) }
1659              
1660             # fill out Moose-compatible API
1661 1     1 1 95 sub inline_environment { +{} }
1662 1     1   7 sub _inline_check { shift->inline_check( @_ ) }
1663 2     2   540 sub _compiled_type_constraint { shift->compiled_check( @_ ) }
1664 1     1 1 10 sub meta { _croak( "Not really a Moose::Meta::TypeConstraint. Sorry!" ) }
1665 2     2 1 17 sub compile_type_constraint { shift->compiled_check }
1666 2     2   29 sub _actually_compile_type_constraint { shift->_build_compiled_check }
1667 1     1 1 365 sub hand_optimized_type_constraint { shift->{hand_optimized_type_constraint} }
1668              
1669             sub has_hand_optimized_type_constraint {
1670 1     1 1 10 exists( shift->{hand_optimized_type_constraint} );
1671             }
1672 207   50 207 1 1606 sub type_parameter { ( shift->parameters || [] )->[0] }
1673              
1674             sub parameterized_from {
1675 5 50   5 1 19 $_[0]->is_parameterized ? shift->parent : _croak( "Not a parameterized type" );
1676             }
1677 2     2 1 14 sub has_parameterized_from { $_[0]->is_parameterized }
1678              
1679             # some stuff for Mouse-compatible API
1680 2     2   16 sub __is_parameterized { shift->is_parameterized( @_ ) }
1681 1     1   11 sub _add_type_coercions { shift->coercion->add_type_coercions( @_ ) }
1682 1     1   667 sub _as_string { shift->qualified_name( @_ ) }
1683 1     1   3 sub _compiled_type_coercion { shift->coercion->compiled_coercion( @_ ) }
1684 2     2   643 sub _identity { Scalar::Util::refaddr( shift ) }
1685              
1686             sub _unite {
1687 1     1   488 require Type::Tiny::Union;
1688 1         6 "Type::Tiny::Union"->new( type_constraints => \@_ );
1689             }
1690              
1691             # Hooks for Type::Tie
1692             sub TIESCALAR {
1693 1     1   1573 require Type::Tie;
1694 1         6 unshift @_, 'Type::Tie::SCALAR';
1695 1         5 goto \&Type::Tie::SCALAR::TIESCALAR;
1696             }
1697              
1698             sub TIEARRAY {
1699 1     1   2565 require Type::Tie;
1700 1         4 unshift @_, 'Type::Tie::ARRAY';
1701 1         4 goto \&Type::Tie::ARRAY::TIEARRAY;
1702             }
1703              
1704             sub TIEHASH {
1705 1     1   2224 require Type::Tie;
1706 1         7 unshift @_, 'Type::Tie::HASH';
1707 1         4 goto \&Type::Tie::HASH::TIEHASH;
1708             }
1709              
1710             1;
1711              
1712             __END__