123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- #ifndef _ZLIST_HPP_
- #define _ZLIST_HPP_
- #include <assert.h>
- #include <array>
- template<typename T,int SIZE>
- struct zlist
- {
- std::array<T,SIZE>*buf;
- uint32_t bpos;
- uint32_t epos;
- uint32_t len;
- zlist()
- :buf(nullptr)
- ,bpos(0)
- ,epos(0)
- ,len(1)
- {
- buf=new std::array<T,SIZE>();
- len = 1;
- while(len < SIZE)
- len <<= 1;
- }
- ~zlist()
- {
- delete buf;
- }
- void clear()
- {
- bpos=epos;
- }
- int index(uint32_t p)const
- {
- int l = p&(len-1);
- return l - len + SIZE;
- //return p&(SIZE-1);
- }
- void push(const T&o)
- {
- if(size()>=SIZE) skip(1);
- buf->at(index(epos++))=o;
- }
- void rpush(const T&o)
- {
- if(size()>=SIZE) rskip(1);
- buf->at(index(--bpos))=o;
- }
- T& grow()
- {
- if(size()>=SIZE) skip(1);
- ++epos;
- return rat(0);
- }
- T& rgrow()
- {
- if(size()>=SIZE) rskip(1);
- --bpos;
- return at(0);
- }
- template<typename Pred>
- int find_if(const Pred&p)const
- {
- for(int i=0,len=size();i<len;i++)
- {
- if(p((*this)[i]))
- return i;
- }
- return -1;
- }
- template<typename Pred>
- int find_last_if(const Pred&p)const
- {
- for(int i=0,len=size();i<len;i++)
- {
- if(p((*this)(i)))
- {
- return len-i-1;
- }
- }
- return -1;
- }
- template<typename Pred>
- void skip_if(const Pred&p)
- {
- while(!empty())
- {
- if(!p(at(0)))
- break;
- skip(1);
- }
- }
- template<typename Pred>
- void for_each(const Pred&p)
- {
- for(unsigned i=bpos;i<epos;i++)
- p(buf->at(index(i)));
- }
- void skip(int count)
- {
- assert(count<=(int)size());
- bpos+=count;
- }
- void rskip(int count)
- {
- assert(count<=(int)size());
- epos-=count;
- }
- bool empty()const
- {
- return epos==bpos;
- }
- int size()const
- {
- return epos-bpos;
- }
- T&at(int i)
- {
- assert(i<(int)size());
- return buf->at(index(bpos+i));
- }
- const T&at(int i) const
- {
- assert(i<(int)size());
- return buf->at(index(bpos+i));
- }
- T&rat(int i)
- {
- assert(i<(int)size());
- return buf->at(index(epos-i-1));
- }
- const T&rat(int i) const
- {
- assert(i<(int)size());
- return buf->at(index(epos-i-1));
- }
- T&operator[](int i)
- {
- return at(i);
- }
- const T&operator[](int i) const
- {
- return at(i);
- }
- T&operator()(int i)
- {
- return rat(i);
- }
- const T&operator()(int i) const
- {
- return rat(i);
- }
- };
- #endif
|