This file is indexed.

/usr/include/alberta/alberta_util_inlines.h is in libalberta-dev 3.0.1-1build1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
/*--------------------------------------------------------------------------*/
/* ALBERTA_UTIL:  tools for messages, memory allocation, parameters, etc.   */
/*                                                                          */
/* file: alberta_util_inline.h                                              */
/*                                                                          */
/* description: header for inline functions of the ALBERTA_UTIL package     */
/*                                                                          */
/*--------------------------------------------------------------------------*/
/*                                                                          */
/*  authors:   Alfred Schmidt                                               */
/*             Zentrum fuer Technomathematik                                */
/*             Fachbereich 3 Mathematik/Informatik                          */
/*             Universitaet Bremen                                          */
/*             Bibliothekstr. 2                                             */
/*             D-28359 Bremen, Germany                                      */
/*                                                                          */
/*             Kunibert G. Siebert                                          */
/*             Institut fuer Mathematik                                     */
/*             Universitaet Augsburg                                        */
/*             Universitaetsstr. 14                                         */
/*             D-86159 Augsburg, Germany                                    */
/*                                                                          */
/*             Claus-Justus Heine                                           */
/*             Abteilung fuer Angewandte Mathematik                         */
/*             Albert-Ludwigs-Universitaet Freiburg                         */
/*             Hermann-Herder-Str. 10                                       */
/*             D-79104 Freiburg im Breisgau, Germany                        */
/*                                                                          */
/*  http://www.mathematik.uni-freiburg.de/IAM/ALBERTA                       */
/*                                                                          */
/*  (c) by A. Schmidt and K.G. Siebert (1996-2003),                         */
/*         C.-J. Heine (2007-2008)                                          */
/*                                                                          */
/*--------------------------------------------------------------------------*/

#ifndef _ALBERTA_UTIL_INLINES_H_
#define _ALBERTA_UTIL_INLINES_H_

#line 40 "./alberta_util_inlines.h.in.in"

#ifndef USE_LIBBLAS
# define USE_LIBBLAS 0
#endif

#if USE_LIBBLAS
#define DNRM2_F77  
#define DAXPY_F77  
#define DCOPY_F77  
#define DDOT_F77   
#define DSCAL_F77  
#define DSWAP_F77  

extern double DNRM2_F77(int *n, const double *x, int *ix);
extern void DAXPY_F77(int *n, double *alpha, const double *x, int *ix,
                      double *y, int *iy);
extern void DCOPY_F77(int *n, const double *x, int *ix, double *y, int *iy);
extern double DDOT_F77(int *n, const double *x, int *ix, const double *y, 
		       int *iy);
extern void DSCAL_F77(int *n, double *alpha, double *x, int *ix);
extern void DSWAP_F77(int *n, double *x, int *ix, double *y, int *iy);
#endif

static inline void daxpy(int n, double alpha, const double *x, 
			 int ix, double *y, int iy)
{
#if USE_LIBBLAS
  DAXPY_F77(&n, &alpha, x, &ix, y, &iy);
#else
  int i;
# if HAVE_OPENMP
#  pragma omp parallel for
# endif
  for (i = 0; i < n; ++i) {
    *y += alpha * *x;
    x += ix;
    y += iy;
  }
# if HAVE_OPENMP
#  pragma omp barrier
# endif
#endif
}

static inline void dexpy(int n, const double *x, int ix, double *y, int iy)
{
#if USE_LIBBLAS
  /* DEXPY_F77(&n, x, &ix, y, &iy); */
  REAL one = 1.0;
  DAXPY_F77(&n, &one, x, &ix, y, &iy);
#else
  int i;
# if HAVE_OPENMP
#  pragma omp parallel for
# endif
  for (i = 0; i < n; ++i) {
    *y += *x;
    x += ix;
    y += iy;
 }
# if HAVE_OPENMP
#  pragma omp barrier
# endif
#endif
}

static inline void dmxpy(int n, const double *x, int ix, double *y, int iy)
{
#if USE_LIBBLAS
  /* DMXPY_F77(&n, x, &ix, y, &iy); */
  REAL mone = -1.0;
  DAXPY_F77(&n, &mone, x, &ix, y, &iy);
#else
  int i;
# if HAVE_OPENMP
#  pragma omp parallel for
# endif
  for (i = 0; i < n; ++i) {
    *y -= *x;
    x += ix;
    y += iy;
 }
# if HAVE_OPENMP
#  pragma omp barrier
# endif
#endif
}

