gearmulator

Emulation of classic VA synths of the late 90s/2000s that are based on Motorola 56300 family DSPs
Log | Files | Refs | Submodules | README | LICENSE

ppodlist.cxx (3814B)


      1 /*
      2  *
      3  *  C++ Portable Types Library (PTypes)
      4  *  Version 2.1.1  Released 27-Jun-2007
      5  *
      6  *  Copyright (C) 2001-2007 Hovik Melikyan
      7  *
      8  *  http://www.melikyan.com/ptypes/
      9  *
     10  */
     11 
     12 #include "ptypes.h"
     13 
     14 
     15 namespace ptypes {
     16 
     17 
     18 void _podlist::idxerror()
     19 {
     20     fatal(CRIT_FIRST + 30, "List index out of bounds");
     21 }
     22 
     23 
     24 _podlist::_podlist(int iitemsize)
     25     : list(0), count(0), capacity(0), itemsize(iitemsize)
     26 {
     27     if (itemsize <= 0 || itemsize > 255)
     28         fatal(CRIT_FIRST + 37, "Invalid item size for podlist");
     29 }
     30 
     31 
     32 _podlist::~_podlist()
     33 {
     34     set_count(0);
     35 }
     36 
     37 
     38 void _podlist::set_capacity(int newcap)
     39 {
     40     if (newcap != capacity)
     41     {
     42         if (newcap < count)
     43             fatal(CRIT_FIRST + 36, "List capacity can't be smaller than count");
     44         list = memrealloc(list, newcap * itemsize);
     45         capacity = newcap;
     46     }
     47 }
     48 
     49 
     50 void _podlist::grow()
     51 {
     52     if (capacity > count)
     53         return;
     54     set_capacity(capacity == 0 ? 4 : ((capacity + 1) / 2) * 3);
     55 }
     56 
     57 
     58 void _podlist::set_count(int newcount, bool zero)
     59 {
     60     if (newcount > count)
     61     {
     62         if (newcount > capacity)
     63             set_capacity(newcount);
     64         if (zero)
     65             memset(doget(count), 0, (newcount - count) * itemsize);
     66         count = newcount;
     67     }
     68     else if (newcount < count)
     69     {
     70         if (newcount < 0)
     71             // wrong newcount: we don't want to generate an error here.
     72             // instead, we'll set count to 0 and wait until some other 
     73             // operation raises an error
     74             newcount = 0;
     75         count = newcount;
     76         if (count == 0)
     77             set_capacity(0);
     78     }
     79 }
     80 
     81 
     82 // doXXX() methods do not perform bounds checking; used internally
     83 // where index is guaranteed to be valid
     84 
     85 void* _podlist::doins(int index)
     86 {
     87     grow();
     88     pchar s = pchar(doget(index));
     89     if (index < count)
     90         memmove(s + itemsize, s, (count - index) * itemsize);
     91     count++;
     92     return s;
     93 }
     94 
     95 
     96 void _podlist::doins(int index, const _podlist& t)
     97 {
     98     if (&t == this)
     99         return;
    100     if (index == count)
    101         add(t);
    102     else
    103     {
    104         if (itemsize != t.itemsize)
    105             fatal(CRIT_FIRST + 35, "Incompatible list");
    106         if (t.count == 0)
    107             return;
    108         int ocnt = count;
    109         set_count(ocnt + t.count);
    110         pchar s = pchar(doget(index));
    111         memmove(s + t.count * itemsize, s, (ocnt - index) * itemsize);
    112         memcpy(s, t.list, t.count * itemsize);
    113     }
    114 }
    115 
    116 
    117 void* _podlist::add()
    118 {
    119     grow();
    120     return doget(count++);
    121 }
    122 
    123 
    124 void _podlist::add(const _podlist& t)
    125 {
    126     if (count == 0)
    127         operator =(t);
    128     else
    129     {
    130         if (itemsize != t.itemsize)
    131             fatal(CRIT_FIRST + 35, "Incompatible list");
    132         int ocnt = count;
    133         int tcnt = t.count;
    134         set_count(ocnt + tcnt);
    135         memcpy(doget(ocnt), t.list, tcnt * itemsize);
    136     }
    137 }
    138 
    139 
    140 _podlist& _podlist::operator =(const _podlist& t)
    141 {
    142     if (&t != this)
    143     {
    144         if (itemsize != t.itemsize)
    145             fatal(CRIT_FIRST + 35, "Incompatible list");
    146         set_count(t.count);
    147         pack();
    148         memcpy(list, t.list, count * itemsize);
    149     }
    150     return *this;
    151 }
    152 
    153 
    154 void _podlist::dodel(int index)
    155 {
    156     count--;
    157     if (index < count)
    158     {
    159         pchar s = pchar(doget(index));
    160         memmove(s, s + itemsize, (count - index) * itemsize);
    161     }
    162     else if (count == 0)
    163         set_capacity(0);
    164 }
    165 
    166 
    167 void _podlist::dodel(int index, int delcount)
    168 {
    169     if (delcount <= 0)
    170         return;
    171     if (index + delcount > count)
    172         delcount = count - index;
    173     count -= delcount;
    174     if (index < count)
    175     {
    176         pchar s = pchar(doget(index));
    177         memmove(s, s + delcount * itemsize, (count - index) * itemsize);
    178     }
    179     else if (count == 0)
    180         set_capacity(0);
    181 }
    182 
    183 
    184 void _podlist::dopop()
    185 {
    186     if (--count == 0)
    187         set_capacity(0);
    188 }
    189 
    190 
    191 }
    192