// SWIG typemaps for std::vector types
// ------------------------------------------------------------------------
// The aim of all that follows would be to integrate std::vector with
// Perl as much as possible, namely, to allow the user to pass and
// be returned Perl arrays.
// const declarations are used to guess the intent of the function being
// exported; therefore, the following rationale is applied:
// -- f(std::vector<T>), f(const std::vector<T>&), f(const std::vector<T>*):
// the parameter being read-only, either a Perl sequence or a
// previously wrapped std::vector<T> can be passed.
// -- f(std::vector<T>&), f(std::vector<T>*):
// the parameter must be modified; therefore, only a wrapped std::vector
// -- std::vector<T> f():
// the vector is returned by copy; therefore, a Perl sequence of T:s
// is returned which is most easily used in other Perl functions
// -- std::vector<T>& f(), std::vector<T>* f(), const std::vector<T>& f(),
// const std::vector<T>* f():
// the vector is returned by reference; therefore, a wrapped std::vector
// ------------------------------------------------------------------------
template<class T> class vector {
%typemap(in) vector<T> (std::vector<T>* v) {
if (SWIG_ConvertPtr($input,(void **) &v,
$&1_descriptor,1) != -1) {
} else if (SvROK($input)) {
AV *av = (AV *)SvRV($input);
if (SvTYPE(av) != SVt_PVAV)
SWIG_croak("Type error in argument $argnum of $symname. "
"Expected an array of " #T);
I32 len = av_len(av) + 1;
for (int i=0; i<len; i++) {
if (SWIG_ConvertPtr(*tv, (void **)&obj,
$descriptor(T *),0) != -1) {
SWIG_croak("Type error in argument $argnum of "
"Expected an array of " #T);
SWIG_croak("Type error in argument $argnum of $symname. "
"Expected an array of " #T);
%typemap(in) const vector<T>& (std::vector<T> temp,
const vector<T>* (std::vector<T> temp,
if (SWIG_ConvertPtr($input,(void **) &v,
$1_descriptor,1) != -1) {
} else if (SvROK($input)) {
AV *av = (AV *)SvRV($input);
if (SvTYPE(av) != SVt_PVAV)
SWIG_croak("Type error in argument $argnum of $symname. "
"Expected an array of " #T);
I32 len = av_len(av) + 1;
for (int i=0; i<len; i++) {
if (SWIG_ConvertPtr(*tv, (void **)&obj,
$descriptor(T *),0) != -1) {
SWIG_croak("Type error in argument $argnum of "
"Expected an array of " #T);
SWIG_croak("Type error in argument $argnum of $symname. "
"Expected an array of " #T);
%typemap(out) vector<T> {
for (unsigned int i=0; i<len; i++) {
SWIG_MakePtr(svs[i], (void*) ptr,
$descriptor(T *), $shadow|$owner);
AV *myav = av_make(len, svs);
$result = newRV_noinc((SV*) myav);
%typecheck(SWIG_TYPECHECK_VECTOR) vector<T> {
if (SWIG_ConvertPtr($input,(void **) &v,
$1_&descriptor,0) != -1) {
} else if (SvROK($input)) {
AV *av = (AV *)SvRV($input);
if (SvTYPE(av) == SVt_PVAV) {
I32 len = av_len(av) + 1;
/* an empty sequence can be of any type */
/* check the first element only */
if (SWIG_ConvertPtr(*tv, (void **)&obj,
$descriptor(T *),0) != -1)
%typecheck(SWIG_TYPECHECK_VECTOR) const vector<T>&,
if (SWIG_ConvertPtr($input,(void **) &v,
$1_descriptor,0) != -1) {
} else if (SvROK($input)) {
AV *av = (AV *)SvRV($input);
if (SvTYPE(av) == SVt_PVAV) {
I32 len = av_len(av) + 1;
/* an empty sequence can be of any type */
/* check the first element only */
if (SWIG_ConvertPtr(*tv, (void **)&obj,
$descriptor(T *),0) != -1)
vector(unsigned int size = 0);
vector(unsigned int size, const T& value);
vector(const vector<T> &);
unsigned int size() const;
void push_back(const T& x);
T pop() throw (std::out_of_range) {
throw std::out_of_range("pop from empty vector");
T& get(int i) throw (std::out_of_range) {
int size = int(self->size());
throw std::out_of_range("vector index out of range");
void set(int i, const T& x) throw (std::out_of_range) {
int size = int(self->size());
throw std::out_of_range("vector index out of range");
// specializations for built-ins
%define specialize_std_vector(T,CHECK_T,TO_T,FROM_T)
template<> class vector<T> {
%typemap(in) vector<T> (std::vector<T>* v) {
if (SWIG_ConvertPtr($input,(void **) &v,
$&1_descriptor,1) != -1){
} else if (SvROK($input)) {
AV *av = (AV *)SvRV($input);
if (SvTYPE(av) != SVt_PVAV)
SWIG_croak("Type error in argument $argnum of $symname. "
"Expected an array of " #T);
I32 len = av_len(av) + 1;
for (int i=0; i<len; i++) {
SWIG_croak("Type error in argument $argnum of "
"Expected an array of " #T);
SWIG_croak("Type error in argument $argnum of $symname. "
"Expected an array of " #T);
%typemap(in) const vector<T>& (std::vector<T> temp,
const vector<T>* (std::vector<T> temp,
if (SWIG_ConvertPtr($input,(void **) &v,
$1_descriptor,1) != -1) {
} else if (SvROK($input)) {
AV *av = (AV *)SvRV($input);
if (SvTYPE(av) != SVt_PVAV)
SWIG_croak("Type error in argument $argnum of $symname. "
"Expected an array of " #T);
I32 len = av_len(av) + 1;
for (int i=0; i<len; i++) {
temp.push_back(TO_T(*tv));
SWIG_croak("Type error in argument $argnum of "
"Expected an array of " #T);
SWIG_croak("Type error in argument $argnum of $symname. "
"Expected an array of " #T);
%typemap(out) vector<T> {
for (size_t i=0; i<len; i++) {
AV *myav = av_make(len, svs);
$result = newRV_noinc((SV*) myav);
%typecheck(SWIG_TYPECHECK_VECTOR) vector<T> {
if (SWIG_ConvertPtr($input,(void **) &v,
$1_&descriptor,0) != -1) {
} else if (SvROK($input)) {
AV *av = (AV *)SvRV($input);
if (SvTYPE(av) == SVt_PVAV) {
I32 len = av_len(av) + 1;
/* an empty sequence can be of any type */
/* check the first element only */
%typecheck(SWIG_TYPECHECK_VECTOR) const vector<T>&,
if (SWIG_ConvertPtr($input,(void **) &v,
$1_descriptor,0) != -1) {
} else if (SvROK($input)) {
AV *av = (AV *)SvRV($input);
if (SvTYPE(av) == SVt_PVAV) {
I32 len = av_len(av) + 1;
/* an empty sequence can be of any type */
/* check the first element only */
vector(unsigned int size = 0);
vector(unsigned int size, T value);
vector(const vector<T> &);
unsigned int size() const;
T pop() throw (std::out_of_range) {
throw std::out_of_range("pop from empty vector");
T get(int i) throw (std::out_of_range) {
int size = int(self->size());
throw std::out_of_range("vector index out of range");
void set(int i, T x) throw (std::out_of_range) {
int size = int(self->size());
throw std::out_of_range("vector index out of range");
specialize_std_vector(bool,SvIOK,SvIVX,sv_setiv);
specialize_std_vector(char,SvIOK,SvIVX,sv_setiv);
specialize_std_vector(int,SvIOK,SvIVX,sv_setiv);
specialize_std_vector(short,SvIOK,SvIVX,sv_setiv);
specialize_std_vector(long,SvIOK,SvIVX,sv_setiv);
specialize_std_vector(unsigned char,SvIOK,SvIVX,sv_setiv);
specialize_std_vector(unsigned int,SvIOK,SvIVX,sv_setiv);
specialize_std_vector(unsigned short,SvIOK,SvIVX,sv_setiv);
specialize_std_vector(unsigned long,SvIOK,SvIVX,sv_setiv);
specialize_std_vector(float,SvNIOK,SwigSvToNumber,sv_setnv);
specialize_std_vector(double,SvNIOK,SwigSvToNumber,sv_setnv);
specialize_std_vector(std::string,SvPOK,SvPVX,SwigSvFromString);