Merge pull request #353 from aldanor/feature/generalized-iterators

Add support for iterators with different begin/end types
This commit is contained in:
Wenzel Jakob
2016-08-25 01:47:38 +02:00
committed by GitHub
5 changed files with 61 additions and 10 deletions

View File

@@ -1119,8 +1119,10 @@ PYBIND11_NOINLINE inline void keep_alive_impl(int Nurse, int Patient, handle arg
keep_alive_impl(nurse, patient);
}
template <typename Iterator, bool KeyIterator = false> struct iterator_state {
Iterator it, end;
template <typename Iterator, typename Sentinel, bool KeyIterator = false>
struct iterator_state {
Iterator it;
Sentinel end;
bool first;
};
@@ -1129,10 +1131,11 @@ NAMESPACE_END(detail)
template <typename... Args> detail::init<Args...> init() { return detail::init<Args...>(); }
template <typename Iterator,
typename Sentinel,
typename ValueType = decltype(*std::declval<Iterator>()),
typename... Extra>
iterator make_iterator(Iterator first, Iterator last, Extra &&... extra) {
typedef detail::iterator_state<Iterator> state;
iterator make_iterator(Iterator first, Sentinel last, Extra &&... extra) {
typedef detail::iterator_state<Iterator, Sentinel> state;
if (!detail::get_type_info(typeid(state))) {
class_<state>(handle(), "")
@@ -1151,10 +1154,11 @@ iterator make_iterator(Iterator first, Iterator last, Extra &&... extra) {
return (iterator) cast(state { first, last, true });
}
template <typename Iterator,
typename KeyType = decltype(std::declval<Iterator>()->first),
typename Sentinel,
typename KeyType = decltype((*std::declval<Iterator>()).first),
typename... Extra>
iterator make_key_iterator(Iterator first, Iterator last, Extra &&... extra) {
typedef detail::iterator_state<Iterator, true> state;
iterator make_key_iterator(Iterator first, Sentinel last, Extra &&... extra) {
typedef detail::iterator_state<Iterator, Sentinel, true> state;
if (!detail::get_type_info(typeid(state))) {
class_<state>(handle(), "")
@@ -1166,7 +1170,7 @@ iterator make_key_iterator(Iterator first, Iterator last, Extra &&... extra) {
s.first = false;
if (s.it == s.end)
throw stop_iteration();
return s.it->first;
return (*s.it).first;
}, return_value_policy::reference_internal, std::forward<Extra>(extra)...);
}

View File

@@ -245,7 +245,7 @@ pybind11::class_<std::vector<T, Allocator>, holder_type> bind_vector(pybind11::m
cl.def("__iter__",
[](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 */
);