#include "gdbsupport/iterator-range.h"
-/* An iterator that uses the 'next' field of a type to iterate. This
- can be used with various GDB types that are stored as linked
- lists. */
+/* An iterator base class for iterating over a field of a type. In order to
+ form a functioning iterator, classes inheriting this should define an
+ operator++, which determines the actual field that is iterated over.
+
+ Instead of factoring out a base class, we could use something like this:
+
+ template<typename T, auto F = &T::next>
+ struct next_iterator
+ {
+ ...
+ self_type &operator++ ()
+ {
+ m_item = m_item->*F;
+ return *this;
+ }
+ ...
+ }
+
+ but that has the drawback that it doesn't work with incomplete T. */
template<typename T>
-struct next_iterator
+struct base_next_iterator
{
- typedef next_iterator self_type;
+ typedef base_next_iterator self_type;
typedef T *value_type;
typedef T *&reference;
typedef T **pointer;
typedef std::forward_iterator_tag iterator_category;
typedef int difference_type;
- explicit next_iterator (T *item)
+ explicit base_next_iterator (T *item)
: m_item (item)
{
}
/* Create a one-past-the-end iterator. */
- next_iterator ()
+ base_next_iterator ()
: m_item (nullptr)
{
}
return m_item != other.m_item;
}
- self_type &operator++ ()
+protected:
+
+ T *m_item;
+};
+
+/* An iterator that uses the 'next' field of a type to iterate. This
+ can be used with various GDB types that are stored as linked
+ lists. */
+
+template<typename T>
+struct next_iterator : base_next_iterator<T> {
+ typedef next_iterator self_type;
+ typedef T *value_type;
+ typedef T *&reference;
+ typedef T **pointer;
+
+ explicit next_iterator (T *item)
+ : base_next_iterator<T> (item)
{
- m_item = m_item->next;
- return *this;
}
-private:
+ next_iterator () = default;
- T *m_item;
+ self_type &operator++ ()
+ {
+ this->m_item = this->m_item->next;
+ return *this;
+ }
};
/* A convenience wrapper to make a range type around a next_iterator. */