]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commit
gdbsupport: make filtered_iterator work with pointers
authorSimon Marchi <simon.marchi@efficios.com>
Thu, 28 Aug 2025 15:10:50 +0000 (11:10 -0400)
committerSimon Marchi <simon.marchi@polymtl.ca>
Fri, 29 Aug 2025 20:08:27 +0000 (16:08 -0400)
commit1e10e9ea96a4141080a7cd7322babe6bcd7c42ba
tree2bea0d0d703fc1a49159063662c6d29c1dfbc1d8
parent7a8821ff0e1badeaa284f6a6ff0b79b8e1fe5237
gdbsupport: make filtered_iterator work with pointers

It's currently not possible to use filtered_iterator with a pointer as
the base iterator type.  This patch makes it possible.  The indended
usage is:

  Foo array[12];
  Foo *begin = array;
  Foo *end = array + ARRAY_SIZE (array);
  filtered_iterator<Foo *, FooFilter> (begin, end);

Here are the things that needed changing:

 - Give filtered_iterator a constructor where the caller provides
   already constructed begin and end iterators.  filtered_iterator
   currently assumes that default-constructing a BaseIterator will
   produce a valid "end" iterator.  This is not the case if BaseIterator
   is a pointer.  The caller needs to pass in the end of the array /
   region to iterate on as the end.

 - Typedefs of member types like wouldn't work:

     typedef typename BaseIterator::value_type value_type;

   The compiler would complain that it's not possible to apply `::` to
   type `BaseIterator` (aka `Foo *`).  Use std::iterator_traits to fix
   it [1].

 - Similarly, the compiler would complain about the use of
   `BaseIterator::operator*` in the return type of
   `filtered_iterator::operator*`.  Fix this by using `decltype(auto)`
   as the return type.  This lets the compiler deduce the return type
   from the return statement.  Unlike `auto`, `decltype(auto)` perfectly
   preserves the "cvref-ness" of the deduced return type.  If the return
   expression yields a `Foo &`, then the function will return a `Foo &`
   (which is what we want), whereas it would return a `Foo` if we used
   just `auto`.

Improve the filtered_iterator unit tests to run the same tests but with
pointers as iterators.  Because the filtered_iterator objects are
initialized differently in the two scenarios, I chose to copy the
existing code and adapt it.  It would probably be possible to add a
layer of abstraction to avoid code duplication, but it would end up more
complicated and messy.  If we ever add a third scenario, we can revisit
that.

[1] https://en.cppreference.com/w/cpp/iterator/iterator_traits.html

Change-Id: Id962ffbcd960a705a82bc5eb4808b4fe118a2761
Approved-By: Tom Tromey <tom@tromey.com>
gdb/unittests/filtered_iterator-selftests.c
gdbsupport/filtered-iterator.h