From: Tom de Vries Date: Thu, 23 Apr 2026 06:35:26 +0000 (+0200) Subject: Factor out base_next_iterator X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c8da7e3e3a8d25ca69c1f2cee403877ec7b71a10;p=thirdparty%2Fbinutils-gdb.git Factor out base_next_iterator Template struct next_iterator allows iterating over the "next" field of T. I decided to generalize this to be able to use any field. A first thought was to use macros, but nowadays we try to do things more in native c++, so I didn't explore that further. Instead, this patch factors out base_next_iterator, which contains all parts not specific to "next", in other words, everything except the operator++. Finally, I explored using a pointer-to-member template argument T::next, but that meant that using an incomplete T was no longer allowed, so it's not a drop-in replacement. I also didn't explore this option further, and made a note of it in the base_next_iterator comment. --- diff --git a/gdbsupport/next-iterator.h b/gdbsupport/next-iterator.h index 0c90428d349..1dee941a252 100644 --- a/gdbsupport/next-iterator.h +++ b/gdbsupport/next-iterator.h @@ -21,27 +21,43 @@ #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 + 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 -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) { } @@ -61,15 +77,34 @@ struct next_iterator 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 +struct next_iterator : base_next_iterator { + typedef next_iterator self_type; + typedef T *value_type; + typedef T *&reference; + typedef T **pointer; + + explicit next_iterator (T *item) + : base_next_iterator (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. */