]> Savannah Git Hosting - gnulib.git/commitdiff
list: Add operations first_node, last_node.
authorBruno Haible <bruno@clisp.org>
Sat, 3 Apr 2021 15:59:47 +0000 (17:59 +0200)
committerBruno Haible <bruno@clisp.org>
Sat, 3 Apr 2021 16:30:45 +0000 (18:30 +0200)
Reported by Marc Nieper-Wißkirchen in
<https://lists.gnu.org/archive/html/bug-gnulib/2021-04/msg00005.html>.

* lib/gl_list.h (gl_list_first_node, gl_list_last_node): New functions.
(struct gl_list_implementation): Add members first_node, last_node.
* lib/gl_array_list.c (gl_array_first_node, gl_array_last_node): New
functions.
(gl_array_list_implementation): Add the new operations.
* lib/gl_carray_list.c (gl_carray_first_node, gl_carray_last_node): New
functions.
(gl_carray_list_implementation): Add the new operations.
* lib/gl_anylinked_list2.h (gl_linked_first_node, gl_linked_last_node):
New functions.
* lib/gl_linked_list.c (gl_linked_list_implementation): Add the new
operations.
* lib/gl_linkedhash_list.c (gl_linkedhash_list_implementation):
Likewise.
* lib/gl_anytree_list2.h (gl_tree_first_node, gl_tree_last_node): New
functions.
* lib/gl_avltree_list.c (gl_avltree_list_implementation): Add the new
operations.
* lib/gl_avltreehash_list.c (gl_avltreehash_list_implementation):
Likewise.
* lib/gl_rbtree_list.c (gl_rbtree_list_implementation): Likewise.
* lib/gl_rbtreehash_list.c (gl_rbtreehash_list_implementation):
Likewise.
* lib/gl_sublist.c (gl_sublist_first_node, gl_sublist_last_node): New
functions.
(gl_sublist_list_implementation): Add the new operations.
* lib/gl_list.hh (class gl_List): Add member functions first_node,
last_node.
* doc/containers.texi: Update table.

15 files changed:
ChangeLog
doc/containers.texi
lib/gl_anylinked_list2.h
lib/gl_anytree_list2.h
lib/gl_array_list.c
lib/gl_avltree_list.c
lib/gl_avltreehash_list.c
lib/gl_carray_list.c
lib/gl_linked_list.c
lib/gl_linkedhash_list.c
lib/gl_list.h
lib/gl_list.hh
lib/gl_rbtree_list.c
lib/gl_rbtreehash_list.c
lib/gl_sublist.c

index 4e2edde41422dacf773786a3e2ec82500aee5b9c..80cce4f17ff4681ffb92ab082f26472533b1259c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,38 @@
+2021-04-03  Bruno Haible  <bruno@clisp.org>
+
+       list: Add operations first_node, last_node.
+       Reported by Marc Nieper-Wißkirchen in
+       <https://lists.gnu.org/archive/html/bug-gnulib/2021-04/msg00005.html>.
+       * lib/gl_list.h (gl_list_first_node, gl_list_last_node): New functions.
+       (struct gl_list_implementation): Add members first_node, last_node.
+       * lib/gl_array_list.c (gl_array_first_node, gl_array_last_node): New
+       functions.
+       (gl_array_list_implementation): Add the new operations.
+       * lib/gl_carray_list.c (gl_carray_first_node, gl_carray_last_node): New
+       functions.
+       (gl_carray_list_implementation): Add the new operations.
+       * lib/gl_anylinked_list2.h (gl_linked_first_node, gl_linked_last_node):
+       New functions.
+       * lib/gl_linked_list.c (gl_linked_list_implementation): Add the new
+       operations.
+       * lib/gl_linkedhash_list.c (gl_linkedhash_list_implementation):
+       Likewise.
+       * lib/gl_anytree_list2.h (gl_tree_first_node, gl_tree_last_node): New
+       functions.
+       * lib/gl_avltree_list.c (gl_avltree_list_implementation): Add the new
+       operations.
+       * lib/gl_avltreehash_list.c (gl_avltreehash_list_implementation):
+       Likewise.
+       * lib/gl_rbtree_list.c (gl_rbtree_list_implementation): Likewise.
+       * lib/gl_rbtreehash_list.c (gl_rbtreehash_list_implementation):
+       Likewise.
+       * lib/gl_sublist.c (gl_sublist_first_node, gl_sublist_last_node): New
+       functions.
+       (gl_sublist_list_implementation): Add the new operations.
+       * lib/gl_list.hh (class gl_List): Add member functions first_node,
+       last_node.
+       * doc/containers.texi: Update table.
+
 2021-04-03  Bruno Haible  <bruno@clisp.org>
 
        xalloc-die: Fix compilation error (regression from 2021-03-28).
