| Store | Cart

[C++-sig] boost python writing converters for list to std::vector<T>

From: Helfer Thomas <helf...@free.fr>
Fri, 20 Apr 2012 17:45:37 +0200
Hi,

using
http://misspent.wordpress.com/2009/09/27/how-to-write-boost-python-converters/, I tried to write a converter for list to std::vector<T> (In the example, T will be double).

The code (see converter.cxx) I wrote is still in early stage of
development (no check) but compiles fine on ubuntu oneiric with boost
python 1.46. I used it to create an std module. However, a simple test
(see test.py) does not work as exepted.

Did I misunderstood something or does boost have a special treatment for
the list object which bypasses converters ? 

Thanks for any help,

Sincerly,

Helfer THomas

#include<vector>
#include<iostream>
#include<algorithm>
#include<iterator>

#include<boost/python.hpp>

template<typename T>
struct Vector_to_python_list
{
   
  static PyObject* convert(std::vector<T> const& v)
  {
    using namespace std;
    using namespace boost::python;
    using boost::python::list;
    list l;
    typename vector<T>::const_iterator p;
    for(p=v.begin();p!=v.end();++p){
      l.append(object(*p));
    }
    return incref(l.ptr());
  }
};
 
template<typename T>
struct Vector_from_python_list
{

    Vector_from_python_list()
    {
      using namespace boost::python;
      using namespace boost::python::converter;
      registry::push_back(&Vector_from_python_list<T>::convertible,
			  &Vector_from_python_list<T>::construct,
			  type_id<std::vector<T> >());
    }
 
    // Determine if obj_ptr can be converted in a std::vector<T>
    static void* convertible(PyObject* obj_ptr)
    {
      if (!PyList_Check(obj_ptr)){
	return 0;
      }
      return obj_ptr;
    }
 
    // Convert obj_ptr into a std::vector<T>
    static void construct(
    PyObject* obj_ptr,
    boost::python::converter::rvalue_from_python_stage1_data* data)
    {
      using namespace boost::python;
      // Extract the character data from the python string
      //      const char* value = PyString_AsString(obj_ptr);
      list l(handle<>(borrowed(obj_ptr)));

      // // Verify that obj_ptr is a string (should be ensured by convertible())
      // assert(value);
 
      // Grab pointer to memory into which to construct the new std::vector<T>
      void* storage = (
        (boost::python::converter::rvalue_from_python_storage<std::vector<T> >*)
        data)->storage.bytes;
 
      // in-place construct the new std::vector<T> using the character data
      // extraced from the python object
      std::vector<T>& v = *(new (storage) std::vector<T>());
 
      // populate the vector from list contains !!!
      int le = len(l);
      v.resize(le);
      for(int i = 0;i!=le;++i){
	v[i] = extract<T>(l[i]);
      }

      // Stash the memory chunk pointer for later use by boost.python
      data->convertible = storage;
    }
};
 
void initializeConverters()
{
}

void
print(std::vector<double>&v)
{
  using namespace std;
  copy(v.begin(),v.end(),
       ostream_iterator<double>(cout," "));
  cout << endl;
}

BOOST_PYTHON_MODULE(std)
{
  using namespace boost::python;
  using namespace boost::python;

  // register the to-python converter
  to_python_converter<
    std::vector<double>,
    Vector_to_python_list<double> >();
 
  // register the from-python converter
    Vector_from_python_list<double>();

  def("display",print);
}

import std
std.display([3.,12.])

_______________________________________________
Cplusplus-sig mailing list
Cplu...@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig
Recent Messages in this Thread
Helfer Thomas Apr 20, 2012 03:45 pm
Jim Bosch Apr 23, 2012 03:28 pm
Messages in this thread