@@ -137,7 +137,7 @@ class intrusive_double_linked_list
137137 template <typename U>
138138 class iterator_impl
139139 {
140- using elem_t = typename std::conditional <std::is_const<U>::value, const node_t , node_t >::type ;
140+ using elem_t = std::conditional_t <std::is_const<U>::value, const node_t , node_t >;
141141
142142 public:
143143 using iterator_category = std::bidirectional_iterator_tag;
@@ -173,24 +173,28 @@ class intrusive_double_linked_list
173173
174174 intrusive_double_linked_list ()
175175 {
176- static_assert (std::is_base_of <node_t , T>::value ,
176+ static_assert (std::is_base_of_v <node_t , T>,
177177 " Provided template argument T must have intrusive_forward_list_element<Tag> as base class" );
178178 }
179179 intrusive_double_linked_list (const intrusive_double_linked_list&) = default ;
180- intrusive_double_linked_list (intrusive_double_linked_list&& other) noexcept : node(other.node)
180+ intrusive_double_linked_list (intrusive_double_linked_list&& other) noexcept : node(other.node), tail(other.tail)
181181 {
182182 other.node = nullptr ;
183+ other.tail = nullptr ;
183184 }
184185 intrusive_double_linked_list& operator =(const intrusive_double_linked_list&) = default ;
185186 intrusive_double_linked_list& operator =(intrusive_double_linked_list&& other) noexcept
186187 {
187188 node = other.node ;
189+ tail = other.tail ;
188190 other.node = nullptr ;
191+ other.tail = nullptr ;
189192 return *this ;
190193 }
191194 ~intrusive_double_linked_list () { clear (); }
192195
193196 T& front () const { return *static_cast <T*>(node); }
197+ T& back () const { return *static_cast <T*>(tail); }
194198
195199 void push_front (T* t)
196200 {
@@ -199,15 +203,36 @@ class intrusive_double_linked_list
199203 new_head->next_node = node;
200204 if (node != nullptr ) {
201205 node->prev_node = new_head;
206+ } else {
207+ tail = new_head;
202208 }
203209 node = new_head;
204210 }
205211
212+ void push_back (T* t)
213+ {
214+ node_t * new_tail = static_cast <node_t *>(t);
215+ new_tail->prev_node = tail;
216+ new_tail->next_node = nullptr ;
217+ if (tail != nullptr ) {
218+ tail->next_node = new_tail;
219+ } else {
220+ node = new_tail;
221+ }
222+ tail = new_tail;
223+ }
224+
206225 void pop (T* t)
207226 {
208227 node_t * to_rem = static_cast <node_t *>(t);
209228 if (to_rem == node) {
210229 node = to_rem->next_node ;
230+ if (node == nullptr ) {
231+ tail = nullptr ;
232+ }
233+ } else if (to_rem == tail) {
234+ tail = to_rem->prev_node ;
235+ // tail==head checked in first if condition.
211236 }
212237 if (to_rem->prev_node != nullptr ) {
213238 to_rem->prev_node ->next_node = to_rem->next_node ;
@@ -218,7 +243,11 @@ class intrusive_double_linked_list
218243 to_rem->next_node = nullptr ;
219244 to_rem->prev_node = nullptr ;
220245 }
246+
221247 void pop_front () { pop (static_cast <T*>(node)); }
248+
249+ void pop_back () { pop (static_cast <T*>(tail)); }
250+
222251 void clear ()
223252 {
224253 while (node != nullptr ) {
@@ -227,6 +256,7 @@ class intrusive_double_linked_list
227256 torem->next_node = nullptr ;
228257 torem->prev_node = nullptr ;
229258 }
259+ tail = nullptr ;
230260 }
231261
232262 bool empty () const { return node == nullptr ; }
@@ -238,6 +268,7 @@ class intrusive_double_linked_list
238268
239269private:
240270 node_t * node = nullptr ;
271+ node_t * tail = nullptr ;
241272};
242273
243274} // namespace srsran
0 commit comments