index cb0c22ac8d7b692aacf2a9093d6bfad701d87256..15c915b93dd7335be551116d96badb6c8916c7b2 100644 (file)
@@ -151,6 +151,24 @@ for the ``sequential list'' data type are:
 @tab @math{O(1)}
 @tab @math{O(@log n)}
 @tab @math{O(@log n)}
+@item @code{gl_list_first_node}
+@tab @math{O(1)}
+@tab @math{O(1)}
+@tab @math{O(1)}
+@tab @math{O(@log n)}
+@tab @math{O(1)}
+@tab @math{O(1)}
+@tab @math{O(@log n)}
+@tab @math{O(@log n)}
+@item @code{gl_list_last_node}
+@tab @math{O(1)}
+@tab @math{O(1)}
+@tab @math{O(1)}
+@tab @math{O(@log n)}
+@tab @math{O(1)}
+@tab @math{O(1)}
+@tab @math{O(@log n)}
+@tab @math{O(@log n)}
 @item @code{gl_list_get_at}
 @tab @math{O(1)}
 @tab @math{O(1)}
index 1434d5991ebc83c51d078811fd378efd1a57aef6..6af3f7670fa056168dd3fdba2bd4ebda9c8ef885 100644 (file)
@@ -229,6 +229,24 @@ gl_linked_previous_node (gl_list_t list, gl_list_node_t node)
   return (node->prev != &list->root ? node->prev : NULL);
 }
 
+static gl_list_node_t _GL_ATTRIBUTE_PURE
+gl_linked_first_node (gl_list_t list)
+{
+  if (list->count > 0)
+    return list->root.next;
+  else
+    return NULL;
+}
+
+static gl_list_node_t _GL_ATTRIBUTE_PURE
+gl_linked_last_node (gl_list_t list)
+{
+  if (list->count > 0)
+    return list->root.prev;
+  else
+    return NULL;
+}
+
 static const void * _GL_ATTRIBUTE_PURE
 gl_linked_get_at (gl_list_t list, size_t position)
 {
index 59fe01dfc1b8e59ee91139d88d5a2aca20d46788..fbf514b92c02a402a67e31a343a4973ece243a44 100644 (file)
@@ -140,6 +140,32 @@ gl_tree_previous_node (gl_list_t list _GL_ATTRIBUTE_MAYBE_UNUSED,
   return node;
 }
 
+static gl_list_node_t _GL_ATTRIBUTE_PURE
+gl_tree_first_node (gl_list_t list _GL_ATTRIBUTE_MAYBE_UNUSED)
+{
+  gl_list_node_t node = list->root;
+
+  if (node != NULL)
+    {
+      while (node->left != NULL)
+        node = node->left;
+    }
+  return node;
+}
+
+static gl_list_node_t _GL_ATTRIBUTE_PURE
+gl_tree_last_node (gl_list_t list _GL_ATTRIBUTE_MAYBE_UNUSED)
+{
+  gl_list_node_t node = list->root;
+
+  if (node != NULL)
+    {
+      while (node->right != NULL)
+        node = node->right;
+    }
+  return node;
+}
+
 /* Returns the node at the given position < gl_tree_size (list).  */
 static gl_list_node_t _GL_ATTRIBUTE_PURE
 node_at (gl_list_node_t root, size_t position)
index e30b881dac595ae2dfc38d51283c2b93779949d1..203e6187fcff9c870f03cc0d17b8de967d41cf9f 100644 (file)
@@ -166,6 +166,24 @@ gl_array_previous_node (gl_list_t list, gl_list_node_t node)
     return NULL;
 }
 
