On 14/10/2016 12:44, Dr. David Alan Gilbert wrote:
>> > +#define QTAILQ_RAW_INSERT_TAIL(head, elm, entry) do {                     
>> >      \
>> > +        *((void **) ((char *) (elm) + (entry) + QTAILQ_NEXT_OFFSET)) = 
>> > NULL;   \
>> > +        *((void **) ((char *) (elm) + (entry) + QTAILQ_PREV_OFFSET)) =    
>> >      \
>> > +            *((void **) ((char *) (head) + QTAILQ_LAST_OFFSET));          
>> >      \
>> > +        **((void ***)((char *) (head) + QTAILQ_LAST_OFFSET)) = (elm);     
>> >      \
>> > +        *((void **) ((char *) (head) + QTAILQ_LAST_OFFSET)) =             
>> >      \
>> > +            (void *) ((char *) (elm) + (entry) + QTAILQ_NEXT_OFFSET);     
>> >      \
>> > +} while (/*CONSTCOND*/0)
> I wonder if there's a simpler way to do this; I'm not sure this works, but 
> something like:
> 
> struct QTAILQDummy {
>     char dummy;
> };
> 
> QTAILQ_HEAD(QTAILQRawHead, struct QTAILQDummy)
> typedef QTAILQ_ENTRY(struct QTAILQDummy) QTAILQRawEntry;
> 
> #define QTAILQ_RAW_FOREACH(elm, head, entry)                                  
>  \
>         for ((elm) = ((struct QTAILQRawHead *)head)->tqh_first)               
>  \
>              (elm);                                                           
>  \
>              (elm) =                                                          
>  \
>              (elm) = ((QTAILQRawEntry *)((char *) (elm) + (entry)))->tqh_next
> 
> and then I think elm gets declared as a struct QTAILQDummy.
> But it does avoid those FIRST_OFFSET/LAST_OFFSET/NEXT_OFFSET/PREV_OFFSET 
> calculations.

Another possibility is a macro like

#define field_at_offset(base, offset, type) \
   ((type) (((char *) (base)) + (offset)))

so that you can do

   *field_at_offset(void **, elm, (entry) + QTAILQ_NEXT_OFFSET) = NULL;
   *field_at_offset(void ***, elm, (entry) + QTAILQ_PREV_OFFSET) =
       *field_at_offset(void ***, head, QTAILQ_LAST_OFFSET);
   **field_at_offset(void ***, head, QTAILQ_LAST_OFFSET) = (elm);
   *field_at_offset(void ***, head, QTAILQ_LAST_OFFSET) =
        field_at_offset(void **, elm, (entry) + QTAILQ_NEXT_OFFSET);

or something like that (note that I've always used the same type for
next and last, by the way).

Paolo

Reply via email to