diff --git a/include/eigenpy/std-vector.hpp b/include/eigenpy/std-vector.hpp index e5a1894a7..77f78c951 100644 --- a/include/eigenpy/std-vector.hpp +++ b/include/eigenpy/std-vector.hpp @@ -352,60 +352,64 @@ struct contains_vector_derived_policies return contains_algo::run(container, key); } }; -} // namespace internal - -struct EmptyPythonVisitor - : public ::boost::python::def_visitor { - template - void visit(classT &) const {} -}; +/// /// \brief Add standard method to a std::vector. -template -struct add_std_method_to_std_vector +/// \tparam NoProxy When set to false, the elements will be copied when +/// returned to Python. +/// +template +struct AddStdMethodToStdVector : public boost::python::def_visitor< - add_std_method_to_std_vector > { - typedef typename Container::value_type value_type; - typedef typename Container::value_type data_type; - typedef size_t index_type; - + AddStdMethodToStdVector > { typedef StdContainerFromPythonList FromPythonListConverter; + AddStdMethodToStdVector(const CoVisitor &co_visitor) + : m_co_visitor(co_visitor) {} + template void visit(Class &cl) const { - details::overload_base_get_item_for_std_vector get_item_visitor; - cl.def("tolist", &FromPythonListConverter::tolist, bp::arg("self"), - "Returns the std::vector as a Python list.") - .def(get_item_visitor) + cl.def(m_co_visitor) + .def("tolist", &FromPythonListConverter::tolist, bp::arg("self"), + "Returns the std::vector as a Python list.") .def("reserve", &Container::reserve, (bp::arg("self"), bp::arg("new_cap")), "Increase the capacity of the vector to a value that's greater " "or equal to new_cap.") .def(CopyableVisitor()); } + + const CoVisitor &m_co_visitor; +}; + +/// Helper to ease AddStdMethodToStdVector construction +template +static AddStdMethodToStdVector +createAddStdMethodToStdVector(const CoVisitor &co_visitor) { + return AddStdMethodToStdVector(co_visitor); +} + +} // namespace internal + +struct EmptyPythonVisitor + : public ::boost::python::def_visitor { + template + void visit(classT &) const {} }; /// /// \brief Expose an std::vector from a type given as template argument. -/// -/// \tparam T Type to expose as std::vector. -/// \tparam Allocator Type for the Allocator in std::vector. +/// \tparam vector_type std::vector type to expose /// \tparam NoProxy When set to false, the elements will be copied when -/// returned to Python. \tparam EnableFromPythonListConverter Enables the +/// returned to Python. +/// \tparam EnableFromPythonListConverter Enables the /// conversion from a Python list to a std::vector /// -/// \sa StdAlignedVectorPythonVisitor -/// template -struct StdVectorPythonVisitor - : public ::boost::python::vector_indexing_suite< - vector_type, NoProxy, - internal::contains_vector_derived_policies >, - public StdContainerFromPythonList { +struct StdVectorPythonVisitor { typedef typename vector_type::value_type value_type; - typedef typename vector_type::allocator_type allocator_type; typedef StdContainerFromPythonList FromPythonListConverter; @@ -422,21 +426,34 @@ struct StdVectorPythonVisitor template static void expose(const std::string &class_name, const std::string &doc_string, const Visitor &visitor) { - if (!register_symbolic_link_to_registered_type(visitor)) { + // Apply visitor on already registered type or if type is not already + // registered, we define and apply the visitor on it + auto add_std_visitor = + internal::createAddStdMethodToStdVector(visitor); + if (!register_symbolic_link_to_registered_type( + add_std_visitor)) { bp::class_ cl(class_name.c_str(), doc_string.c_str()); - cl.def(StdVectorPythonVisitor()) - .def(bp::init( - bp::args("self", "size", "value"), - "Constructor from a given size and a given value.")) + // Standard vector indexing definition + boost::python::vector_indexing_suite< + vector_type, NoProxy, + internal::contains_vector_derived_policies > + vector_indexing; + + cl.def(bp::init( + bp::args("self", "size", "value"), + "Constructor from a given size and a given value.")) .def(bp::init(bp::args("self", "other"), "Copy constructor")) - .def(visitor) + .def(vector_indexing) + .def(add_std_visitor) .def_pickle(PickleVector()); } - // Register conversion - FromPythonListConverter::register_converter(); + if (EnableFromPythonListConverter) { + // Register conversion + FromPythonListConverter::register_converter(); + } } }; @@ -450,8 +467,9 @@ void exposeStdVectorEigenSpecificType(const char *name) { typedef std::vector > VecMatType; std::string full_name = "StdVec_"; full_name += name; - StdVectorPythonVisitor::expose( - full_name.c_str(), add_std_method_to_std_vector()); + StdVectorPythonVisitor::expose( + full_name.c_str(), + details::overload_base_get_item_for_std_vector()); } } // namespace eigenpy