packaging: Add python3-base dependency
[platform/upstream/gdb.git] / gdb / inferior-iter.h
1 /* Inferior iterators and ranges for GDB, the GNU debugger.
2
3    Copyright (C) 2018-2023 Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 #ifndef INFERIOR_ITER_H
21 #define INFERIOR_ITER_H
22
23 #include "gdbsupport/filtered-iterator.h"
24 #include "gdbsupport/safe-iterator.h"
25
26 /* A forward iterator that iterates over all inferiors.  */
27
28 class all_inferiors_iterator
29 {
30 public:
31   typedef all_inferiors_iterator self_type;
32   typedef struct inferior *value_type;
33   typedef struct inferior *&reference;
34   typedef struct inferior **pointer;
35   typedef std::forward_iterator_tag iterator_category;
36   typedef int difference_type;
37
38   /* Create an iterator pointing at HEAD.  */
39   all_inferiors_iterator (process_stratum_target *proc_target,
40                           const intrusive_list<inferior> &list)
41     : m_proc_target (proc_target), m_inf_iter (list.begin ())
42   {
43     intrusive_list<inferior>::iterator end;
44
45     /* Advance M_INF to the first inferior's position.  */
46     for (; m_inf_iter != end; ++m_inf_iter)
47       if (m_inf_matches ())
48         return;
49   }
50
51   /* Create a one-past-end iterator.  */
52   all_inferiors_iterator ()
53     : m_proc_target (nullptr)
54   {}
55
56   all_inferiors_iterator &operator++ ()
57   {
58     advance ();
59     return *this;
60   }
61
62   inferior *operator* () const
63   { return &*m_inf_iter; }
64
65   bool operator!= (const all_inferiors_iterator &other) const
66   { return m_inf_iter != other.m_inf_iter; }
67
68 private:
69   /* Advance to next inferior, skipping filtered inferiors.  */
70   void advance ()
71   {
72     intrusive_list<inferior>::iterator end;
73
74     /* The loop below is written in the natural way as-if we'd always
75        start at the beginning of the inferior list.  This
76        fast-forwards the algorithm to the actual current position.  */
77     goto start;
78
79     while (m_inf_iter != end)
80       {
81         if (m_inf_matches ())
82           return;
83       start:
84         ++m_inf_iter;
85       }
86   }
87
88   bool m_inf_matches ()
89   {
90     return (m_proc_target == nullptr
91             || m_proc_target == m_inf_iter->process_target ());
92   }
93
94   process_stratum_target *m_proc_target;
95   intrusive_list<inferior>::iterator m_inf_iter;
96 };
97
98 /* A range adapter that makes it possible to iterate over all
99    inferiors with range-for.  */
100
101 using all_inferiors_range = iterator_range<all_inferiors_iterator>;
102
103 /* Filter for filtered_iterator.  Filters out exited inferiors.  */
104
105 struct exited_inferior_filter
106 {
107   bool operator() (inferior *inf)
108   {
109     return inf->pid != 0;
110   }
111 };
112
113 /* Iterate over all non-exited inferiors.  */
114
115 using all_non_exited_inferiors_iterator
116   = filtered_iterator<all_inferiors_iterator, exited_inferior_filter>;
117
118 /* A range adapter that makes it possible to iterate over all
119    non-exited inferiors with range-for.  */
120
121 using all_non_exited_inferiors_range
122   = iterator_range<all_non_exited_inferiors_iterator>;
123
124 /* Iterate over all inferiors, safely.  */
125
126 using all_inferiors_safe_iterator
127   = basic_safe_iterator<all_inferiors_iterator>;
128
129 /* A range adapter that makes it possible to iterate over all
130    inferiors with range-for "safely".  I.e., it is safe to delete the
131    currently-iterated inferior.  */
132
133 using all_inferiors_safe_range = iterator_range<all_inferiors_safe_iterator>;
134
135 #endif /* !defined (INFERIOR_ITER_H) */