TYPEMAP
POSIX::RT::Timer	T_INTOBJ
POSIX::RT::Clock	T_INTOBJ
Time::Spec	T_OPAQUEOBJ
clockid_t	T_PACKED
timer_init	T_SLURP_VAR
struct timespec	T_TIMESPEC

INPUT
T_OPAQUEOBJ
    {
		SV * sv = $arg;
		if (SvROK(sv) && SvPOK(SvRV(sv)) && SvCUR(SvRV(sv)) == sizeof(*$var))
			$var = ($type)SvPV_nolen(SvRV(sv));
		else
			croak(\"%s: %s is not of type %s\", ${$ALIAS?\q[GvNAME(CvGV(cv))]:\qq[\"$pname\"]}, \"$var\", \"$ntype\");
    }

T_OPAQUEOBJ_MAYBE
	{
		SV * sv = $arg;
		if (SvOK(sv)) {
			if (SvROK(sv) && SvPOK(SvRV(sv)) && SvCUR(SvRV(sv)) == sizeof(*$var))
				$var = ($type)SvPV_nolen(SvRV(sv));
			else
				croak(\"%s: %s is not of type %s\", ${$ALIAS?\q[GvNAME(CvGV(cv))]:\qq[\"$pname\"]}, \"$var\", \"$ntype\");
		} else
			$var = NULL;
	}

T_TIMESPEC
	if (SvROK($arg) && sv_derived_from($arg, \"Time::Spec\")) {
		$var = *(struct timespec*)SvPV_nolen(SvRV($arg));
	} else {
		NV input = SvNV($arg);
		$var.tv_sec  = (time_t) floor(input);
		$var.tv_nsec = (long) ((input - $var.tv_sec) * 1000000000);
	}
T_INTOBJ
    {
		SV * sv = $arg;
		if (SvROK(sv) && sv_derived_from(sv, \"$ntype\"))
			$var = ($type)SvUV(SvRV(sv));
		else
			croak(\"%s: %s is not of type %s\", ${$ALIAS?\q[GvNAME(CvGV(cv))]:\qq[\"$pname\"]}, \"$var\", \"$ntype\");
    }

T_INTREF
    {
		SV * sv = $arg;
		if (SvROK(sv) && SvIOK(SvRV(sv)))
			$var = ($type)SvUV(SvRV(sv));
		else 
			croak(\"%s: %s is not a reference\", ${$ALIAS?\q[GvNAME(CvGV(cv))]:\qq[\"$pname\"]}, \"$var\");
    }

T_SLURP_VAL
	$var = ${ntype}_gather(&ST($argoff), items - $argoff)
T_SLURP_VAR
	${ntype}_gather(&$var, &ST($argoff), items - $argoff)
T_SLURP_AV
	$var = av_make(items - $argoff, &ST($argoff))

OUTPUT
T_OPAQUEOBJ
	{
		sv_usepvn(newSVrv($arg, \"$ntype\"), (char*)$var, sizeof(*$var));
		SvREADONLY_on(SvRV($arg));
	}

T_OPAQUEOBJ_MAYBE
	if (SvOK($var)) {
		sv_usepvn(newSVrv($arg, \"$ntype\"), (char*)$var, sizeof(*$var));
		SvREADONLY_on(SvRV($arg));
	}

T_TIMESPEC
	sv_setnv($arg, $var.tv_sec + $var.tv_nsec / 1000000000.0);
T_INTOBJ
	{
		sv_setref_uv($arg, \"$ntype\", (UV)$var);
		SvREADONLY_on(SvRV($arg));
	}

T_INTREF
	{
		sv_setref_uv($arg, NULL, (UV)$var);
		SvREADONLY_on(SvRV($arg));
	}