static inline void dcopy(int n, const double *x, int ix, double *y, int iy)
{
#if USE_LIBBLAS
  DCOPY_F77(&n, x, &ix, y, &iy);
#else
  int i;
# if HAVE_OPENMP
#  pragma omp parallel for
# endif
  for (i = 0; i < n; ++i) {
    *y = *x;
    x += ix;
    y += iy;
  }
# if HAVE_OPENMP
#  pragma omp barrier
# endif
#endif
}

static inline double ddot(int n, const double *x, int ix,
			  const double *y, int iy)
{
#if USE_LIBBLAS
  return DDOT_F77(&n, x, &ix, y, &iy);
#else
  int i;
  REAL result = 0.0;
# if HAVE_OPENMP
#  pragma omp parallel for reduction(+:result)
# endif
  for (i = 0; i < n; ++i) {
    result += *x * *y;
    x += ix;
    y += iy;
  }
# if HAVE_OPENMP
#  pragma omp barrier
# endif
  return result;
#endif
}

static inline double dnrm2(int n, const double *x, int ix)
{
#if USE_LIBBLAS
  return DNRM2_F77(&n, x, &ix);
#else
  return sqrt(ddot(n , x, ix, x, ix));
#endif
}

static inline void dscal(int n, double alpha, double *x, int ix)
{
#if USE_LIBBLAS
  DSCAL_F77(&n, &alpha, x, &ix);
#else
  int i, nix = n*ix;
# if HAVE_OPENMP
#  pragma omp parallel for
# endif
  for (i = 0; i < nix; i += ix) {
    x[i] *= alpha;
  }
# if HAVE_OPENMP
#  pragma omp barrier
# endif
#endif
}

static inline void dswap(int n, double *x, int ix, double *y, int iy)
{
#if USE_LIBBLAS
  DSWAP_F77(&n, x, &ix, y, &iy);
#else
  int i;
# if HAVE_OPENMP
#  pragma omp parallel for
# endif
  for (i = 0; i < n; ++i) {
    REAL swap = *y; *y = *x; *x = swap;
    x += ix;
    y += iy;
  }
# if HAVE_OPENMP
#  pragma omp barrier
# endif
#endif
}

static inline void dxpay(int n, const double *x, int ix, double alpha,
			 double *y, int iy)
{
#if false && USE_LIBBLAS
  /*DXPAY_F77(&n, x, &ix, &alpha, y, &iy);*/
  DSCAL_F77(&n, &alpha, y, &ix);
  dexpy(n, x, ix, y, iy);
#else
  int i;
# if HAVE_OPENMP
#  pragma omp parallel for
# endif
  for (i = 0; i < n; ++i) {
    *y = alpha * *y + *x;
    x += ix;
    y += iy;
  }
# if HAVE_OPENMP
#  pragma omp barrier
# endif
#endif
  return;
}

static inline void drandn(int n, double *x, int seed)
{
#if false && USE_LIBBLAS
  DRANDN_F77(&n, x, &seed);
#else
  int i;

  if (seed > 0) {
    srand(seed);
  }
# if HAVE_OPENMP
#  pragma omp parallel for
# endif
  for (i = 0; i < n; ++i) {
    x[i] = (double)rand() / (double)RAND_MAX;
  }
# if HAVE_OPENMP
#  pragma omp barrier
# endif
#endif
  return;
}

static inline void dset(int n, double alpha, double *x, int ix)
{
  int i;
#if HAVE_OPENMP
# pragma omp parallel for
#endif
  for (i = 0; i < n; ++i) {
    *x = alpha;
    x += ix;
  }
#if HAVE_OPENMP
# pragma omp barrier
#endif
}

/* Standard scp function. */
static inline REAL std_scp(void *dummy, int dim, const REAL *x, const REAL *y)
{
  return ddot(dim, x, 1, y, 1);
}

/******************************************************************************
 *
 * bit-field operations for the boundary flags (e.g.)
 *
 */

static inline bool bitfield_tst(const FLAGS *bits, int nr)
{
  int word = nr / (sizeof(*bits) * 8);
  int bit  = nr % (sizeof(*bits) * 8);
  
  return (bits[word] & (1 << bit)) != 0;
}

