/* A safe iterator for GDB, the GNU debugger. Copyright (C) 2018-2019 Free Software Foundation, Inc. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef COMMON_SAFE_ITERATOR_H #define COMMON_SAFE_ITERATOR_H /* A forward iterator that wraps Iterator, such that when iterating with iterator IT, it is possible to delete *IT without invalidating IT. Suitably wrapped in a range type and used with range-for, this allow convenient patterns like this: // range_safe() returns a range type whose begin()/end() methods // return safe iterators. for (foo *f : range_safe ()) { if (f->should_delete ()) { // The ++it operation implicitly done by the range-for is // still OK after this. delete f; } } */ template class basic_safe_iterator { public: typedef basic_safe_iterator self_type; typedef typename Iterator::value_type value_type; typedef typename Iterator::reference reference; typedef typename Iterator::pointer pointer; typedef typename Iterator::iterator_category iterator_category; typedef typename Iterator::difference_type difference_type; /* Construct by forwarding all arguments to the underlying iterator. */ template explicit basic_safe_iterator (Args &&...args) : m_it (std::forward (args)...), m_next (m_it) { if (m_it != m_end) ++m_next; } /* Create a one-past-end iterator. */ basic_safe_iterator () {} value_type operator* () const { return *m_it; } self_type &operator++ () { m_it = m_next; if (m_it != m_end) ++m_next; return *this; } bool operator== (const self_type &other) const { return m_it == other.m_it; } bool operator!= (const self_type &other) const { return m_it != other.m_it; } private: /* The current element. */ Iterator m_it {}; /* The next element. Always one element ahead of M_IT. */ Iterator m_next {}; /* A one-past-end iterator. */ Iterator m_end {}; }; #endif /* COMMON_SAFE_ITERATOR_H */