Skip to content

Commit 91d5fcb

Browse files
committed
[std-map] fix for non-default constructible types
1 parent 826798a commit 91d5fcb

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

include/eigenpy/std-map.hpp

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,45 @@ struct dict_to_map {
159159
}
160160
};
161161

162+
/// Policies which handle the non-default constructible case
163+
/// and set_item() using emplace().
164+
template <class Container, bool NoProxy>
165+
struct emplace_set_derived_policies
166+
: bp::map_indexing_suite<
167+
Container, NoProxy,
168+
emplace_set_derived_policies<Container, NoProxy> > {
169+
typedef typename Container::key_type index_type;
170+
typedef typename Container::value_type::second_type data_type;
171+
typedef typename Container::value_type value_type;
172+
using DerivedPolicies =
173+
bp::detail::final_map_derived_policies<Container, NoProxy>;
174+
175+
template <class Class>
176+
static void extension_def(Class& cl) {
177+
// Wrap the map's element (value_type)
178+
std::string elem_name = "map_indexing_suite_";
179+
bp::object class_name(cl.attr("__name__"));
180+
bp::extract<std::string> class_name_extractor(class_name);
181+
elem_name += class_name_extractor();
182+
elem_name += "_entry";
183+
namespace mpl = boost::mpl;
184+
185+
typedef typename mpl::if_<
186+
mpl::and_<boost::is_class<data_type>, mpl::bool_<!NoProxy> >,
187+
bp::return_internal_reference<>, bp::default_call_policies>::type
188+
get_data_return_policy;
189+
190+
bp::class_<value_type>(elem_name.c_str(), bp::no_init)
191+
.def("__repr__", &DerivedPolicies::print_elem)
192+
.def("data", &DerivedPolicies::get_data, get_data_return_policy())
193+
.def("key", &DerivedPolicies::get_key);
194+
}
195+
196+
static void set_item(Container& container, index_type i, data_type const& v) {
197+
container.emplace(i, v);
198+
}
199+
};
200+
162201
/**
163202
* @brief Expose the map-like container, e.g. (std::map).
164203
*
@@ -167,8 +206,9 @@ struct dict_to_map {
167206
* returned to Python.
168207
*/
169208
template <class Container, bool NoProxy = false>
170-
struct GenericMapVisitor : public bp::map_indexing_suite<Container, NoProxy>,
171-
public dict_to_map<Container> {
209+
struct GenericMapVisitor
210+
: public emplace_set_derived_policies<Container, NoProxy>,
211+
public dict_to_map<Container> {
172212
typedef dict_to_map<Container> FromPythonDictConverter;
173213

174214
static void expose(const std::string& class_name,

unittest/std_map.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ boost::unordered_map<std::string, T1> copy_boost(
2828
return obj;
2929
}
3030

31+
struct X {
32+
X() = delete;
33+
X(int x) : val(x) {}
34+
int val;
35+
};
36+
3137
BOOST_PYTHON_MODULE(std_map) {
3238
eigenpy::enableEigenPy();
3339

@@ -39,6 +45,8 @@ BOOST_PYTHON_MODULE(std_map) {
3945
eigenpy::GenericMapVisitor<boost::unordered_map<std::string, int> >::expose(
4046
"boost_map_int");
4147

48+
eigenpy::GenericMapVisitor<std::map<std::string, X> >::expose("StdMap_X");
49+
4250
bp::def("std_map_to_dict", std_map_to_dict<double>);
4351
bp::def("copy", copy<double>);
4452
bp::def("copy_boost", copy_boost<int>);

0 commit comments

Comments
 (0)