static inline void bitfield_set(FLAGS *bits, int nr)
{
  int word = nr / (sizeof(*bits) * 8);
  int bit  = nr % (sizeof(*bits) * 8);
  
  bits[word] |= 1 << bit;
}

static inline void bitfield_clr(FLAGS *bits, int nr)
{
  int word = nr / (sizeof(*bits) * 8);
  int bit  = nr % (sizeof(*bits) * 8);
  
  bits[word] &= ~(1 << bit);
}

static inline void bitfield_inv(FLAGS *bits, int nr)
{
  int word = nr / (sizeof(*bits) * 8);
  int bit  = nr % (sizeof(*bits) * 8);
  
  bits[word] ^= (1 << bit);
}

static inline int bitfield_nwords(int nbits)
{
  return (nbits + sizeof(FLAGS)*8 - 1) / (sizeof(FLAGS)*8);
}

static inline void bitfield_zap(FLAGS *bits, int nbits)
{
  int i;
  
  for (i = 0; i < bitfield_nwords(nbits); i++) {
    bits[i] = 0;
  }
}

static inline void bitfield_fill(FLAGS *bits, int nbits)
{
  int i;
  
  for (i = 0; i < bitfield_nwords(nbits); i++) {
    bits[i] = ~(FLAGS)0;
  }
}

static inline void bitfield_cpy(FLAGS *to, const FLAGS *from, int nbits)
{
  int i;
  
  for (i = 0; i < bitfield_nwords(nbits); i++) {
    to[i] = from[i];
  }
}

/* Return true if A and B have common bits set. NBITS must be a multiple
 * of 8.
 */
static inline bool bitfield_andp(const FLAGS *a, const FLAGS *b,
				 int offset, int nbits)
{
  int i;
  
  i       = bitfield_nwords(offset);
  offset %= sizeof(FLAGS)*8;
  if (offset != 0) {
    FLAGS mask = ~0UL;
    mask <<= offset;
    if (a[i-1] & b[i-1] & mask) {
      return true;
    }
  }
  for (i = bitfield_nwords(offset); i < bitfield_nwords(nbits); i++) {
    if (a[i] & b[i]) {
      return true;
    }
  }
  return false;
}

/* Compare two bitfields as unsigned numbers */
static inline int bitfield_cmp(const FLAGS *a, const FLAGS *b, int nbits)
{
  int i;
  
  for (i = bitfield_nwords(nbits) - 1; i >= 0; i--) {
    if (a[i] > b[i]) {
      return 1;
    }
    if (a[i] < b[i]) {
      return -1;
    }
  }
  return 0;
}

/* bit-wise and */
static inline void bitfield_and(FLAGS *to, const FLAGS *from, int nbits)
{
  int i;
  
  for (i = 0; i < bitfield_nwords(nbits); i++) {
    to[i] &= from[i];
  }
}

/* bit-wise or */
static inline void bitfield_or(FLAGS *to, const FLAGS *from, int nbits)
{
  int i;
  
  for (i = 0; i < bitfield_nwords(nbits); i++) {
    to[i] |= from[i];
  }
}

/* bit-wise xor */
static inline void bitfield_xor(FLAGS *to, const FLAGS *from, int nbits)
{
  int i;
  
  for (i = 0; i < bitfield_nwords(nbits); i++) {
    to[i] ^= from[i];
  }
}

static inline int ffs_flags(FLAGS bits)
{
  FUNCNAME("ffs_flags");

  TEST_EXIT(sizeof(long) == sizeof(FLAGS),
	    "FIXME: sizeof(long) != sizeof(FLAGS)\n");
  TEST_EXIT(sizeof(long) >= 4,
	    "FIXME: sizeof(long) < 4\n");

#if HAVE_FFSL
# if !HAVE_DECL_FFSL
  extern int ffsl(long int i);
# endif
  return ffsl(bits)-1;
#else
  {
    int r = 0;
    FLAGS mask = ~(FLAGS)0;

    if (!bits) {
      return -1;
    }

    /* The MIN() stuff is only to disable a compiler warning */
    if (sizeof(FLAGS) == 16) {
      mask >>= MIN(64, sizeof(FLAGS)*8-1);
      if (!(bits & mask)) {
	bits >>= MIN(64, sizeof(FLAGS)*8-1);
	r     += 64;
      }
    }
    if (sizeof(FLAGS) >= 8) {
      mask >>= MIN(32, sizeof(FLAGS)*8-1);
      if (!(bits & 0xFFFFFFFF)) {
	bits >>= MIN(32, sizeof(FLAGS)*8-1);
	r += 32;
      }
    }
    if (!(bits & 0xFFFF)) {
      bits >>= 16;
      r += 16;
    }
    /* assume longs are at least 2 bytes ... ;) */
    if (!(bits & 0xFF)) {
      bits >>= 8;
      r += 8;
    }
    if (!(bits & 0xF)) {
      bits >>= 4;
      r += 4;
    }
    if (!(bits & 0x3)) {
      bits >>= 2;
      r += 2;
    }
    if (!(bits & 0x1)) {
      bits >>= 1;
      r += 1;
    }
    return r;
  }
#endif
}

