Is there a convenient way handle C typedef which may have different value on various platform ?
For example
#if defined(_WIN32)
#define foo_t int32_t
#elif defined(_WIN64)
#define foo_t int64_t
#else
#define foo_t long
#endif
void handle_foo(foo_t* in) {
...
}
Currently I am handle this in Perl 6 like this
sub handle_foo32(int32 is rw) is native(Str) { * }
sub handle_foo64(int64 is rw) is native(Str) { * }
sub handle_foo00(long is rw) is native(Str) { * }
sub handle-foo(Int $in) {
if $*DISTRO.is-win {
given $*KERNEL.bits {
when 32 {
handle_foo32(my int32 $ = $in);
}
when 64 {
handle_foo64(my int64 $ = $in);
}
}
} else {
handle_foo00(my long $ = $in);
}
}
Perhaps the most direct translation is to use constant
to introduce a new symbol, computed at compile time.
my constant foo_t = do if $*DISTRO.is-win {
given $*KERNEL.bits {
when 32 { int32 }
when 64 { int64 }
}
} else {
long
}
A constant bound to a type object acts just like a type, and can be used in the signature.
sub handle_foo(foo_t is rw) is native { * }
I don't think so. But since $*DISTRO.is-win
and $*KERNEL.bits
are effectively constants, you can move the decision on which version to use to compile time:
sub handle_foo32(int32 is rw) is native(Str) { * }
sub handle_foo64(int64 is rw) is native(Str) { * }
sub handle_foo00(long is rw) is native(Str) { * }
my constant &handler = $*DISTRO.is-win
?? $*KERNEL.bits == 32
?? &handle_foo32
!! &handle_foo64
!! &handle_foo00;
Except this won't of course help you with the differently sized parameters for each version. So I guess you would need another layer of indirection for that.
Perhaps as inspiration, here's how I handled similar issues: https://github.com/lizmat/P5getpwnam/blob/master/lib/P5getpwnam.pm6
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With