//========================================================================== // CIRCULARBUFFER.H - part of // // OMNeT++/OMNEST // Discrete System Simulation in C++ // //========================================================================== /*--------------------------------------------------------------* Copyright (C) 1992-2017 Andras Varga Copyright (C) 2006-2017 OpenSim Ltd. This file is distributed WITHOUT ANY WARRANTY. See the file `license' for details on this and other legal matters. *--------------------------------------------------------------*/ #ifndef __OMNETPP_TKENV_CIRCULARBUFFER_H #define __OMNETPP_TKENV_CIRCULARBUFFER_H #include "tkdefs.h" #include "omnetpp/simkerneldefs.h" // for ASSERT namespace omnetpp { namespace tkenv { /** * A limited STL-like circular buffer implementation. */ template class circular_buffer { private: T *cb; // size of the circular buffer int cbsize; // always power of 2 int cbhead, cbtail; // cbhead is inclusive, cbtail is exclusive private: void grow() { ASSERT(cbhead == cbtail); // here it means full, not empty int newsize = 2*cbsize; T *newcb = new T[newsize]; memcpy(newcb, cb + cbhead, (cbsize - cbhead)*sizeof(T)); memcpy(newcb + (cbsize - cbhead), cb, cbtail*sizeof(T)); delete[] cb; cb = newcb; cbhead = 0; cbtail = cbsize; cbsize = newsize; } // unimplemented: circular_buffer(const circular_buffer&); void operator=(const circular_buffer&); public: circular_buffer(int capacity=32) : cb(new T[capacity]), cbsize(capacity), cbhead(0), cbtail(0) { } ~circular_buffer() { delete[] cb; } void push_back(T d) { cb[cbtail] = d; cbtail = (cbtail + 1) & (cbsize-1); if (cbtail == cbhead) grow(); } void pop_front() { ASSERT(cbhead != cbtail); cbhead = (cbhead + 1) & (cbsize-1); } T front() const { ASSERT(cbhead != cbtail); return cb[cbhead]; } T back() const { ASSERT(cbhead != cbtail); return cb[(cbtail - 1) & (cbsize-1)]; } T operator[](int i) const { ASSERT(cbhead != cbtail); return cb[(cbhead + i) & (cbsize-1)]; } int size() const { return (cbtail - cbhead) & (cbsize-1); } bool empty() const { return cbhead == cbtail; } void clear() { cbhead = cbtail = 0; } }; } // namespace tkenv } // namespace omnetpp #endif