Skip to content

Commit 5f1cc0e

Browse files
Joris Vaillantjcarpent
authored andcommitted
core: Preserve the old API and simplify some inheritance
1 parent 32515e7 commit 5f1cc0e

File tree

1 file changed

+58
-40
lines changed

1 file changed

+58
-40
lines changed

include/eigenpy/std-vector.hpp

Lines changed: 58 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -352,60 +352,64 @@ struct contains_vector_derived_policies
352352
return contains_algo<key_type>::run(container, key);
353353
}
354354
};
355-
} // namespace internal
356-
357-
struct EmptyPythonVisitor
358-
: public ::boost::python::def_visitor<EmptyPythonVisitor> {
359-
template <class classT>
360-
void visit(classT &) const {}
361-
};
362355

356+
///
363357
/// \brief Add standard method to a std::vector.
364-
template <typename Container, bool NoProxy = false>
365-
struct add_std_method_to_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 AddStdMethodToStdVector
366363
: public boost::python::def_visitor<
367-
add_std_method_to_std_vector<Container> > {
368-
typedef typename Container::value_type value_type;
369-
typedef typename Container::value_type data_type;
370-
typedef size_t index_type;
371-
364+
AddStdMethodToStdVector<Container, NoProxy, CoVisitor> > {
372365
typedef StdContainerFromPythonList<Container, NoProxy>
373366
FromPythonListConverter;
374367

368+
AddStdMethodToStdVector(const CoVisitor &co_visitor)
369+
: m_co_visitor(co_visitor) {}
370+
375371
template <class Class>
376372
void visit(Class &cl) const {
377-
details::overload_base_get_item_for_std_vector<Container> get_item_visitor;
378-
cl.def("tolist", &FromPythonListConverter::tolist, bp::arg("self"),
379-
"Returns the std::vector as a Python list.")
380-
.def(get_item_visitor)
373+
cl.def(m_co_visitor)
374+
.def("tolist", &FromPythonListConverter::tolist, bp::arg("self"),
375+
"Returns the std::vector as a Python list.")
381376
.def("reserve", &Container::reserve,
382377
(bp::arg("self"), bp::arg("new_cap")),
383378
"Increase the capacity of the vector to a value that's greater "
384379
"or equal to new_cap.")
385380
.def(CopyableVisitor<Container>());
386381
}
382+
383+
const CoVisitor &m_co_visitor;
384+
};
385+
386+
/// Helper to ease AddStdMethodToStdVector construction
387+
template <typename Container, bool NoProxy, typename CoVisitor>
388+
static AddStdMethodToStdVector<Container, NoProxy, CoVisitor>
389+
createAddStdMethodToStdVector(const CoVisitor &co_visitor) {
390+
return AddStdMethodToStdVector<Container, NoProxy, CoVisitor>(co_visitor);
391+
}
392+
393+
} // namespace internal
394+
395+
struct EmptyPythonVisitor
396+
: public ::boost::python::def_visitor<EmptyPythonVisitor> {
397+
template <class classT>
398+
void visit(classT &) const {}
387399
};
388400

389401
///
390402
/// \brief Expose an std::vector from a type given as template argument.
391-
///
392-
/// \tparam T Type to expose as std::vector<T>.
393-
/// \tparam Allocator Type for the Allocator in std::vector<T,Allocator>.
403+
/// \tparam vector_type std::vector type to expose
394404
/// \tparam NoProxy When set to false, the elements will be copied when
395-
/// returned to Python. \tparam EnableFromPythonListConverter Enables the
405+
/// returned to Python.
406+
/// \tparam EnableFromPythonListConverter Enables the
396407
/// conversion from a Python list to a std::vector<T,Allocator>
397408
///
398-
/// \sa StdAlignedVectorPythonVisitor
399-
///
400409
template <class vector_type, bool NoProxy = false,
401410
bool EnableFromPythonListConverter = true>
402-
struct StdVectorPythonVisitor
403-
: public ::boost::python::vector_indexing_suite<
404-
vector_type, NoProxy,
405-
internal::contains_vector_derived_policies<vector_type, NoProxy> >,
406-
public StdContainerFromPythonList<vector_type, NoProxy> {
411+
struct StdVectorPythonVisitor {
407412
typedef typename vector_type::value_type value_type;
408-
typedef typename vector_type::allocator_type allocator_type;
409413
typedef StdContainerFromPythonList<vector_type, NoProxy>
410414
FromPythonListConverter;
411415

@@ -422,21 +426,34 @@ struct StdVectorPythonVisitor
422426
template <typename Visitor>
423427
static void expose(const std::string &class_name,
424428
const std::string &doc_string, const Visitor &visitor) {
425-
if (!register_symbolic_link_to_registered_type<vector_type>(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::createAddStdMethodToStdVector<vector_type, NoProxy>(visitor);
433+
if (!register_symbolic_link_to_registered_type<vector_type>(
434+
add_std_visitor)) {
426435
bp::class_<vector_type> cl(class_name.c_str(), doc_string.c_str());
427-
cl.def(StdVectorPythonVisitor())
428436

429-
.def(bp::init<size_t, const value_type &>(
430-
bp::args("self", "size", "value"),
431-
"Constructor from a given size and a given value."))
437+
// Standard vector indexing definition
438+
boost::python::vector_indexing_suite<
439+
vector_type, NoProxy,
440+
internal::contains_vector_derived_policies<vector_type, NoProxy> >
441+
vector_indexing;
442+
443+
cl.def(bp::init<size_t, const value_type &>(
444+
bp::args("self", "size", "value"),
445+
"Constructor from a given size and a given value."))
432446
.def(bp::init<const vector_type &>(bp::args("self", "other"),
433447
"Copy constructor"))
434448

435-
.def(visitor)
449+
.def(vector_indexing)
450+
.def(add_std_visitor)
436451
.def_pickle(PickleVector<vector_type>());
437452
}
438-
// Register conversion
439-
FromPythonListConverter::register_converter();
453+
if (EnableFromPythonListConverter) {
454+
// Register conversion
455+
FromPythonListConverter::register_converter();
456+
}
440457
}
441458
};
442459

@@ -450,8 +467,9 @@ void exposeStdVectorEigenSpecificType(const char *name) {
450467
typedef std::vector<MatType, Eigen::aligned_allocator<MatType> > VecMatType;
451468
std::string full_name = "StdVec_";
452469
full_name += name;
453-
StdVectorPythonVisitor<VecMatType, false>::expose(
454-
full_name.c_str(), add_std_method_to_std_vector<VecMatType, false>());
470+
StdVectorPythonVisitor<VecMatType>::expose(
471+
full_name.c_str(),
472+
details::overload_base_get_item_for_std_vector<VecMatType>());
455473
}
456474

457475
} // namespace eigenpy

0 commit comments

Comments
 (0)