ring

dynamic ring array
git clone https://noulin.net/git/ring.git
Log | Files | Refs | LICENSE

cRing.c (6302B)


      1 //
      2 //
      3 //
      4 
      5 #include "libsheepyObject.h"
      6 #include "cRing.h"
      7 #include "cRingInternal.h"
      8 
      9 #define internal static
     10 
     11 #include <stdlib.h>
     12 #include <string.h>
     13 #include <stdio.h>
     14 
     15 void initiateRing(ringt *self);
     16 void initiateAllocateRing(ringt **self);
     17 void finalizeRing(void);
     18 internal void freeRing(ringt *self);
     19 internal void terminateRing(ringt **self);
     20 internal char* toStringRing(ringt *self);
     21 internal ringt* duplicateRing(ringt *self);
     22 internal void smashRing(ringt **self);
     23 internal void finishRing(ringt **self);
     24 internal void setSizeRing(ringt *self, size_t size);
     25 internal bool rIsEmptyRing(smallArrayt *self);
     26 internal bool isFullRing(ringt *self);
     27 internal i64 countRing(ringt *self);
     28 internal i64 maxCountRing(ringt *self);
     29 internal baset* lastRing(ringt *self);
     30 internal baset* firstRing(ringt *self);
     31 internal baset* getFromRing(ringt *self, intmax_t index);
     32 
     33 // replace parent functions
     34 internal smallArrayt* pushRing(smallArrayt *self, baset *value);
     35 internal baset* popRing(smallArrayt *self);
     36 internal smallArrayt* prependRing(smallArrayt *self, baset *value);
     37 internal baset* dequeueRing(smallArrayt *self);
     38 
     39 void initiateRing(ringt *self) {
     40 
     41   self->type = "ring";
     42 
     43   if (!ringF) {
     44     ringF            = malloc(sizeof(ringFunctionst));
     45     registerMethodsSmallArray((smallArrayFunctionst *) ringF);
     46 
     47     // SAME AS PARENT
     48     /* ringF->free      = freeRing; */
     49     /* ringF->terminate = terminateRing; */
     50     /* ringF->toString  = toStringRing; */
     51     ringF->duplicate = duplicateRing;
     52     /* ringF->smash     = smashRing; */
     53     /* ringF->finish    = finishRing; */
     54 
     55     ringF->setSize      = setSizeRing;
     56     ringF->isFull       = isFullRing;
     57     ringF->count        = countRing;
     58     ringF->maxCount     = maxCountRing;
     59     ringF->last         = lastRing;
     60     ringF->first        = firstRing;
     61     ringF->send         = pushRing;
     62     ringF->recv         = dequeueRing;
     63     ringF->getFrom      = getFromRing;
     64 
     65     // save and replace parent class functions
     66     ringF->parentIsEmpty= ringF->isEmpty;
     67     ringF->parentPush   = ringF->push;
     68     ringF->parentPop    = ringF->pop;
     69     ringF->parentPrepend= ringF->prepend;
     70     ringF->parentDequeue= ringF->dequeue;
     71 
     72     ringF->isEmpty      = rIsEmptyRing;
     73     ringF->push         = pushRing;
     74     ringF->pop          = popRing;
     75     ringF->prepend      = prependRing;
     76     ringF->dequeue      = dequeueRing;
     77 
     78   }
     79   self->f                 = ringF;
     80 
     81   self->a                 = NULL;
     82   self->last = self->head = 0;
     83   self->isEmpty           = true;
     84 }
     85 
     86 void initiateAllocateRing(ringt **self) {
     87 
     88   if (self) {
     89     (*self) = malloc(sizeof(ringt));
     90     if (*self) {
     91       initiateRing(*self);
     92     }
     93   }
     94 }
     95 
     96 void finalizeRing(void) {
     97 
     98   if (ringF) {
     99     free(ringF);
    100     ringF = NULL;
    101   }
    102 }
    103 
    104 ringt* allocRing(void) {
    105   ringt *r;
    106 
    107   initiateAllocateRing(&r);
    108   return(r);
    109 }
    110 
    111 
    112 // SAME AS PARENT
    113 /* internal void freeRing(ringt *self) { */
    114 /*  */
    115 /*   // */
    116 /*   return; */
    117 /* } */
    118 /*  */
    119 /* internal void terminateRing(ringt **self) { */
    120 /*  */
    121 /*   (*self)->f->free(*self); */
    122 /*   free(*self); */
    123 /*   *self = NULL; */
    124 /* } */
    125 /*  */
    126 /*  */
    127 /* internal char* toStringRing(ringt *self) { */
    128 /*  */
    129 /*   return(strdup("- class template")); */
    130 /* } */
    131 
    132 internal ringt* duplicateRing(ringt *self) {
    133 
    134   createAllocateRing(dup);
    135   forEachSArray(self->a, o)
    136       if (o)
    137         sArrayPushTiny(&(dup->a), sDuplicateTiny(o));
    138   dup->last    = self->last;
    139   dup->head    = self->head;
    140   dup->isEmpty = self->isEmpty;
    141   return(dup);
    142 }
    143 
    144 // SAME AS PARENT
    145 /* internal void smashRing(ringt **self) { */
    146 /*  */
    147 /*   free(*self); */
    148 /*   *self = NULL; */
    149 /* } */
    150 /*  */
    151 /* internal void finishRing(ringt **self) { */
    152 /*  */
    153 /*   free(*self); */
    154 /*   *self = NULL; */
    155 /* } */
    156 
    157 internal void setSizeRing(ringt *self, size_t size) {
    158   range(i, size) {
    159     self->f->parentPush( cAr(self), NULL);
    160   }
    161 }
    162 
    163 internal bool rIsEmptyRing(smallArrayt *self) {
    164   return ((ringt *)self)->isEmpty;
    165 }
    166 
    167 internal bool isFullRing(ringt *self) {
    168 
    169   if (self->isEmpty) return false;
    170 
    171   return (((self->last+1) % lenO(cAr(self))) == self->head);
    172 }
    173 
    174 internal i64 countRing(ringt *self) {
    175 
    176   if (self->isEmpty)            return 0;
    177   if (self->last >= self->head) return (self->last - self->head +1);
    178   else                          return (lenO(cAr(self)) - self->head + self->last +1);
    179 }
    180 
    181 internal i64 maxCountRing(ringt *self) {
    182   return lenO(cAr(self));
    183 }
    184 
    185 internal smallArrayt* pushRing(smallArrayt *self, baset *value) {
    186 
    187   cast(ringt *, rg, self);
    188   if (rg->f->isFull(rg)) return self;
    189 
    190   if (rg->isEmpty) {
    191     rg->isEmpty = false;
    192   }
    193   else {
    194     rg->last++;
    195     rg->last %= lenO(cAr(self));
    196   }
    197   self->f->set(self, rg->last, value);
    198   return self;
    199 }
    200 
    201 internal baset* popRing(smallArrayt *self) {
    202 
    203   cast(ringt *, rg, self);
    204 
    205   baset *r = self->f->get(self, rg->last);
    206 
    207   if (!rg->isEmpty && (rg->last == rg->head))
    208      rg->isEmpty = true;
    209   else if (!rg->isEmpty && (rg->last != rg->head))
    210     rg->last--;
    211     if (rg->last < 0)
    212       rg->last += lenO(cAr(self));
    213     rg->last %= lenO(cAr(self));
    214   return r;
    215 }
    216 
    217 internal smallArrayt* prependRing(smallArrayt *self, baset *value) {
    218 
    219   cast(ringt *, rg, self);
    220 
    221   if (rg->f->isFull(rg)) return self;
    222 
    223   if (rg->f->isEmpty) {
    224     rg->f->isEmpty = false;
    225   }
    226   else {
    227     rg->head--;
    228     if (rg->head < 0) {
    229       rg->head += lenO(cAr(self));
    230     }
    231     rg->head %= lenO(cAr(self));
    232   }
    233 
    234   self->f->set(self, rg->head, value);
    235   return self;
    236 }
    237 
    238 internal baset* dequeueRing(smallArrayt *self) {
    239 
    240   cast(ringt *, rg, self);
    241 
    242   baset *r = self->f->get(self, rg->head);
    243 
    244   if (!rg->isEmpty && (rg->last == rg->head)) {
    245     rg->isEmpty = true;
    246   }
    247   else if (!rg->isEmpty && (rg->last != rg->head)) {
    248     rg->head++;
    249     rg->head %= lenO(cAr(self));
    250   }
    251 
    252   return r;
    253 }
    254 
    255 internal baset* lastRing(ringt *self) {
    256   if (self->isEmpty) return NULL;
    257   return self->f->get( cAr(self), self->last);
    258 }
    259 
    260 internal baset* firstRing(ringt *self) {
    261   if (self->isEmpty) return NULL;
    262   return self->f->get( cAr(self), self->head);
    263 }
    264 
    265 internal baset* getFromRing(ringt *self, intmax_t index) {
    266 
    267   if (self->isEmpty) return NULL;
    268 
    269   baset *r = self->f->get( cAr(self), (index + self->head) % lenO(cAr(self)));
    270   return r;
    271 }
    272 
    273 bool checkLibsheepyVersionRing(const char *currentLibsheepyVersion) {
    274   return eqG(currentLibsheepyVersion, LIBSHEEPY_VERSION);
    275 }
    276