+static gl_list_node_t _GL_ATTRIBUTE_PURE
+gl_array_first_node (gl_list_t list)
+{
+  if (list->count > 0)
+    return INDEX_TO_NODE (0);
+  else
+    return NULL;
+}
+
+static gl_list_node_t _GL_ATTRIBUTE_PURE
+gl_array_last_node (gl_list_t list)
+{
+  if (list->count > 0)
+    return INDEX_TO_NODE (list->count - 1);
+  else
+    return NULL;
+}
+
 static const void * _GL_ATTRIBUTE_PURE
 gl_array_get_at (gl_list_t list, size_t position)
 {
@@ -651,6 +669,8 @@ const struct gl_list_implementation gl_array_list_implementation =
     gl_array_node_nx_set_value,
     gl_array_next_node,
     gl_array_previous_node,
+    gl_array_first_node,
+    gl_array_last_node,
     gl_array_get_at,
     gl_array_nx_set_at,
     gl_array_search_from_to,
index 241949ad8a9ff3176becb37331d3ec09b1341237..801b1415fab06fffef4066ef42091d1db1c4f1a3 100644 (file)
@@ -77,6 +77,8 @@ const struct gl_list_implementation gl_avltree_list_implementation =
     gl_tree_node_nx_set_value,
     gl_tree_next_node,
     gl_tree_previous_node,
+    gl_tree_first_node,
+    gl_tree_last_node,
     gl_tree_get_at,
     gl_tree_nx_set_at,
     gl_tree_search_from_to,
index 5d0be7e6031294c1e59ca2f3d85f533d241a4c39..9a96f68fedd34996ed631fe0142f7a040d4d5f35 100644 (file)
@@ -100,6 +100,8 @@ const struct gl_list_implementation gl_avltreehash_list_implementation =
     gl_tree_node_nx_set_value,
     gl_tree_next_node,
     gl_tree_previous_node,
+    gl_tree_first_node,
+    gl_tree_last_node,
     gl_tree_get_at,
     gl_tree_nx_set_at,
     gl_tree_search_from_to,
index a50f093240a779404e5e56bf453a9a24f637fb68..add4cc3c8dcda6b1fa87ff833a59b536b8f8b4dc 100644 (file)
@@ -181,6 +181,24 @@ gl_carray_previous_node (gl_list_t list, gl_list_node_t node)
     return NULL;
 }
 