/* Find first set bit, starting at offset */
static inline int bitfield_ffs(const FLAGS *bits, int offset, int nbits)
{
  int i, r, i0;
  FLAGS mask = (~(FLAGS)0) << offset;
  
  i0 = offset > 0 ? bitfield_nwords(offset) - 1 : 0;

  for (i = i0; i < bitfield_nwords(nbits); i++) {
    if ((r = ffs_flags(*bits++ & mask)) >= 0) {
      r += i * sizeof(*bits) * 8;
      return r;
    }
    mask = ~(FLAGS)0;
  }
  return -1;
}

/******************************************************************************/

/*******************************************************************************
 *
 * Doubly linked list managenent/
 *
 * A doubly linked list is abstracted as a pair of a next and a prev
 * pointer. The empty list is characterised by the prev and next
 * pointer of the list-head pointing back to the list-head.
 *
 */

/** Inititializer for the list head. */
#define DBL_LIST_INITIALIZER(name) \
  { (DBL_LIST_NODE *)&(name), (DBL_LIST_NODE *)&(name) }

#define DBL_LIST(name)					\
  DBL_LIST_NODE name = DBL_LIST_INITIALIZER(name)

#define DBL_LIST_INIT(ptr) do {			\
    (ptr)->next = (ptr); (ptr)->prev = (ptr);	\
  } while (0)

/**
 * list_entry - get the struct for this entry
 * @param[in] ptr the struct list_head pointer.
 * @param[in] type the type of the struct this is embedded in.
 * @param[in] member the name of the list_struct within the struct.
 *
 * Example:
 *
 * @code
 * struct my_struct {
 *   int datum;
 *   DBL_LIST_NODE node;
 * };
 *
 *
 * DBL_LIST_NODE *pos; // pointing to &my_struct::node
 * struct my_struct *ptr = dbl_list_entry(pos, struct my_struct, node);
 * @end code
 */
#define dbl_list_entry(ptr, type, member) \
	((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))

/** Iterate over list of given type, it is safe to call
 * dbl_list_delete(pos) inside the loop.
 *
 * @param[in,out] pos The position pointer to use as a loop counter. It
 * has type @c type (i.e. not DBL_LIST_NODE).
 *
 * @param[in,out] next Storage for pos->next, in case pos is deleted
 * from the list inside the loop.
 *
 * @param[in,out] head The list head, DBL_LIST_NODE.
 * 
 * @param[in] type The type of the struct this list's nodes are
 * embedded in.
 *
 * @param[in[ member The name of the DBL_LIST_NODE within the struct.
 */
#define dbl_list_for_each_entry_safe(pos, nextptr, head, type, member)	\
	for (pos = dbl_list_entry((head)->next, type, member),		\
	       (nextptr) = (pos)->member.next;				\
	     &pos->member != (head);					\
	     (pos) = dbl_list_entry(nextptr, type, member),		\
	       (nextptr) = (pos)->member.next)

/** Iterate over list of given type in reverse direction, it is safe
 * to call dbl_list_delete(pos) inside the loop.
 *
 * @param[in,out] pos The position pointer to use as a loop counter. It
 * has type @c type (i.e. not DBL_LIST_NODE).
 *
 * @param[in,out] next Storage for pos->next, in case pos is deleted
 * from the list inside the loop.
 *
 * @param[in,out] head The list head, DBL_LIST_NODE.
 * 
 * @param[in] type The type of the struct this list's nodes are
 * embedded in.
 *
 * @param[in[ member The name of the DBL_LIST_NODE within the struct.
 */
