Skip to content

Commit 51de65c

Browse files
committed
[std-map] add more general visitor for map types
+ test boost::unordered_map + pull StdMapPythonVisitor out of eigenpy::python namespace (shouldn't exist, add using-decl for backwards compatibility)
1 parent 9537d8f commit 51de65c

File tree

3 files changed

+41
-19
lines changed

3 files changed

+41
-19
lines changed

include/eigenpy/std-map.hpp

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,6 @@ struct overload_base_get_item_for_std_map
7070
// Rohan Budhiraja.
7171
///////////////////////////////////////////////////////////////////////////////
7272

73-
namespace python {
74-
7573
namespace bp = boost::python;
7674

7775
/**
@@ -162,39 +160,50 @@ struct dict_to_map {
162160
};
163161

164162
/**
165-
* @brief Expose an std::map from a type given as template argument.
163+
* @brief Expose the map-like container, e.g. (std::map).
166164
*
167-
* @param[in] T Type to expose as std::map<T>.
168-
* @param[in] Compare Type for the Compare in std::map<T,Compare,Allocator>.
169-
* @param[in] Allocator Type for the Allocator in
170-
* std::map<T,Compare,Allocator>.
165+
* @param[in] Container Container to expose.
171166
* @param[in] NoProxy When set to false, the elements will be copied when
172167
* returned to Python.
173168
*/
174-
template <class Key, class T, class Compare = std::less<Key>,
175-
class Allocator = std::allocator<std::pair<const Key, T> >,
176-
bool NoProxy = false>
177-
struct StdMapPythonVisitor
178-
: public bp::map_indexing_suite<
179-
typename std::map<Key, T, Compare, Allocator>, NoProxy>,
180-
public dict_to_map<std::map<Key, T, Compare, Allocator> > {
181-
typedef std::map<Key, T, Compare, Allocator> Container;
169+
template <class Container, bool NoProxy = false>
170+
struct GenericMapVisitor : public bp::map_indexing_suite<Container, NoProxy>,
171+
public dict_to_map<Container> {
182172
typedef dict_to_map<Container> FromPythonDictConverter;
183173

184174
static void expose(const std::string& class_name,
185175
const std::string& doc_string = "") {
186176
namespace bp = bp;
187177

188178
bp::class_<Container>(class_name.c_str(), doc_string.c_str())
189-
.def(StdMapPythonVisitor())
179+
.def(GenericMapVisitor())
190180
.def("todict", &FromPythonDictConverter::todict, bp::arg("self"),
191-
"Returns the std::map as a Python dictionary.")
181+
"Returns the map type as a Python dictionary.")
192182
.def_pickle(PickleMap<Container>());
193183
// Register conversion
194184
FromPythonDictConverter::register_converter();
195185
}
196186
};
197187

188+
/**
189+
* @brief Expose an std::map from a type given as template argument.
190+
*
191+
* @param[in] T Type to expose as std::map<T>.
192+
* @param[in] Compare Type for the Compare in std::map<T,Compare,Allocator>.
193+
* @param[in] Allocator Type for the Allocator in
194+
* std::map<T,Compare,Allocator>.
195+
* @param[in] NoProxy When set to false, the elements will be copied when
196+
* returned to Python.
197+
*/
198+
template <class Key, class T, class Compare = std::less<Key>,
199+
class Allocator = std::allocator<std::pair<const Key, T> >,
200+
bool NoProxy = false>
201+
struct StdMapPythonVisitor
202+
: GenericMapVisitor<std::map<Key, T, Compare, Allocator>, NoProxy> {};
203+
204+
namespace python {
205+
// fix previous mistake
206+
using ::eigenpy::StdMapPythonVisitor;
198207
} // namespace python
199208
} // namespace eigenpy
200209

unittest/python/test_std_map.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
from std_map import copy, std_map_to_dict
1+
from std_map import copy, copy_boost, std_map_to_dict
22

33
t = {"one": 1.0, "two": 2.0}
4+
t2 = {"one": 1, "two": 2, "three": 3}
45

56
assert std_map_to_dict(t) == t
67
assert std_map_to_dict(copy(t)) == t
8+
m = copy_boost(t2)
9+
assert m.todict() == t2

unittest/std_map.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
#include <eigenpy/eigenpy.hpp>
55
#include <eigenpy/std-map.hpp>
6-
#include <iostream>
6+
#include <boost/unordered_map.hpp>
77

88
namespace bp = boost::python;
99

@@ -22,6 +22,12 @@ std::map<std::string, T1> copy(const std::map<std::string, T1>& map) {
2222
return out;
2323
}
2424

25+
template <typename T1>
26+
boost::unordered_map<std::string, T1> copy_boost(
27+
const boost::unordered_map<std::string, T1>& obj) {
28+
return obj;
29+
}
30+
2531
BOOST_PYTHON_MODULE(std_map) {
2632
eigenpy::enableEigenPy();
2733

@@ -30,6 +36,10 @@ BOOST_PYTHON_MODULE(std_map) {
3036
std::allocator<std::pair<const std::string, double> >,
3137
true>::expose("StdMap_Double");
3238

39+
eigenpy::GenericMapVisitor<boost::unordered_map<std::string, int> >::expose(
40+
"boost_map_int");
41+
3342
bp::def("std_map_to_dict", std_map_to_dict<double>);
3443
bp::def("copy", copy<double>);
44+
bp::def("copy_boost", copy_boost<int>);
3545
}

0 commit comments

Comments
 (0)