Skip to content

Commit 49c04c3

Browse files
committed
fix: regression in #3271
1 parent 0fb981b commit 49c04c3

File tree

3 files changed

+15
-6
lines changed

3 files changed

+15
-6
lines changed

include/pybind11/pybind11.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1967,26 +1967,26 @@ struct iterator_state {
19671967

19681968
// Note: these helpers take the iterator by non-const reference because some
19691969
// iterators in the wild can't be dereferenced when const.
1970-
template <typename Iterator>
1970+
template <typename Iterator, typename ResultType = decltype(*std::declval<Iterator>())>
19711971
struct iterator_access {
1972-
using result_type = decltype((*std::declval<Iterator>()));
1972+
using result_type = ResultType;
19731973
// NOLINTNEXTLINE(readability-const-return-type) // PR #3263
19741974
result_type operator()(Iterator &it) const {
19751975
return *it;
19761976
}
19771977
};
19781978

1979-
template <typename Iterator>
1979+
template <typename Iterator, typename ResultType = decltype((*std::declval<Iterator>()).first) >
19801980
struct iterator_key_access {
1981-
using result_type = decltype(((*std::declval<Iterator>()).first));
1981+
using result_type = ResultType;
19821982
result_type operator()(Iterator &it) const {
19831983
return (*it).first;
19841984
}
19851985
};
19861986

1987-
template <typename Iterator>
1987+
template <typename Iterator, typename ResultType = decltype((*std::declval<Iterator>()).second)>
19881988
struct iterator_value_access {
1989-
using result_type = decltype(((*std::declval<Iterator>()).second));
1989+
using result_type = ResultType;
19901990
result_type operator()(Iterator &it) const {
19911991
return (*it).second;
19921992
}

tests/test_sequences_and_iterators.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ TEST_SUBMODULE(sequences_and_iterators, m) {
306306
public:
307307
explicit IntPairs(std::vector<std::pair<int, int>> data) : data_(std::move(data)) {}
308308
const std::pair<int, int>* begin() const { return data_.data(); }
309+
const std::pair<int, int>* end() const { return data_.data() + data_.size(); }
309310
private:
310311
std::vector<std::pair<int, int>> data_;
311312
};
@@ -320,6 +321,10 @@ TEST_SUBMODULE(sequences_and_iterators, m) {
320321
.def("nonzero_values", [](const IntPairs& s) {
321322
return py::make_value_iterator(NonZeroIterator<std::pair<int, int>>(s.begin()), NonZeroSentinel());
322323
}, py::keep_alive<0, 1>())
324+
// test iterator with keep_alive (doesn't work, but tests compile)
325+
.def("make_iterator_keep_alive", [](IntPairs& self) {
326+
return py::make_iterator(self, py::keep_alive<0, 1>());
327+
}, py::keep_alive<0, 1>())
323328
;
324329

325330
// test_iterater_referencing

tests/test_sequences_and_iterators.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ def test_generalized_iterators():
2121
assert list(m.IntPairs([(1, 2), (2, 0), (0, 3), (4, 5)]).nonzero()) == [(1, 2)]
2222
assert list(m.IntPairs([(0, 3), (1, 2), (3, 4)]).nonzero()) == []
2323

24+
# keep_alive can't be attached
25+
with pytest.raises(RuntimeError):
26+
m.IntPairs([(1, 2), (3, 4), (0, 5)]).make_iterator_keep_alive()
27+
2428
assert list(m.IntPairs([(1, 2), (3, 4), (0, 5)]).nonzero_keys()) == [1, 3]
2529
assert list(m.IntPairs([(1, 2), (2, 0), (0, 3), (4, 5)]).nonzero_keys()) == [1]
2630
assert list(m.IntPairs([(0, 3), (1, 2), (3, 4)]).nonzero_keys()) == []

0 commit comments

Comments
 (0)