our
$VERSION
=
'0.50'
;
BEGIN {
local
$@ =
undef
;
my
$has_ref_util
=
eval
{
require
Ref::Util; Ref::Util->VERSION(
'0.112'
); 1 };
sub
_HAS_REF_UTIL () {
$has_ref_util
}
}
declare(
'Item'
,
inline
=>
sub
{
'1'
}
);
declare(
'Undef'
,
parent
=> t(
'Item'
),
inline
=>
sub
{
'!defined('
.
$_
[1] .
')'
;
}
);
declare(
'Defined'
,
parent
=> t(
'Item'
),
inline
=>
sub
{
'defined('
.
$_
[1] .
')'
;
}
);
declare(
'Bool'
,
parent
=> t(
'Item'
),
inline
=>
sub
{
return
sprintf
(
<<'EOF', ( $_[1] ) x 7 );
(
(
!ref( %s )
&& (
!defined( %s )
|| %s eq q{}
|| %s eq '1'
|| %s eq '0'
)
)
||
(
Scalar::Util::blessed( %s )
&& defined overload::Method( %s, 'bool' )
)
)
EOF
}
);
declare(
'Value'
,
parent
=> t(
'Defined'
),
inline
=>
sub
{
$_
[0]->parent->inline_check(
$_
[1] ) .
' && !ref('
.
$_
[1] .
')'
;
}
);
declare(
'Ref'
,
parent
=> t(
'Defined'
),
inline
=>
sub
{
'ref('
.
$_
[1] .
')'
}
);
declare(
'Str'
,
parent
=> t(
'Value'
),
inline
=>
sub
{
return
sprintf
(
<<'EOF', ( $_[1] ) x 6 );
(
(
defined( %s )
&& !ref( %s )
&& (
( ref( \%s ) eq 'SCALAR' )
|| do { ( ref( \( my $val = %s ) ) eq 'SCALAR' ) }
)
)
||
(
Scalar::Util::blessed( %s )
&& defined overload::Method( %s, q{""} )
)
)
EOF
}
);
declare(
'Num'
,
parent
=> t(
'Str'
),
inline
=>
sub
{
return
sprintf
(
<<'EOF', ( $_[1] ) x 5 );
(
(
defined( %s )
&& !ref( %s )
&& (
do {
( my $val = %s ) =~
/\A
-?[0-9]+(?:\.[0-9]+)?
(?:[Ee][\-+]?[0-9]+)?
\z/x
}
)
)
||
(
Scalar::Util::blessed( %s )
&& defined overload::Method( %s, '0+' )
)
)
EOF
}
);
declare(
'Int'
,
parent
=> t(
'Num'
),
inline
=>
sub
{
return
sprintf
(
<<'EOF', ( $_[1] ) x 6 );
(
(
defined( %s )
&& !ref( %s )
&& (
do {
my $val1 = %s;
$val1 =~ /\A-?[0-9]+(?:[Ee]\+?[0-9]+)?\z/
&& $val1 == int($val1)
}
)
)
||
(
Scalar::Util::blessed( %s )
&& defined overload::Method( %s, '0+' )
&& (
do {
my $val2 = %s + 0;
$val2 =~ /\A-?[0-9]+(?:[Ee]\+?[0-9]+)?\z/
&& $val2 == int($val2)
}
)
)
)
EOF
}
);
{
my
$ref_check
= _HAS_REF_UTIL
?
'Ref::Util::is_plain_coderef(%s)'
:
q{ref(%s) eq 'CODE'}
;
declare(
'CodeRef'
,
parent
=> t(
'Ref'
),
inline
=>
sub
{
return
sprintf
(
<<"EOF", ( $_[1] ) x 3 );
(
$ref_check
||
(
Scalar::Util::blessed( %s )
&& defined overload::Method( %s, '&{}' )
)
)
EOF
}
);
}
{
unless
(
exists
&re::is_regexp
|| _HAS_REF_UTIL ) {
*re::is_regexp
=
sub
{
eval
{ B::svref_2object(
$_
[0] )->MAGIC->TYPE eq
'r'
};
};
}
my
$ref_check
= _HAS_REF_UTIL
?
'Ref::Util::is_regexpref(%s)'
:
're::is_regexp(%s)'
;
declare(
'RegexpRef'
,
parent
=> t(
'Ref'
),
inline
=>
sub
{
return
sprintf
(
<<"EOF", ( $_[1] ) x 3 );
(
$ref_check
||
(
Scalar::Util::blessed( %s )
&& defined overload::Method( %s, 'qr' )
)
)
EOF
},
);
}
{
my
$ref_check
= _HAS_REF_UTIL
?
'Ref::Util::is_plain_globref(%s)'
:
q{ref( %s ) eq 'GLOB'}
;
declare(
'GlobRef'
,
parent
=> t(
'Ref'
),
inline
=>
sub
{
return
sprintf
(
<<"EOF", ( $_[1] ) x 3 );
(
$ref_check
||
(
Scalar::Util::blessed( %s )
&& defined overload::Method( %s, '*{}' )
)
)
EOF
}
);
}
{
my
$ref_check
= _HAS_REF_UTIL
?
'Ref::Util::is_plain_globref(%s)'
:
q{ref( %s ) eq 'GLOB'}
;
declare(
'FileHandle'
,
parent
=> t(
'Ref'
),
inline
=>
sub
{
return
sprintf
(
<<"EOF", ( $_[1] ) x 6 );
(
(
$ref_check
&& Scalar::Util::openhandle( %s )
)
||
(
Scalar::Util::blessed( %s )
&&
(
%s->isa('IO::Handle')
||
(
defined overload::Method( %s, '*{}' )
&& Scalar::Util::openhandle( *{ %s } )
)
)
)
)
EOF
}
);
}
{
my
$ref_check
= _HAS_REF_UTIL
?
'Ref::Util::is_blessed_ref(%s)'
:
'Scalar::Util::blessed(%s)'
;
declare(
'Object'
,
parent
=> t(
'Ref'
),
inline
=>
sub
{
sprintf
(
$ref_check
,
$_
[1] ) },
);
}
declare(
'ClassName'
,
parent
=> t(
'Str'
),
inline
=>
sub
{
return
sprintf
(
<<'EOF', $_[0]->parent->inline_check( $_[1] ), ( $_[1] ) x 2 );
(
( %s )
&& length "%s"
&& Specio::Helpers::is_class_loaded( "%s" )
)
EOF
},
);
{
my
$ref_check
= _HAS_REF_UTIL
?
'Ref::Util::is_plain_scalarref(%s) || Ref::Util::is_plain_refref(%s)'
:
q{ref( %s ) eq 'SCALAR' || ref( %s ) eq 'REF'}
;
my
$base_scalarref_check
=
sub
{
return
sprintf
(
<<"EOF", ( $_[0] ) x 4 );
(
(
$ref_check
)
||
(
Scalar::Util::blessed( %s )
&& defined overload::Method( %s, '\${}' )
)
)
EOF
};
declare(
'ScalarRef'
,
type_class
=>
'Specio::Constraint::Parameterizable'
,
parent
=> t(
'Ref'
),
inline
=>
sub
{
$base_scalarref_check
->(
$_
[1] ) },
parameterized_inline_generator
=>
sub
{
shift
;
my
$parameter
=
shift
;
my
$val
=
shift
;
return
sprintf
(
'( ( %s ) && ( %s ) )'
,
$base_scalarref_check
->(
$val
),
$parameter
->inline_check(
'${'
.
$val
.
'}'
),
);
}
);
}
{
my
$ref_check
= _HAS_REF_UTIL
?
'Ref::Util::is_plain_arrayref(%s)'
:
q{ref( %s ) eq 'ARRAY'}
;
my
$base_arrayref_check
=
sub
{
return
sprintf
(
<<"EOF", ( $_[0] ) x 3 );
(
$ref_check
||
(
Scalar::Util::blessed( %s )
&& defined overload::Method( %s, '\@{}' )
)
)
EOF
};
declare(
'ArrayRef'
,
type_class
=>
'Specio::Constraint::Parameterizable'
,
parent
=> t(
'Ref'
),
inline
=>
sub
{
$base_arrayref_check
->(
$_
[1] ) },
parameterized_inline_generator
=>
sub
{
shift
;
my
$parameter
=
shift
;
my
$val
=
shift
;
return
sprintf
(
'( ( %s ) && ( List::Util::all { %s } @{ %s } ) )'
,
$base_arrayref_check
->(
$val
),
$parameter
->inline_check(
'$_'
),
$val
,
);
}
);
}
{
my
$ref_check
= _HAS_REF_UTIL
?
'Ref::Util::is_plain_hashref(%s)'
:
q{ref( %s ) eq 'HASH'}
;
my
$base_hashref_check
=
sub
{
return
sprintf
(
<<"EOF", ( $_[0] ) x 3 );
(
$ref_check
||
(
Scalar::Util::blessed( %s )
&& defined overload::Method( %s, '%%{}' )
)
)
EOF
};
declare(
'HashRef'
,
type_class
=>
'Specio::Constraint::Parameterizable'
,
parent
=> t(
'Ref'
),
inline
=>
sub
{
$base_hashref_check
->(
$_
[1] ) },
parameterized_inline_generator
=>
sub
{
shift
;
my
$parameter
=
shift
;
my
$val
=
shift
;
return
sprintf
(
'( ( %s ) && ( List::Util::all { %s } values %%{ %s } ) )'
,
$base_hashref_check
->(
$val
),
$parameter
->inline_check(
'$_'
),
$val
,
);
}
);
}
declare(
'Maybe'
,
type_class
=>
'Specio::Constraint::Parameterizable'
,
parent
=> t(
'Item'
),
inline
=>
sub
{
'1'
},
parameterized_inline_generator
=>
sub
{
shift
;
my
$parameter
=
shift
;
my
$val
=
shift
;
return
sprintf
(
<<'EOF', $val, $parameter->inline_check($val) );
( !defined( %s ) || ( %s ) )
EOF
},
);
1;