xref: /netbsd-src/external/gpl3/gdb/dist/gdbsupport/reference-to-pointer-iterator.h (revision 5ba1f45f2a09259cc846f20c7c5501604d633c90)
14b169a6bSchristos /* An iterator wrapper that yields pointers instead of references.
2*5ba1f45fSchristos    Copyright (C) 2021-2024 Free Software Foundation, Inc.
34b169a6bSchristos 
44b169a6bSchristos    This file is part of GDB.
54b169a6bSchristos 
64b169a6bSchristos    This program is free software; you can redistribute it and/or modify
74b169a6bSchristos    it under the terms of the GNU General Public License as published by
84b169a6bSchristos    the Free Software Foundation; either version 3 of the License, or
94b169a6bSchristos    (at your option) any later version.
104b169a6bSchristos 
114b169a6bSchristos    This program is distributed in the hope that it will be useful,
124b169a6bSchristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
134b169a6bSchristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
144b169a6bSchristos    GNU General Public License for more details.
154b169a6bSchristos 
164b169a6bSchristos    You should have received a copy of the GNU General Public License
174b169a6bSchristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
184b169a6bSchristos 
194b169a6bSchristos #ifndef GDBSUPPORT_REFERENCE_TO_POINTER_ITERATOR_H
204b169a6bSchristos #define GDBSUPPORT_REFERENCE_TO_POINTER_ITERATOR_H
214b169a6bSchristos 
224b169a6bSchristos /* Wrap an iterator that yields references to objects so that it yields
234b169a6bSchristos    pointers to objects instead.
244b169a6bSchristos 
254b169a6bSchristos    This is useful for example to bridge the gap between iterators on intrusive
264b169a6bSchristos    lists, which yield references, and the rest of GDB, which for legacy reasons
274b169a6bSchristos    expects to iterate on pointers.  */
284b169a6bSchristos 
294b169a6bSchristos template <typename IteratorType>
304b169a6bSchristos struct reference_to_pointer_iterator
314b169a6bSchristos {
324b169a6bSchristos   using self_type = reference_to_pointer_iterator;
334b169a6bSchristos   using value_type = typename IteratorType::value_type *;
344b169a6bSchristos   using reference = typename IteratorType::value_type *&;
354b169a6bSchristos   using pointer = typename IteratorType::value_type **;
364b169a6bSchristos   using iterator_category = typename IteratorType::iterator_category;
374b169a6bSchristos   using difference_type = typename IteratorType::difference_type;
384b169a6bSchristos 
39*5ba1f45fSchristos   /* Construct a reference_to_pointer_iterator, passing args to the underlying
404b169a6bSchristos      iterator.  */
414b169a6bSchristos   template <typename... Args>
424b169a6bSchristos   reference_to_pointer_iterator (Args &&...args)
434b169a6bSchristos     : m_it (std::forward<Args> (args)...)
444b169a6bSchristos   {}
454b169a6bSchristos 
464b169a6bSchristos   /* Create a past-the-end iterator.
474b169a6bSchristos 
484b169a6bSchristos      Assumes that default-constructing an underlying iterator creates a
494b169a6bSchristos      past-the-end iterator.  */
504b169a6bSchristos   reference_to_pointer_iterator ()
514b169a6bSchristos   {}
524b169a6bSchristos 
534b169a6bSchristos   /* Need these as the variadic constructor would be a better match
544b169a6bSchristos      otherwise.  */
554b169a6bSchristos   reference_to_pointer_iterator (reference_to_pointer_iterator &) = default;
564b169a6bSchristos   reference_to_pointer_iterator (const reference_to_pointer_iterator &) = default;
574b169a6bSchristos   reference_to_pointer_iterator (reference_to_pointer_iterator &&) = default;
584b169a6bSchristos 
594b169a6bSchristos   reference_to_pointer_iterator &operator= (const reference_to_pointer_iterator &) = default;
604b169a6bSchristos   reference_to_pointer_iterator &operator= (reference_to_pointer_iterator &&) = default;
614b169a6bSchristos 
624b169a6bSchristos   value_type operator* () const
634b169a6bSchristos   { return &*m_it; }
644b169a6bSchristos 
654b169a6bSchristos   self_type &operator++ ()
664b169a6bSchristos   {
674b169a6bSchristos     ++m_it;
684b169a6bSchristos     return *this;
694b169a6bSchristos   }
704b169a6bSchristos 
71*5ba1f45fSchristos   self_type &operator++ (int)
72*5ba1f45fSchristos   {
73*5ba1f45fSchristos     m_it++;
74*5ba1f45fSchristos     return *this;
75*5ba1f45fSchristos   }
76*5ba1f45fSchristos 
77*5ba1f45fSchristos   self_type &operator-- ()
78*5ba1f45fSchristos   {
79*5ba1f45fSchristos     --m_it;
80*5ba1f45fSchristos     return *this;
81*5ba1f45fSchristos   }
82*5ba1f45fSchristos 
83*5ba1f45fSchristos   self_type &operator-- (int)
84*5ba1f45fSchristos   {
85*5ba1f45fSchristos     m_it--;
86*5ba1f45fSchristos     return *this;
87*5ba1f45fSchristos   }
88*5ba1f45fSchristos 
894b169a6bSchristos   bool operator== (const self_type &other) const
904b169a6bSchristos   { return m_it == other.m_it; }
914b169a6bSchristos 
924b169a6bSchristos   bool operator!= (const self_type &other) const
934b169a6bSchristos   { return m_it != other.m_it; }
944b169a6bSchristos 
954b169a6bSchristos private:
964b169a6bSchristos   /* The underlying iterator.  */
974b169a6bSchristos   IteratorType m_it;
984b169a6bSchristos };
994b169a6bSchristos 
1004b169a6bSchristos #endif /* GDBSUPPORT_REFERENCE_TO_POINTER_ITERATOR_H */
101