+static gl_list_node_t _GL_ATTRIBUTE_PURE
+gl_carray_first_node (gl_list_t list)
+{
+  if (list->count > 0)
+    return INDEX_TO_NODE (0);
+  else
+    return NULL;
+}
+
+static gl_list_node_t _GL_ATTRIBUTE_PURE
+gl_carray_last_node (gl_list_t list)
+{
+  if (list->count > 0)
+    return INDEX_TO_NODE (list->count - 1);
+  else
+    return NULL;
+}
+
 static const void * _GL_ATTRIBUTE_PURE
 gl_carray_get_at (gl_list_t list, size_t position)
 {
@@ -844,6 +862,8 @@ const struct gl_list_implementation gl_carray_list_implementation =
     gl_carray_node_nx_set_value,
     gl_carray_next_node,
     gl_carray_previous_node,
+    gl_carray_first_node,
+    gl_carray_last_node,
     gl_carray_get_at,
     gl_carray_nx_set_at,
     gl_carray_search_from_to,
index f46d45bd9b9b3df1cd19ec0893c544e23a7d9552..087968e6d928ca7d3c4d58b943302c2a0ad1f332 100644 (file)
@@ -38,6 +38,8 @@ const struct gl_list_implementation gl_linked_list_implementation =
     gl_linked_node_nx_set_value,
     gl_linked_next_node,
     gl_linked_previous_node,
+    gl_linked_first_node,
+    gl_linked_last_node,
     gl_linked_get_at,
     gl_linked_nx_set_at,
     gl_linked_search_from_to,
index 2c76baec03a2f64303407aa0d7a628b824020433..70eca522b6803dcbc4e079b2648f1d3ef4155b5f 100644 (file)
@@ -86,6 +86,8 @@ const struct gl_list_implementation gl_linkedhash_list_implementation =
     gl_linked_node_nx_set_value,
     gl_linked_next_node,
     gl_linked_previous_node,
+    gl_linked_first_node,
+    gl_linked_last_node,
     gl_linked_get_at,
     gl_linked_nx_set_at,
     gl_linked_search_from_to,
index 3c1aede0a619cdf57ee1cde795ef0aecbdd38ba6..7fc22bbce9735cdf66716bb5c6167970cecd2cfc 100644 (file)
@@ -73,6 +73,8 @@ extern "C" {
    gl_list_node_set_value      O(1)     O(1)     O(1)      O(1)    O((log n)²)/O(1)
    gl_list_next_node           O(1)     O(1)   O(log n)    O(1)       O(log n)
    gl_list_previous_node       O(1)     O(1)   O(log n)    O(1)       O(log n)
+   gl_list_first_node          O(1)     O(1)   O(log n)    O(1)       O(log n)
+   gl_list_last_node           O(1)     O(1)   O(log n)    O(1)       O(log n)
    gl_list_get_at              O(1)     O(n)   O(log n)    O(n)       O(log n)
    gl_list_get_first           O(1)     O(1)   O(log n)    O(1)       O(log n)
    gl_list_get_last            O(1)     O(1)   O(log n)    O(1)       O(log n)
@@ -207,6 +209,23 @@ extern gl_list_node_t gl_list_next_node (gl_list_t list, gl_list_node_t node);
    if the given node is the first (leftmost) one in the list.  */
 extern gl_list_node_t gl_list_previous_node (gl_list_t list, gl_list_node_t node);
 
+/* Returns the first node in the list, or NULL if the list is empty.
+   This function is useful for iterating through the list like this:
+     gl_list_node_t node;
+     for (node = gl_list_first_node (list); node != NULL; node = gl_list_next_node (node))
+       ...
+ */
+extern gl_list_node_t gl_list_first_node (gl_list_t list);
+
+/* Returns the last node in the list, or NULL if the list is empty.
+   This function is useful for iterating through the list in backward order,
+   like this:
+     gl_list_node_t node;
+     for (node = gl_list_last_node (list); node != NULL; node = gl_list_previous_node (node))
+       ...
+ */
+extern gl_list_node_t gl_list_last_node (gl_list_t list);
+
 /* Returns the element at a given position in the list.
    POSITION must be >= 0 and < gl_list_size (list).  */
 extern const void * gl_list_get_at (gl_list_t list, size_t position);
@@ -507,6 +526,8 @@ struct gl_list_implementation
                             const void *elt);
   gl_list_node_t (*next_node) (gl_list_t list, gl_list_node_t node);
   gl_list_node_t (*previous_node) (gl_list_t list, gl_list_node_t node);
+  gl_list_node_t (*first_node) (gl_list_t list);
+  gl_list_node_t (*last_node) (gl_list_t list);
   const void * (*get_at) (gl_list_t list, size_t position);
   gl_list_node_t (*nx_set_at) (gl_list_t list, size_t position,
                                const void *elt);
@@ -631,6 +652,20 @@ gl_list_previous_node (gl_list_t list, gl_list_node_t node)
          ->previous_node (list, node);
 }
 
