Re: GList changes



On Tue, 10 Aug 1999, Karl Nelson wrote:

> 
> These functions simplify the 3 cases of insert to 2, and 
> allow the user to not need to deal with head and iter at
> the same time.
> 
> New functions 
>   g_list_insert_link(GList *head,gpointer data,GList* iter); 
>   g_list_insert_after_link(GList *head,gpointer data,GList* iter); 
> 
> The other functions are converted to use these.

hi karl.

first off, i couldn't apply your patch to either glib-1-2 nor HEAD,
some hunks failed both trees.
for further patches, could you please tell what version your patch
exactly applies to and provide unified diffs? also it'd be nice if
you could adhere to the normal glib coding style (here, put spaces
around "=", after commas, etc). also, additions to GList should also
come with a GSList counterpart where appropriate.

on actuall matters, i'm not exactly sure what functionality you want
to provide, especially why you proposed addition of two functions.
if we want to provide an interface for random insertion, relative
to specific list nodes, we should probably follow the GNode example:

GNode*   g_node_insert_before   (GNode            *parent,
                                 GNode            *sibling,
                                 GNode            *node);

for GList and GSList this would pretty much be:

GSList* g_slist_insert_before        (GSList        *slist,
                                      GSList        *sibling,
                                      gpointer       data);
GList*  g_list_insert_before         (GList         *list,
                                      GList         *sibling,
                                      gpointer       data);
GSList* g_slist_insert_link_before   (GSList        *slist,
                                      GSList        *sibling,
                                      GSList        *new_node);
GList*  g_list_insert_link_before    (GList         *list,
                                      GList         *sibling,
                                      GList         *new_node);

also, changing the implementation of the existing insertion functions
in terms of the new sibling-relative-insertion variants is not neccessary,
this just imposes an extra function indirection (performance impact)
and the existing implementation are probably better optimized for the
specific cases (i did actually go through the implementations in Dec 97
to optimize them as much as possible).

FYI, i have appended implementations of g_slist_insert_before() and
g_list_insert_before() to this mail, they can easily be adapted for the
insert_link case. you can also find them in the beast module in
beast/bse/glib-extra.c, i intend to merge most of that stuff after more
thorough testing and optimization into glib HEAD.


>  
> --Karl
> 

---
ciaoTJ

GSList*
g_slist_insert_before (GSList  *slist,
		       GSList  *sibling,
		       gpointer data)
{
  if (!slist)
    {
      slist = g_slist_alloc ();
      slist->data = data;
      g_return_val_if_fail (sibling == NULL, slist);
      return slist;
    }
  else
    {
      GSList *node, *last = NULL;

      for (node = slist; node; last = node, node = last->next)
	if (node == sibling)
	  break;
      if (!last)
	{
	  node = g_slist_alloc ();
	  node->data = data;
	  node->next = slist;

	  return node;
	}
      else
	{
	  node = g_slist_alloc ();
	  node->data = data;
	  node->next = last->next;
	  last->next = node;

	  return slist;
	}
    }
}

GList*
g_list_insert_before (GList   *list,
		      GList   *sibling,
		      gpointer data)
{
  if (!list)
    {
      list = g_list_alloc ();
      list->data = data;
      g_return_val_if_fail (sibling == NULL, list);
      return list;
    }
  else if (sibling)
    {
      GList *node;

      node = g_list_alloc ();
      node->data = data;
      if (sibling->prev)
	{
	  node->prev = sibling->prev;
	  node->prev->next = node;
	  node->next = sibling;
	  sibling->prev = node;
	  return list;
	}
      else
	{
	  node->next = sibling;
	  sibling->prev = node;
	  g_return_val_if_fail (sibling == list, node);
	  return node;
	}
    }
  else
    {
      GList *last;

      last = list;
      while (last->next)
	last = last->next;

      last->next = g_list_alloc ();
      last->next->data = data;
      last->next->prev = last;

      return list;
    }
}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]