]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gdbsupport/intrusive-list: sprinkle noexcept
authorSimon Marchi <simon.marchi@efficios.com>
Mon, 12 Aug 2024 17:09:02 +0000 (13:09 -0400)
committerSimon Marchi <simon.marchi@efficios.com>
Fri, 13 Sep 2024 11:38:56 +0000 (07:38 -0400)
Some methods of intrusive_list are marked noexcept.  But really,
everything in that file could be noexcept.  Add it everywhere.

The only one I had a doubt about is clear_and_dispose: what if the
disposer throws?  The boost equivalent [1] is noexcept and requires the
disposer not to throw.  The rationale is probably the same as for
destructors.  What if the disposer throws for an element in the middle
of the list?  Do you skip the remaining elements?  Do you swallow the
exception and keep calling the disposer for the remaining elements?
It's simpler to say no exceptions allowed.

[1] https://www.boost.org/doc/libs/1_79_0/doc/html/boost/intrusive/list.html#idm33710-bb

Change-Id: I402646cb12c6b7906f4bdc2ad85203d8c8cdf2cc
Reviewed-by: Keith Seitz <keiths@redhat.com>
gdbsupport/intrusive_list.h

index 2262d9fb4270d184a77f01b17c6af2bdb64ec352..3c9245fd052f832d9d0de8d3f808882c8b622b11 100644 (file)
@@ -27,7 +27,7 @@ template<typename T>
 class intrusive_list_node
 {
 public:
-  bool is_linked () const
+  bool is_linked () const noexcept
   {
     return next != INTRUSIVE_LIST_UNLINKED_VALUE;
   }
@@ -56,7 +56,7 @@ private:
 template<typename T>
 struct intrusive_base_node
 {
-  static intrusive_list_node<T> *as_node (T *elem)
+  static intrusive_list_node<T> *as_node (T *elem) noexcept
   { return elem; }
 };
 
@@ -65,7 +65,7 @@ struct intrusive_base_node
 template<typename T, intrusive_list_node<T> T::*MemberNode>
 struct intrusive_member_node
 {
-  static intrusive_list_node<T> *as_node (T *elem)
+  static intrusive_list_node<T> *as_node (T *elem) noexcept
   { return &(elem->*MemberNode); }
 };
 
@@ -86,29 +86,29 @@ struct intrusive_list_base_iterator
   using node_type = intrusive_list_node<T>;
 
   /* Create an iterator pointing to ELEM.  */
-  explicit intrusive_list_base_iterator (pointer elem)
+  explicit intrusive_list_base_iterator (pointer elem) noexcept
     : m_elem (elem)
   {}
 
   /* Create a past-the-end iterator.  */
-  intrusive_list_base_iterator ()
+  intrusive_list_base_iterator () noexcept
     : m_elem (nullptr)
   {}
 
-  reference operator* () const
+  reference operator* () const noexcept
   { return *m_elem; }
 
-  pointer operator-> () const
+  pointer operator-> () const noexcept
   { return m_elem; }
 
-  bool operator== (const self_type &other) const
+  bool operator== (const self_type &other) const noexcept
   { return m_elem == other.m_elem; }
 
-  bool operator!= (const self_type &other) const
+  bool operator!= (const self_type &other) const noexcept
   { return m_elem != other.m_elem; }
 
 protected:
-  static node_type *as_node (pointer elem)
+  static node_type *as_node (pointer elem) noexcept
   { return AsNode::as_node (elem); }
 
   /* A past-end-the iterator points to the list's head.  */
@@ -131,14 +131,14 @@ struct intrusive_list_iterator
   using base::base;
   using base::m_elem;
 
-  self_type &operator++ ()
+  self_type &operator++ () noexcept
   {
     node_type *node = this->as_node (m_elem);
     m_elem = node->next;
     return *this;
   }
 
-  self_type operator++ (int)
+  self_type operator++ (int) noexcept
   {
     self_type temp = *this;
     node_type *node = this->as_node (m_elem);
@@ -146,14 +146,14 @@ struct intrusive_list_iterator
     return temp;
   }
 
-  self_type &operator-- ()
+  self_type &operator-- () noexcept
   {
     node_type *node = this->as_node (m_elem);
     m_elem = node->prev;
     return *this;
   }
 
-  self_type operator-- (int)
+  self_type operator-- (int) noexcept
   {
     self_type temp = *this;
     node_type *node = this->as_node (m_elem);
@@ -178,14 +178,14 @@ struct intrusive_list_reverse_iterator
   using base::m_elem;
   using node_type = typename base::node_type;
 
-  self_type &operator++ ()
+  self_type &operator++ () noexcept
   {
     node_type *node = this->as_node (m_elem);
     m_elem = node->prev;
     return *this;
   }
 
-  self_type operator++ (int)
+  self_type operator++ (int) noexcept
   {
     self_type temp = *this;
     node_type *node = this->as_node (m_elem);
@@ -193,14 +193,14 @@ struct intrusive_list_reverse_iterator
     return temp;
   }
 
-  self_type &operator-- ()
+  self_type &operator-- () noexcept
   {
     node_type *node = this->as_node (m_elem);
     m_elem = node->next;
     return *this;
   }
 
-  self_type operator-- (int)
+  self_type operator-- (int) noexcept
   {
     self_type temp = *this;
     node_type *node = this->as_node (m_elem);
@@ -243,14 +243,14 @@ public:
     = const intrusive_list_reverse_iterator<T, AsNode>;
   using node_type = intrusive_list_node<T>;
 
-  intrusive_list () = default;
+  intrusive_list () noexcept = default;
 
   ~intrusive_list ()
   {
     clear ();
   }
 
-  intrusive_list (intrusive_list &&other)
+  intrusive_list (intrusive_list &&other) noexcept
     : m_front (other.m_front),
       m_back (other.m_back)
   {
@@ -258,7 +258,7 @@ public:
     other.m_back = nullptr;
   }
 
-  intrusive_list &operator= (intrusive_list &&other)
+  intrusive_list &operator= (intrusive_list &&other) noexcept
   {
     m_front = other.m_front;
     m_back = other.m_back;
@@ -268,47 +268,47 @@ public:
     return *this;
   }
 
-  void swap (intrusive_list &other)
+  void swap (intrusive_list &other) noexcept
   {
     std::swap (m_front, other.m_front);
     std::swap (m_back, other.m_back);
   }
 
-  iterator iterator_to (reference value)
+  iterator iterator_to (reference value) noexcept
   {
     return iterator (&value);
   }
 
-  const_iterator iterator_to (const_reference value)
+  const_iterator iterator_to (const_reference value) noexcept
   {
     return const_iterator (&value);
   }
 
-  reference front ()
+  reference front () noexcept
   {
     gdb_assert (!this->empty ());
     return *m_front;
   }
 
-  const_reference front () const
+  const_reference front () const noexcept
   {
     gdb_assert (!this->empty ());
     return *m_front;
   }
 
-  reference back ()
+  reference back () noexcept
   {
     gdb_assert (!this->empty ());
     return *m_back;
   }
 
-  const_reference back () const
+  const_reference back () const noexcept
   {
     gdb_assert (!this->empty ());
     return *m_back;
   }
 
-  void push_front (reference elem)
+  void push_front (reference elem) noexcept
   {
     intrusive_list_node<T> *elem_node = as_node (&elem);
 
@@ -321,7 +321,7 @@ public:
       this->push_front_non_empty (elem);
   }
 
-  void push_back (reference elem)
+  void push_back (reference elem) noexcept
   {
     intrusive_list_node<T> *elem_node = as_node (&elem);
 
@@ -335,7 +335,7 @@ public:
   }
 
   /* Inserts ELEM before POS.  */
-  void insert (const_iterator pos, reference elem)
+  void insert (const_iterator pos, reference elem) noexcept
   {
     if (this->empty ())
       return this->push_empty (elem);
@@ -362,7 +362,7 @@ public:
   }
 
   /* Move elements from LIST at the end of the current list.  */
-  void splice (intrusive_list &&other)
+  void splice (intrusive_list &&other) noexcept
   {
     if (other.empty ())
       return;
@@ -388,13 +388,13 @@ public:
     other.m_back = nullptr;
   }
 
-  void pop_front ()
+  void pop_front () noexcept
   {
     gdb_assert (!this->empty ());
     erase_element (*m_front);
   }
 
-  void pop_back ()
+  void pop_back () noexcept
   {
     gdb_assert (!this->empty ());
     erase_element (*m_back);
@@ -402,7 +402,7 @@ public:
 
 private:
   /* Push ELEM in the list, knowing the list is empty.  */
-  void push_empty (reference elem)
+  void push_empty (reference elem) noexcept
   {
     gdb_assert (this->empty ());
 
@@ -418,7 +418,7 @@ private:
   }
 
   /* Push ELEM at the front of the list, knowing the list is not empty.  */
-  void push_front_non_empty (reference elem)
+  void push_front_non_empty (reference elem) noexcept
   {
     gdb_assert (!this->empty ());
 
@@ -435,7 +435,7 @@ private:
   }
 
   /* Push ELEM at the back of the list, knowing the list is not empty.  */
-  void push_back_non_empty (reference elem)
+  void push_back_non_empty (reference elem) noexcept
   {
     gdb_assert (!this->empty ());
 
@@ -451,7 +451,7 @@ private:
     m_back = &elem;
   }
 
-  void erase_element (reference elem)
+  void erase_element (reference elem) noexcept
   {
     intrusive_list_node<T> *elem_node = as_node (&elem);
 
@@ -489,7 +489,7 @@ private:
 public:
   /* Remove the element pointed by I from the list.  The element
      pointed by I is not destroyed.  */
-  iterator erase (const_iterator i)
+  iterator erase (const_iterator i) noexcept
   {
     iterator ret = i;
     ++ret;
@@ -500,7 +500,7 @@ public:
   }
 
   /* Erase all the elements.  The elements are not destroyed.  */
-  void clear ()
+  void clear () noexcept
   {
     while (!this->empty ())
       pop_front ();
@@ -509,7 +509,7 @@ public:
   /* Erase all the elements.  Disposer::operator()(pointer) is called
      for each of the removed elements.  */
   template<typename Disposer>
-  void clear_and_dispose (Disposer disposer)
+  void clear_and_dispose (Disposer disposer) noexcept
   {
     while (!this->empty ())
       {
@@ -519,7 +519,7 @@ public:
       }
   }
 
-  bool empty () const
+  bool empty () const noexcept
   {
     return m_front == nullptr;
   }
@@ -585,7 +585,7 @@ public:
   }
 
 private:
-  static node_type *as_node (pointer elem)
+  static node_type *as_node (pointer elem) noexcept
   {
     return AsNode::as_node (elem);
   }