Skip to content

Commit 17c1e27

Browse files
authored
fix: Revert pfect args make iterator (#4234)
* Revert "chore: perfectly forward all make_iterator args (#3980)" This reverts commit 8da58da. * Redo unrelated optimization in commit * Add tests for ambiguous overloads
1 parent 91cfb77 commit 17c1e27

File tree

3 files changed

+35
-14
lines changed

3 files changed

+35
-14
lines changed

include/pybind11/pybind11.h

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2333,7 +2333,7 @@ template <typename Access,
23332333
typename Sentinel,
23342334
typename ValueType,
23352335
typename... Extra>
2336-
iterator make_iterator_impl(Iterator &&first, Sentinel &&last, Extra &&...extra) {
2336+
iterator make_iterator_impl(Iterator first, Sentinel last, Extra &&...extra) {
23372337
using state = detail::iterator_state<Access, Policy, Iterator, Sentinel, ValueType, Extra...>;
23382338
// TODO: state captures only the types of Extra, not the values
23392339

@@ -2359,7 +2359,7 @@ iterator make_iterator_impl(Iterator &&first, Sentinel &&last, Extra &&...extra)
23592359
Policy);
23602360
}
23612361

2362-
return cast(state{std::forward<Iterator>(first), std::forward<Sentinel>(last), true});
2362+
return cast(state{first, last, true});
23632363
}
23642364

23652365
PYBIND11_NAMESPACE_END(detail)
@@ -2370,15 +2370,13 @@ template <return_value_policy Policy = return_value_policy::reference_internal,
23702370
typename Sentinel,
23712371
typename ValueType = typename detail::iterator_access<Iterator>::result_type,
23722372
typename... Extra>
2373-
iterator make_iterator(Iterator &&first, Sentinel &&last, Extra &&...extra) {
2373+
iterator make_iterator(Iterator first, Sentinel last, Extra &&...extra) {
23742374
return detail::make_iterator_impl<detail::iterator_access<Iterator>,
23752375
Policy,
23762376
Iterator,
23772377
Sentinel,
23782378
ValueType,
2379-
Extra...>(std::forward<Iterator>(first),
2380-
std::forward<Sentinel>(last),
2381-
std::forward<Extra>(extra)...);
2379+
Extra...>(first, last, std::forward<Extra>(extra)...);
23822380
}
23832381

23842382
/// Makes a python iterator over the keys (`.first`) of a iterator over pairs from a
@@ -2388,15 +2386,13 @@ template <return_value_policy Policy = return_value_policy::reference_internal,
23882386
typename Sentinel,
23892387
typename KeyType = typename detail::iterator_key_access<Iterator>::result_type,
23902388
typename... Extra>
2391-
iterator make_key_iterator(Iterator &&first, Sentinel &&last, Extra &&...extra) {
2389+
iterator make_key_iterator(Iterator first, Sentinel last, Extra &&...extra) {
23922390
return detail::make_iterator_impl<detail::iterator_key_access<Iterator>,
23932391
Policy,
23942392
Iterator,
23952393
Sentinel,
23962394
KeyType,
2397-
Extra...>(std::forward<Iterator>(first),
2398-
std::forward<Sentinel>(last),
2399-
std::forward<Extra>(extra)...);
2395+
Extra...>(first, last, std::forward<Extra>(extra)...);
24002396
}
24012397

24022398
/// Makes a python iterator over the values (`.second`) of a iterator over pairs from a
@@ -2406,15 +2402,13 @@ template <return_value_policy Policy = return_value_policy::reference_internal,
24062402
typename Sentinel,
24072403
typename ValueType = typename detail::iterator_value_access<Iterator>::result_type,
24082404
typename... Extra>
2409-
iterator make_value_iterator(Iterator &&first, Sentinel &&last, Extra &&...extra) {
2405+
iterator make_value_iterator(Iterator first, Sentinel last, Extra &&...extra) {
24102406
return detail::make_iterator_impl<detail::iterator_value_access<Iterator>,
24112407
Policy,
24122408
Iterator,
24132409
Sentinel,
24142410
ValueType,
2415-
Extra...>(std::forward<Iterator>(first),
2416-
std::forward<Sentinel>(last),
2417-
std::forward<Extra>(extra)...);
2411+
Extra...>(first, last, std::forward<Extra>(extra)...);
24182412
}
24192413

24202414
/// Makes an iterator over values of an stl container or other container supporting

tests/test_sequences_and_iterators.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,4 +559,23 @@ TEST_SUBMODULE(sequences_and_iterators, m) {
559559
[]() { return py::make_iterator<py::return_value_policy::copy>(list); });
560560
m.def("make_iterator_2",
561561
[]() { return py::make_iterator<py::return_value_policy::automatic>(list); });
562+
563+
// test_iterator on c arrays
564+
// #4100: ensure lvalue required as increment operand
565+
class CArrayHolder {
566+
public:
567+
CArrayHolder(double x, double y, double z) {
568+
values[0] = x;
569+
values[1] = y;
570+
values[2] = z;
571+
};
572+
double values[3];
573+
};
574+
575+
py::class_<CArrayHolder>(m, "CArrayHolder")
576+
.def(py::init<double, double, double>())
577+
.def(
578+
"__iter__",
579+
[](const CArrayHolder &v) { return py::make_iterator(v.values, v.values + 3); },
580+
py::keep_alive<0, 1>());
562581
}

tests/test_sequences_and_iterators.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,3 +241,11 @@ def test_iterator_rvp():
241241
assert list(m.make_iterator_1()) == [1, 2, 3]
242242
assert list(m.make_iterator_2()) == [1, 2, 3]
243243
assert not isinstance(m.make_iterator_1(), type(m.make_iterator_2()))
244+
245+
246+
def test_carray_iterator():
247+
"""#4100: Check for proper iterator overload with C-Arrays"""
248+
args_gt = list(float(i) for i in range(3))
249+
arr_h = m.CArrayHolder(*args_gt)
250+
args = list(arr_h)
251+
assert args_gt == args

0 commit comments

Comments
 (0)