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) */ 136