|  | /* Owning version of intrusive_list for GDB, the GNU debugger. | 
|  | Copyright (C) 2024-2025 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 <http://www.gnu.org/licenses/>.  */ | 
|  |  | 
|  | #ifndef GDBSUPPORT_OWNING_INTRUSIVE_LIST_H | 
|  | #define GDBSUPPORT_OWNING_INTRUSIVE_LIST_H | 
|  |  | 
|  | #include "intrusive_list.h" | 
|  |  | 
|  | /* An owning version of intrusive_list.  */ | 
|  |  | 
|  | template<typename T, typename AsNode = intrusive_base_node<T>> | 
|  | class owning_intrusive_list : private intrusive_list<T, AsNode> | 
|  | { | 
|  | using base = intrusive_list<T, AsNode>; | 
|  |  | 
|  | public: | 
|  | using value_type = typename base::value_type; | 
|  | using reference = typename base::reference; | 
|  | using iterator = typename base::iterator; | 
|  | using reverse_iterator = typename base::reverse_iterator; | 
|  | using const_iterator = typename base::const_iterator; | 
|  | using unique_pointer = std::unique_ptr<T>; | 
|  |  | 
|  | using base::iterator_to; | 
|  | using base::front; | 
|  | using base::back; | 
|  | using base::empty; | 
|  | using base::begin; | 
|  | using base::cbegin; | 
|  | using base::end; | 
|  | using base::cend; | 
|  | using base::rbegin; | 
|  | using base::crbegin; | 
|  | using base::rend; | 
|  | using base::crend; | 
|  |  | 
|  | owning_intrusive_list () noexcept = default; | 
|  |  | 
|  | owning_intrusive_list (owning_intrusive_list &&other) noexcept | 
|  | : base (std::move (other)) | 
|  | { | 
|  | } | 
|  |  | 
|  | ~owning_intrusive_list () | 
|  | { this->clear (); } | 
|  |  | 
|  | owning_intrusive_list &operator= (owning_intrusive_list &&other) noexcept | 
|  | { | 
|  | this->clear (); | 
|  | this->base::operator= (std::move (other)); | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | void swap (owning_intrusive_list &other) noexcept | 
|  | { this->base::swap (other); } | 
|  |  | 
|  | /* Insert ELEM at the front of the list. | 
|  |  | 
|  | The list takes ownership of ELEM.  */ | 
|  | void push_front (unique_pointer elem) noexcept | 
|  | { this->base::push_front (*elem.release ()); } | 
|  |  | 
|  | /* Insert ELEM at the back of the list. | 
|  |  | 
|  | The list takes ownership of ELEM.  */ | 
|  | void push_back (unique_pointer elem) noexcept | 
|  | { this->base::push_back (*elem.release ()); } | 
|  |  | 
|  | /* Insert ELEM before POS in the list. | 
|  |  | 
|  | The list takes ownership of ELEM.  */ | 
|  | iterator insert (const_iterator pos, unique_pointer elem) noexcept | 
|  | { return  this->base::insert (pos, *elem.release ());  } | 
|  |  | 
|  | void splice (owning_intrusive_list &&other) noexcept | 
|  | { this->base::splice (std::move (other)); } | 
|  |  | 
|  | /* Remove the element at the front of the list.  The element is destroyed.  */ | 
|  | void pop_front () noexcept | 
|  | { | 
|  | unique_pointer holder (&this->front ()); | 
|  | this->base::pop_front (); | 
|  | } | 
|  |  | 
|  | /* Remove the element at the back of the list.  The element is destroyed.  */ | 
|  | void pop_back () noexcept | 
|  | { | 
|  | unique_pointer holder (&this->back ()); | 
|  | this->base::pop_back (); | 
|  | } | 
|  |  | 
|  | /* Remove the element pointed by I from the list.  The element | 
|  | pointed by I is destroyed.  */ | 
|  | iterator erase (const_iterator i) noexcept | 
|  | { | 
|  | unique_pointer holder (&*i); | 
|  | return this->base::erase (i); | 
|  | } | 
|  |  | 
|  | /* Remove all elements from the list.  All elements are destroyed.  */ | 
|  | void clear () noexcept | 
|  | { | 
|  | while (!this->empty ()) | 
|  | this->pop_front (); | 
|  | } | 
|  |  | 
|  | /* Construct an element in-place at the front of the list. | 
|  |  | 
|  | Return a reference to the new element.  */ | 
|  | template<typename... Args> | 
|  | reference emplace_front (Args &&...args) | 
|  | { return this->emplace (this->begin (), std::forward<Args> (args)...); } | 
|  |  | 
|  | /* Construct an element in-place at the back of the list. | 
|  |  | 
|  | Return a reference to the new element.  */ | 
|  | template<typename... Args> | 
|  | reference emplace_back (Args &&...args) | 
|  | { return this->emplace (this->end (), std::forward<Args> (args)...); } | 
|  |  | 
|  | /* Construct an element in-place in the list, before POS. | 
|  |  | 
|  | Return a reference to the new element.  */ | 
|  | template<typename... Args> | 
|  | reference emplace (const_iterator pos, Args &&...args) | 
|  | { | 
|  | return *this->insert (pos, | 
|  | std::make_unique<T> (std::forward<Args> (args)...)); | 
|  | } | 
|  |  | 
|  | /* Return type for the release method.  */ | 
|  | struct release_ret | 
|  | { | 
|  | /* Iterator to the following element in the list.  */ | 
|  | iterator next; | 
|  |  | 
|  | /* The released element.  */ | 
|  | unique_pointer released; | 
|  | }; | 
|  |  | 
|  | release_ret release (const_iterator i) noexcept | 
|  | { | 
|  | iterator next = i; | 
|  | ++next; | 
|  | unique_pointer released (&*i); | 
|  |  | 
|  | this->unlink_element (*i); | 
|  |  | 
|  | return { next, std::move (released) }; | 
|  | } | 
|  | }; | 
|  |  | 
|  | #endif /* GDBSUPPORT_OWNING_INTRUSIVE_LIST_H */ |