1/* A forward filtered iterator for GDB, the GNU debugger.
2   Copyright (C) 2018-2023 Free Software Foundation, Inc.
3
4   This file is part of GDB.
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 3 of the License, or
9   (at your option) any later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
18
19#ifndef COMMON_FILTERED_ITERATOR_H
20#define COMMON_FILTERED_ITERATOR_H
21
22/* A filtered iterator.  This wraps BaseIterator and automatically
23   skips elements that FilterFunc filters out.  Requires that
24   default-constructing a BaseIterator creates a valid one-past-end
25   iterator.  */
26
27template<typename BaseIterator, typename FilterFunc>
28class filtered_iterator
29{
30public:
31  typedef filtered_iterator self_type;
32  typedef typename BaseIterator::value_type value_type;
33  typedef typename BaseIterator::reference reference;
34  typedef typename BaseIterator::pointer pointer;
35  typedef typename BaseIterator::iterator_category iterator_category;
36  typedef typename BaseIterator::difference_type difference_type;
37
38  /* Construct by forwarding all arguments to the underlying
39     iterator.  */
40  template<typename... Args>
41  explicit filtered_iterator (Args &&...args)
42    : m_it (std::forward<Args> (args)...)
43  { skip_filtered (); }
44
45  /* Create a one-past-end iterator.  */
46  filtered_iterator () = default;
47
48  /* Need these as the variadic constructor would be a better match
49     otherwise.  */
50  filtered_iterator (filtered_iterator &) = default;
51  filtered_iterator (const filtered_iterator &) = default;
52  filtered_iterator (filtered_iterator &&) = default;
53  filtered_iterator (const filtered_iterator &&other)
54    : filtered_iterator (static_cast<const filtered_iterator &> (other))
55  {}
56
57  value_type operator* () const { return *m_it; }
58
59  self_type &operator++ ()
60  {
61    ++m_it;
62    skip_filtered ();
63    return *this;
64  }
65
66  bool operator== (const self_type &other) const
67  { return m_it == other.m_it; }
68
69  bool operator!= (const self_type &other) const
70  { return m_it != other.m_it; }
71
72private:
73
74  void skip_filtered ()
75  {
76    for (; m_it != m_end; ++m_it)
77      if (m_filter (*m_it))
78	break;
79  }
80
81private:
82  FilterFunc m_filter {};
83  BaseIterator m_it {};
84  BaseIterator m_end {};
85};
86
87#endif /* COMMON_FILTERED_ITERATOR_H */
88