7 #include <QExplicitlySharedDataPointer>
46 void inc(
unsigned int& i)
51 void dec(
unsigned int& i)
58 return buff_ + ((head_ + i) & mask_);
64 if (nmax < 1) nmax = 1;
69 if (buff_)
delete [] buff_;
77 while (cap_ < nmax) cap_ <<= 1;
79 if (buff_)
delete [] buff_;
93 push(v);
return (*
this);
122 template<
class T,
int N>
123 class running_average
128 explicit running_average(
const T& v = 0)
132 while (p!=pend) *p++ = v;
135 running_average& operator<<(
const T& v)
138 if (p==pend) p = &data[0];
144 for(
int i = 0; i<N; ++i) m += data[i];
149 for(
int i=0; i<N; ++i) data[i]=0;
156 class buffer :
public QSharedData
159 typedef QVector<T> container_t;
162 typedef buffer<T> _Self;
183 if (circular_ && sz && sz!=tail)
185 T* head = mem.data();
187 int ntemp = mem.size() - cp;
192 memcpy(temp,head,tail*
sizeof(T));
193 memmove(head,head+tail,m*
sizeof(T));
194 memcpy(head + m,temp,tail*
sizeof(T));
198 memcpy(temp,head+tail,m*
sizeof(T));
199 memmove(head+m,head,tail*
sizeof(T));
200 memcpy(head,temp,m*
sizeof(T));
203 }
else if (tail > sz) {
204 memmove(head, head + tail - sz, sz*
sizeof(T));
206 }
else if (tail == 0) {
207 memmove(head, head + cp - sz, sz*
sizeof(T));
211 int nback = sz - tail;
212 if (nfront <= ntemp) {
213 memcpy(temp,head,nfront*
sizeof(T));
214 memmove(head,head + (cp - nback),nback*
sizeof(T));
215 memcpy(head + nback,temp,nfront*
sizeof(T));
217 memcpy(temp, head + (cp - nback),nback*
sizeof(T));
218 memmove(head+nback,head,nfront*
sizeof(T));
219 memcpy(head,temp,nback*
sizeof(T));
227 int idx_(
int i)
const
229 return circular_ ? (tail - sz + i + cp) % cp : i;
232 void set_(
int i,
const T& v)
243 for(
int i=1; i<n; ++i)
251 recalcBounds =
false;
255 explicit buffer(
int acap = 0) : mem((int)acap),
256 sz(0), cp(acap), circular_(false), tail(0),
257 x1(0), x2(0), recalcBounds(true)
260 buffer(
const _Self& rhs) : QSharedData(rhs), mem(rhs.mem),
261 sz(rhs.sz), cp(rhs.cp), circular_(rhs.circular_), tail(rhs.tail),
262 x1(rhs.x1), x2(rhs.x2), recalcBounds(rhs.recalcBounds)
269 _Self& operator=(
const _Self& rhs)
274 circular_ = rhs.circular_;
278 recalcBounds = rhs.recalcBounds;
282 bool operator == (
const _Self& rhs)
const
284 if (sz != rhs.sz)
return false;
286 if (mem.constData() == rhs.mem.constData())
return true;
288 for(
int i=0; i<size(); i++)
289 if ((*
this)[i]!=rhs[i])
return false;
293 bool operator != (
const _Self& rhs)
const
295 return !((*this)==rhs);
298 int size()
const {
return (
int)sz; }
300 bool isCircular()
const {
return circular_; }
301 void setCircular(
bool on)
303 if (on==circular_)
return;
305 mem.resize(on ? cp + cp/2 : cp);
309 int capacity()
const {
return (
int)cp; }
311 void setCapacity(
int c)
321 if (sz==cp) tail = sz;
341 if (n>cp) setCapacity(n);
343 if (n>sz) ::memset(mem.data()+sz,0,n*
sizeof(T));
360 const T& operator[](
int i)
const
364 const T&
get(
int i)
const
368 void push(
const T& v)
375 if (sz==cp) mem.resize(++cp);
380 void push(
const T* v,
int n)
386 memcpy(mem.data(),v+n-cp,cp*
sizeof(T));
390 else if (n<=cp-tail) {
391 memcpy(mem.data()+tail,v,n*
sizeof(T));
394 if (sz==cp) tail %= cp;
397 memcpy(mem.data()+tail,v,m*
sizeof(T));
399 memcpy(mem.data(),v,n*
sizeof(T));
404 if (sz+n>cp) { cp = sz+n; mem.resize(cp); }
405 memcpy(mem.data()+sz,v,n*
sizeof(T));
414 if (circular_) tail = (tail - 1) % sz;
417 const T* constData()
const
419 const_cast< _Self *
>( this )->normalize_();
420 return mem.constData();
427 container_t vector()
const
429 const_cast< _Self *
>( this )->normalize_();
430 return mem.mid(0,sz);
435 const_cast< _Self *
>( this )->calcBounds_();
441 const_cast< _Self *
>( this )->calcBounds_();
448 for(
int i=0; i<n; ++i) s +=
get(i);
453 double s1(0.0), s2(0.0);
455 for(
int i=0; i<n; ++i) {
462 if (s1<=0.0)
return 0.0;
463 else return sqrt(s1);
circular_buffer(unsigned int nmax=1)
Construct a circular_buffer with capacity nmax.
unsigned int capacity() const
return the buffer's capacity
void push(const T &v)
insert an element.
const T & last() const
const ref to last element inserted
const T & operator[](int i) const
const ref to the i-th element
T & operator[](int i)
ref to the i-th element
A circular LIFO buffer class.
void pop()
remove the last inserted element
self_t & operator<<(const T &v)
insertion operator is the same as push()
void alloc(unsigned int nmax)
allocate memory for nmax elements (nmax is adjusted to 2^N).