TYPEMAP
int	T_IV
signed int	T_IV
short	T_IV
signed short	T_IV
long	T_IV
signed long	T_IV
char	T_IV
signed char	T_IV
short int	T_IV
signed short int	T_IV
long int	T_IV
signed long int	T_IV
long long	T_IV
signed long long	T_IV
time_t	T_IV
Sint16	T_IV
Sint32	T_IV
Sint64	T_IV
unsigned int	T_UV
unsigned short	T_UV
unsigned long	T_UV
unsigned char	T_UV
unsigned short int	T_UV
unsigned long int	T_UV
unsigned long long	T_UV
unsigned	T_UV
Uint16	T_UV
Uint32	T_UV
Uint64	T_UV
size_t	T_UV
bool	T_UV
float	T_NV
double	T_NV
long double	T_NV
const int	T_IV
const signed int	T_IV
const short	T_IV
const signed short	T_IV
const long	T_IV
const signed long	T_IV
const char	T_IV
const signed char	T_IV
const short int	T_IV
const signed short int	T_IV
const long int	T_IV
const signed long int	T_IV
const long long	T_IV
const signed long long	T_IV
const time_t	T_IV
const Sint16	T_IV
const Sint32	T_IV
const Sint64	T_IV
const unsigned int	T_UV
const unsigned short	T_UV
const unsigned long	T_UV
const unsigned char	T_UV
const unsigned short int	T_UV
const unsigned long int	T_UV
const unsigned long long	T_UV
const unsigned	T_UV
const Uint16	T_UV
const Uint32	T_UV
const Uint64	T_UV
const size_t	T_UV
const bool	T_UV
const float	T_NV
const double	T_NV
const long double	T_NV
HV *	T_HvRV
AV *	T_AvRV
std::string	T_STD_STRING
std::string*	T_STD_STRING_PTR
std::vector< double >*	T_STD_VECTOR_DOUBLE_PTR
std::vector<double>*	T_STD_VECTOR_DOUBLE_PTR
std::vector< double >	T_STD_VECTOR_DOUBLE
std::vector<double>	T_STD_VECTOR_DOUBLE
std::vector< int >*	T_STD_VECTOR_INT_PTR
std::vector<int>*	T_STD_VECTOR_INT_PTR
std::vector< int >	T_STD_VECTOR_INT
std::vector<int>	T_STD_VECTOR_INT
std::vector< unsigned int >*	T_STD_VECTOR_UINT_PTR
std::vector<unsigned int>*	T_STD_VECTOR_UINT_PTR
std::vector< unsigned int >	T_STD_VECTOR_UINT
std::vector<unsigned int>	T_STD_VECTOR_UINT
std::vector<std::string>	T_STD_VECTOR_STD_STRING
std::vector<std::string>*	T_STD_VECTOR_STD_STRING_PTR
std::vector<char*>	T_STD_VECTOR_CSTRING
std::vector<char*>*	T_STD_VECTOR_CSTRING_PTR

