LiquidFun
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
b2GrowableBuffer.h
1 /*
2 * Copyright (c) 2014 Google, Inc.
3 *
4 * This software is provided 'as-is', without any express or implied
5 * warranty. In no event will the authors be held liable for any damages
6 * arising from the use of this software.
7 * Permission is granted to anyone to use this software for any purpose,
8 * including commercial applications, and to alter it and redistribute it
9 * freely, subject to the following restrictions:
10 * 1. The origin of this software must not be misrepresented; you must not
11 * claim that you wrote the original software. If you use this software
12 * in a product, an acknowledgment in the product documentation would be
13 * appreciated but is not required.
14 * 2. Altered source versions must be plainly marked as such, and must not be
15 * misrepresented as being the original software.
16 * 3. This notice may not be removed or altered from any source distribution.
17 */
18 #ifndef B2_GROWABLE_BUFFER_H
19 #define B2_GROWABLE_BUFFER_H
20 
21 #include <Box2D/Common/b2BlockAllocator.h>
22 #include <string.h>
23 #include <memory.h>
24 #include <algorithm>
25 
26 
29 template <typename T>
31 {
32 public:
34  data(NULL),
35  count(0),
36  capacity(0),
37  allocator(&allocator)
38  {
39  #if defined(LIQUIDFUN_SIMD_NEON)
40  // b2ParticleAssemply.neon.s assumes these values are at fixed offsets.
41  // If this assert fails, be sure to update the assembly offsets!
42  // ldr r3, [r9, #0] @ r3 = out = contacts.data
43  // ldr r6, [r9, #8] @ r6 = contacts.capacity
44  b2Assert((intptr_t)&data - (intptr_t)(this) == 0
45  && (intptr_t)&capacity - (intptr_t)(this) == 8);
46  #endif // defined(LIQUIDFUN_SIMD_NEON)
47  }
48 
50  data(NULL),
51  count(rhs.count),
52  capacity(rhs.capacity),
53  allocator(rhs.allocator)
54  {
55  if (rhs.data != NULL)
56  {
57  data = (T*) allocator->Allocate(sizeof(T) * capacity);
58  memcpy(data, rhs.data, sizeof(T) * count);
59  }
60  }
61 
63  {
64  Free();
65  }
66 
67  T& Append()
68  {
69  if (count >= capacity)
70  {
71  Grow();
72  }
73  return data[count++];
74  }
75 
76  void Reserve(int32 newCapacity)
77  {
78  if (capacity >= newCapacity)
79  return;
80 
81  // Reallocate and copy.
82  T* newData = (T*) allocator->Allocate(sizeof(T) * newCapacity);
83  if (data)
84  {
85  memcpy(newData, data, sizeof(T) * count);
86  allocator->Free(data, sizeof(T) * capacity);
87  }
88 
89  // Update pointer and capacity.
90  capacity = newCapacity;
91  data = newData;
92  }
93 
94  void Grow()
95  {
96  // Double the capacity.
97  int32 newCapacity = capacity ? 2 * capacity
99  b2Assert(newCapacity > capacity);
100  Reserve(newCapacity);
101  }
102 
103  void Free()
104  {
105  if (data == NULL)
106  return;
107 
108  allocator->Free(data, sizeof(data[0]) * capacity);
109  data = NULL;
110  capacity = 0;
111  count = 0;
112  }
113 
114  void Shorten(const T* newEnd)
115  {
116  b2Assert(newEnd >= data);
117  count = (int32) (newEnd - data);
118  }
119 
120  T& operator[](int i)
121  {
122  return data[i];
123  }
124 
125  const T& operator[](int i) const
126  {
127  return data[i];
128  }
129 
130  T* Data()
131  {
132  return data;
133  }
134 
135  const T* Data() const
136  {
137  return data;
138  }
139 
140  T* Begin()
141  {
142  return data;
143  }
144 
145  const T* Begin() const
146  {
147  return data;
148  }
149 
150  T* End()
151  {
152  return &data[count];
153  }
154 
155  const T* End() const
156  {
157  return &data[count];
158  }
159 
160  int32 GetCount() const
161  {
162  return count;
163  }
164 
165  void SetCount(int32 newCount)
166  {
167  b2Assert(0 <= newCount && newCount <= capacity);
168  count = newCount;
169  }
170 
171  int32 GetCapacity() const
172  {
173  return capacity;
174  }
175 
176  template<class UnaryPredicate>
177  T* RemoveIf(UnaryPredicate pred)
178  {
179  T* newEnd = std::remove_if(data, data + count, pred);
180  Shorten(newEnd);
181  return newEnd;
182  }
183 
184  template<class BinaryPredicate>
185  T* Unique(BinaryPredicate pred)
186  {
187  T* newEnd = std::unique(data, data + count, pred);
188  Shorten(newEnd);
189  return newEnd;
190  }
191 
192 private:
193  T* data;
194  int32 count;
195  int32 capacity;
196  b2BlockAllocator* allocator;
197 };
198 
199 #endif // B2_GROWABLE_BUFFER_H
200 
void Free(void *p, int32 size)
Free memory. This uses b2Free if the size is larger than b2_maxBlockSize.
Definition: b2BlockAllocator.cpp:163
Definition: b2GrowableBuffer.h:30
Definition: b2BlockAllocator.h:36
#define b2_minParticleSystemBufferCapacity
The initial size of particle data buffers.
Definition: b2Settings.h:194
void * Allocate(int32 size)
Allocate memory. This uses b2Alloc if the size is larger than b2_maxBlockSize.
Definition: b2BlockAllocator.cpp:105