Skip to content

Commit

Permalink
Fix STL caster regression for containers with proxies
Browse files Browse the repository at this point in the history
  • Loading branch information
dean0x7d committed Sep 1, 2017
1 parent 61f70fc commit a7cc2cc
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 4 deletions.
8 changes: 8 additions & 0 deletions docs/changelog.rst
Expand Up @@ -11,6 +11,14 @@ v2.3.0 (Not yet released)

* TBD

v2.2.1 (Not yet released)
-----------------------------------------------------

* Fixed a regression where the automatic ``std::vector<bool>`` caster would
fail to compile. The same fix also applies to any container which returns
element proxies instead of references.
`#1053 <https://github.com/pybind/pybind11/pull/1053>`_.

v2.2.0 (August 31, 2017)
-----------------------------------------------------

Expand Down
8 changes: 4 additions & 4 deletions include/pybind11/stl.h
Expand Up @@ -83,7 +83,7 @@ template <typename Type, typename Key> struct set_caster {
template <typename T>
static handle cast(T &&src, return_value_policy policy, handle parent) {
pybind11::set s;
for (auto &value: src) {
for (auto &&value : src) {
auto value_ = reinterpret_steal<object>(key_conv::cast(forward_like<T>(value), policy, parent));
if (!value_ || !s.add(value_))
return handle();
Expand Down Expand Up @@ -117,7 +117,7 @@ template <typename Type, typename Key, typename Value> struct map_caster {
template <typename T>
static handle cast(T &&src, return_value_policy policy, handle parent) {
dict d;
for (auto &kv: src) {
for (auto &&kv : src) {
auto key = reinterpret_steal<object>(key_conv::cast(forward_like<T>(kv.first), policy, parent));
auto value = reinterpret_steal<object>(value_conv::cast(forward_like<T>(kv.second), policy, parent));
if (!key || !value)
Expand Down Expand Up @@ -159,7 +159,7 @@ template <typename Type, typename Value> struct list_caster {
static handle cast(T &&src, return_value_policy policy, handle parent) {
list l(src.size());
size_t index = 0;
for (auto &value: src) {
for (auto &&value : src) {
auto value_ = reinterpret_steal<object>(value_conv::cast(forward_like<T>(value), policy, parent));
if (!value_)
return handle();
Expand Down Expand Up @@ -213,7 +213,7 @@ template <typename ArrayType, typename Value, bool Resizable, size_t Size = 0> s
static handle cast(T &&src, return_value_policy policy, handle parent) {
list l(src.size());
size_t index = 0;
for (auto &value: src) {
for (auto &&value : src) {
auto value_ = reinterpret_steal<object>(value_conv::cast(forward_like<T>(value), policy, parent));
if (!value_)
return handle();
Expand Down
5 changes: 5 additions & 0 deletions tests/test_stl.cpp
Expand Up @@ -48,6 +48,11 @@ TEST_SUBMODULE(stl, m) {
// test_vector
m.def("cast_vector", []() { return std::vector<int>{1}; });
m.def("load_vector", [](const std::vector<int> &v) { return v.at(0) == 1 && v.at(1) == 2; });
// `std::vector<bool>` is special because it returns a proxy object instead of reference
m.def("cast_bool_vector", []() { return std::vector<bool>{true, false}; });
m.def("load_bool_vector", [](const std::vector<bool> &v) {
return v.at(0) == true && v.at(1) == false;
});
// Unnumbered regression (caused by #936): pointers to stl containers aren't castable
static std::vector<RValueCaster> lvv{2};
m.def("cast_ptr_vector", []() { return &lvv; });
Expand Down
3 changes: 3 additions & 0 deletions tests/test_stl.py
Expand Up @@ -12,6 +12,9 @@ def test_vector(doc):
assert m.load_vector(l)
assert m.load_vector(tuple(l))

assert m.cast_bool_vector() == [True, False]
assert m.load_bool_vector([True, False])

assert doc(m.cast_vector) == "cast_vector() -> List[int]"
assert doc(m.load_vector) == "load_vector(arg0: List[int]) -> bool"

Expand Down

0 comments on commit a7cc2cc

Please sign in to comment.