zlist.h 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #ifndef _ZLIST_HPP_
  2. #define _ZLIST_HPP_
  3. #include <assert.h>
  4. #include <array>
  5. template<typename T,int SIZE>
  6. struct zlist
  7. {
  8. std::array<T,SIZE>*buf;
  9. uint32_t bpos;
  10. uint32_t epos;
  11. uint32_t len;
  12. zlist()
  13. :buf(nullptr)
  14. ,bpos(0)
  15. ,epos(0)
  16. ,len(1)
  17. {
  18. buf=new std::array<T,SIZE>();
  19. len = 1;
  20. while(len < SIZE)
  21. len <<= 1;
  22. }
  23. ~zlist()
  24. {
  25. delete buf;
  26. }
  27. void clear()
  28. {
  29. bpos=epos;
  30. }
  31. int index(uint32_t p)const
  32. {
  33. int l = p&(len-1);
  34. return l - len + SIZE;
  35. //return p&(SIZE-1);
  36. }
  37. void push(const T&o)
  38. {
  39. if(size()>=SIZE) skip(1);
  40. buf->at(index(epos++))=o;
  41. }
  42. void rpush(const T&o)
  43. {
  44. if(size()>=SIZE) rskip(1);
  45. buf->at(index(--bpos))=o;
  46. }
  47. T& grow()
  48. {
  49. if(size()>=SIZE) skip(1);
  50. ++epos;
  51. return rat(0);
  52. }
  53. T& rgrow()
  54. {
  55. if(size()>=SIZE) rskip(1);
  56. --bpos;
  57. return at(0);
  58. }
  59. template<typename Pred>
  60. int find_if(const Pred&p)const
  61. {
  62. for(int i=0,len=size();i<len;i++)
  63. {
  64. if(p((*this)[i]))
  65. return i;
  66. }
  67. return -1;
  68. }
  69. template<typename Pred>
  70. int find_last_if(const Pred&p)const
  71. {
  72. for(int i=0,len=size();i<len;i++)
  73. {
  74. if(p((*this)(i)))
  75. {
  76. return len-i-1;
  77. }
  78. }
  79. return -1;
  80. }
  81. template<typename Pred>
  82. void skip_if(const Pred&p)
  83. {
  84. while(!empty())
  85. {
  86. if(!p(at(0)))
  87. break;
  88. skip(1);
  89. }
  90. }
  91. template<typename Pred>
  92. void for_each(const Pred&p)
  93. {
  94. for(unsigned i=bpos;i<epos;i++)
  95. p(buf->at(index(i)));
  96. }
  97. void skip(int count)
  98. {
  99. assert(count<=(int)size());
  100. bpos+=count;
  101. }
  102. void rskip(int count)
  103. {
  104. assert(count<=(int)size());
  105. epos-=count;
  106. }
  107. bool empty()const
  108. {
  109. return epos==bpos;
  110. }
  111. int size()const
  112. {
  113. return epos-bpos;
  114. }
  115. T&at(int i)
  116. {
  117. assert(i<(int)size());
  118. return buf->at(index(bpos+i));
  119. }
  120. const T&at(int i) const
  121. {
  122. assert(i<(int)size());
  123. return buf->at(index(bpos+i));
  124. }
  125. T&rat(int i)
  126. {
  127. assert(i<(int)size());
  128. return buf->at(index(epos-i-1));
  129. }
  130. const T&rat(int i) const
  131. {
  132. assert(i<(int)size());
  133. return buf->at(index(epos-i-1));
  134. }
  135. T&operator[](int i)
  136. {
  137. return at(i);
  138. }
  139. const T&operator[](int i) const
  140. {
  141. return at(i);
  142. }
  143. T&operator()(int i)
  144. {
  145. return rat(i);
  146. }
  147. const T&operator()(int i) const
  148. {
  149. return rat(i);
  150. }
  151. };
  152. #endif