view release on metacpan or search on metacpan
bench/is_extended.pl view on Meta::CPAN
#!/usr/bin/env perl
use strict;
use warnings;
use Benchmark qw(cmpthese);
use lib 'blib/lib', 'blib/arch';
use Scalar::Util qw(blessed looks_like_number);
use util qw(is_num is_int is_blessed is_scalar_ref is_regex is_glob);
print "=" x 60, "\n";
print "Extended Type Predicates Benchmark\n";
print "=" x 60, "\n\n";
my $num = 42.5;
my $int = 42;
my $str = "hello";
my $obj = bless {}, 'MyClass';
my $sref = \my $x;
my $regex = qr/foo/;
print "=== is_num ===\n";
cmpthese(-2, {
'util::is_num' => sub { is_num($num) },
'looks_like_number' => sub { looks_like_number($num) },
});
print "\n=== is_num (string) ===\n";
cmpthese(-2, {
'util::is_num' => sub { is_num($str) },
'looks_like_number' => sub { looks_like_number($str) },
});
print "\n=== is_int ===\n";
cmpthese(-2, {
'util::is_int' => sub { is_int($int) },
'pure_perl' => sub { $int == int($int) },
});
print "\n=== is_blessed ===\n";
cmpthese(-2, {
lib/object.pm view on Meta::CPAN
=head3 Complete Example
/* MyTypes.xs */
#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "object_types.h"
static bool check_positive_int(pTHX_ SV *val) {
if (!SvIOK(val) && !(SvPOK(val) && looks_like_number(val)))
return false;
return SvIV(val) > 0;
}
static bool check_email(pTHX_ SV *val) {
if (SvROK(val)) return false;
STRLEN len;
const char *pv = SvPV(val, len);
const char *at = memchr(pv, '@', len);
return at && at != pv && at != pv + len - 1;
lib/util.pm view on Meta::CPAN
if (is_hash($config)) { ... }
if (is_code($callback)) { ... }
if (is_defined($value)) { ... }
# Boolean/Truthiness predicates
if (is_true($value)) { ... } # Perl truth semantics
if (is_false($value)) { ... } # Perl false semantics
my $normalized = bool($value); # Normalize to 1 or ''
# Extended type predicates
if (is_num($value)) { ... } # Numeric value or looks like number
if (is_int($value)) { ... } # Integer value
if (is_blessed($obj)) { ... } # Blessed reference
if (is_scalar_ref($ref)) { ... } # Scalar reference
if (is_regex($qr)) { ... } # Compiled regex (qr//)
if (is_glob(*FH)) { ... } # Glob
# Numeric predicates
if (is_positive($num)) { ... } # > 0
if (is_negative($num)) { ... } # < 0
if (is_zero($num)) { ... } # == 0
lib/util.pm view on Meta::CPAN
=head1 EXTENDED TYPE PREDICATES
These functions use custom ops for extended type checking.
=head2 is_num
my $bool = is_num($value);
Returns true if C<$value> is numeric (has a numeric value or
looks like a number). Uses C<looks_like_number> for strings.
=head2 is_int
my $bool = is_int($value);
Returns true if C<$value> is an integer. Returns true for
whole number floats like 5.0.
=head2 is_blessed
t/1030-util-predicates-valid.t view on Meta::CPAN
# Numbers
ok(is_num(0), 'is_num: 0');
ok(is_num(42), 'is_num: positive int');
ok(is_num(-42), 'is_num: negative int');
ok(is_num(3.14), 'is_num: float');
ok(is_num(-3.14), 'is_num: negative float');
ok(is_num(1e10), 'is_num: scientific notation');
};
subtest 'is_num edge cases' => sub {
# String that looks like number
ok(is_num('42'), 'is_num: string 42');
ok(is_num('3.14'), 'is_num: string 3.14');
ok(is_num('-5'), 'is_num: string -5');
ok(is_num('1e10'), 'is_num: string scientific');
# Special values (Perl's looks_like_number considers these numeric)
ok(is_num(0.0), 'is_num: 0.0');
ok(is_num('NaN'), 'is_num: string NaN (Perl considers numeric)');
ok(is_num('inf'), 'is_num: string inf (Perl considers numeric)');
# Whitespace (Perl's looks_like_number accepts leading/trailing spaces)
ok(is_num(' 42 '), 'is_num: number with spaces (Perl accepts)');
ok(!is_num('42abc'), 'is_num: number with trailing text');
};
# ============================================
# is_int
# ============================================
subtest 'is_int basic' => sub {
# Not integers
t/1030-util-predicates-valid.t view on Meta::CPAN
# Normalize to true (1)
is(bool(1), 1, 'bool: 1 -> 1');
is(bool(-1), 1, 'bool: -1 -> 1');
is(bool('hello'), 1, 'bool: string -> 1');
is(bool([]), 1, 'bool: array -> 1');
is(bool({}), 1, 'bool: hash -> 1');
};
subtest 'is_true/is_false edge cases' => sub {
# String that looks numeric
ok(is_true('00'), 'is_true: string 00 is true');
ok(is_true('0.0'), 'is_true: string 0.0 is true');
ok(is_true('0e0'), 'is_true: string 0e0 is true');
# Numeric zero variations
ok(!is_true(0.0), 'is_true: 0.0 is false');
ok(!is_true(-0), 'is_true: -0 is false');
# Whitespace
ok(is_true(' '), 'is_true: space is true');
t/4006-object-types-custom.t view on Meta::CPAN
# ==== Test XS-level type registration API ====
# This tests the Perl-level API, but demonstrates the pattern
# that XS modules would use at the C level
# The C-level API works like this (in an external .xs file):
#
# #include "object_types.h"
#
# static bool check_positive_int(pTHX_ SV *val) {
# if (!SvIOK(val) && !looks_like_number(val)) return false;
# return SvIV(val) > 0;
# }
#
# BOOT:
# object_register_type_xs(aTHX_ "PositiveInt", check_positive_int, NULL);
#
# The registered C function is called directly from the setter op
# with no Perl callback overhead (~5 cycles vs ~100 cycles)
# For now, test with Perl callbacks (same flow, different overhead)
t/4007-object-edge-cases.t view on Meta::CPAN
$obj->num(-999);
is($obj->num, -999, 'Int accepts negative');
$obj->num(999999999);
is($obj->num, 999999999, 'Int accepts large positive');
# Float should be rejected or truncated
eval { $obj->num(3.14) };
like($@, qr/Type constraint failed/, 'Int rejects float');
# String that looks like int
$obj->num('42');
is($obj->num, '42', 'Int accepts numeric string');
eval { $obj->num('42.5') };
like($@, qr/Type constraint failed/, 'Int rejects decimal string');
};
# ==== Num Edge Cases ====
subtest 'Num edge cases' => sub {
xs/const/const.c view on Meta::CPAN
SV *val = cSVOPx_sv(argop);
SV *newval = newSVsv(val);
OP *markerop;
/* Make it deeply readonly if it's a reference */
if (SvROK(newval)) {
_make_readonly(aTHX_ SvRV(newval));
}
SvREADONLY_on(newval);
/* Create a custom op that looks like SVOP but uses our pp func */
markerop = newSVOP(OP_CUSTOM, 0, newval);
markerop->op_ppaddr = pp_confold_marker;
op_free(entersubop);
return markerop;
}
/* Non-constant arg - fall through to XS for runtime evaluation */
}
/* Fall through to XS implementation */
xs/const/ppport.h view on Meta::CPAN
}
usage() if $opt{help};
strip() if $opt{strip};
$opt{'compat-version'} = 5.003_07 unless exists $opt{'compat-version'};
$opt{'compat-version'} = int_parse_version($opt{'compat-version'});
my $int_min_perl = int_parse_version(5.003_07);
# Each element of this hash looks something like:
# 'Poison' => {
# 'base' => '5.008000',
# 'provided' => 1,
# 'todo' => '5.003007'
# },
my %API = map { /^(\w+)\|([^|]*)\|([^|]*)\|(\w*)$/
? ( $1 => {
($2 ? ( base => $2 ) : ()),
($3 ? ( todo => $3 ) : ()),
(index($4, 'v') >= 0 ? ( varargs => 1 ) : ()),
xs/const/ppport.h view on Meta::CPAN
LONGJMP_tb_pb|5.033003||Viu
LONGLONGSIZE|5.005000|5.005000|Vn
LONGSIZE|5.004000|5.003007|oVn
LOOKBEHIND_END_t8_p8|||Viu
LOOKBEHIND_END_t8_pb|||Viu
LOOKBEHIND_END_t8|||Viu
LOOKBEHIND_END_tb_p8|||Viu
LOOKBEHIND_END_tb_pb|||Viu
LOOKBEHIND_END_tb|||Viu
LOOKBEHIND_END|||Viu
looks_like_bool|5.027008||Viu
looks_like_number|5.003007|5.003007|
LOOP_PAT_MODS|5.009005||Viu
lop|5.005000||Viu
lossless_NV_to_IV|5.031001||Vniu
LOWEST_ANYOF_HRx_BYTE|5.031002||Viu
L_R_TZSET|5.009005|5.009005|Vn
lsbit_pos32|5.035003||cVnu
lsbit_pos|5.035004||Viu
lsbit_pos64|5.035003||cVnu
lsbit_pos_uintmax|5.035003||Viu
lseek|5.005000||Viu
xs/const/ppport.h view on Meta::CPAN
# define D_PPP_TO_FOLD_CALLEE(s,r,l) \
Perl__to_utf8_fold_flags(aTHX_ s, r, l, FOLD_FLAGS_FULL, NULL)
# endif
/* The actual implementation of the backported macros. If too short, croak,
* otherwise call the original that doesn't have an upper limit parameter */
# define D_PPP_GENERIC_MULTI_ARG_TO(name, s, e,r,l) \
(((((e) - (s)) <= 0) \
/* We could just do nothing, but modern perls croak */ \
? (croak("Attempting case change on zero length string"), \
0) /* So looks like it returns something, and will compile */ \
: ((e) - (s)) < UTF8SKIP(s)) \
? (croak(D_PPP_TOO_SHORT_MSG, \
s[0], (int) ((e) - (s)), (int) UTF8SKIP(s)), \
0) \
: D_PPP_TO_ ## name ## _CALLEE(s,r,l))
#ifndef toUPPER_utf8_safe
# define toUPPER_utf8_safe(s,e,r,l) \
D_PPP_GENERIC_MULTI_ARG_TO(UPPER,s,e,r,l)
#endif
xs/const/ppport.h view on Meta::CPAN
D_PPP_GENERIC_SINGLE_ARG_TO_UVCHR(title, c, s, l)
#endif
#ifndef toFOLD_uvchr
# define toFOLD_uvchr(c, s, l) toLOWER_uvchr(c, s, l)
#endif
# define D_PPP_GENERIC_SINGLE_ARG_TO_UTF8(name, s, e, r, l) \
(((((e) - (s)) <= 0) \
? (croak("Attempting case change on zero length string"), \
0) /* So looks like it returns something, and will compile */ \
: ((e) - (s)) < UTF8SKIP(s)) \
? (croak(D_PPP_TOO_SHORT_MSG, \
s[0], (int) ((e) - (s)), (int) UTF8SKIP(s)), \
0) \
/* Get the changed code point and store its UTF-8 */ \
: D_PPP_UV_TO_UTF8(r, to_utf8_ ## name(s)), \
/* Then store its length, and re-get code point for return */ \
*(l) = UTF8SKIP(r), to_utf8_ ## name(r))
/* Warning: toUPPER_utf8_safe, toLOWER_utf8_safe, toTITLE_utf8_safe,
xs/doubly/ppport.h view on Meta::CPAN
}
usage() if $opt{help};
strip() if $opt{strip};
$opt{'compat-version'} = 5.003_07 unless exists $opt{'compat-version'};
$opt{'compat-version'} = int_parse_version($opt{'compat-version'});
my $int_min_perl = int_parse_version(5.003_07);
# Each element of this hash looks something like:
# 'Poison' => {
# 'base' => '5.008000',
# 'provided' => 1,
# 'todo' => '5.003007'
# },
my %API = map { /^(\w+)\|([^|]*)\|([^|]*)\|(\w*)$/
? ( $1 => {
($2 ? ( base => $2 ) : ()),
($3 ? ( todo => $3 ) : ()),
(index($4, 'v') >= 0 ? ( varargs => 1 ) : ()),
xs/doubly/ppport.h view on Meta::CPAN
LONGJMP_tb_pb|5.033003||Viu
LONGLONGSIZE|5.005000|5.005000|Vn
LONGSIZE|5.004000|5.003007|oVn
LOOKBEHIND_END_t8_p8|||Viu
LOOKBEHIND_END_t8_pb|||Viu
LOOKBEHIND_END_t8|||Viu
LOOKBEHIND_END_tb_p8|||Viu
LOOKBEHIND_END_tb_pb|||Viu
LOOKBEHIND_END_tb|||Viu
LOOKBEHIND_END|||Viu
looks_like_bool|5.027008||Viu
looks_like_number|5.003007|5.003007|
LOOP_PAT_MODS|5.009005||Viu
lop|5.005000||Viu
lossless_NV_to_IV|5.031001||Vniu
LOWEST_ANYOF_HRx_BYTE|5.031002||Viu
L_R_TZSET|5.009005|5.009005|Vn
lsbit_pos32|5.035003||cVnu
lsbit_pos|5.035004||Viu
lsbit_pos64|5.035003||cVnu
lsbit_pos_uintmax|5.035003||Viu
lseek|5.005000||Viu
xs/doubly/ppport.h view on Meta::CPAN
# define D_PPP_TO_FOLD_CALLEE(s,r,l) \
Perl__to_utf8_fold_flags(aTHX_ s, r, l, FOLD_FLAGS_FULL, NULL)
# endif
/* The actual implementation of the backported macros. If too short, croak,
* otherwise call the original that doesn't have an upper limit parameter */
# define D_PPP_GENERIC_MULTI_ARG_TO(name, s, e,r,l) \
(((((e) - (s)) <= 0) \
/* We could just do nothing, but modern perls croak */ \
? (croak("Attempting case change on zero length string"), \
0) /* So looks like it returns something, and will compile */ \
: ((e) - (s)) < UTF8SKIP(s)) \
? (croak(D_PPP_TOO_SHORT_MSG, \
s[0], (int) ((e) - (s)), (int) UTF8SKIP(s)), \
0) \
: D_PPP_TO_ ## name ## _CALLEE(s,r,l))
#ifndef toUPPER_utf8_safe
# define toUPPER_utf8_safe(s,e,r,l) \
D_PPP_GENERIC_MULTI_ARG_TO(UPPER,s,e,r,l)
#endif
xs/doubly/ppport.h view on Meta::CPAN
D_PPP_GENERIC_SINGLE_ARG_TO_UVCHR(title, c, s, l)
#endif
#ifndef toFOLD_uvchr
# define toFOLD_uvchr(c, s, l) toLOWER_uvchr(c, s, l)
#endif
# define D_PPP_GENERIC_SINGLE_ARG_TO_UTF8(name, s, e, r, l) \
(((((e) - (s)) <= 0) \
? (croak("Attempting case change on zero length string"), \
0) /* So looks like it returns something, and will compile */ \
: ((e) - (s)) < UTF8SKIP(s)) \
? (croak(D_PPP_TOO_SHORT_MSG, \
s[0], (int) ((e) - (s)), (int) UTF8SKIP(s)), \
0) \
/* Get the changed code point and store its UTF-8 */ \
: D_PPP_UV_TO_UTF8(r, to_utf8_ ## name(s)), \
/* Then store its length, and re-get code point for return */ \
*(l) = UTF8SKIP(r), to_utf8_ ## name(r))
/* Warning: toUPPER_utf8_safe, toLOWER_utf8_safe, toTITLE_utf8_safe,
xs/file/ppport.h view on Meta::CPAN
}
usage() if $opt{help};
strip() if $opt{strip};
$opt{'compat-version'} = 5.003_07 unless exists $opt{'compat-version'};
$opt{'compat-version'} = int_parse_version($opt{'compat-version'});
my $int_min_perl = int_parse_version(5.003_07);
# Each element of this hash looks something like:
# 'Poison' => {
# 'base' => '5.008000',
# 'provided' => 1,
# 'todo' => '5.003007'
# },
my %API = map { /^(\w+)\|([^|]*)\|([^|]*)\|(\w*)$/
? ( $1 => {
($2 ? ( base => $2 ) : ()),
($3 ? ( todo => $3 ) : ()),
(index($4, 'v') >= 0 ? ( varargs => 1 ) : ()),
xs/file/ppport.h view on Meta::CPAN
LONGJMP_tb_pb|5.033003||Viu
LONGLONGSIZE|5.005000|5.005000|Vn
LONGSIZE|5.004000|5.003007|oVn
LOOKBEHIND_END_t8_p8|||Viu
LOOKBEHIND_END_t8_pb|||Viu
LOOKBEHIND_END_t8|||Viu
LOOKBEHIND_END_tb_p8|||Viu
LOOKBEHIND_END_tb_pb|||Viu
LOOKBEHIND_END_tb|||Viu
LOOKBEHIND_END|||Viu
looks_like_bool|5.027008||Viu
looks_like_number|5.003007|5.003007|
LOOP_PAT_MODS|5.009005||Viu
lop|5.005000||Viu
lossless_NV_to_IV|5.031001||Vniu
LOWEST_ANYOF_HRx_BYTE|5.031002||Viu
L_R_TZSET|5.009005|5.009005|Vn
lsbit_pos32|5.035003||cVnu
lsbit_pos|5.035004||Viu
lsbit_pos64|5.035003||cVnu
lsbit_pos_uintmax|5.035003||Viu
lseek|5.005000||Viu
xs/file/ppport.h view on Meta::CPAN
# define D_PPP_TO_FOLD_CALLEE(s,r,l) \
Perl__to_utf8_fold_flags(aTHX_ s, r, l, FOLD_FLAGS_FULL, NULL)
# endif
/* The actual implementation of the backported macros. If too short, croak,
* otherwise call the original that doesn't have an upper limit parameter */
# define D_PPP_GENERIC_MULTI_ARG_TO(name, s, e,r,l) \
(((((e) - (s)) <= 0) \
/* We could just do nothing, but modern perls croak */ \
? (croak("Attempting case change on zero length string"), \
0) /* So looks like it returns something, and will compile */ \
: ((e) - (s)) < UTF8SKIP(s)) \
? (croak(D_PPP_TOO_SHORT_MSG, \
s[0], (int) ((e) - (s)), (int) UTF8SKIP(s)), \
0) \
: D_PPP_TO_ ## name ## _CALLEE(s,r,l))
#ifndef toUPPER_utf8_safe
# define toUPPER_utf8_safe(s,e,r,l) \
D_PPP_GENERIC_MULTI_ARG_TO(UPPER,s,e,r,l)
#endif
xs/file/ppport.h view on Meta::CPAN
D_PPP_GENERIC_SINGLE_ARG_TO_UVCHR(title, c, s, l)
#endif
#ifndef toFOLD_uvchr
# define toFOLD_uvchr(c, s, l) toLOWER_uvchr(c, s, l)
#endif
# define D_PPP_GENERIC_SINGLE_ARG_TO_UTF8(name, s, e, r, l) \
(((((e) - (s)) <= 0) \
? (croak("Attempting case change on zero length string"), \
0) /* So looks like it returns something, and will compile */ \
: ((e) - (s)) < UTF8SKIP(s)) \
? (croak(D_PPP_TOO_SHORT_MSG, \
s[0], (int) ((e) - (s)), (int) UTF8SKIP(s)), \
0) \
/* Get the changed code point and store its UTF-8 */ \
: D_PPP_UV_TO_UTF8(r, to_utf8_ ## name(s)), \
/* Then store its length, and re-get code point for return */ \
*(l) = UTF8SKIP(r), to_utf8_ ## name(r))
/* Warning: toUPPER_utf8_safe, toLOWER_utf8_safe, toTITLE_utf8_safe,
xs/heap/ppport.h view on Meta::CPAN
}
usage() if $opt{help};
strip() if $opt{strip};
$opt{'compat-version'} = 5.003_07 unless exists $opt{'compat-version'};
$opt{'compat-version'} = int_parse_version($opt{'compat-version'});
my $int_min_perl = int_parse_version(5.003_07);
# Each element of this hash looks something like:
# 'Poison' => {
# 'base' => '5.008000',
# 'provided' => 1,
# 'todo' => '5.003007'
# },
my %API = map { /^(\w+)\|([^|]*)\|([^|]*)\|(\w*)$/
? ( $1 => {
($2 ? ( base => $2 ) : ()),
($3 ? ( todo => $3 ) : ()),
(index($4, 'v') >= 0 ? ( varargs => 1 ) : ()),
xs/heap/ppport.h view on Meta::CPAN
LONGJMP_tb_pb|5.033003||Viu
LONGLONGSIZE|5.005000|5.005000|Vn
LONGSIZE|5.004000|5.003007|oVn
LOOKBEHIND_END_t8_p8|||Viu
LOOKBEHIND_END_t8_pb|||Viu
LOOKBEHIND_END_t8|||Viu
LOOKBEHIND_END_tb_p8|||Viu
LOOKBEHIND_END_tb_pb|||Viu
LOOKBEHIND_END_tb|||Viu
LOOKBEHIND_END|||Viu
looks_like_bool|5.027008||Viu
looks_like_number|5.003007|5.003007|
LOOP_PAT_MODS|5.009005||Viu
lop|5.005000||Viu
lossless_NV_to_IV|5.031001||Vniu
LOWEST_ANYOF_HRx_BYTE|5.031002||Viu
L_R_TZSET|5.009005|5.009005|Vn
lsbit_pos32|5.035003||cVnu
lsbit_pos|5.035004||Viu
lsbit_pos64|5.035003||cVnu
lsbit_pos_uintmax|5.035003||Viu
lseek|5.005000||Viu
xs/heap/ppport.h view on Meta::CPAN
# define D_PPP_TO_FOLD_CALLEE(s,r,l) \
Perl__to_utf8_fold_flags(aTHX_ s, r, l, FOLD_FLAGS_FULL, NULL)
# endif
/* The actual implementation of the backported macros. If too short, croak,
* otherwise call the original that doesn't have an upper limit parameter */
# define D_PPP_GENERIC_MULTI_ARG_TO(name, s, e,r,l) \
(((((e) - (s)) <= 0) \
/* We could just do nothing, but modern perls croak */ \
? (croak("Attempting case change on zero length string"), \
0) /* So looks like it returns something, and will compile */ \
: ((e) - (s)) < UTF8SKIP(s)) \
? (croak(D_PPP_TOO_SHORT_MSG, \
s[0], (int) ((e) - (s)), (int) UTF8SKIP(s)), \
0) \
: D_PPP_TO_ ## name ## _CALLEE(s,r,l))
#ifndef toUPPER_utf8_safe
# define toUPPER_utf8_safe(s,e,r,l) \
D_PPP_GENERIC_MULTI_ARG_TO(UPPER,s,e,r,l)
#endif
xs/heap/ppport.h view on Meta::CPAN
D_PPP_GENERIC_SINGLE_ARG_TO_UVCHR(title, c, s, l)
#endif
#ifndef toFOLD_uvchr
# define toFOLD_uvchr(c, s, l) toLOWER_uvchr(c, s, l)
#endif
# define D_PPP_GENERIC_SINGLE_ARG_TO_UTF8(name, s, e, r, l) \
(((((e) - (s)) <= 0) \
? (croak("Attempting case change on zero length string"), \
0) /* So looks like it returns something, and will compile */ \
: ((e) - (s)) < UTF8SKIP(s)) \
? (croak(D_PPP_TOO_SHORT_MSG, \
s[0], (int) ((e) - (s)), (int) UTF8SKIP(s)), \
0) \
/* Get the changed code point and store its UTF-8 */ \
: D_PPP_UV_TO_UTF8(r, to_utf8_ ## name(s)), \
/* Then store its length, and re-get code point for return */ \
*(l) = UTF8SKIP(r), to_utf8_ ## name(r))
/* Warning: toUPPER_utf8_safe, toLOWER_utf8_safe, toTITLE_utf8_safe,
xs/lru/ppport.h view on Meta::CPAN
}
usage() if $opt{help};
strip() if $opt{strip};
$opt{'compat-version'} = 5.003_07 unless exists $opt{'compat-version'};
$opt{'compat-version'} = int_parse_version($opt{'compat-version'});
my $int_min_perl = int_parse_version(5.003_07);
# Each element of this hash looks something like:
# 'Poison' => {
# 'base' => '5.008000',
# 'provided' => 1,
# 'todo' => '5.003007'
# },
my %API = map { /^(\w+)\|([^|]*)\|([^|]*)\|(\w*)$/
? ( $1 => {
($2 ? ( base => $2 ) : ()),
($3 ? ( todo => $3 ) : ()),
(index($4, 'v') >= 0 ? ( varargs => 1 ) : ()),
xs/lru/ppport.h view on Meta::CPAN
LONGJMP_tb_pb|5.033003||Viu
LONGLONGSIZE|5.005000|5.005000|Vn
LONGSIZE|5.004000|5.003007|oVn
LOOKBEHIND_END_t8_p8|||Viu
LOOKBEHIND_END_t8_pb|||Viu
LOOKBEHIND_END_t8|||Viu
LOOKBEHIND_END_tb_p8|||Viu
LOOKBEHIND_END_tb_pb|||Viu
LOOKBEHIND_END_tb|||Viu
LOOKBEHIND_END|||Viu
looks_like_bool|5.027008||Viu
looks_like_number|5.003007|5.003007|
LOOP_PAT_MODS|5.009005||Viu
lop|5.005000||Viu
lossless_NV_to_IV|5.031001||Vniu
LOWEST_ANYOF_HRx_BYTE|5.031002||Viu
L_R_TZSET|5.009005|5.009005|Vn
lsbit_pos32|5.035003||cVnu
lsbit_pos|5.035004||Viu
lsbit_pos64|5.035003||cVnu
lsbit_pos_uintmax|5.035003||Viu
lseek|5.005000||Viu
xs/lru/ppport.h view on Meta::CPAN
# define D_PPP_TO_FOLD_CALLEE(s,r,l) \
Perl__to_utf8_fold_flags(aTHX_ s, r, l, FOLD_FLAGS_FULL, NULL)
# endif
/* The actual implementation of the backported macros. If too short, croak,
* otherwise call the original that doesn't have an upper limit parameter */
# define D_PPP_GENERIC_MULTI_ARG_TO(name, s, e,r,l) \
(((((e) - (s)) <= 0) \
/* We could just do nothing, but modern perls croak */ \
? (croak("Attempting case change on zero length string"), \
0) /* So looks like it returns something, and will compile */ \
: ((e) - (s)) < UTF8SKIP(s)) \
? (croak(D_PPP_TOO_SHORT_MSG, \
s[0], (int) ((e) - (s)), (int) UTF8SKIP(s)), \
0) \
: D_PPP_TO_ ## name ## _CALLEE(s,r,l))
#ifndef toUPPER_utf8_safe
# define toUPPER_utf8_safe(s,e,r,l) \
D_PPP_GENERIC_MULTI_ARG_TO(UPPER,s,e,r,l)
#endif
xs/lru/ppport.h view on Meta::CPAN
D_PPP_GENERIC_SINGLE_ARG_TO_UVCHR(title, c, s, l)
#endif
#ifndef toFOLD_uvchr
# define toFOLD_uvchr(c, s, l) toLOWER_uvchr(c, s, l)
#endif
# define D_PPP_GENERIC_SINGLE_ARG_TO_UTF8(name, s, e, r, l) \
(((((e) - (s)) <= 0) \
? (croak("Attempting case change on zero length string"), \
0) /* So looks like it returns something, and will compile */ \
: ((e) - (s)) < UTF8SKIP(s)) \
? (croak(D_PPP_TOO_SHORT_MSG, \
s[0], (int) ((e) - (s)), (int) UTF8SKIP(s)), \
0) \
/* Get the changed code point and store its UTF-8 */ \
: D_PPP_UV_TO_UTF8(r, to_utf8_ ## name(s)), \
/* Then store its length, and re-get code point for return */ \
*(l) = UTF8SKIP(r), to_utf8_ ## name(r))
/* Warning: toUPPER_utf8_safe, toLOWER_utf8_safe, toTITLE_utf8_safe,
xs/noop/ppport.h view on Meta::CPAN
}
usage() if $opt{help};
strip() if $opt{strip};
$opt{'compat-version'} = 5.003_07 unless exists $opt{'compat-version'};
$opt{'compat-version'} = int_parse_version($opt{'compat-version'});
my $int_min_perl = int_parse_version(5.003_07);
# Each element of this hash looks something like:
# 'Poison' => {
# 'base' => '5.008000',
# 'provided' => 1,
# 'todo' => '5.003007'
# },
my %API = map { /^(\w+)\|([^|]*)\|([^|]*)\|(\w*)$/
? ( $1 => {
($2 ? ( base => $2 ) : ()),
($3 ? ( todo => $3 ) : ()),
(index($4, 'v') >= 0 ? ( varargs => 1 ) : ()),
xs/noop/ppport.h view on Meta::CPAN
LONGJMP_tb_pb|5.033003||Viu
LONGLONGSIZE|5.005000|5.005000|Vn
LONGSIZE|5.004000|5.003007|oVn
LOOKBEHIND_END_t8_p8|||Viu
LOOKBEHIND_END_t8_pb|||Viu
LOOKBEHIND_END_t8|||Viu
LOOKBEHIND_END_tb_p8|||Viu
LOOKBEHIND_END_tb_pb|||Viu
LOOKBEHIND_END_tb|||Viu
LOOKBEHIND_END|||Viu
looks_like_bool|5.027008||Viu
looks_like_number|5.003007|5.003007|
LOOP_PAT_MODS|5.009005||Viu
lop|5.005000||Viu
lossless_NV_to_IV|5.031001||Vniu
LOWEST_ANYOF_HRx_BYTE|5.031002||Viu
L_R_TZSET|5.009005|5.009005|Vn
lsbit_pos32|5.035003||cVnu
lsbit_pos|5.035004||Viu
lsbit_pos64|5.035003||cVnu
lsbit_pos_uintmax|5.035003||Viu
lseek|5.005000||Viu
xs/noop/ppport.h view on Meta::CPAN
# define D_PPP_TO_FOLD_CALLEE(s,r,l) \
Perl__to_utf8_fold_flags(aTHX_ s, r, l, FOLD_FLAGS_FULL, NULL)
# endif
/* The actual implementation of the backported macros. If too short, croak,
* otherwise call the original that doesn't have an upper limit parameter */
# define D_PPP_GENERIC_MULTI_ARG_TO(name, s, e,r,l) \
(((((e) - (s)) <= 0) \
/* We could just do nothing, but modern perls croak */ \
? (croak("Attempting case change on zero length string"), \
0) /* So looks like it returns something, and will compile */ \
: ((e) - (s)) < UTF8SKIP(s)) \
? (croak(D_PPP_TOO_SHORT_MSG, \
s[0], (int) ((e) - (s)), (int) UTF8SKIP(s)), \
0) \
: D_PPP_TO_ ## name ## _CALLEE(s,r,l))
#ifndef toUPPER_utf8_safe
# define toUPPER_utf8_safe(s,e,r,l) \
D_PPP_GENERIC_MULTI_ARG_TO(UPPER,s,e,r,l)
#endif
xs/noop/ppport.h view on Meta::CPAN
D_PPP_GENERIC_SINGLE_ARG_TO_UVCHR(title, c, s, l)
#endif
#ifndef toFOLD_uvchr
# define toFOLD_uvchr(c, s, l) toLOWER_uvchr(c, s, l)
#endif
# define D_PPP_GENERIC_SINGLE_ARG_TO_UTF8(name, s, e, r, l) \
(((((e) - (s)) <= 0) \
? (croak("Attempting case change on zero length string"), \
0) /* So looks like it returns something, and will compile */ \
: ((e) - (s)) < UTF8SKIP(s)) \
? (croak(D_PPP_TOO_SHORT_MSG, \
s[0], (int) ((e) - (s)), (int) UTF8SKIP(s)), \
0) \
/* Get the changed code point and store its UTF-8 */ \
: D_PPP_UV_TO_UTF8(r, to_utf8_ ## name(s)), \
/* Then store its length, and re-get code point for return */ \
*(l) = UTF8SKIP(r), to_utf8_ ## name(r))
/* Warning: toUPPER_utf8_safe, toLOWER_utf8_safe, toTITLE_utf8_safe,
xs/nvec/ppport.h view on Meta::CPAN
}
usage() if $opt{help};
strip() if $opt{strip};
$opt{'compat-version'} = 5.003_07 unless exists $opt{'compat-version'};
$opt{'compat-version'} = int_parse_version($opt{'compat-version'});
my $int_min_perl = int_parse_version(5.003_07);
# Each element of this hash looks something like:
# 'Poison' => {
# 'base' => '5.008000',
# 'provided' => 1,
# 'todo' => '5.003007'
# },
my %API = map { /^(\w+)\|([^|]*)\|([^|]*)\|(\w*)$/
? ( $1 => {
($2 ? ( base => $2 ) : ()),
($3 ? ( todo => $3 ) : ()),
(index($4, 'v') >= 0 ? ( varargs => 1 ) : ()),
xs/nvec/ppport.h view on Meta::CPAN
LONGJMP_tb_pb|5.033003||Viu
LONGLONGSIZE|5.005000|5.005000|Vn
LONGSIZE|5.004000|5.003007|oVn
LOOKBEHIND_END_t8_p8|||Viu
LOOKBEHIND_END_t8_pb|||Viu
LOOKBEHIND_END_t8|||Viu
LOOKBEHIND_END_tb_p8|||Viu
LOOKBEHIND_END_tb_pb|||Viu
LOOKBEHIND_END_tb|||Viu
LOOKBEHIND_END|||Viu
looks_like_bool|5.027008||Viu
looks_like_number|5.003007|5.003007|
LOOP_PAT_MODS|5.009005||Viu
lop|5.005000||Viu
lossless_NV_to_IV|5.031001||Vniu
LOWEST_ANYOF_HRx_BYTE|5.031002||Viu
L_R_TZSET|5.009005|5.009005|Vn
lsbit_pos32|5.035003||cVnu
lsbit_pos|5.035004||Viu
lsbit_pos64|5.035003||cVnu
lsbit_pos_uintmax|5.035003||Viu
lseek|5.005000||Viu
xs/nvec/ppport.h view on Meta::CPAN
# define D_PPP_TO_FOLD_CALLEE(s,r,l) \
Perl__to_utf8_fold_flags(aTHX_ s, r, l, FOLD_FLAGS_FULL, NULL)
# endif
/* The actual implementation of the backported macros. If too short, croak,
* otherwise call the original that doesn't have an upper limit parameter */
# define D_PPP_GENERIC_MULTI_ARG_TO(name, s, e,r,l) \
(((((e) - (s)) <= 0) \
/* We could just do nothing, but modern perls croak */ \
? (croak("Attempting case change on zero length string"), \
0) /* So looks like it returns something, and will compile */ \
: ((e) - (s)) < UTF8SKIP(s)) \
? (croak(D_PPP_TOO_SHORT_MSG, \
s[0], (int) ((e) - (s)), (int) UTF8SKIP(s)), \
0) \
: D_PPP_TO_ ## name ## _CALLEE(s,r,l))
#ifndef toUPPER_utf8_safe
# define toUPPER_utf8_safe(s,e,r,l) \
D_PPP_GENERIC_MULTI_ARG_TO(UPPER,s,e,r,l)
#endif
xs/nvec/ppport.h view on Meta::CPAN
D_PPP_GENERIC_SINGLE_ARG_TO_UVCHR(title, c, s, l)
#endif
#ifndef toFOLD_uvchr
# define toFOLD_uvchr(c, s, l) toLOWER_uvchr(c, s, l)
#endif
# define D_PPP_GENERIC_SINGLE_ARG_TO_UTF8(name, s, e, r, l) \
(((((e) - (s)) <= 0) \
? (croak("Attempting case change on zero length string"), \
0) /* So looks like it returns something, and will compile */ \
: ((e) - (s)) < UTF8SKIP(s)) \
? (croak(D_PPP_TOO_SHORT_MSG, \
s[0], (int) ((e) - (s)), (int) UTF8SKIP(s)), \
0) \
/* Get the changed code point and store its UTF-8 */ \
: D_PPP_UV_TO_UTF8(r, to_utf8_ ## name(s)), \
/* Then store its length, and re-get code point for return */ \
*(l) = UTF8SKIP(r), to_utf8_ ## name(r))
/* Warning: toUPPER_utf8_safe, toLOWER_utf8_safe, toTITLE_utf8_safe,
xs/object/object.c view on Meta::CPAN
return true;
case TYPE_DEFINED:
/* SvOK checks if defined, but be defensive for older Perls */
/* where constant 0 might have edge cases */
return SvOK(val) || SvIOK(val) || SvNOK(val) || SvPOK(val);
case TYPE_STR:
return SvOK(val) && !SvROK(val); /* defined non-ref */
case TYPE_INT:
if (SvIOK(val)) return true;
if (SvPOK(val)) {
/* String that looks like integer */
STRLEN len;
const char *pv;
const char *p;
pv = SvPV(val, len);
if (len == 0) return false;
p = pv;
if (*p == '-' || *p == '+') p++;
while (*p && *p >= '0' && *p <= '9') p++;
return p == pv + len;
}
return false;
case TYPE_NUM:
return SvNIOK(val) || (SvPOK(val) && looks_like_number(val));
case TYPE_BOOL:
/* Accept 0, 1, "", or boolean SVs */
if (SvIOK(val)) {
IV iv = SvIV(val);
return iv == 0 || iv == 1;
}
return SvTRUE(val) || !SvOK(val) || (SvPOK(val) && SvCUR(val) == 0);
case TYPE_ARRAYREF:
return SvROK(val) && SvTYPE(SvRV(val)) == SVt_PVAV;
case TYPE_HASHREF:
xs/object/object_types.h view on Meta::CPAN
* object_types.h - Type registration API for external XS modules
*
* Include this header in your XS module to register optimized C-level
* type checks that bypass Perl callback overhead entirely.
*
* Usage in your .xs file:
*
* #include "object_types.h"
*
* static bool check_positive_int(pTHX_ SV *val) {
* if (!SvIOK(val) && !looks_like_number(val)) return false;
* return SvIV(val) > 0;
* }
*
* static bool check_email(pTHX_ SV *val) {
* if (SvROK(val)) return false;
* STRLEN len;
* const char *pv = SvPV(val, len);
* return memchr(pv, '@', len) != NULL;
* }
*
xs/object/ppport.h view on Meta::CPAN
}
usage() if $opt{help};
strip() if $opt{strip};
$opt{'compat-version'} = 5.003_07 unless exists $opt{'compat-version'};
$opt{'compat-version'} = int_parse_version($opt{'compat-version'});
my $int_min_perl = int_parse_version(5.003_07);
# Each element of this hash looks something like:
# 'Poison' => {
# 'base' => '5.008000',
# 'provided' => 1,
# 'todo' => '5.003007'
# },
my %API = map { /^(\w+)\|([^|]*)\|([^|]*)\|(\w*)$/
? ( $1 => {
($2 ? ( base => $2 ) : ()),
($3 ? ( todo => $3 ) : ()),
(index($4, 'v') >= 0 ? ( varargs => 1 ) : ()),
xs/object/ppport.h view on Meta::CPAN
LONGJMP_tb_pb|5.033003||Viu
LONGLONGSIZE|5.005000|5.005000|Vn
LONGSIZE|5.004000|5.003007|oVn
LOOKBEHIND_END_t8_p8|||Viu
LOOKBEHIND_END_t8_pb|||Viu
LOOKBEHIND_END_t8|||Viu
LOOKBEHIND_END_tb_p8|||Viu
LOOKBEHIND_END_tb_pb|||Viu
LOOKBEHIND_END_tb|||Viu
LOOKBEHIND_END|||Viu
looks_like_bool|5.027008||Viu
looks_like_number|5.003007|5.003007|
LOOP_PAT_MODS|5.009005||Viu
lop|5.005000||Viu
lossless_NV_to_IV|5.031001||Vniu
LOWEST_ANYOF_HRx_BYTE|5.031002||Viu
L_R_TZSET|5.009005|5.009005|Vn
lsbit_pos32|5.035003||cVnu
lsbit_pos|5.035004||Viu
lsbit_pos64|5.035003||cVnu
lsbit_pos_uintmax|5.035003||Viu
lseek|5.005000||Viu
xs/object/ppport.h view on Meta::CPAN
# define D_PPP_TO_FOLD_CALLEE(s,r,l) \
Perl__to_utf8_fold_flags(aTHX_ s, r, l, FOLD_FLAGS_FULL, NULL)
# endif
/* The actual implementation of the backported macros. If too short, croak,
* otherwise call the original that doesn't have an upper limit parameter */
# define D_PPP_GENERIC_MULTI_ARG_TO(name, s, e,r,l) \
(((((e) - (s)) <= 0) \
/* We could just do nothing, but modern perls croak */ \
? (croak("Attempting case change on zero length string"), \
0) /* So looks like it returns something, and will compile */ \
: ((e) - (s)) < UTF8SKIP(s)) \
? (croak(D_PPP_TOO_SHORT_MSG, \
s[0], (int) ((e) - (s)), (int) UTF8SKIP(s)), \
0) \
: D_PPP_TO_ ## name ## _CALLEE(s,r,l))
#ifndef toUPPER_utf8_safe
# define toUPPER_utf8_safe(s,e,r,l) \
D_PPP_GENERIC_MULTI_ARG_TO(UPPER,s,e,r,l)
#endif
xs/object/ppport.h view on Meta::CPAN
D_PPP_GENERIC_SINGLE_ARG_TO_UVCHR(title, c, s, l)
#endif
#ifndef toFOLD_uvchr
# define toFOLD_uvchr(c, s, l) toLOWER_uvchr(c, s, l)
#endif
# define D_PPP_GENERIC_SINGLE_ARG_TO_UTF8(name, s, e, r, l) \
(((((e) - (s)) <= 0) \
? (croak("Attempting case change on zero length string"), \
0) /* So looks like it returns something, and will compile */ \
: ((e) - (s)) < UTF8SKIP(s)) \
? (croak(D_PPP_TOO_SHORT_MSG, \
s[0], (int) ((e) - (s)), (int) UTF8SKIP(s)), \
0) \
/* Get the changed code point and store its UTF-8 */ \
: D_PPP_UV_TO_UTF8(r, to_utf8_ ## name(s)), \
/* Then store its length, and re-get code point for return */ \
*(l) = UTF8SKIP(r), to_utf8_ ## name(r))
/* Warning: toUPPER_utf8_safe, toLOWER_utf8_safe, toTITLE_utf8_safe,
xs/ppport.h view on Meta::CPAN
}
usage() if $opt{help};
strip() if $opt{strip};
$opt{'compat-version'} = 5.003_07 unless exists $opt{'compat-version'};
$opt{'compat-version'} = int_parse_version($opt{'compat-version'});
my $int_min_perl = int_parse_version(5.003_07);
# Each element of this hash looks something like:
# 'Poison' => {
# 'base' => '5.008000',
# 'provided' => 1,
# 'todo' => '5.003007'
# },
my %API = map { /^(\w+)\|([^|]*)\|([^|]*)\|(\w*)$/
? ( $1 => {
($2 ? ( base => $2 ) : ()),
($3 ? ( todo => $3 ) : ()),
(index($4, 'v') >= 0 ? ( varargs => 1 ) : ()),
xs/ppport.h view on Meta::CPAN
LONGJMP_tb_pb|5.033003||Viu
LONGLONGSIZE|5.005000|5.005000|Vn
LONGSIZE|5.004000|5.003007|oVn
LOOKBEHIND_END_t8_p8|||Viu
LOOKBEHIND_END_t8_pb|||Viu
LOOKBEHIND_END_t8|||Viu
LOOKBEHIND_END_tb_p8|||Viu
LOOKBEHIND_END_tb_pb|||Viu
LOOKBEHIND_END_tb|||Viu
LOOKBEHIND_END|||Viu
looks_like_bool|5.027008||Viu
looks_like_number|5.003007|5.003007|
LOOP_PAT_MODS|5.009005||Viu
lop|5.005000||Viu
lossless_NV_to_IV|5.031001||Vniu
LOWEST_ANYOF_HRx_BYTE|5.031002||Viu
L_R_TZSET|5.009005|5.009005|Vn
lsbit_pos32|5.035003||cVnu
lsbit_pos|5.035004||Viu
lsbit_pos64|5.035003||cVnu
lsbit_pos_uintmax|5.035003||Viu
lseek|5.005000||Viu
xs/ppport.h view on Meta::CPAN
# define D_PPP_TO_FOLD_CALLEE(s,r,l) \
Perl__to_utf8_fold_flags(aTHX_ s, r, l, FOLD_FLAGS_FULL, NULL)
# endif
/* The actual implementation of the backported macros. If too short, croak,
* otherwise call the original that doesn't have an upper limit parameter */
# define D_PPP_GENERIC_MULTI_ARG_TO(name, s, e,r,l) \
(((((e) - (s)) <= 0) \
/* We could just do nothing, but modern perls croak */ \
? (croak("Attempting case change on zero length string"), \
0) /* So looks like it returns something, and will compile */ \
: ((e) - (s)) < UTF8SKIP(s)) \
? (croak(D_PPP_TOO_SHORT_MSG, \
s[0], (int) ((e) - (s)), (int) UTF8SKIP(s)), \
0) \
: D_PPP_TO_ ## name ## _CALLEE(s,r,l))
#ifndef toUPPER_utf8_safe
# define toUPPER_utf8_safe(s,e,r,l) \
D_PPP_GENERIC_MULTI_ARG_TO(UPPER,s,e,r,l)
#endif
xs/ppport.h view on Meta::CPAN
D_PPP_GENERIC_SINGLE_ARG_TO_UVCHR(title, c, s, l)
#endif
#ifndef toFOLD_uvchr
# define toFOLD_uvchr(c, s, l) toLOWER_uvchr(c, s, l)
#endif
# define D_PPP_GENERIC_SINGLE_ARG_TO_UTF8(name, s, e, r, l) \
(((((e) - (s)) <= 0) \
? (croak("Attempting case change on zero length string"), \
0) /* So looks like it returns something, and will compile */ \
: ((e) - (s)) < UTF8SKIP(s)) \
? (croak(D_PPP_TOO_SHORT_MSG, \
s[0], (int) ((e) - (s)), (int) UTF8SKIP(s)), \
0) \
/* Get the changed code point and store its UTF-8 */ \
: D_PPP_UV_TO_UTF8(r, to_utf8_ ## name(s)), \
/* Then store its length, and re-get code point for return */ \
*(l) = UTF8SKIP(r), to_utf8_ ## name(r))
/* Warning: toUPPER_utf8_safe, toLOWER_utf8_safe, toTITLE_utf8_safe,
xs/slot/ppport.h view on Meta::CPAN
}
usage() if $opt{help};
strip() if $opt{strip};
$opt{'compat-version'} = 5.003_07 unless exists $opt{'compat-version'};
$opt{'compat-version'} = int_parse_version($opt{'compat-version'});
my $int_min_perl = int_parse_version(5.003_07);
# Each element of this hash looks something like:
# 'Poison' => {
# 'base' => '5.008000',
# 'provided' => 1,
# 'todo' => '5.003007'
# },
my %API = map { /^(\w+)\|([^|]*)\|([^|]*)\|(\w*)$/
? ( $1 => {
($2 ? ( base => $2 ) : ()),
($3 ? ( todo => $3 ) : ()),
(index($4, 'v') >= 0 ? ( varargs => 1 ) : ()),
xs/slot/ppport.h view on Meta::CPAN
LONGJMP_tb_pb|5.033003||Viu
LONGLONGSIZE|5.005000|5.005000|Vn
LONGSIZE|5.004000|5.003007|oVn
LOOKBEHIND_END_t8_p8|||Viu
LOOKBEHIND_END_t8_pb|||Viu
LOOKBEHIND_END_t8|||Viu
LOOKBEHIND_END_tb_p8|||Viu
LOOKBEHIND_END_tb_pb|||Viu
LOOKBEHIND_END_tb|||Viu
LOOKBEHIND_END|||Viu
looks_like_bool|5.027008||Viu
looks_like_number|5.003007|5.003007|
LOOP_PAT_MODS|5.009005||Viu
lop|5.005000||Viu
lossless_NV_to_IV|5.031001||Vniu
LOWEST_ANYOF_HRx_BYTE|5.031002||Viu
L_R_TZSET|5.009005|5.009005|Vn
lsbit_pos32|5.035003||cVnu
lsbit_pos|5.035004||Viu
lsbit_pos64|5.035003||cVnu
lsbit_pos_uintmax|5.035003||Viu
lseek|5.005000||Viu
xs/slot/ppport.h view on Meta::CPAN
# define D_PPP_TO_FOLD_CALLEE(s,r,l) \
Perl__to_utf8_fold_flags(aTHX_ s, r, l, FOLD_FLAGS_FULL, NULL)
# endif
/* The actual implementation of the backported macros. If too short, croak,
* otherwise call the original that doesn't have an upper limit parameter */
# define D_PPP_GENERIC_MULTI_ARG_TO(name, s, e,r,l) \
(((((e) - (s)) <= 0) \
/* We could just do nothing, but modern perls croak */ \
? (croak("Attempting case change on zero length string"), \
0) /* So looks like it returns something, and will compile */ \
: ((e) - (s)) < UTF8SKIP(s)) \
? (croak(D_PPP_TOO_SHORT_MSG, \
s[0], (int) ((e) - (s)), (int) UTF8SKIP(s)), \
0) \
: D_PPP_TO_ ## name ## _CALLEE(s,r,l))
#ifndef toUPPER_utf8_safe
# define toUPPER_utf8_safe(s,e,r,l) \
D_PPP_GENERIC_MULTI_ARG_TO(UPPER,s,e,r,l)
#endif
xs/slot/ppport.h view on Meta::CPAN
D_PPP_GENERIC_SINGLE_ARG_TO_UVCHR(title, c, s, l)
#endif
#ifndef toFOLD_uvchr
# define toFOLD_uvchr(c, s, l) toLOWER_uvchr(c, s, l)
#endif
# define D_PPP_GENERIC_SINGLE_ARG_TO_UTF8(name, s, e, r, l) \
(((((e) - (s)) <= 0) \
? (croak("Attempting case change on zero length string"), \
0) /* So looks like it returns something, and will compile */ \
: ((e) - (s)) < UTF8SKIP(s)) \
? (croak(D_PPP_TOO_SHORT_MSG, \
s[0], (int) ((e) - (s)), (int) UTF8SKIP(s)), \
0) \
/* Get the changed code point and store its UTF-8 */ \
: D_PPP_UV_TO_UTF8(r, to_utf8_ ## name(s)), \
/* Then store its length, and re-get code point for return */ \
*(l) = UTF8SKIP(r), to_utf8_ ## name(r))
/* Warning: toUPPER_utf8_safe, toLOWER_utf8_safe, toTITLE_utf8_safe,
xs/util/ppport.h view on Meta::CPAN
keyword|||
leave_scope|||
lex_end|||
lex_start|||
linklist|||
listkids|||
list|||
load_module_nocontext|||vn
load_module|5.006000||pv
localize|||
looks_like_bool|||
looks_like_number|||
lop|||
mPUSHi|5.009002||p
mPUSHn|5.009002||p
mPUSHp|5.009002||p
mPUSHs|5.011000||p
mPUSHu|5.009002||p
mXPUSHi|5.009002||p
mXPUSHn|5.009002||p
mXPUSHp|5.009002||p
mXPUSHs|5.011000||p
xs/util/util.c view on Meta::CPAN
return (SvROK(elem) && SvTYPE(SvRV(elem)) == SVt_PVHV) ? TRUE : FALSE;
}
static bool builtin_is_code(pTHX_ SV *elem) {
return (SvROK(elem) && SvTYPE(SvRV(elem)) == SVt_PVCV) ? TRUE : FALSE;
}
static bool builtin_is_positive(pTHX_ SV *elem) {
if (SvIOK(elem)) return SvIV(elem) > 0;
if (SvNOK(elem)) return SvNV(elem) > 0;
if (SvPOK(elem) && looks_like_number(elem)) return SvNV(elem) > 0;
return FALSE;
}
static bool builtin_is_negative(pTHX_ SV *elem) {
if (SvIOK(elem)) return SvIV(elem) < 0;
if (SvNOK(elem)) return SvNV(elem) < 0;
if (SvPOK(elem) && looks_like_number(elem)) return SvNV(elem) < 0;
return FALSE;
}
static bool builtin_is_zero(pTHX_ SV *elem) {
if (SvIOK(elem)) return SvIV(elem) == 0;
if (SvNOK(elem)) return SvNV(elem) == 0.0;
if (SvPOK(elem) && looks_like_number(elem)) return SvNV(elem) == 0.0;
return FALSE;
}
static bool builtin_is_even(pTHX_ SV *elem) {
if (!SvIOK(elem) && !SvNOK(elem)) {
if (!SvPOK(elem) || !looks_like_number(elem)) return FALSE;
}
IV val = SvIV(elem);
return (val % 2) == 0;
}
static bool builtin_is_odd(pTHX_ SV *elem) {
if (!SvIOK(elem) && !SvNOK(elem)) {
if (!SvPOK(elem) || !looks_like_number(elem)) return FALSE;
}
IV val = SvIV(elem);
return (val % 2) != 0;
}
static bool builtin_is_empty(pTHX_ SV *elem) {
if (!SvOK(elem)) return TRUE;
if (SvROK(elem)) {
SV *rv = SvRV(elem);
if (SvTYPE(rv) == SVt_PVAV) return AvFILL((AV*)rv) < 0;
xs/util/util.c view on Meta::CPAN
static bool builtin_is_nonempty(pTHX_ SV *elem) {
return !builtin_is_empty(aTHX_ elem);
}
static bool builtin_is_string(pTHX_ SV *elem) {
return (SvPOK(elem) && !SvIOK(elem) && !SvNOK(elem) && !SvROK(elem)) ? TRUE : FALSE;
}
static bool builtin_is_number(pTHX_ SV *elem) {
if (SvIOK(elem) || SvNOK(elem)) return TRUE;
if (SvPOK(elem) && looks_like_number(elem)) return TRUE;
return FALSE;
}
static bool builtin_is_integer(pTHX_ SV *elem) {
if (SvIOK(elem) && !SvNOK(elem)) return TRUE;
if (SvNOK(elem)) {
NV val = SvNV(elem);
return val == (NV)(IV)val;
}
if (SvPOK(elem) && looks_like_number(elem)) {
NV val = SvNV(elem);
return val == (NV)(IV)val;
}
return FALSE;
}
/* ============================================
Callback registry functions
============================================ */
xs/util/util.c view on Meta::CPAN
dSP;
SV *sv = TOPs;
SETs(SvTRUE(sv) ? &PL_sv_yes : &PL_sv_no);
RETURN;
}
/* ============================================
Extended type predicate custom ops - blazing fast!
============================================ */
/* is_num: check if value is numeric (has numeric value or looks like number) */
static OP* pp_is_num(pTHX) {
dSP;
SV *sv = TOPs;
/* SvNIOK: has numeric (NV or IV) value cached */
/* Also check looks_like_number for strings that can be numbers */
SETs((SvNIOK(sv) || looks_like_number(sv)) ? &PL_sv_yes : &PL_sv_no);
RETURN;
}
/* is_int: check if value is an integer */
static OP* pp_is_int(pTHX) {
dSP;
SV *sv = TOPs;
/* SvIOK: has integer value cached */
if (SvIOK(sv)) {
SETs(&PL_sv_yes);
} else if (SvNOK(sv)) {
/* It's a float - check if it's a whole number */
NV nv = SvNV(sv);
SETs((nv == (NV)(IV)nv) ? &PL_sv_yes : &PL_sv_no);
} else if (looks_like_number(sv)) {
/* String that looks like a number - check if integer */
STRLEN len;
const char *pv = SvPV(sv, len);
/* Simple check: no decimal point or exponent */
bool has_dot = FALSE;
STRLEN i;
for (i = 0; i < len; i++) {
if (pv[i] == '.' || pv[i] == 'e' || pv[i] == 'E') {
has_dot = TRUE;
break;
}
xs/util/util.c view on Meta::CPAN
/* ============================================
Numeric predicate custom ops - blazing fast!
Direct SvNV comparison, minimal overhead
============================================ */
/* is_positive: check if value is > 0 */
static OP* pp_is_positive(pTHX) {
dSP;
SV *sv = TOPs;
if (SvNIOK(sv) || looks_like_number(sv)) {
NV nv = SvNV(sv);
SETs((nv > 0) ? &PL_sv_yes : &PL_sv_no);
} else {
SETs(&PL_sv_no);
}
RETURN;
}
/* is_negative: check if value is < 0 */
static OP* pp_is_negative(pTHX) {
dSP;
SV *sv = TOPs;
if (SvNIOK(sv) || looks_like_number(sv)) {
NV nv = SvNV(sv);
SETs((nv < 0) ? &PL_sv_yes : &PL_sv_no);
} else {
SETs(&PL_sv_no);
}
RETURN;
}
/* is_zero: check if value is == 0 */
static OP* pp_is_zero(pTHX) {
dSP;
SV *sv = TOPs;
if (SvNIOK(sv) || looks_like_number(sv)) {
NV nv = SvNV(sv);
SETs((nv == 0) ? &PL_sv_yes : &PL_sv_no);
} else {
SETs(&PL_sv_no);
}
RETURN;
}
/* ============================================
Numeric utility custom ops
xs/util/util.c view on Meta::CPAN
SV *sv = TOPs;
if (SvIOK(sv)) {
SETs((SvIVX(sv) & 1) == 0 ? &PL_sv_yes : &PL_sv_no);
} else if (SvNIOK(sv)) {
NV nv = SvNV(sv);
if (nv == (NV)(IV)nv) {
SETs(((IV)nv & 1) == 0 ? &PL_sv_yes : &PL_sv_no);
} else {
SETs(&PL_sv_no);
}
} else if (looks_like_number(sv)) {
SETs((SvIV(sv) & 1) == 0 ? &PL_sv_yes : &PL_sv_no);
} else {
SETs(&PL_sv_no);
}
RETURN;
}
/* is_odd: check if integer is odd (single bitwise AND) */
static OP* pp_is_odd(pTHX) {
dSP;
SV *sv = TOPs;
if (SvIOK(sv)) {
SETs((SvIVX(sv) & 1) == 1 ? &PL_sv_yes : &PL_sv_no);
} else if (SvNIOK(sv)) {
NV nv = SvNV(sv);
if (nv == (NV)(IV)nv) {
SETs(((IV)nv & 1) == 1 ? &PL_sv_yes : &PL_sv_no);
} else {
SETs(&PL_sv_no);
}
} else if (looks_like_number(sv)) {
SETs((SvIV(sv) & 1) == 1 ? &PL_sv_yes : &PL_sv_no);
} else {
SETs(&PL_sv_no);
}
RETURN;
}
/* is_between: check if value is between min and max (inclusive) */
static OP* pp_is_between(pTHX) {
dSP;
SV *max_sv = POPs;
SV *min_sv = POPs;
SV *val_sv = TOPs;
if (SvNIOK(val_sv) || looks_like_number(val_sv)) {
NV val = SvNV(val_sv);
NV min = SvNV(min_sv);
NV max = SvNV(max_sv);
SETs((val >= min && val <= max) ? &PL_sv_yes : &PL_sv_no);
} else {
SETs(&PL_sv_no);
}
RETURN;
}
xs/util/util.c view on Meta::CPAN
/* ============================================
Numeric custom ops
============================================ */
/* sign: return -1, 0, or 1 based on value */
static OP* pp_sign(pTHX) {
dSP;
SV *sv = TOPs;
if (!SvNIOK(sv) && !looks_like_number(sv)) {
SETs(&PL_sv_undef);
RETURN;
}
NV nv = SvNV(sv);
if (nv > 0) {
SETs(sv_2mortal(newSViv(1)));
} else if (nv < 0) {
SETs(sv_2mortal(newSViv(-1)));
} else {
xs/util/util.c view on Meta::CPAN
}
/* ============================================
Extended type predicate XS fallbacks
============================================ */
static XS(xs_is_num) {
dXSARGS;
if (items != 1) croak("Usage: util::is_num($value)");
SV *sv = ST(0);
ST(0) = (SvNIOK(sv) || looks_like_number(sv)) ? &PL_sv_yes : &PL_sv_no;
XSRETURN(1);
}
static XS(xs_is_int) {
dXSARGS;
if (items != 1) croak("Usage: util::is_int($value)");
SV *sv = ST(0);
if (SvIOK(sv)) {
ST(0) = &PL_sv_yes;
} else if (SvNOK(sv)) {
NV nv = SvNV(sv);
ST(0) = (nv == (NV)(IV)nv) ? &PL_sv_yes : &PL_sv_no;
} else if (looks_like_number(sv)) {
STRLEN len;
const char *pv = SvPV(sv, len);
bool has_dot = FALSE;
STRLEN i;
for (i = 0; i < len; i++) {
if (pv[i] == '.' || pv[i] == 'e' || pv[i] == 'E') {
has_dot = TRUE;
break;
}
}
xs/util/util.c view on Meta::CPAN
}
/* ============================================
Numeric predicate XS fallbacks
============================================ */
static XS(xs_is_positive) {
dXSARGS;
if (items != 1) croak("Usage: util::is_positive($value)");
SV *sv = ST(0);
if (SvNIOK(sv) || looks_like_number(sv)) {
NV nv = SvNV(sv);
ST(0) = (nv > 0) ? &PL_sv_yes : &PL_sv_no;
} else {
ST(0) = &PL_sv_no;
}
XSRETURN(1);
}
static XS(xs_is_negative) {
dXSARGS;
if (items != 1) croak("Usage: util::is_negative($value)");
SV *sv = ST(0);
if (SvNIOK(sv) || looks_like_number(sv)) {
NV nv = SvNV(sv);
ST(0) = (nv < 0) ? &PL_sv_yes : &PL_sv_no;
} else {
ST(0) = &PL_sv_no;
}
XSRETURN(1);
}
static XS(xs_is_zero) {
dXSARGS;
if (items != 1) croak("Usage: util::is_zero($value)");
SV *sv = ST(0);
if (SvNIOK(sv) || looks_like_number(sv)) {
NV nv = SvNV(sv);
ST(0) = (nv == 0) ? &PL_sv_yes : &PL_sv_no;
} else {
ST(0) = &PL_sv_no;
}
XSRETURN(1);
}
/* ============================================
Numeric utility XS fallbacks
xs/util/util.c view on Meta::CPAN
SV *sv = ST(0);
if (SvIOK(sv)) {
ST(0) = (SvIVX(sv) & 1) == 0 ? &PL_sv_yes : &PL_sv_no;
} else if (SvNIOK(sv)) {
NV nv = SvNV(sv);
if (nv == (NV)(IV)nv) {
ST(0) = ((IV)nv & 1) == 0 ? &PL_sv_yes : &PL_sv_no;
} else {
ST(0) = &PL_sv_no;
}
} else if (looks_like_number(sv)) {
ST(0) = (SvIV(sv) & 1) == 0 ? &PL_sv_yes : &PL_sv_no;
} else {
ST(0) = &PL_sv_no;
}
XSRETURN(1);
}
static XS(xs_is_odd) {
dXSARGS;
if (items != 1) croak("Usage: util::is_odd($value)");
SV *sv = ST(0);
if (SvIOK(sv)) {
ST(0) = (SvIVX(sv) & 1) == 1 ? &PL_sv_yes : &PL_sv_no;
} else if (SvNIOK(sv)) {
NV nv = SvNV(sv);
if (nv == (NV)(IV)nv) {
ST(0) = ((IV)nv & 1) == 1 ? &PL_sv_yes : &PL_sv_no;
} else {
ST(0) = &PL_sv_no;
}
} else if (looks_like_number(sv)) {
ST(0) = (SvIV(sv) & 1) == 1 ? &PL_sv_yes : &PL_sv_no;
} else {
ST(0) = &PL_sv_no;
}
XSRETURN(1);
}
static XS(xs_is_between) {
dXSARGS;
if (items != 3) croak("Usage: util::is_between($value, $min, $max)");
SV *val_sv = ST(0);
SV *min_sv = ST(1);
SV *max_sv = ST(2);
if (SvNIOK(val_sv) || looks_like_number(val_sv)) {
NV val = SvNV(val_sv);
NV min = SvNV(min_sv);
NV max = SvNV(max_sv);
ST(0) = (val >= min && val <= max) ? &PL_sv_yes : &PL_sv_no;
} else {
ST(0) = &PL_sv_no;
}
XSRETURN(1);
}
xs/util/util.c view on Meta::CPAN
/* ============================================
Numeric XS fallbacks
============================================ */
static XS(xs_sign) {
dXSARGS;
if (items != 1) croak("Usage: util::sign($number)");
SV *sv = ST(0);
if (!SvNIOK(sv) && !looks_like_number(sv)) {
ST(0) = &PL_sv_undef;
XSRETURN(1);
}
NV nv = SvNV(sv);
if (nv > 0) {
ST(0) = sv_2mortal(newSViv(1));
} else if (nv < 0) {
ST(0) = sv_2mortal(newSViv(-1));
} else {
xs/util/util_callbacks.h view on Meta::CPAN
/*
* The following built-in predicates are available:
*
* Type checks:
* :is_defined - SvOK(elem)
* :is_ref - SvROK(elem)
* :is_array - arrayref
* :is_hash - hashref
* :is_code - coderef
* :is_string - plain scalar (not ref, not number)
* :is_number - numeric (IV, NV, or looks_like_number)
* :is_integer - integer value (no fractional part)
*
* Boolean checks:
* :is_true - SvTRUE(elem)
* :is_false - !SvTRUE(elem)
*
* Numeric checks:
* :is_positive - value > 0
* :is_negative - value < 0
* :is_zero - value == 0