Commit 2b308e01 by Ivan Smirnov

Add support for iterators with differing end type

parent c5a1c8a6
...@@ -1117,8 +1117,10 @@ PYBIND11_NOINLINE inline void keep_alive_impl(int Nurse, int Patient, handle arg ...@@ -1117,8 +1117,10 @@ PYBIND11_NOINLINE inline void keep_alive_impl(int Nurse, int Patient, handle arg
keep_alive_impl(nurse, patient); keep_alive_impl(nurse, patient);
} }
template <typename Iterator, bool KeyIterator = false> struct iterator_state { template <typename Iterator, typename Sentinel, bool KeyIterator = false>
Iterator it, end; struct iterator_state {
Iterator it;
Sentinel end;
bool first; bool first;
}; };
...@@ -1127,10 +1129,11 @@ NAMESPACE_END(detail) ...@@ -1127,10 +1129,11 @@ NAMESPACE_END(detail)
template <typename... Args> detail::init<Args...> init() { return detail::init<Args...>(); } template <typename... Args> detail::init<Args...> init() { return detail::init<Args...>(); }
template <typename Iterator, template <typename Iterator,
typename Sentinel,
typename ValueType = decltype(*std::declval<Iterator>()), typename ValueType = decltype(*std::declval<Iterator>()),
typename... Extra> typename... Extra>
iterator make_iterator(Iterator first, Iterator last, Extra &&... extra) { iterator make_iterator(Iterator first, Sentinel last, Extra &&... extra) {
typedef detail::iterator_state<Iterator> state; typedef detail::iterator_state<Iterator, Sentinel> state;
if (!detail::get_type_info(typeid(state))) { if (!detail::get_type_info(typeid(state))) {
class_<state>(handle(), "") class_<state>(handle(), "")
...@@ -1149,10 +1152,11 @@ iterator make_iterator(Iterator first, Iterator last, Extra &&... extra) { ...@@ -1149,10 +1152,11 @@ iterator make_iterator(Iterator first, Iterator last, Extra &&... extra) {
return (iterator) cast(state { first, last, true }); return (iterator) cast(state { first, last, true });
} }
template <typename Iterator, template <typename Iterator,
typename Sentinel,
typename KeyType = decltype((*std::declval<Iterator>()).first), typename KeyType = decltype((*std::declval<Iterator>()).first),
typename... Extra> typename... Extra>
iterator make_key_iterator(Iterator first, Iterator last, Extra &&... extra) { iterator make_key_iterator(Iterator first, Sentinel last, Extra &&... extra) {
typedef detail::iterator_state<Iterator, true> state; typedef detail::iterator_state<Iterator, Sentinel, true> state;
if (!detail::get_type_info(typeid(state))) { if (!detail::get_type_info(typeid(state))) {
class_<state>(handle(), "") class_<state>(handle(), "")
......
...@@ -245,7 +245,7 @@ pybind11::class_<std::vector<T, Allocator>, holder_type> bind_vector(pybind11::m ...@@ -245,7 +245,7 @@ pybind11::class_<std::vector<T, Allocator>, holder_type> bind_vector(pybind11::m
cl.def("__iter__", cl.def("__iter__",
[](Vector &v) { [](Vector &v) {
return pybind11::make_iterator<ItType, T>(v.begin(), v.end()); return pybind11::make_iterator<ItType, ItType, T>(v.begin(), v.end());
}, },
pybind11::keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */ pybind11::keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */
); );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment