Fix past-the-end dereference in values_and_holders

The value and holder iterator code had a past-the-end iterator
dereference.  While of course invalid, the dereference didn't actually
cause any problems (which is why it wasn't caught before) because the
dereferenced value is never actually used and `vector` implementations
appear to allow dereferencing the past-the-end iterator.  Under a MSVC
debug build, however, it fails a debug assertion and aborts.

This amends the iterator to just store and use a pointer to the vector
(rather than adding a second past-the-end iterator member), checking the
type index against the type vector size.
diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h
index c7b8edc..27d5622 100644
--- a/include/pybind11/cast.h
+++ b/include/pybind11/cast.h
@@ -311,14 +311,13 @@
     struct iterator {
     private:
         instance *inst;
-        using vec_iter = std::vector<detail::type_info *>::const_iterator;
-        vec_iter typeit;
+        const type_vec *types;
         value_and_holder curr;
         friend struct values_and_holders;
-        iterator(instance *inst, const type_vec &tinfo)
-            : inst{inst}, typeit{tinfo.begin()},
+        iterator(instance *inst, const type_vec *tinfo)
+            : inst{inst}, types{tinfo},
             curr(inst /* instance */,
-                 tinfo.size() > 0 ? *typeit : nullptr /* type info */,
+                 types->empty() ? nullptr : (*types)[0] /* type info */,
                  0, /* vpos: (non-simple types only): the first vptr comes first */
                  0 /* index */)
         {}
@@ -328,18 +327,17 @@
         bool operator==(const iterator &other) { return curr.index == other.curr.index; }
         bool operator!=(const iterator &other) { return curr.index != other.curr.index; }
         iterator &operator++() {
-            if (!inst->simple_layout) {
-                curr.vh += 1 + (*typeit)->holder_size_in_ptrs;
-                curr.type = *(++typeit);
-            }
+            if (!inst->simple_layout)
+                curr.vh += 1 + (*types)[curr.index]->holder_size_in_ptrs;
             ++curr.index;
+            curr.type = curr.index < types->size() ? (*types)[curr.index] : nullptr;
             return *this;
         }
         value_and_holder &operator*() { return curr; }
         value_and_holder *operator->() { return &curr; }
     };
 
-    iterator begin() { return iterator(inst, tinfo); }
+    iterator begin() { return iterator(inst, &tinfo); }
     iterator end() { return iterator(tinfo.size()); }
 
     iterator find(const type_info *find_type) {