1#ifndef APE_ROLLBUFFER_H
2#define APE_ROLLBUFFER_H
3
4template <class TYPE> class CRollBuffer
5{
6public:
7
8    CRollBuffer()
9    {
10        m_pData = NULL;
11        m_pCurrent = NULL;
12    }
13
14    ~CRollBuffer()
15    {
16        SAFE_ARRAY_DELETE(m_pData);
17    }
18
19    int Create(int nWindowElements, int nHistoryElements)
20    {
21        SAFE_ARRAY_DELETE(m_pData)
22        m_nWindowElements = nWindowElements;
23        m_nHistoryElements = nHistoryElements;
24
25        m_pData = new TYPE[m_nWindowElements + m_nHistoryElements];
26        if (m_pData == NULL)
27            return ERROR_INSUFFICIENT_MEMORY;
28
29        Flush();
30        return 0;
31    }
32
33    void Flush()
34    {
35        ZeroMemory(m_pData, (m_nHistoryElements + 1) * sizeof(TYPE));
36        m_pCurrent = &m_pData[m_nHistoryElements];
37    }
38
39    void Roll()
40    {
41        memcpy(&m_pData[0], &m_pCurrent[-m_nHistoryElements], m_nHistoryElements * sizeof(TYPE));
42        m_pCurrent = &m_pData[m_nHistoryElements];
43    }
44
45    __inline void IncrementSafe()
46    {
47        m_pCurrent++;
48        if (m_pCurrent == &m_pData[m_nWindowElements + m_nHistoryElements])
49            Roll();
50    }
51
52    __inline void IncrementFast()
53    {
54        m_pCurrent++;
55    }
56
57    __inline TYPE & operator[](const int nIndex) const
58    {
59        return m_pCurrent[nIndex];
60    }
61
62protected:
63
64    TYPE * m_pData;
65    TYPE * m_pCurrent;
66    int m_nHistoryElements;
67    int m_nWindowElements;
68};
69
70template <class TYPE, int WINDOW_ELEMENTS, int HISTORY_ELEMENTS> class CRollBufferFast
71{
72public:
73
74    CRollBufferFast()
75    {
76        m_pData = new TYPE[WINDOW_ELEMENTS + HISTORY_ELEMENTS];
77        Flush();
78    }
79
80    ~CRollBufferFast()
81    {
82        SAFE_ARRAY_DELETE(m_pData);
83    }
84
85    void Flush()
86    {
87        ZeroMemory(m_pData, (HISTORY_ELEMENTS + 1) * sizeof(TYPE));
88        m_pCurrent = &m_pData[HISTORY_ELEMENTS];
89    }
90
91    void Roll()
92    {
93        memcpy(&m_pData[0], &m_pCurrent[-HISTORY_ELEMENTS], HISTORY_ELEMENTS * sizeof(TYPE));
94        m_pCurrent = &m_pData[HISTORY_ELEMENTS];
95    }
96
97    __inline void IncrementSafe()
98    {
99        m_pCurrent++;
100        if (m_pCurrent == &m_pData[WINDOW_ELEMENTS + HISTORY_ELEMENTS])
101            Roll();
102    }
103
104    __inline void IncrementFast()
105    {
106        m_pCurrent++;
107    }
108
109    __inline TYPE & operator[](const int nIndex) const
110    {
111        return m_pCurrent[nIndex];
112    }
113
114protected:
115
116    TYPE * m_pData;
117    TYPE * m_pCurrent;
118};
119
120#endif // #ifndef APE_ROLLBUFFER_H
121