diff options
Diffstat (limited to 'mps/code/ring.h')
| -rw-r--r-- | mps/code/ring.h | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/mps/code/ring.h b/mps/code/ring.h new file mode 100644 index 00000000000..43c71600ec0 --- /dev/null +++ b/mps/code/ring.h | |||
| @@ -0,0 +1,108 @@ | |||
| 1 | /* impl.h.ring: RING INTERFACE | ||
| 2 | * | ||
| 3 | * $HopeName: MMsrc!ring.h(MMdevel_pekka_locus.1) $ | ||
| 4 | * Copyright (C) 1999 Harlequin Limited. All rights reserved. | ||
| 5 | */ | ||
| 6 | |||
| 7 | |||
| 8 | #ifndef ring_h | ||
| 9 | #define ring_h | ||
| 10 | |||
| 11 | #include "check.h" | ||
| 12 | #include "mpmtypes.h" | ||
| 13 | |||
| 14 | |||
| 15 | /* RingStruct -- double-ended queue structure | ||
| 16 | * | ||
| 17 | * .ring: The ring structure is used as a field in other structures | ||
| 18 | * in order to link them together into "rings". See impl.c.ring. | ||
| 19 | */ | ||
| 20 | |||
| 21 | typedef struct RingStruct *Ring; | ||
| 22 | typedef struct RingStruct { /* double-ended queue structure */ | ||
| 23 | Ring next, prev; /* links to next and prev element */ | ||
| 24 | } RingStruct; | ||
| 25 | |||
| 26 | |||
| 27 | #define RingNONE ((Ring)0) | ||
| 28 | |||
| 29 | extern Bool RingCheck(Ring ring); | ||
| 30 | extern Bool RingCheckSingle(Ring ring); | ||
| 31 | extern Bool RingIsSingle(Ring ring); | ||
| 32 | |||
| 33 | /* .ring.init: */ | ||
| 34 | extern void (RingInit)(Ring ring); | ||
| 35 | #define RingInit(ring) \ | ||
| 36 | BEGIN \ | ||
| 37 | Ring _ring = (ring); \ | ||
| 38 | AVER(_ring != NULL); \ | ||
| 39 | _ring->next = _ring; \ | ||
| 40 | _ring->prev = _ring; \ | ||
| 41 | AVER(RingCheck(_ring)); \ | ||
| 42 | END | ||
| 43 | |||
| 44 | /* .ring.finish: */ | ||
| 45 | extern void (RingFinish)(Ring ring); | ||
| 46 | #define RingFinish(ring) \ | ||
| 47 | BEGIN \ | ||
| 48 | Ring _ring = (ring); \ | ||
| 49 | AVER(RingCheckSingle(_ring)); \ | ||
| 50 | _ring->next = RingNONE; \ | ||
| 51 | _ring->prev = RingNONE; \ | ||
| 52 | END | ||
| 53 | |||
| 54 | /* .ring.append: */ | ||
| 55 | extern void (RingAppend)(Ring ring, Ring new); | ||
| 56 | #define RingAppend(ring, new) \ | ||
| 57 | BEGIN \ | ||
| 58 | Ring _ring = (ring), _new = (new); \ | ||
| 59 | AVER(RingCheck(_ring)); \ | ||
| 60 | AVER(RingCheckSingle(_new)); \ | ||
| 61 | _new->prev = _ring->prev; \ | ||
| 62 | _new->next = _ring; \ | ||
| 63 | _ring->prev->next = _new; \ | ||
| 64 | _ring->prev = _new; \ | ||
| 65 | END | ||
| 66 | |||
| 67 | /* .ring.insert: */ | ||
| 68 | extern void (RingInsert)(Ring ring, Ring new); | ||
| 69 | #define RingInsert(ring, new) \ | ||
| 70 | BEGIN \ | ||
| 71 | Ring _ring = (ring), _new = (new); \ | ||
| 72 | AVER(RingCheck(_ring)); \ | ||
| 73 | AVER(RingCheckSingle(_new)); \ | ||
| 74 | _new->prev = _ring; \ | ||
| 75 | _new->next = _ring->next; \ | ||
| 76 | _ring->next->prev = _new; \ | ||
| 77 | _ring->next = _new; \ | ||
| 78 | END | ||
| 79 | |||
| 80 | /* .ring.remove: */ | ||
| 81 | extern void (RingRemove)(Ring old); | ||
| 82 | #define RingRemove(old) \ | ||
| 83 | BEGIN \ | ||
| 84 | Ring _old = (old); \ | ||
| 85 | AVER(RingCheck(_old)); \ | ||
| 86 | AVER(!RingIsSingle(_old)); \ | ||
| 87 | _old->next->prev = _old->prev; \ | ||
| 88 | _old->prev->next = _old->next; \ | ||
| 89 | _old->next = _old; \ | ||
| 90 | _old->prev = _old; \ | ||
| 91 | END | ||
| 92 | |||
| 93 | /* .ring.next: */ | ||
| 94 | extern Ring (RingNext)(Ring ring); | ||
| 95 | #define RingNext(ring) ((ring)->next) | ||
| 96 | |||
| 97 | /* .ring.elt: See design.mps.ring.elt */ | ||
| 98 | #define RING_ELT(type, field, node) \ | ||
| 99 | ((type)((char *)(node) - (size_t)(&((type)0)->field))) | ||
| 100 | |||
| 101 | /* .ring.for: See design.mps.ring.for */ | ||
| 102 | #define RING_FOR(node, ring, next) \ | ||
| 103 | for(node = RingNext(ring), next = RingNext(node); \ | ||
| 104 | node != (ring); \ | ||
| 105 | node = (next), next = RingNext(node)) | ||
| 106 | |||
| 107 | |||
| 108 | #endif /* ring_h */ | ||