Affix

 view release on metacpan or  search on metacpan

t/005_varargs.t  view on Meta::CPAN

use v5.40;
use lib '../lib', 'lib';
use blib;
use Test2::Tools::Affix qw[:all];
use Affix               qw[:all];
#
$|++;
#
my $c_code = <<'END_C';
#include "std.h"
//ext: .c
#include <stdarg.h>
#include <string.h>
#include <stdio.h>

typedef struct {
    int x, y;
} Point;

/*
 * Sums values based on format string.
 * i: int
 * d: double
 * P: Point {int, int}
 */
DLLEXPORT int var_sum(const char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    int total = 0;
    while (*fmt) {
        switch (*fmt++) {
            case 'i': total += va_arg(ap, int); break;
            case 'd': total += (int)va_arg(ap, double); break;
            case 's': {
                char* s = va_arg(ap, char*);
                total += s ? strlen(s) : 0;
                break;
            }
            case 'P': {
                Point p = va_arg(ap, Point);
                total += p.x + p.y;
                break;
            }
        }
    }
    va_end(ap);
    return total;
}
END_C
my $lib = compile_ok( $c_code, { name => 'variadic_dynamic_lib' } );

# Bind with "Empty" Variadic Signature
# We define the fixed arguments (*char) and end with a semicolon.
# We do NOT specify any optional types here. Affix must generate them at runtime.
# Signature: (*char;)->int
isa_ok my $fn = wrap( $lib, 'var_sum', [ Pointer [Char], VarArgs ] => Int ), ['Affix'];
subtest 'Runtime Type Inference' => sub {

    # 3 Integers
    # Affix should generate JIT for: (*char; sint64, sint64, sint64)->int
    is $fn->( "iii", 10, 20, 30 ), 60, 'Inferred 3 integers';



( run in 0.607 second using v1.01-cache-2.11-cpan-437f7b0c052 )