PolyVox  0.2.1
Open source voxel management library
Array.inl
Go to the documentation of this file.
1 /*******************************************************************************
2 Copyright (c) 2005-2009 David Williams
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 
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
11 
12 1. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would be
15 appreciated but is not required.
16 
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 
20 3. This notice may not be removed or altered from any source
21 distribution.
22 *******************************************************************************/
23 
24 namespace PolyVox
25 {
30  template <uint32_t noOfDims, typename ElementType>
32  :m_pDimensions(0)
33  ,m_pOffsets(0)
34  ,m_uNoOfElements(0)
35  ,m_pElements(0)
36  {
37  }
38 
45  template <uint32_t noOfDims, typename ElementType>
46  Array<noOfDims, ElementType>::Array(const uint32_t (&pDimensions)[noOfDims])
47  :m_pDimensions(0)
48  ,m_pOffsets(0)
49  ,m_uNoOfElements(0)
50  ,m_pElements(0)
51  {
52  resize(pDimensions);
53  }
54 
58  template <uint32_t noOfDims, typename ElementType>
60  {
61  deallocate();
62  }
63 
73  template <uint32_t noOfDims, typename ElementType>
74  SubArray<noOfDims-1, ElementType> Array<noOfDims, ElementType>::operator[](uint32_t uIndex)
75  {
76  assert(uIndex<m_pDimensions[0]);
77  return
78  SubArray<noOfDims-1, ElementType>(&m_pElements[uIndex*m_pOffsets[0]],
79  m_pDimensions+1, m_pOffsets+1);
80  }
81 
91  template <uint32_t noOfDims, typename ElementType>
92  const SubArray<noOfDims-1, ElementType> Array<noOfDims, ElementType>::operator[](uint32_t uIndex) const
93  {
94  assert(uIndex<m_pDimensions[0]);
95  return
96  SubArray<noOfDims-1, ElementType>(&m_pElements[uIndex*m_pOffsets[0]],
97  m_pDimensions+1, m_pOffsets+1);
98  }
99 
104  template <uint32_t noOfDims, typename ElementType>
106  {
107  return m_uNoOfElements;
108  }
109 
118  template <uint32_t noOfDims, typename ElementType>
120  {
121  return m_pElements;
122  }
123 
130  template <uint32_t noOfDims, typename ElementType>
131  void Array<noOfDims, ElementType>::resize(const uint32_t (&pDimensions)[noOfDims])
132  {
133  deallocate();
134 
135  m_pDimensions = new uint32_t[noOfDims];
136  m_pOffsets = new uint32_t[noOfDims];
137 
138  // Calculate all the information you need to use the array
139  m_uNoOfElements = 1;
140  for (uint32_t i = 0; i<noOfDims; i++)
141  {
142  assert(pDimensions[i] != 0);
143 
144  m_uNoOfElements *= pDimensions[i];
145  m_pDimensions[i] = pDimensions[i];
146  m_pOffsets[i] = 1;
147  for (uint32_t k=noOfDims-1; k>i; k--)
148  {
149  m_pOffsets[i] *= pDimensions[k];
150  }
151  }
152  // Allocate new elements, let exception propagate
153  m_pElements = new ElementType[m_uNoOfElements];
154  }
155 
162  template <uint32_t noOfDims, typename ElementType>
164  {
165  //Implement this function without temporary 'Array'
166  //objects, as the destructors will free the memory...
167  uint32_t* m_pTempDimensions = m_pDimensions;
168  uint32_t* m_pTempOffsets = m_pOffsets;
169  uint32_t m_uTempNoOfElements = m_uNoOfElements;
170  ElementType* m_pTempElements = m_pElements;
171 
172  m_pDimensions = rhs.m_pDimensions;
173  m_pOffsets = rhs.m_pOffsets;
174  m_uNoOfElements = rhs.m_uNoOfElements;
175  m_pElements = rhs.m_pElements;
176 
177  rhs.m_pDimensions = m_pTempDimensions;
178  rhs.m_pOffsets = m_pTempOffsets;
179  rhs.m_uNoOfElements = m_uTempNoOfElements;
180  rhs.m_pElements = m_pTempElements;
181  }
182 
186  template <uint32_t noOfDims, typename ElementType>
187  uint32_t Array<noOfDims, ElementType>::getDimension(uint32_t uDimension)
188  {
189  assert(uDimension < noOfDims);
190  return m_pDimensions[uDimension];
191  }
192 
193  template <uint32_t noOfDims, typename ElementType>
195  :m_pElements(0)
196  ,m_pDimensions(0)
197  ,m_pOffsets(0)
198  ,m_uNoOfElements(0)
199  {
200  //Not implemented
201  assert(false);
202  }
203 
204  template <uint32_t noOfDims, typename ElementType>
205  Array<noOfDims, ElementType>& Array<noOfDims, ElementType>::operator=(const Array<noOfDims, ElementType>& rhs)
206  {
207  //Not implemented
208  assert(false);
209 
210  return *this;
211  }
212 
213  template <uint32_t noOfDims, typename ElementType>
214  void Array<noOfDims, ElementType>::deallocate(void)
215  {
216  delete[] m_pDimensions;
217  m_pDimensions = 0;
218  delete[] m_pOffsets;
219  m_pOffsets = 0;
220  delete[] m_pElements;
221  m_pElements = 0;
222 
223  m_uNoOfElements = 0;
224  }
225 
226  //****************************************************************************//
227  // One dimensional specialisation begins here //
228  //****************************************************************************//
229 
230  template <typename ElementType>
232  : m_pElements(0)
233  ,m_pDimensions(0)
234  {
235  }
236 
237  template <typename ElementType>
238  Array<1, ElementType>::Array(const uint32_t (&pDimensions)[1])
239  : m_pElements(0)
240  ,m_pDimensions(0)
241  {
242  resize(pDimensions);
243  }
244 
245  template <typename ElementType>
247  {
248  deallocate();
249  }
250 
251  template <typename ElementType>
252  ElementType& Array<1, ElementType>::operator[] (uint32_t uIndex)
253  {
254  assert(uIndex<m_pDimensions[0]);
255  return m_pElements[uIndex];
256  }
257 
258  template <typename ElementType>
259  const ElementType& Array<1, ElementType>::operator[] (uint32_t uIndex) const
260  {
261  assert(uIndex<m_pDimensions[0]);
262  return m_pElements[uIndex];
263  }
264 
265  template <typename ElementType>
267  {
268  return m_pDimensions[0];
269  }
270 
271  template <typename ElementType>
272  ElementType* Array<1, ElementType>::getRawData(void) const
273  {
274  return m_pElements;
275  }
276 
277  template <typename ElementType>
278  void Array<1, ElementType>::resize(const uint32_t (&pDimensions)[1])
279  {
280  deallocate();
281 
282  m_pDimensions = new uint32_t[1];
283  m_pDimensions[0] = pDimensions[0];
284 
285  // Allocate new elements, let exception propagate
286  m_pElements = new ElementType[m_pDimensions[0]];
287  }
288 
289  template <typename ElementType>
291  {
292  //Implement this function without temporary 'Array'
293  //objects, as the destructors will free the memory...
294  uint32_t* m_pTempDimensions = m_pDimensions;
295  ElementType* m_pTempElements = m_pElements;
296 
297  m_pDimensions = rhs.m_pDimensions;
298  m_pElements = rhs.m_pElements;
299 
300  rhs.m_pDimensions = m_pTempDimensions;
301  rhs.m_pElements = m_pTempElements;
302  }
303 
304  template <typename ElementType>
306  : m_pElements(0)
307  ,m_pDimensions(0)
308  {
309  //Not implemented
310  assert(false);
311  }
312 
313  template <typename ElementType>
314  Array<1, ElementType>& Array<1, ElementType>::operator=(const Array<1, ElementType>& rhs)
315  {
316  //Not implemented
317  assert(false);
318 
319  return *this;
320  }
321 
322  template <typename ElementType>
323  void Array<1, ElementType>::deallocate(void)
324  {
325  delete[] m_pDimensions;
326  m_pDimensions = 0;
327  delete[] m_pElements;
328  m_pElements = 0;
329  }
330 }//namespace PolyVox