std-vector.hpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2016-2020 CNRS INRIA
3 //
4 
5 #ifndef __pinocchio_python_utils_std_vector_hpp__
6 #define __pinocchio_python_utils_std_vector_hpp__
7 
8 #include <boost/python.hpp>
9 #include <boost/python/stl_iterator.hpp>
10 #include <boost/python/suite/indexing/vector_indexing_suite.hpp>
11 
12 #include <string>
13 #include <vector>
14 #include <iterator>
15 
17 
18 namespace pinocchio
19 {
20  namespace python
21  {
22 
23  namespace details
24  {
25  template<typename Container>
27  : public boost::python::def_visitor< overload_base_get_item_for_std_vector<Container> >
28  {
30  typedef typename Container::value_type data_type;
31  typedef size_t index_type;
32 
33  template <class Class>
34  void visit(Class& cl) const
35  {
36  cl
37  .def("__getitem__", &base_get_item);
38  }
39 
40  private:
41 
42  static boost::python::object
43  base_get_item(boost::python::back_reference<Container&> container, PyObject* i_)
44  {
45  namespace bp = ::boost::python;
46 
47  index_type idx = convert_index(container.get(), i_);
48  typename Container::iterator i = container.get().begin();
49  std::advance(i, idx);
50  if (i == container.get().end())
51  {
52  PyErr_SetString(PyExc_KeyError, "Invalid index");
53  bp::throw_error_already_set();
54  }
55 
56  typename bp::to_python_indirect<data_type&,bp::detail::make_reference_holder> convert;
57  return bp::object(bp::handle<>(convert(*i)));
58  }
59 
60  static index_type
61  convert_index(Container & container, PyObject* i_)
62  {
63  namespace bp = boost::python;
64  bp::extract<long> i(i_);
65  if (i.check())
66  {
67  long index = i();
68  if (index < 0)
69  index += container.size();
70  if (index >= long(container.size()) || index < 0)
71  {
72  PyErr_SetString(PyExc_IndexError, "Index out of range");
73  bp::throw_error_already_set();
74  }
75  return index;
76  }
77 
78  PyErr_SetString(PyExc_TypeError, "Invalid index type");
79  bp::throw_error_already_set();
80  return index_type();
81  }
82  };
83  }
84 
90  template<typename vector_type>
92  {
93  typedef typename vector_type::value_type T;
94 
96  static void* convertible(PyObject* obj_ptr)
97  {
98  namespace bp = boost::python;
99 
100  // Check if it is a list
101  if(!PyList_Check(obj_ptr)) return 0;
102 
103  // Retrieve the underlying list
104  bp::object bp_obj(bp::handle<>(bp::borrowed(obj_ptr)));
105  bp::list bp_list(bp_obj);
106  bp::ssize_t list_size = bp::len(bp_list);
107 
108  // Check if all the elements contained in the current vector is of type T
109  for(bp::ssize_t k = 0; k < list_size; ++k)
110  {
111  bp::extract<T> elt(bp_list[k]);
112  if(!elt.check()) return 0;
113  }
114 
115  return obj_ptr;
116  }
117 
119  static void construct(PyObject* obj_ptr,
120  boost::python::converter::rvalue_from_python_stage1_data * memory)
121  {
122  namespace bp = boost::python;
123 
124  // Extract the list
125  bp::object bp_obj(bp::handle<>(bp::borrowed(obj_ptr)));
126  bp::list bp_list(bp_obj);
127 
128  void * storage = reinterpret_cast< bp::converter::rvalue_from_python_storage<vector_type>*>
129  (reinterpret_cast<void*>(memory))->storage.bytes;
130 
131  typedef bp::stl_input_iterator<T> iterator;
132 
133  // Build the std::vector
134  new (storage) vector_type(iterator(bp_list),
135  iterator());
136 
137  // Validate the construction
138  memory->convertible = storage;
139  }
140 
141  static void register_converter()
142  {
143  ::boost::python::converter::registry::push_back(&convertible,
144  &construct,
145  ::boost::python::type_id<vector_type>());
146  }
147 
148  static ::boost::python::list tolist(vector_type & self)
149  {
150  namespace bp = boost::python;
151 
152  typedef bp::iterator<vector_type> iterator;
153  bp::list python_list(iterator()(self));
154 
155  return python_list;
156  }
157  };
158 
169  template<class T, class Allocator = std::allocator<T>, bool NoProxy = false, bool EnableFromPythonListConverter = true>
171  : public ::boost::python::vector_indexing_suite<typename std::vector<T,Allocator>, NoProxy>
172  , public StdContainerFromPythonList< std::vector<T,Allocator> >
173  {
174  typedef std::vector<T,Allocator> vector_type;
176 
177  static ::boost::python::class_<vector_type> expose(const std::string & class_name,
178  const std::string & doc_string = "")
179  {
180  namespace bp = boost::python;
181 
182  bp::class_<vector_type> cl(class_name.c_str(),doc_string.c_str());
183  cl
184  .def(StdVectorPythonVisitor())
185  .def("tolist",&FromPythonListConverter::tolist,bp::arg("self"),
186  "Returns the std::vector as a Python list.")
187  .def_pickle(PickleVector<vector_type>());
188 
189  // Register conversion
190  if(EnableFromPythonListConverter)
191  FromPythonListConverter::register_converter();
192 
193  return cl;
194  }
195  };
196 
197  } // namespace python
198 } // namespace pinocchio
199 
200 #endif // ifndef __pinocchio_python_utils_std_vector_hpp__
static boost::python::object base_get_item(boost::python::back_reference< Container & > container, PyObject *i_)
Definition: std-vector.hpp:43
::boost::python::list tolist(vector_type &self)
Definition: std-vector.hpp:148
static void * convertible(PyObject *obj_ptr)
Check if obj_ptr can be converted.
Definition: std-vector.hpp:96
StdContainerFromPythonList< vector_type > FromPythonListConverter
Definition: std-vector.hpp:175
static void construct(PyObject *obj_ptr, boost::python::converter::rvalue_from_python_stage1_data *memory)
Allocate the std::vector and fill it with the element contained in the list.
Definition: std-vector.hpp:119
Expose an std::vector from a type given as template argument.
Definition: std-vector.hpp:170
Register the conversion from a Python list to a std::vector.
Definition: std-vector.hpp:91
static index_type convert_index(Container &container, PyObject *i_)
Definition: std-vector.hpp:61
Scalar value_type
Definition: eigen_plugin.hpp:2
std::vector< T, Allocator > vector_type
Definition: std-vector.hpp:174
static::boost::python::class_< vector_type > expose(const std::string &class_name, const std::string &doc_string="")
Definition: std-vector.hpp:177
Create a pickle interface for the std::vector and aligned vector.
Main pinocchio namespace.
Definition: timings.cpp:30


pinocchio
Author(s):
autogenerated on Tue Jun 1 2021 02:45:04