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
>;
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
;
52 owning_intrusive_list () noexcept
= default;
54 owning_intrusive_list (owning_intrusive_list
&&other
) noexcept
55 : base (std::move (other
))
59 ~owning_intrusive_list ()
62 owning_intrusive_list
&operator= (owning_intrusive_list
&&other
) noexcept
65 this->base::operator= (std::move (other
));
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 ())
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. */
149 /* Iterator to the following element in the list. */
152 /* The released element. */
153 unique_pointer released
;
156 release_ret
release (const_iterator i
) noexcept
160 unique_pointer
released (&*i
);
162 this->unlink_element (*i
);
164 return { next
, std::move (released
) };
168 #endif /* GDBSUPPORT_OWNING_INTRUSIVE_LIST_H */