@@ -352,6 +352,44 @@ struct contains_vector_derived_policies
352352 return contains_algo<key_type>::run (container, key);
353353 }
354354};
355+
356+ // /
357+ // / \brief Add standard method to a std::vector.
358+ // / \tparam NoProxy When set to false, the elements will be copied when
359+ // / returned to Python.
360+ // /
361+ template <typename Container, bool NoProxy, typename CoVisitor>
362+ struct ExposeStdMethodToStdVector
363+ : public boost::python::def_visitor<
364+ ExposeStdMethodToStdVector<Container, NoProxy, CoVisitor> > {
365+ typedef StdContainerFromPythonList<Container, NoProxy>
366+ FromPythonListConverter;
367+
368+ ExposeStdMethodToStdVector (const CoVisitor &co_visitor)
369+ : m_co_visitor(co_visitor) {}
370+
371+ template <class Class >
372+ void visit (Class &cl) const {
373+ cl.def (m_co_visitor)
374+ .def (" tolist" , &FromPythonListConverter::tolist, bp::arg (" self" ),
375+ " Returns the std::vector as a Python list." )
376+ .def (" reserve" , &Container::reserve,
377+ (bp::arg (" self" ), bp::arg (" new_cap" )),
378+ " Increase the capacity of the vector to a value that's greater "
379+ " or equal to new_cap." )
380+ .def (CopyableVisitor<Container>());
381+ }
382+
383+ const CoVisitor &m_co_visitor;
384+ };
385+
386+ // / Helper to ease ExposeStdMethodToStdVector construction
387+ template <typename Container, bool NoProxy, typename CoVisitor>
388+ static ExposeStdMethodToStdVector<Container, NoProxy, CoVisitor>
389+ createExposeStdMethodToStdVector (const CoVisitor &co_visitor) {
390+ return ExposeStdMethodToStdVector<Container, NoProxy, CoVisitor>(co_visitor);
391+ }
392+
355393} // namespace internal
356394
357395struct EmptyPythonVisitor
@@ -362,24 +400,16 @@ struct EmptyPythonVisitor
362400
363401// /
364402// / \brief Expose an std::vector from a type given as template argument.
365- // /
366- // / \tparam T Type to expose as std::vector<T>.
367- // / \tparam Allocator Type for the Allocator in std::vector<T,Allocator>.
368- // / \tparam NoProxy When set to false, the elements will be copied when returned
369- // / to Python. \tparam EnableFromPythonListConverter Enables the conversion from
370- // / a Python list to a std::vector<T,Allocator>
371- // /
372- // / \sa StdAlignedVectorPythonVisitor
403+ // / \tparam vector_type std::vector type to expose
404+ // / \tparam NoProxy When set to false, the elements will be copied when
405+ // / returned to Python.
406+ // / \tparam EnableFromPythonListConverter Enables the
407+ // / conversion from a Python list to a std::vector<T,Allocator>
373408// /
374409template <class vector_type , bool NoProxy = false ,
375410 bool EnableFromPythonListConverter = true >
376- struct StdVectorPythonVisitor
377- : public ::boost::python::vector_indexing_suite<
378- vector_type, NoProxy,
379- internal::contains_vector_derived_policies<vector_type, NoProxy> >,
380- public StdContainerFromPythonList<vector_type, NoProxy> {
411+ struct StdVectorPythonVisitor {
381412 typedef typename vector_type::value_type value_type;
382- typedef typename vector_type::allocator_type allocator_type;
383413 typedef StdContainerFromPythonList<vector_type, NoProxy>
384414 FromPythonListConverter;
385415
@@ -388,40 +418,42 @@ struct StdVectorPythonVisitor
388418 expose (class_name, doc_string, EmptyPythonVisitor ());
389419 }
390420
391- template <typename VisitorDerived>
392- static void expose (
393- const std::string &class_name,
394- const boost::python::def_visitor<VisitorDerived> &visitor) {
421+ template <typename Visitor>
422+ static void expose (const std::string &class_name, const Visitor &visitor) {
395423 expose (class_name, " " , visitor);
396424 }
397425
398- template <typename VisitorDerived>
399- static void expose (
400- const std::string &class_name, const std::string &doc_string,
401- const boost::python::def_visitor<VisitorDerived> &visitor) {
402- if (!register_symbolic_link_to_registered_type<vector_type>()) {
426+ template <typename Visitor>
427+ static void expose (const std::string &class_name,
428+ const std::string &doc_string, const Visitor &visitor) {
429+ // Apply visitor on already registered type or if type is not already
430+ // registered, we define and apply the visitor on it
431+ auto add_std_visitor =
432+ internal::createExposeStdMethodToStdVector<vector_type, NoProxy>(
433+ visitor);
434+ if (!register_symbolic_link_to_registered_type<vector_type>(
435+ add_std_visitor)) {
403436 bp::class_<vector_type> cl (class_name.c_str (), doc_string.c_str ());
404- cl.def (StdVectorPythonVisitor ())
405437
406- .def (bp::init<size_t , const value_type &>(
407- bp::args (" self" , " size" , " value" ),
408- " Constructor from a given size and a given value." ))
438+ // Standard vector indexing definition
439+ boost::python::vector_indexing_suite<
440+ vector_type, NoProxy,
441+ internal::contains_vector_derived_policies<vector_type, NoProxy> >
442+ vector_indexing;
443+
444+ cl.def (bp::init<size_t , const value_type &>(
445+ bp::args (" self" , " size" , " value" ),
446+ " Constructor from a given size and a given value." ))
409447 .def (bp::init<const vector_type &>(bp::args (" self" , " other" ),
410448 " Copy constructor" ))
411449
412- .def (" tolist" , &FromPythonListConverter::tolist, bp::arg (" self" ),
413- " Returns the std::vector as a Python list." )
414- .def (visitor)
415- .def (" reserve" , &vector_type::reserve,
416- (bp::arg (" self" ), bp::arg (" new_cap" )),
417- " Increase the capacity of the vector to a value that's greater "
418- " or equal to new_cap." )
419- .def_pickle (PickleVector<vector_type>())
420- .def (CopyableVisitor<vector_type>());
421-
450+ .def (vector_indexing)
451+ .def (add_std_visitor)
452+ .def_pickle (PickleVector<vector_type>());
453+ }
454+ if (EnableFromPythonListConverter) {
422455 // Register conversion
423- if (EnableFromPythonListConverter)
424- FromPythonListConverter::register_converter ();
456+ FromPythonListConverter::register_converter ();
425457 }
426458 }
427459};
@@ -436,7 +468,7 @@ void exposeStdVectorEigenSpecificType(const char *name) {
436468 typedef std::vector<MatType, Eigen::aligned_allocator<MatType> > VecMatType;
437469 std::string full_name = " StdVec_" ;
438470 full_name += name;
439- StdVectorPythonVisitor<VecMatType, false >::expose (
471+ StdVectorPythonVisitor<VecMatType>::expose (
440472 full_name.c_str (),
441473 details::overload_base_get_item_for_std_vector<VecMatType>());
442474}
0 commit comments