Genralizing Pointer Routines

Gisle Aas aas at aase.nr.no
Thu Dec 13 04:06:45 AEST 1990


In article <14714 at smoke.brl.mil> gwyn at smoke.brl.mil (Doug Gwyn) writes:
   In article <cbN7yBm00UhW45Cnh2 at andrew.cmu.edu> rg2c+ at andrew.cmu.edu (Robert Nelson Gasch) writes:
   >In PASCAL, if you have 3 linked lists of different pointer types,
   >you have to write 3 different Insert, search & delete routines; one
   >for each pointer type. I was wondering if these routines can be 
   >generalized for any pointer type in C?

   Yes, the simplest scheme is to have a special "linkage" substructure
   as the first member of each type of node structure.  By appropriate
   use of casts etc., common link-manipulation routines can be used for
   all the node types, in a portable ("strictly conforming") manner.

Or you could use the preprocessor. These macros operate on double
linked lists. The idea should be simple to extend.

#ifdef lint
   int _ZERO_;
#else
   #define _ZERO_ 0
#endif
#define STATEMENT(s)    do {s} while (_ZERO_)

/* don't use this macro directly */
#define _dl_insert(z,d,first,prev,next)         \
   if (first) {                                 \
      z->prev = d->prev;                        \
      z->next = d;                              \
      d->prev->next = z;                        \
      d->prev = z;                              \
   } else {                                     \
      first = z;                                \
      z->next = z;                              \
      z->prev = z;                              \
   }

/* insert the element z just before the element d which is a member of
 * the list starting with element first.
 */
#define dl_insert(z,d,first,prev,next)          \
STATEMENT(                                      \
   _dl_insert(z,d,first,prev,next);             \
   if (d == first)                              \
      first = z;                                \
)

#define dl_insert_first(z,first,prev,next)      \
STATEMENT(                                      \
   _dl_insert(z,first,first,prev,next);         \
   first = z;                                   \
)

#define dl_insert_last(z,first,prev,next)       \
STATEMENT(                                      \
   _dl_insert(z,first,first,prev,next);         \
)

#define dl_remove(z,first,prev,next)            \
STATEMENT(                                      \
   z->next->prev = z->prev;                     \
   z->prev->next = z->next;                     \
   if (z == first) first = z->next;             \
   if (z == first) first = NULL;                \
)


/*---- Example of use, not tested ----*/

struct node *list1 = NULL, *list2 = NULL;   /* list heads */
struct node {
   sometype foo;
   ...

   struct node *next1, *prev1;
   struct node *next2, *prev2;
}


x = malloc(sizeof(node));
dl_insert_first(x,list1,prev1,next2);
dl_insert_last(x,list2,prev2,next2);
dl_remove(x,list2,prev2,next2);

--
Gisle Aas               |  snail: Boks 114 Blindern, N-0314 Oslo, Norway
Norsk Regnesentral      |  X.400: G=Gisle;S=Aas;O=nr;P=uninett;C=no
voice: +47-2-453561     |  inet:  Gisle.Aas at nr.no



More information about the Comp.lang.c mailing list