summaryrefslogtreecommitdiff
path: root/src/ringbuffer.h
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2010-10-15 15:12:31 +0000
committerMike Buland <eichlan@xagasoft.com>2010-10-15 15:12:31 +0000
commit93c028162318a00b9bd03fc4a48383f830cc529d (patch)
tree26a2edd7b3e12922d046cfbc41a40fce819c56d9 /src/ringbuffer.h
parent867dae89929a11a421ec21af71d494ad0ecc1963 (diff)
downloadlibbu++-93c028162318a00b9bd03fc4a48383f830cc529d.tar.gz
libbu++-93c028162318a00b9bd03fc4a48383f830cc529d.tar.bz2
libbu++-93c028162318a00b9bd03fc4a48383f830cc529d.tar.xz
libbu++-93c028162318a00b9bd03fc4a48383f830cc529d.zip
RingBuffer is now SharedCore. I think that's all the container classes, there
may be a few other things that should change too, we'll see. Played with doxygen docs on List, we can actually use @cond to remove things from the docs, either permenently or conditionally, and so I could trick it into making all of the sharedcore classes inherit from the same SharedCore in the docs instead of different ones. Or, just not inherit from SharedCore at all. What to do...? :-P I also got rid of ListHash, it wasn't working out yet anyway.
Diffstat (limited to 'src/ringbuffer.h')
-rw-r--r--src/ringbuffer.h207
1 files changed, 163 insertions, 44 deletions
diff --git a/src/ringbuffer.h b/src/ringbuffer.h
index e984d18..04add42 100644
--- a/src/ringbuffer.h
+++ b/src/ringbuffer.h
@@ -10,97 +10,216 @@
10 10
11#include <memory> 11#include <memory>
12#include "bu/exceptionbase.h" 12#include "bu/exceptionbase.h"
13#include "bu/queue.h"
14#include "bu/sharedcore.h"
13 15
14namespace Bu 16namespace Bu
15{ 17{
16 /** 18 template<typename value, typename valuealloc> class RingBuffer;
17 *@ingroup Containers 19
18 */ 20 template<typename value, typename valuealloc>
19 template<typename value, typename valuealloc=std::allocator<value> > 21 class RingBufferCore
20 class RingBuffer
21 { 22 {
22 public: 23 friend class RingBuffer<value, valuealloc>;
23 RingBuffer( int nCapacity ) : 24 friend class SharedCore<RingBuffer<value, valuealloc>,
24 nCapacity( nCapacity ), 25 RingBufferCore<value, valuealloc> >;
25 nStart( -1 ), 26 private:
26 nEnd( -2 ) 27 RingBufferCore() :
28 iCapacity( 0 ),
29 iStart( -1 ),
30 iEnd( -2 ),
31 aData( NULL )
27 { 32 {
28 aData = va.allocate( nCapacity );
29 } 33 }
30 34
31 virtual ~RingBuffer() 35 virtual ~RingBufferCore()
32 { 36 {
33 for( int j = nStart; j < nEnd; j=(j+1%nCapacity) ) 37 clear();
34 {
35 va.destroy( &aData[j] );
36 }
37 va.deallocate( aData, nCapacity );
38 } 38 }
39 39
40 int getCapacity() 40 void init( int iNewCapacity )
41 { 41 {
42 return nCapacity; 42 if( iCapacity > 0 )
43 } 43 return;
44 44
45 bool isFilled() 45 iCapacity = iNewCapacity;
46 { 46 iStart = -1;
47 return (nStart == nEnd); 47 iEnd = -2;
48 aData = va.allocate( iCapacity );
48 } 49 }
49 50
50 bool isEmpty() 51 void clear()
51 { 52 {
52 return (nStart == -1); 53 for( int j = iStart; j < iEnd; j=(j+1%iCapacity) )
54 {
55 va.destroy( &aData[j] );
56 }
57 va.deallocate( aData, iCapacity );
58 aData = NULL;
59 iCapacity = 0;
53 } 60 }
54 61
55 void enqueue( const value &v ) 62 void enqueue( const value &v )
56 { 63 {
57 if( nStart == -1 ) 64 if( iStart == -1 )
58 { 65 {
59 nStart = 0; 66 iStart = 0;
60 nEnd = 1; 67 iEnd = 1;
61 va.construct( &aData[0], v ); 68 va.construct( &aData[0], v );
62 } 69 }
63 else if( nStart == nEnd ) 70 else if( iStart == iEnd )
64 { 71 {
65 throw ExceptionBase("Hey, it's full!"); 72 throw ExceptionBase("Hey, it's full!");
66 } 73 }
67 else 74 else
68 { 75 {
69 va.construct( &aData[nEnd], v ); 76 va.construct( &aData[iEnd], v );
70 nEnd = (nEnd+1)%nCapacity; 77 iEnd = (iEnd+1)%iCapacity;
71 } 78 }
72 } 79 }
73 80
74 value dequeue() 81 value dequeue()
75 { 82 {
76 if( nStart == -1 ) 83 if( iStart == -1 )
77 { 84 {
78 throw ExceptionBase("No data"); 85 throw ExceptionBase("No data");
79 } 86 }
80 else 87 else
81 { 88 {
82 value &v = aData[nStart]; 89 value &v = aData[iStart];
83 va.destroy( &aData[nStart] ); 90 va.destroy( &aData[iStart] );
84 nStart = (nStart+1)%nCapacity; 91 iStart = (iStart+1)%iCapacity;
85 if( nStart == nEnd ) 92 if( iStart == iEnd )
86 { 93 {
87 nStart = -1; 94 iStart = -1;
88 nEnd = -2; 95 iEnd = -2;
89 } 96 }
90 return v; 97 return v;
91 } 98 }
92 } 99 }
93 100
94 value &operator[]( int nIndex ) 101 value &get( int iIndex )
95 { 102 {
96 return aData[(nIndex+nStart)%nCapacity]; 103 return aData[(iIndex+iStart)%iCapacity];
97 } 104 }
98 105
99 private: 106 int getSize()
100 int nCapacity; 107 {
108 if( iStart < 0 )
109 return 0;
110 if( iEnd == iStart )
111 return iCapacity;
112 if( iEnd < iStart )
113 return iEnd-iStart;
114 return iCapacity-(iEnd-iStart);
115 }
116
117 int iCapacity;
118 int iStart, iEnd;
101 value *aData; 119 value *aData;
102 valuealloc va; 120 valuealloc va;
103 int nStart, nEnd; 121 };
122
123 /**
124 *@ingroup Containers
125 */
126 template<typename value, typename valuealloc=std::allocator<value> >
127 class RingBuffer : public Queue<value>, public SharedCore<
128 RingBuffer<value, valuealloc>,
129 RingBufferCore<value, valuealloc>
130 >
131 {
132 private:
133 typedef RingBuffer<value, valuealloc> MyType;
134 typedef RingBufferCore<value, valuealloc> Core;
135
136 protected:
137 using SharedCore<MyType, Core>::core;
138 using SharedCore<MyType, Core>::_hardCopy;
139 using SharedCore<MyType, Core>::_allocateCore;
140
141 public:
142 RingBuffer( int iCapacity )
143 {
144 core->init( iCapacity );
145 }
146
147 RingBuffer( const RingBuffer &rSrc ) :
148 SharedCore<MyType, Core>( rSrc )
149 {
150 }
151
152 virtual ~RingBuffer()
153 {
154 }
155
156 int getCapacity() const
157 {
158 return core->iCapacity;
159 }
160
161 bool isFilled() const
162 {
163 return (core->iStart == core->iEnd);
164 }
165
166 bool isEmpty() const
167 {
168 return (core->iStart == -1);
169 }
170
171 virtual void enqueue( const value &v )
172 {
173 _hardCopy();
174
175 core->enqueue( v );
176 }
177
178 virtual value dequeue()
179 {
180 _hardCopy();
181
182 return core->dequeue();
183 }
184
185 virtual int getSize() const
186 {
187 return core->getSize();
188 }
189
190 virtual value &peek()
191 {
192 _hardCopy();
193
194 return core->get( 0 );
195 }
196
197 virtual const value &peek() const
198 {
199 return core->get( 0 );
200 }
201
202 value &operator[]( int iIndex )
203 {
204 _hardCopy();
205
206 return core->get( iIndex );
207 }
208
209 protected:
210 virtual Core *_copyCore( Core *src )
211 {
212 Core *pRet = _allocateCore();
213
214 pRet->init( src->iCapacity );
215 int iSize = src->getSize();
216 for( int j = 0; j < iSize; j++ )
217 {
218 pRet->enqueue( src->get( j ) );
219 }
220
221 return pRet;
222 }
104 }; 223 };
105} 224}
106 225