Allolib  1.0
C++ Components For Interactive Multimedia
al_Buffer.hpp
1 #ifndef INCLUDE_AL_BUFFER_HPP
2 #define INCLUDE_AL_BUFFER_HPP
3 
4 /* Allocore --
5  Multimedia / virtual environment application class library
6 
7  Copyright (C) 2009. AlloSphere Research Group, Media Arts & Technology, UCSB.
8  Copyright (C) 2012. The Regents of the University of California.
9  All rights reserved.
10 
11  Redistribution and use in source and binary forms, with or without
12  modification, are permitted provided that the following conditions are met:
13 
14  Redistributions of source code must retain the above copyright notice,
15  this list of conditions and the following disclaimer.
16 
17  Redistributions in binary form must reproduce the above copyright
18  notice, this list of conditions and the following disclaimer in the
19  documentation and/or other materials provided with the distribution.
20 
21  Neither the name of the University of California nor the names of its
22  contributors may be used to endorse or promote products derived from
23  this software without specific prior written permission.
24 
25  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  POSSIBILITY OF SUCH DAMAGE.
36 
37 
38  File description:
39  Variably sized one-dimensional array
40 
41  File author(s):
42  Lance Putnam, 2010, putnam.lance@gmail.com
43  Keehong Youn, 2017, younkeehong@gmail.com
44 
45 */
46 
47 #include <algorithm>
48 #include <vector>
49 
50 namespace al {
51 
52 #if 0
53 
55 
61 template <class T, class Alloc=std::allocator<T> >
62 class Buffer : protected Alloc{
63  typedef Alloc super;
64 public:
65 
67  explicit Buffer(int size=0)
68  : mElems(size), mSize(size)
69  {}
70 
73  Buffer(int size, int capacity)
74  : mElems(capacity), mSize(size)
75  {}
76 
77  ~Buffer(){}
78 
79 
80  int capacity() const { return mElems.size(); }
81  int size() const { return mSize; }
82  const T * elems() const { return &mElems[0]; }
83  T * elems(){ return &mElems[0]; }
84 
85 
87  T& operator[](int i){ return mElems[i]; }
88 
90  const T& operator[](int i) const { return mElems[i]; }
91 
93 
97  void assign(int n, const T& v){ mElems.assign(n,v); }
98 
100  T& last(){ return mElems[size()-1]; }
101  const T& last() const { return mElems[size()-1]; }
102 
104  void reset(){ mSize=0; }
105 
107 
112  void resize(int n){
113  mElems.resize(n);
114  setSize(n);
115  }
116 
118 
121  void size(int n){
122  if(capacity() < n) resize(n);
123  else setSize(n);
124  }
125 
127  void append(const T& v, double growFactor=2){
128 
129  // Grow array if too small
130  if(size() >= capacity()){
131  // Copy argument since it may be an element in current memory range
132  // which may become invalid after the resize.
133  const T vsafecopy = v;
134  mElems.resize((size() ? size() : 4)*growFactor);
135  super::construct(elems()+size(), vsafecopy);
136  }
137  else{
138  super::construct(elems()+size(), v);
139  }
140  ++mSize;
141  }
143  void push_back(const T& v, double growFactor=2) { append(v, growFactor); }
144 
146 
149  void append(const Buffer<T>& src){
150  append(src.elems(), src.size());
151  }
152 
154  void append(const T * src, int len){
155  int oldsize = size();
156  size(size() + len);
157  std::copy(src, src + len, mElems.begin() + oldsize);
158  }
159 
161  void repeatLast(){ append(last()); }
162 
163 
165 
169  template <int n, bool dup>
170  void expand(){
171  size(size()*n);
172  const int Nd = dup ? n : 1;
173  for(int i=size()/n-1; i>=0; --i){
174  const T& v = (*this)[i];
175  for(int j=0; j<Nd; ++j) Alloc::construct(elems()+n*i+j, v);
176  }
177  }
178 
179 private:
180  std::vector<T, Alloc> mElems;
181  int mSize; // logical size array
182 
183  void setSize(int n){ mSize=n; }
184 };
185 
186 #endif
187 
189 
194 template <class T, class Alloc = std::allocator<T> >
195 class RingBuffer : protected Alloc {
196  public:
198  RingBuffer() : mPos(-1), mFill(0) {}
199 
202  explicit RingBuffer(unsigned size, const T& v = T()) : mPos(size), mFill(0) {
203  resize(size, v);
204  }
205 
207  size_t size() const { return mElems.size(); }
208 
210  int pos() const { return mPos; }
211 
213  int fill() const { return mFill; }
214 
216  T& operator[](int i) { return mElems[i]; }
217 
219  const T& operator[](int i) const { return mElems[i]; }
220 
222 
228  T& next() {
229  if (mFill < size()) ++mFill;
230  ++mPos;
231  if (pos() == size()) {
232  mPos = 0;
233  }
234  return mElems[pos()];
235  }
236 
238  void write(const T& v) { Alloc::construct(&next(), v); }
239 
241  T& read(int i) { return mElems[wrapOnce(pos() - i, size())]; }
242 
244  const T& read(int i) const { return readFrom(pos(), i); }
245 
247 
251  const T& readFrom(int from, int dist) const {
252  return mElems[wrapOnce(from - dist, size())];
253  }
254 
256  T& newest() { return mElems[pos()]; }
257 
259  const T& newest() const { return mElems[pos()]; }
260 
262  void reset() {
263  mPos = size() - 1;
264  mFill = 0;
265  }
266 
268 
271  void resize(int n, const T& v = T()) {
272  mElems.resize(n, v);
273  if (mPos >= n) mPos = n - 1;
274  }
275 
276  protected:
277  std::vector<T, Alloc> mElems;
278  int mPos;
279  int mFill;
280 
281  // Moves value one period closer to interval [0, max)
282  static int wrapOnce(int v, int max) {
283  if (v < 0) return v + max;
284  if (v >= max) return v - max;
285  return v;
286  }
287 };
288 
290 
297 template <int N, class T>
298 class ShiftBuffer {
299  public:
301  ShiftBuffer(const T& v = T()) { assign(v); }
302 
304  static int size() { return N; }
305 
307  const T* elems() const { return &mElems[0]; }
308 
310  T* elems() { return &mElems[0]; }
311 
313  T& operator[](int i) { return mElems[i]; }
314 
316  const T& operator[](int i) const { return mElems[i]; }
317 
319  void operator()(const T& v) {
320  for (int i = N - 1; i > 0; --i) mElems[i] = mElems[i - 1];
321  mElems[0] = v;
322  }
323 
325  void assign(const T& v) {
326  for (int i = 0; i < N; ++i) mElems[i] = v;
327  }
328 
330  void zero() { memset(mElems, 0, N * sizeof(T)); }
331 
332  protected:
333  T mElems[N];
334 };
335 
336 } // namespace al
337 
338 #endif
Ring buffer.
Definition: al_Buffer.hpp:195
void reset()
Set write position to start of array and zero fill amount.
Definition: al_Buffer.hpp:262
const T & readFrom(int from, int dist) const
Get reference to older element relative to some newer element (read-only)
Definition: al_Buffer.hpp:251
void write(const T &v)
Write new element.
Definition: al_Buffer.hpp:238
T & read(int i)
Get reference to element relative to newest element.
Definition: al_Buffer.hpp:241
int pos() const
Get absolute index of most recently written element.
Definition: al_Buffer.hpp:210
T & next()
Obtain next element in buffer.
Definition: al_Buffer.hpp:228
int fill() const
Get fill amount of buffer.
Definition: al_Buffer.hpp:213
const T & operator[](int i) const
Get element at absolute index (read-only)
Definition: al_Buffer.hpp:219
size_t size() const
Get number of elements.
Definition: al_Buffer.hpp:207
const T & read(int i) const
Get reference to element relative to newest element (read-only)
Definition: al_Buffer.hpp:244
const T & newest() const
Definition: al_Buffer.hpp:259
T & operator[](int i)
Get element at absolute index.
Definition: al_Buffer.hpp:216
RingBuffer(unsigned size, const T &v=T())
Definition: al_Buffer.hpp:202
void resize(int n, const T &v=T())
Resize buffer.
Definition: al_Buffer.hpp:271
RingBuffer()
Default constructor; does not allocate memory.
Definition: al_Buffer.hpp:198
Constant size shift buffer.
Definition: al_Buffer.hpp:298
const T & operator[](int i) const
Get reference to element at index (read-only)
Definition: al_Buffer.hpp:316
const T * elems() const
Get pointer to elements (read-only)
Definition: al_Buffer.hpp:307
void assign(const T &v)
Set all elements to argument.
Definition: al_Buffer.hpp:325
static int size()
Get number of elements.
Definition: al_Buffer.hpp:304
void operator()(const T &v)
Push new element onto buffer. Newest element is at index 0.
Definition: al_Buffer.hpp:319
T * elems()
Get pointer to elements.
Definition: al_Buffer.hpp:310
void zero()
Zero bytes of all elements.
Definition: al_Buffer.hpp:330
ShiftBuffer(const T &v=T())
Definition: al_Buffer.hpp:301
T & operator[](int i)
Get reference to element at index.
Definition: al_Buffer.hpp:313
T max(const T &v1, const T &v2, const T &v3)
Definition: al_App.hpp:23
T dist(const Vec< N, T > &a, const Vec< N, U > &b)
Returns distance between two vectors.
Definition: al_Vec.hpp:676