#define dbl_list_for_each_entry_rev_safe(pos, prevptr, head, type, member) \
	for (pos = dbl_list_entry((head)->prev, type, member),		\
	       (nextptr) = (pos)->member.prev;				\
	     &pos->member != (head);					\
	     (pos) = dbl_list_entry(nextptr, type, member),		\
	       (prevptr) = (pos)->member.prev)

/** Iterate over list of given type, it is @b not safe to call
 * dbl_list_delete(pos) inside the loop.
 *
 * @param[in,out] pos The position pointer to use as a loop counter. It
 * has type @c type (i.e. not DBL_LIST_NODE).
 *
 * @param[in,out] head The list head, DBL_LIST_NODE.
 * 
 * @param[in] type The type of the struct this list's nodes are
 * embedded in.
 *
 * @param[in[ member The name of the DBL_LIST_NODE within the struct.
 */
#define dbl_list_for_each_entry(pos, head, type, member)		\
  for ((pos) = dbl_list_entry((head)->next, type, member);		\
       &(pos)->member != (head);					\
       (pos) = dbl_list_entry((pos)->member.next, type, member))

/** Iterate over list of given type in reverse direction, it is @b not
 * safe to call dbl_list_delete(pos) inside the loop.
 *
 * @param[in,out] pos The position pointer to use as a loop counter. It
 * has type @c type (i.e. not DBL_LIST_NODE).
 *
 * @param[in,out] head The list head, DBL_LIST_NODE.
 * 
 * @param[in] type The type of the struct this list's nodes are
 * embedded in.
 *
 * @param[in[ member The name of the DBL_LIST_NODE within the struct.
 */
#define dbl_list_for_each_entry_rev(pos, head, type, member)		\
  for ((pos) = dbl_list_entry((head)->prev, type, member);		\
       &(pos)->member != (head);					\
       (pos) = dbl_list_entry((pos)->member.prev, type, member))

/* A do-while loop for cyclic list, i.e. the list head itself belongs
 * to a real data-item.
 *
 * The expected usage is:
 *
 * dbl_list_do_cyclic(list, my_list_struct, node_name) {
 *   ... but NEVER delete elements
 * } dbl_list_while_cyclic(list, my_list_struct, node_name)
 *
 * When the loop has finished then LIST should point again to the
 * first element, so it should be safe to do the loop with the
 * list-head.
 *
 * Breaking out of the loop will leave you with "list" pointing to the
 * current element.
 */
#define dbl_list_do_cyclic(list, type, member)		\
  {							\
    const DBL_LIST_NODE *_AI_anchor = &(list)->member;	\
    do

#define dbl_list_while_cyclic(list, type, member)			\
  while ((list) = dbl_list_entry((list)->member.next, type, member),	\
	 &(list)->member != _AI_anchor);				\
  }

#define dbl_list_do_cyclic_rev(list, type, member)		\
  {								\
    const DBL_LIST_NODE *_AI_anchor = (list)->member.prev;	\
    (list) = dbl_list_entry((list)->member.prev, type, member);	\
    do

#define dbl_list_while_cyclic_rev(list, type, member)			\
  while ((list) = dbl_list_entry((list)->member.prev, type, member),	\
	 &(list)->member != _AI_anchor);				\
  }

/** Add newnode to head, where newnode will be the new first element
 * of the list.
 */
static inline void
dbl_list_add_head(DBL_LIST_NODE *head, DBL_LIST_NODE *newnode)
{
  head->next->prev = newnode;
  newnode->next = head->next;
  newnode->prev = head;
  head->next = newnode;
}

/** Add newnode to head, where newnode will become the new last
 * element of the list.
 */
static inline void
dbl_list_add_tail(DBL_LIST_NODE *head, DBL_LIST_NODE *newnode)
{
  head->prev->next = newnode;
  newnode->prev    = head->prev;
  newnode->next    = head;
  head->prev       = newnode;
}

/** Delete entry from the list it belongs to. Afterwards entry will
 * point to itself.
 */
static inline void dbl_list_del(DBL_LIST_NODE *entry)
{
  entry->next->prev = entry->prev;
  entry->prev->next = entry->next;
  entry->next       = entry;
  entry->prev       = entry;
}

/** Return true if the given list-head is an empty list. */
static inline bool dbl_list_empty(const DBL_LIST_NODE *head)
{
  return head->next == head;
}

/******************************************************************************/

#endif  /* _ALBERTA_UTIL_INLINES_H_  */

/*
 * Local Variables: ***
 * mode: C ***
 * End: ***
 */