INPUT
O_OBJECT
	if( sv_isobject($arg) && (SvTYPE(SvRV($arg)) == SVt_PVMG) )
		$var = ($type)SvIV((SV*)SvRV( $arg ));
	else{
		warn( \"${Package}::$func_name() -- $var is not a blessed SV reference\" );
		XSRETURN_UNDEF;
	}
T_OBJECT
	if( SvROK($arg) )
		$var = ($type)SvIV((SV*)SvRV( $arg ));
	else{
		warn( \"${Package}::$func_name() -- $var is not an SV reference\" );
		XSRETURN_UNDEF;
	}
O_HvRV
	if( sv_isobject($arg) && (SvTYPE(SvRV($arg)) == SVt_PVHV) )
		$var = (HV*)SvRV( $arg );
	else {
		warn( \"${Package}::$func_name() -- $var is not a blessed HV reference\" );
		XSRETURN_UNDEF;
	}
T_HvRV
	if( SvROK($arg) && (SvTYPE(SvRV($arg)) == SVt_PVHV) )
		$var = (HV*)SvRV( $arg );
	else {
		warn( \"${Package}::$func_name() -- $var is not an HV reference\" );
		XSRETURN_UNDEF;
	}
O_AvRV
	if( sv_isobject($arg) && (SvTYPE(SvRV($arg)) == SVt_PVAV) )
		$var = (AV*)SvRV( $arg );
	else {
		warn( \"${Package}::$func_name() -- $var is not a blessed AV reference\" );
		XSRETURN_UNDEF;
	}
T_AvRV
	if( SvROK($arg) && (SvTYPE(SvRV($arg)) == SVt_PVAV) )
		$var = (AV*)SvRV( $arg );
	else {
		warn( \"${Package}::$func_name() -- $var is not an AV reference\" );
		XSRETURN_UNDEF;
	}
T_STD_STRING
    $var = std::string( SvPV_nolen( $arg ), SvCUR( $arg ) );
T_STD_STRING_PTR
    $var = new std::string( SvPV_nolen( $arg ), SvCUR( $arg ) );
T_STD_VECTOR_DOUBLE
	if (SvROK($arg) && SvTYPE(SvRV($arg))==SVt_PVAV) {
	  AV* av = (AV*)SvRV($arg);
	  const unsigned int len = av_len(av)+1;
	  $var = std::vector<double>(len);
	  SV** elem;
	  for (unsigned int i = 0; i < len; i++) {
	    elem = av_fetch(av, i, 0);
	    if (elem != NULL)
	      ${var}[i] = SvNV(*elem);
	    else
	      ${var}[i] = 0.;
	  }
	}
	else
	  Perl_croak(aTHX_ \"%s: %s is not an array reference\",
	             ${$ALIAS?\q[GvNAME(CvGV(cv))]:\qq[\"$pname\"]},
	             \"$var\");
T_STD_VECTOR_DOUBLE_PTR
	if (SvROK($arg) && SvTYPE(SvRV($arg))==SVt_PVAV) {
	  AV* av = (AV*)SvRV($arg);
	  const unsigned int len = av_len(av)+1;
	  $var = new std::vector<double>(len);
	  SV** elem;
	  for (unsigned int i = 0; i < len; i++) {
	    elem = av_fetch(av, i, 0);
	    if (elem != NULL)
	      (*$var)[i] = SvNV(*elem);
	    else
	      (*$var)[i] = 0.;
	  }
	}
	else
	  Perl_croak(aTHX_ \"%s: %s is not an array reference\",
	             ${$ALIAS?\q[GvNAME(CvGV(cv))]:\qq[\"$pname\"]},
	             \"$var\");
T_STD_VECTOR_INT
	if (SvROK($arg) && SvTYPE(SvRV($arg))==SVt_PVAV) {
	  AV* av = (AV*)SvRV($arg);
	  const unsigned int len = av_len(av)+1;
	  $var = std::vector<int>(len);
	  SV** elem;
	  for (unsigned int i = 0; i < len; i++) {
	    elem = av_fetch(av, i, 0);
	    if (elem != NULL)
	      ${var}[i] = SvIV(*elem);
	    else
	      ${var}[i] = 0;
	  }
	}
	else
	  Perl_croak(aTHX_ \"%s: %s is not an array reference\",
	             ${$ALIAS?\q[GvNAME(CvGV(cv))]:\qq[\"$pname\"]},
	             \"$var\");
T_STD_VECTOR_INT_PTR
	if (SvROK($arg) && SvTYPE(SvRV($arg))==SVt_PVAV) {
	  AV* av = (AV*)SvRV($arg);
	  const unsigned int len = av_len(av)+1;
	  $var = new std::vector<int>(len);
	  SV** elem;
	  for (unsigned int i = 0; i < len; i++) {
	    elem = av_fetch(av, i, 0);
	    if (elem != NULL)
	      (*$var)[i] = SvIV(*elem);
	    else
	      (*$var)[i] = 0.;
	  }
	}
	else
	  Perl_croak(aTHX_ \"%s: %s is not an array reference\",
	             ${$ALIAS?\q[GvNAME(CvGV(cv))]:\qq[\"$pname\"]},
	             \"$var\");
T_STD_VECTOR_UINT
	if (SvROK($arg) && SvTYPE(SvRV($arg))==SVt_PVAV) {
	  AV* av = (AV*)SvRV($arg);
	  const unsigned int len = av_len(av)+1;
	  $var = std::vector<unsigned int>(len);
	  SV** elem;
	  for (unsigned int i = 0; i < len; i++) {
	    elem = av_fetch(av, i, 0);
	    if (elem != NULL)
	      ${var}[i] = SvUV(*elem);
	    else
	      ${var}[i] = 0;
	  }
	}
	else
	  Perl_croak(aTHX_ \"%s: %s is not an array reference\",
	             ${$ALIAS?\q[GvNAME(CvGV(cv))]:\qq[\"$pname\"]},
	             \"$var\");
T_STD_VECTOR_UINT_PTR
	if (SvROK($arg) && SvTYPE(SvRV($arg))==SVt_PVAV) {
	  AV* av = (AV*)SvRV($arg);
	  const unsigned int len = av_len(av)+1;
	  $var = new std::vector<unsigned int>(len);
	  SV** elem;
	  for (unsigned int i = 0; i < len; i++) {
	    elem = av_fetch(av, i, 0);
	    if (elem != NULL)
	      (*$var)[i] = SvUV(*elem);
	    else
	      (*$var)[i] = 0.;
	  }
	}
	else
	  Perl_croak(aTHX_ \"%s: %s is not an array reference\",
	             ${$ALIAS?\q[GvNAME(CvGV(cv))]:\qq[\"$pname\"]},
	             \"$var\");
T_STD_VECTOR_STD_STRING
	if (SvROK($arg) && SvTYPE(SvRV($arg))==SVt_PVAV) {
	  AV* av = (AV*)SvRV($arg);
	  const unsigned int alen = av_len(av)+1;
	  $var = std::vector<std::string>(alen);
	  STRLEN len;
	  char* tmp;
	  SV** elem;
	  for (unsigned int i = 0; i < alen; i++) {
	    elem = av_fetch(av, i, 0);
	    if (elem != NULL) {
	    tmp = SvPV(*elem, len);
	      ${var}[i] = std::string(tmp, len);
	    }
	    else
	      ${var}[i] = std::string(\"\");
	  }
	}
	else
	  Perl_croak(aTHX_ \"%s: %s is not an array reference\",
	             ${$ALIAS?\q[GvNAME(CvGV(cv))]:\qq[\"$pname\"]},
	             \"$var\");
T_STD_VECTOR_STD_STRING_PTR
	if (SvROK($arg) && SvTYPE(SvRV($arg))==SVt_PVAV) {
	  AV* av = (AV*)SvRV($arg);
	  const unsigned int alen = av_len(av)+1;
	  $var = new std::vector<std::string>(alen);
	  STRLEN len;
	  char* tmp;
	  SV** elem;
	  for (unsigned int i = 0; i < alen; i++) {
	    elem = av_fetch(av, i, 0);
	    if (elem != NULL) {
	      tmp = SvPV(*elem, len);
	      (*$var)[i] = std::string(tmp, len);
	    }
	    else
	      (*$var)[i] = std::string(\"\");
	  }
	}
	else
	  Perl_croak(aTHX_ \"%s: %s is not an array reference\",
	             ${$ALIAS?\q[GvNAME(CvGV(cv))]:\qq[\"$pname\"]},
	             \"$var\");
T_STD_VECTOR_CSTRING
	if (SvROK($arg) && SvTYPE(SvRV($arg))==SVt_PVAV) {
	  AV* av = (AV*)SvRV($arg);
	  const unsigned int len = av_len(av)+1;
	  $var = std::vector<char*>(len);
	  SV** elem;
	  for (unsigned int i = 0; i < len; i++) {
	    elem = av_fetch(av, i, 0);
	    if (elem != NULL) {
	      ${var}[i] = SvPV_nolen(*elem);
	    else
	      ${var}[i] = NULL;
	  }
	}
	else
	  Perl_croak(aTHX_ \"%s: %s is not an array reference\",
	             ${$ALIAS?\q[GvNAME(CvGV(cv))]:\qq[\"$pname\"]},
	             \"$var\");
T_STD_VECTOR_CSTRING_PTR
	if (SvROK($arg) && SvTYPE(SvRV($arg))==SVt_PVAV) {
	  AV* av = (AV*)SvRV($arg);
	  const unsigned int len = av_len(av)+1;
	  $var = new std::vector<char*>(len);
	  SV** elem;
	  for (unsigned int i = 0; i < len; i++) {
	    elem = av_fetch(av, i, 0);
	    if (elem != NULL) {
	      (*$var)[i] = SvPV_nolen(*elem);
	    else
	      (*$var)[i] = NULL;
	  }
	}
	else
	  Perl_croak(aTHX_ \"%s: %s is not an array reference\",
	             ${$ALIAS?\q[GvNAME(CvGV(cv))]:\qq[\"$pname\"]},
	             \"$var\");

OUTPUT
O_OBJECT
	sv_setref_pv( $arg, CLASS, (void*)$var );
T_OBJECT
	sv_setref_pv( $arg, Nullch, (void*)$var );
O_HvRV
	$arg = sv_bless( newRV((SV*)$var), gv_stashpv(CLASS,1) );
T_HvRV
	$arg = newRV((SV*)$var);
O_AvRV
	$arg = sv_bless( newRV((SV*)$var), gv_stashpv(CLASS,1) );
T_AvRV
	$arg = newRV((SV*)$var);
T_STD_STRING
    $arg = newSVpvn( $var.c_str(), $var.length() );
T_STD_STRING_PTR
    $arg = newSVpvn( $var->c_str(), $var->length() );
T_STD_VECTOR_DOUBLE
	AV* av = newAV();
	$arg = newRV_noinc((SV*)av);
	const unsigned int len = $var.size();
	av_extend(av, len-1);
	for (unsigned int i = 0; i < len; i++) {
	  av_store(av, i, newSVnv(${var}[i]));
	}
T_STD_VECTOR_DOUBLE_PTR
	AV* av = newAV();
	$arg = newRV_noinc((SV*)av);
	const unsigned int len = $var->size();
	av_extend(av, len-1);
	for (unsigned int i = 0; i < len; i++) {
	  av_store(av, i, newSVnv((*$var)[i]));
	}
T_STD_VECTOR_INT
	AV* av = newAV();
	$arg = newRV_noinc((SV*)av);
	const unsigned int len = $var.size();
	av_extend(av, len-1);
	for (unsigned int i = 0; i < len; i++) {
	  av_store(av, i, newSViv(${var}[i]));
	}
T_STD_VECTOR_INT_PTR
	AV* av = newAV();
	$arg = newRV_noinc((SV*)av);
	const unsigned int len = $var->size();
	av_extend(av, len-1);
	for (unsigned int i = 0; i < len; i++) {
	  av_store(av, i, newSViv((*$var)[i]));
	}
T_STD_VECTOR_UINT
	AV* av = newAV();
	$arg = newRV_noinc((SV*)av);
	const unsigned int len = $var.size();
	av_extend(av, len-1);
	for (unsigned int i = 0; i < len; i++) {
	  av_store(av, i, newSVuv(${var}[i]));
	}
T_STD_VECTOR_UINT_PTR
	AV* av = newAV();
	$arg = newRV_noinc((SV*)av);
	const unsigned int len = $var->size();
	av_extend(av, len-1);
	for (unsigned int i = 0; i < len; i++) {
	  av_store(av, i, newSVuv((*$var)[i]));
	}
T_STD_VECTOR_STD_STRING
	AV* av = newAV();
	$arg = newRV_noinc((SV*)av);
	const unsigned int len = $var.size();
	av_extend(av, len-1);
	for (unsigned int i = 0; i < len; i++) {
	  const std::string& str = ${var}[i];
	  STRLEN len = str.length();
	  av_store(av, i, newSVpv(str.c_str(), len));
	}
T_STD_VECTOR_STD_STRING_PTR
	AV* av = newAV();
	$arg = newRV_noinc((SV*)av);
	const unsigned int len = $var->size();
	av_extend(av, len-1);
	for (unsigned int i = 0; i < len; i++) {
	  const std::string& str = (*$var)[i];
	  STRLEN len = str.length();
	  av_store(av, i, newSVpv(str.c_str(), len));
	}
T_STD_VECTOR_CSTRING
	AV* av = newAV();
	$arg = newRV_noinc((SV*)av);
	const unsigned int len = $var.size();
	av_extend(av, len-1);
	for (unsigned int i = 0; i < len; i++) {
	  STRLEN len = strlen(${var}[i]);
	  av_store(av, i, newSVpv(${var}[i], len));
	}
T_STD_VECTOR_CSTRING_PTR
	AV* av = newAV();
	$arg = newRV_noinc((SV*)av);
	const unsigned int len = $var->size();
	av_extend(av, len-1);
	for (unsigned int i = 0; i < len; i++) {
	  STRLEN len = strlen((*$var)[i]);
	  av_store(av, i, newSVpv((*$var)[i], len));
	}