7 #ifndef __eigenpy_utils_std_vector_hpp__
8 #define __eigenpy_utils_std_vector_hpp__
10 #include <boost/mpl/if.hpp>
11 #include <boost/python.hpp>
12 #include <boost/python/stl_iterator.hpp>
13 #include <boost/python/suite/indexing/vector_indexing_suite.hpp>
19 #include "eigenpy/config.hpp"
27 template <
typename vector_type,
bool NoProxy = false>
36 if (!PyList_Check(obj_ptr))
return false;
39 bp::object bp_obj(bp::handle<>(bp::borrowed(obj_ptr)));
40 bp::list bp_list(bp_obj);
41 bp::ssize_t list_size = bp::len(bp_list);
44 for (bp::ssize_t k = 0; k < list_size; ++k) {
45 bp::extract<T> elt(bp_list[k]);
46 if (!elt.check())
return false;
52 template <
typename vector_type,
bool NoProxy>
54 static ::boost::python::list
run(vector_type &
vec,
const bool deep_copy) {
58 for (
size_t k = 0; k <
vec.size(); ++k) {
65 template <
typename vector_type>
67 static ::boost::python::list
run(vector_type &
vec,
const bool) {
68 typedef bp::iterator<vector_type> iterator;
69 return bp::list(iterator()(
vec));
76 template <
typename Container>
78 :
public boost::python::def_visitor<
79 overload_base_get_item_for_std_vector<Container> > {
84 template <
class Class>
91 boost::python::back_reference<Container &> container, PyObject *i_) {
93 typename Container::iterator i = container.get().begin();
95 if (i == container.get().end()) {
96 PyErr_SetString(PyExc_KeyError,
"Invalid index");
97 bp::throw_error_already_set();
100 typename bp::to_python_indirect<
data_type &,
101 bp::detail::make_reference_holder>
103 return bp::object(bp::handle<>(convert(*i)));
107 bp::extract<long> i(i_);
110 if (index < 0) index += (long)container.size();
111 if (index >=
long(container.size()) || index < 0) {
112 PyErr_SetString(PyExc_IndexError,
"Index out of range");
113 bp::throw_error_already_set();
118 PyErr_SetString(PyExc_TypeError,
"Invalid index type");
119 bp::throw_error_already_set();
129 template <
typename MatrixType>
131 : converter::extract_rvalue<Eigen::Ref<MatrixType> > {
135 typedef converter::extract_rvalue<RefType>
base;
148 template <
typename Scalar,
int Rows,
int Cols,
int Options,
int MaxRows,
150 struct extract<
Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &>
152 Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> > {
153 typedef Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols>
160 template <
typename Derived>
161 struct extract<
Eigen::MatrixBase<Derived> &>
169 template <
typename Derived>
170 struct extract<
Eigen::RefBase<Derived> &>
178 namespace converter {
180 template <
typename Type,
class Allocator>
181 struct reference_arg_from_python<std::vector<Type, Allocator> &>
182 : arg_lvalue_from_python_base {
189 : arg_lvalue_from_python_base(converter::get_lvalue_from_python(
199 bool is_convertible =
201 if (!is_convertible)
return;
203 typedef ::eigenpy::StdContainerFromPythonList<vector_type> Constructor;
204 Constructor::construct(py_obj, &m_data.stage1);
206 void *&m_result =
const_cast<void *&
>(result());
207 m_result = m_data.stage1.convertible;
208 vec_ptr =
reinterpret_cast<vector_type *
>(m_data.storage.bytes);
212 return ::boost::python::detail::void_ptr_to_reference(result(),
217 if (m_data.stage1.convertible == m_data.storage.bytes) {
220 list bp_list(handle<>(borrowed(m_source)));
221 for (
size_t i = 0; i <
vec.size(); ++i) {
222 typename extract_type::result_type elt =
extract_type(bp_list[i]);
229 rvalue_from_python_data<ref_vector_type>
m_data;
242 template <
class Container>
248 template <
typename _Tp, std::
size_t Size>
259 template <
typename vector_type,
bool NoProxy>
261 typedef typename vector_type::value_type
T;
269 if (!PyList_Check(obj_ptr))
return 0;
272 bp::object bp_obj(bp::handle<>(bp::borrowed(obj_ptr)));
273 bp::list bp_list(bp_obj);
274 bp::ssize_t list_size = bp::len(bp_list);
277 for (bp::ssize_t k = 0; k < list_size; ++k) {
278 bp::extract<T> elt(bp_list[k]);
279 if (!elt.check())
return 0;
289 boost::python::converter::rvalue_from_python_stage1_data *memory) {
291 bp::object bp_obj(bp::handle<>(bp::borrowed(obj_ptr)));
292 bp::list bp_list(bp_obj);
296 bp::converter::rvalue_from_python_storage<vector_type> *
>(
297 reinterpret_cast<void *
>(memory))
300 typedef bp::stl_input_iterator<T> iterator;
303 new (storage) vector_type(iterator(bp_list), iterator());
306 memory->convertible = storage;
310 ::boost::python::converter::registry::push_back(
314 static ::boost::python::list
tolist(vector_type &
self,
315 const bool deep_copy =
false) {
322 template <
typename T,
323 bool has_operator_equal_value =
324 std::is_base_of<std::true_type, has_operator_equal<T> >
::value>
327 template <
typename T>
329 template <
class Container,
typename key_type>
330 static bool run(
const Container &container, key_type
const &key) {
331 return std::find(container.begin(), container.end(), key) !=
336 template <
typename T>
338 template <
class Container,
typename key_type>
339 static bool run(
const Container &container, key_type
const &key) {
340 for (
size_t k = 0; k < container.size(); ++k) {
341 if (&container[k] == &key)
return true;
347 template <
class Container,
bool NoProxy>
349 :
public ::boost::python::vector_indexing_suite<
351 contains_vector_derived_policies<Container, NoProxy> > {
364 template <
typename Container,
bool NoProxy,
typename CoVisitor>
366 :
public boost::python::def_visitor<
367 ExposeStdMethodToStdVector<Container, NoProxy, CoVisitor> > {
374 template <
class Class>
378 (bp::arg(
"self"), bp::arg(
"deep_copy") =
false),
379 "Returns the std::vector as a Python list.")
380 .def(
"reserve", &Container::reserve,
381 (bp::arg(
"self"), bp::arg(
"new_cap")),
382 "Increase the capacity of the vector to a value that's greater "
383 "or equal to new_cap.")
391 template <
typename Container,
bool NoProxy,
typename CoVisitor>
400 :
public ::boost::python::def_visitor<EmptyPythonVisitor> {
401 template <
class classT>
406 template <
typename vector_type,
bool T_picklable = false>
408 static void run(bp::class_<vector_type> &) {}
411 template <
typename vector_type>
413 static void run(bp::class_<vector_type> &cl) {
427 template <
class vector_type,
bool NoProxy =
false,
428 bool EnableFromPythonListConverter =
true,
bool pickable =
true>
434 static void expose(
const std::string &class_name,
435 const std::string &doc_string =
"") {
439 template <
typename DerivedVisitor>
440 static void expose(
const std::string &class_name,
441 const bp::def_visitor<DerivedVisitor> &visitor) {
442 expose(class_name,
"", visitor);
445 template <
typename DerivedVisitor>
446 static void expose(
const std::string &class_name,
447 const std::string &doc_string,
448 const bp::def_visitor<DerivedVisitor> &visitor) {
451 auto add_std_visitor =
452 internal::createExposeStdMethodToStdVector<vector_type, NoProxy>(
454 if (!register_symbolic_link_to_registered_type<vector_type>(
456 bp::class_<vector_type> cl(class_name.c_str(), doc_string.c_str());
459 boost::python::vector_indexing_suite<
460 vector_type, NoProxy,
464 cl.def(bp::init<size_t, const value_type &>(
465 bp::args(
"self",
"size",
"value"),
466 "Constructor from a given size and a given value."))
467 .def(bp::init<const vector_type &>(bp::args(
"self",
"other"),
470 .def(vector_indexing)
471 .def(add_std_visitor);
475 if (EnableFromPythonListConverter) {
487 template <
typename MatType>
489 typedef std::vector<MatType, Eigen::aligned_allocator<MatType> > VecMatType;
490 std::string full_name =
"StdVec_";
499 #endif // ifndef __eigenpy_utils_std_vector_hpp__