+GL_LIST_INLINE gl_list_node_t
+gl_list_first_node (gl_list_t list)
+{
+  return ((const struct gl_list_impl_base *) list)->vtable
+         ->first_node (list);
+}
+
+GL_LIST_INLINE gl_list_node_t
+gl_list_last_node (gl_list_t list)
+{
+  return ((const struct gl_list_impl_base *) list)->vtable
+         ->last_node (list);
+}
+
 GL_LIST_INLINE const void *
 gl_list_get_at (gl_list_t list, size_t position)
 {
index 7bff5ddd9c36a58a6e939e6672ed15efd5b95318..af2ca67474bd95e30ca86360c1dcb76ce5c5d70b 100644 (file)
@@ -134,6 +134,14 @@ public:
   gl_list_node_t previous_node (gl_list_node_t node) const
     { return gl_list_previous_node (_ptr, node); }
 
+  /* Returns the first node in the list, or NULL if the list is empty.  */
+  gl_list_node_t first_node () const
+    { return gl_list_first_node (_ptr); }
+
+  /* Returns the last node in the list, or NULL if the list is empty.  */
+  gl_list_node_t last_node () const
+    { return gl_list_last_node (_ptr); }
+
   /* Returns the element at a given position in the list.
      POSITION must be >= 0 and < gl_list_size (list).  */
   ELTYPE * get_at (size_t position) const
index 185ed820e4f145f0fab72871dc679c43e4de9091..9a053b42e4e4d3bffbe922e9a8b327f6cef26268 100644 (file)
@@ -78,6 +78,8 @@ const struct gl_list_implementation gl_rbtree_list_implementation =
     gl_tree_node_nx_set_value,
     gl_tree_next_node,
     gl_tree_previous_node,
+    gl_tree_first_node,
+    gl_tree_last_node,
     gl_tree_get_at,
     gl_tree_nx_set_at,
     gl_tree_search_from_to,
index c4a3c7d3093812dfe98b6ac2eb3aec6eaefe8586..d8fcb8eb5edf1c2e688d2711b250cf0f5aa6ff81 100644 (file)
@@ -101,6 +101,8 @@ const struct gl_list_implementation gl_rbtreehash_list_implementation =
     gl_tree_node_nx_set_value,
     gl_tree_next_node,
     gl_tree_previous_node,
+    gl_tree_first_node,
+    gl_tree_last_node,
     gl_tree_get_at,
     gl_tree_nx_set_at,
     gl_tree_search_from_to,
index bdd7d5006532c126089535b68e6d526b3120b9f3..63359b834f774355d74e3a4aa439942d50d5aae7 100644 (file)
@@ -122,6 +122,25 @@ gl_sublist_previous_node (gl_list_t list, gl_list_node_t node)
     return NULL;
 }
 
+static gl_list_node_t
+gl_sublist_first_node (gl_list_t list)
+{
+  if (list->end > list->start)
+    return INDEX_TO_NODE (0);
+  else
+    return NULL;
+}
+
+static gl_list_node_t
+gl_sublist_last_node (gl_list_t list)
+{
+  size_t count = list->end - list->start;
+  if (count > 0)
+    return INDEX_TO_NODE (count - 1);
+  else
+    return NULL;
+}
+
 static const void *
 gl_sublist_get_at (gl_list_t list, size_t position)
 {
@@ -413,6 +432,8 @@ static const struct gl_list_implementation gl_sublist_list_implementation =
     gl_sublist_node_nx_set_value,
     gl_sublist_next_node,
     gl_sublist_previous_node,
+    gl_sublist_first_node,
+    gl_sublist_last_node,
     gl_sublist_get_at,
     gl_sublist_nx_set_at,
     gl_sublist_search_from_to,