1 /* Owning version of intrusive_list for GDB, the GNU debugger. 2 Copyright (C) 2024 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 GDBSUPPORT_OWNING_INTRUSIVE_LIST_H 20 #define GDBSUPPORT_OWNING_INTRUSIVE_LIST_H 21 22 #include "intrusive_list.h" 23 24 /* An owning version of intrusive_list. */ 25 26 template<typename T, typename AsNode = intrusive_base_node<T>> 27 class owning_intrusive_list : private intrusive_list<T, AsNode> 28 { 29 using base = intrusive_list<T, AsNode>; 30 31 public: 32 using value_type = typename base::value_type; 33 using reference = typename base::reference; 34 using iterator = typename base::iterator; 35 using reverse_iterator = typename base::reverse_iterator; 36 using const_iterator = typename base::const_iterator; 37 using unique_pointer = std::unique_ptr<T>; 38 39 using base::iterator_to; 40 using base::front; 41 using base::back; 42 using base::empty; 43 using base::begin; 44 using base::cbegin; 45 using base::end; 46 using base::cend; 47 using base::rbegin; 48 using base::crbegin; 49 using base::rend; 50 using base::crend; 51 52 owning_intrusive_list () noexcept = default; 53 54 owning_intrusive_list (owning_intrusive_list &&other) noexcept 55 : base (std::move (other)) 56 { 57 } 58 59 ~owning_intrusive_list () 60 { this->clear (); } 61 62 owning_intrusive_list &operator= (owning_intrusive_list &&other) noexcept 63 { 64 this->clear (); 65 this->base::operator= (std::move (other)); 66 return *this; 67 } 68 69 void swap (owning_intrusive_list &other) noexcept 70 { this->base::swap (other); } 71 72 /* Insert ELEM at the front of the list. 73 74 The list takes ownership of ELEM. */ 75 void push_front (unique_pointer elem) noexcept 76 { this->base::push_front (*elem.release ()); } 77 78 /* Insert ELEM at the back of the list. 79 80 The list takes ownership of ELEM. */ 81 void push_back (unique_pointer elem) noexcept 82 { this->base::push_back (*elem.release ()); } 83 84 /* Insert ELEM before POS in the list. 85 86 The list takes ownership of ELEM. */ 87 iterator insert (const_iterator pos, unique_pointer elem) noexcept 88 { return this->base::insert (pos, *elem.release ()); } 89 90 void splice (owning_intrusive_list &&other) noexcept 91 { this->base::splice (std::move (other)); } 92 93 /* Remove the element at the front of the list. The element is destroyed. */ 94 void pop_front () noexcept 95 { 96 unique_pointer holder (&this->front ()); 97 this->base::pop_front (); 98 } 99 100 /* Remove the element at the back of the list. The element is destroyed. */ 101 void pop_back () noexcept 102 { 103 unique_pointer holder (&this->back ()); 104 this->base::pop_back (); 105 } 106 107 /* Remove the element pointed by I from the list. The element 108 pointed by I is destroyed. */ 109 iterator erase (const_iterator i) noexcept 110 { 111 unique_pointer holder (&*i); 112 return this->base::erase (i); 113 } 114 115 /* Remove all elements from the list. All elements are destroyed. */ 116 void clear () noexcept 117 { 118 while (!this->empty ()) 119 this->pop_front (); 120 } 121 122 /* Construct an element in-place at the front of the list. 123 124 Return a reference to the new element. */ 125 template<typename... Args> 126 reference emplace_front (Args &&...args) 127 { return this->emplace (this->begin (), std::forward<Args> (args)...); } 128 129 /* Construct an element in-place at the back of the list. 130 131 Return a reference to the new element. */ 132 template<typename... Args> 133 reference emplace_back (Args &&...args) 134 { return this->emplace (this->end (), std::forward<Args> (args)...); } 135 136 /* Construct an element in-place in the list, before POS. 137 138 Return a reference to the new element. */ 139 template<typename... Args> 140 reference emplace (const_iterator pos, Args &&...args) 141 { 142 return *this->insert (pos, 143 std::make_unique<T> (std::forward<Args> (args)...)); 144 } 145 146 /* Return type for the release method. */ 147 struct release_ret 148 { 149 /* Iterator to the following element in the list. */ 150 iterator next; 151 152 /* The released element. */ 153 unique_pointer released; 154 }; 155 156 release_ret release (const_iterator i) noexcept 157 { 158 iterator next = i; 159 ++next; 160 unique_pointer released (&*i); 161 162 this->unlink_element (*i); 163 164 return { next, std::move (released) }; 165 } 166 }; 167 168 #endif /* GDBSUPPORT_OWNING_INTRUSIVE_LIST_H */ 169