Automatic date update in version.in
[binutils-gdb.git] / gdbsupport / owning_intrusive_list.h
blob4c72d9bdf2c3d320ed1b3b11997aa0dcf7ac4f84
1 /* Owning version of intrusive_list for GDB, the GNU debugger.
2 Copyright (C) 2024 Free Software Foundation, Inc.
4 This file is part of GDB.
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.
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.
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/>. */
19 #ifndef GDBSUPPORT_OWNING_INTRUSIVE_LIST_H
20 #define GDBSUPPORT_OWNING_INTRUSIVE_LIST_H
22 #include "intrusive_list.h"
24 /* An owning version of intrusive_list. */
26 template<typename T, typename AsNode = intrusive_base_node<T>>
27 class owning_intrusive_list : private intrusive_list<T, AsNode>
29 using base = intrusive_list<T, AsNode>;
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>;
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;
52 owning_intrusive_list () noexcept = default;
54 owning_intrusive_list (owning_intrusive_list &&other) noexcept
55 : base (std::move (other))
59 ~owning_intrusive_list ()
60 { this->clear (); }
62 owning_intrusive_list &operator= (owning_intrusive_list &&other) noexcept
64 this->clear ();
65 this->base::operator= (std::move (other));
66 return *this;
69 void swap (owning_intrusive_list &other) noexcept
70 { this->base::swap (other); }
72 /* Insert ELEM at the front of the list.
74 The list takes ownership of ELEM. */
75 void push_front (unique_pointer elem) noexcept
76 { this->base::push_front (*elem.release ()); }
78 /* Insert ELEM at the back of the list.
80 The list takes ownership of ELEM. */
81 void push_back (unique_pointer elem) noexcept
82 { this->base::push_back (*elem.release ()); }
84 /* Insert ELEM before POS in the list.
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 ()); }
90 void splice (owning_intrusive_list &&other) noexcept
91 { this->base::splice (std::move (other)); }
93 /* Remove the element at the front of the list. The element is destroyed. */
94 void pop_front () noexcept
96 unique_pointer holder (&this->front ());
97 this->base::pop_front ();
100 /* Remove the element at the back of the list. The element is destroyed. */
101 void pop_back () noexcept
103 unique_pointer holder (&this->back ());
104 this->base::pop_back ();
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
111 unique_pointer holder (&*i);
112 return this->base::erase (i);
115 /* Remove all elements from the list. All elements are destroyed. */
116 void clear () noexcept
118 while (!this->empty ())
119 this->pop_front ();
122 /* Construct an element in-place at the front of the list.
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)...); }
129 /* Construct an element in-place at the back of the list.
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)...); }
136 /* Construct an element in-place in the list, before POS.
138 Return a reference to the new element. */
139 template<typename... Args>
140 reference emplace (const_iterator pos, Args &&...args)
142 return *this->insert (pos,
143 std::make_unique<T> (std::forward<Args> (args)...));
146 /* Return type for the release method. */
147 struct release_ret
149 /* Iterator to the following element in the list. */
150 iterator next;
152 /* The released element. */
153 unique_pointer released;
156 release_ret release (const_iterator i) noexcept
158 iterator next = i;
159 ++next;
160 unique_pointer released (&*i);
162 this->unlink_element (*i);
164 return { next, std::move (released) };
168 #endif /* GDBSUPPORT_OWNING_INTRUSIVE_LIST_H */