Boost logo

Boost :

From: John Hunter (jdhunter_at_[hidden])
Date: 2001-11-16 17:07:20


>>>>> "Paul" == Paul F Kunz <paul_kunz_at_[hidden]> writes:

    Paul> Its the second argument that has me stuck.

I have a template mechanism that exposes vector<T> to python. You can
instantiate a python vector<T> like

    VectorPy<float> vf( m, "VecFloats" );

which creates a python class VecFloats that can be passed to functions
expecting a vector<float>. You must include the header of any class
that you want to instantiate in VectorPy.cpp and use the macro
INSTANTIATE_TEMPLATE defined there. I have only tested this with gcc.

-- begin VectorPy.h --

/* VectorPy.h -- John Hunter
 */

#ifndef _VECTORPY_H
#define _VECTORPY_H

#include <vector>
#include <string>
#include <boost/python/class_builder.hpp>

namespace python = boost::python;
template<typename T>
class VectorPy : public python::class_builder<std::vector<T> >
{
public:
  VectorPy(python::module_builder& m, const string& className);
};

#endif

-- end VectorPy.h --

-- begin VectorPy.cpp --

#include <stringstream>
#include <string>
#include <boost/smart_ptr.hpp>
//#include "DateFinancialPy.h" //you can instantiate user defined classes too
#include "VectorPy.h"
 

template<typename T>
void
v_push_back( std::vector<T>& v, const T& x )
{
  v.push_back(x);
}

template<typename T>
T
v_get_item( const std::vector<T>& v, const size_t& i )
{

  /* problem with returning null because it returns an int where T is
     expected. This causes implicit type conversion and problems with
     some user classes as well as the boost ptr types.

  if ( i>=v.size()) {
    PyErr_SetString(PyExc_IndexError, "index out of range");
    return NULL;
  }
  */

  return v[i];
}

template<typename T>
void
v_set_item( std::vector<T>& v, const size_t& i, const T& val )
{
  v[i] = val;
}

template<typename T>
void
v_resize( std::vector<T>& v, const size_t& i )
{
  v.resize(i);
}

template<typename T>
void
v_clear( std::vector<T>& v )
{
  v.clear();
}

template<typename T>
size_t
v_size( const std::vector<T>& v )
{
  return v.size();
}

template<typename T>
VectorPy<T>::VectorPy(python::module_builder& m, const string& className )
  : boost::python::class_builder<std::vector<T> >(m, className.c_str() )
{
  
  def(python::constructor<>());
  def(python::constructor<size_t>());
  def(python::constructor<size_t,T>());
  def(v_push_back<T>, "push_back");
  def(v_size<T>, "size");
  def(v_resize<T>, "resize");
  def(v_clear<T>, "clear");
  def(v_get_item<T>, "__getitem__");
  def(v_set_item<T>, "__setitem__");

}

//template instantiations
#define INSTANTIATE_TEMPLATE(T) \
template class std::vector<T>;\
template void v_push_back( std::vector<T>&, const T&);\
template void v_resize( std::vector<T>&, const size_t& );\
template void v_clear( std::vector<T>& );\
template size_t v_size( const std::vector<T>&);\
template T v_get_item( const std::vector<T>&, const size_t& );\
template void v_set_item( std::vector<T>&, const size_t&, const T& );\
template class VectorPy<T>;

INSTANTIATE_TEMPLATE(float)
INSTANTIATE_TEMPLATE(int)
INSTANTIATE_TEMPLATE(string)
//INSTANTIATE_TEMPLATE(DateFinancial)

-- end VectorPy.cpp --


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk