https://mooseframework.inl.gov
MooseArray.h
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #pragma once
11 
12 #include <vector>
13 #include <memory>
14 #include "MooseError.h"
15 
16 template <typename T>
17 class MooseArray
18 {
19 public:
20  typedef T value_type;
21 
25  MooseArray() : _data(nullptr), _size(0), _allocated_size(0) {}
26 
30  explicit MooseArray(const unsigned int size) : _data(nullptr), _size(0), _allocated_size(0)
31  {
32  resize(size);
33  }
34 
39  explicit MooseArray(const unsigned int size, const T & default_value)
40  : _data(nullptr), _size(0), _allocated_size(0)
41  {
42  resize(size);
43 
44  setAllValues(default_value);
45  }
46 
47  explicit MooseArray(const MooseArray & rhs) : _data(nullptr), _size(0), _allocated_size(0)
48  {
49  resize(rhs._size);
50 
51  for (unsigned int i = 0; i < _size; i++)
52  _data[i] = rhs._data[i];
53  }
54 
55  ~MooseArray() = default;
56 
61  void setAllValues(const T & value);
62 
66  void release()
67  {
68  if (_data_ptr)
69  {
70  _data_ptr.reset();
71  _data = nullptr;
72  _allocated_size = _size = 0;
73  }
74  }
75 
84  void clear();
85 
101  template <bool value_initialize = false>
102  void resize(unsigned int size);
103 
117  void resize(unsigned int size, const T & default_value);
118 
123  unsigned int size() const;
124 
128  T & operator[](const unsigned int i);
129 
133  const T & operator[](const unsigned int i) const;
134 
139  void swap(MooseArray & rhs);
140 
146  void shallowCopy(const MooseArray & rhs);
147 
153  void shallowCopy(std::vector<T> & rhs);
154 
160  MooseArray<T> & operator=(const std::vector<T> & rhs);
161 
167  MooseArray<T> & operator=(const MooseArray<T> & rhs);
168 
174  std::vector<T> stdVector() const;
175 
177 
180  const T * data() const { return _data; }
181  T * data() { return _data; }
183 
184 private:
186  std::unique_ptr<T[]> _data_ptr;
187 
188  // Actual data pointer (from inside of the smart pointer).
189  T * _data;
190 
192  unsigned int _size;
193 
195  unsigned int _allocated_size;
196 };
197 
198 template <typename T>
199 inline void
201 {
202  for (unsigned int i = 0; i < _size; i++)
203  _data[i] = value;
204 }
205 
206 template <typename T>
207 inline void
209 {
210  _size = 0;
211 }
212 
213 template <typename T>
214 template <bool value_initialize>
215 inline void
216 MooseArray<T>::resize(unsigned int size)
217 {
218  if (size > _allocated_size)
219  {
220  if constexpr (value_initialize)
221  _data_ptr.reset(new T[size]());
222  else
223  _data_ptr = std::make_unique<T[]>(size);
224  mooseAssert(_data_ptr, "Failed to allocate MooseArray memory!");
225 
226  _data = _data_ptr.get();
227  _allocated_size = size;
228  }
229 
230  _size = size;
231 }
232 
233 template <typename T>
234 inline void
235 MooseArray<T>::resize(unsigned int size, const T & default_value)
236 {
237  if (size > _allocated_size)
238  {
239  auto new_pointer = std::make_unique<T[]>(size);
240  mooseAssert(new_pointer, "Failed to allocate MooseArray memory!");
241 
242  if (_data)
243  for (unsigned int i = 0; i < _size; i++)
244  new_pointer[i] = _data[i];
245 
246  _data_ptr = std::move(new_pointer);
247  _data = _data_ptr.get();
248  _allocated_size = size;
249  }
250 
251  for (unsigned int i = _size; i < size; i++)
252  _data[i] = default_value;
253 
254  _size = size;
255 }
256 
257 template <typename T>
258 inline unsigned int
260 {
261  return _size;
262 }
263 
264 template <typename T>
265 inline T &
266 MooseArray<T>::operator[](const unsigned int i)
267 {
268  mooseAssert(i < _size,
269  "Access out of bounds in MooseArray (i: " << i << " size: " << _size << ")");
270 
271  return _data[i];
272 }
273 
274 template <typename T>
275 inline const T &
276 MooseArray<T>::operator[](const unsigned int i) const
277 {
278  mooseAssert(i < _size,
279  "Access out of bounds in MooseArray (i: " << i << " size: " << _size << ")");
280 
281  return _data[i];
282 }
283 
284 template <typename T>
285 inline void
287 {
288  _data_ptr.swap(rhs._data_ptr);
289  std::swap(_data, rhs._data);
290  std::swap(_size, rhs._size);
291  std::swap(_allocated_size, rhs._allocated_size);
292 }
293 
294 template <typename T>
295 inline void
297 {
298  _data_ptr.reset();
299  _data = rhs._data;
300  _size = rhs._size;
301  _allocated_size = rhs._allocated_size;
302 }
303 
304 template <typename T>
305 inline void
306 MooseArray<T>::shallowCopy(std::vector<T> & rhs)
307 {
308  _data_ptr.reset();
309  _data = &rhs[0];
310  _size = rhs.size();
311  _allocated_size = rhs.size();
312 }
313 
314 template <typename T>
315 inline MooseArray<T> &
316 MooseArray<T>::operator=(const std::vector<T> & rhs)
317 {
318  unsigned int rhs_size = rhs.size();
319 
320  resize(rhs_size);
321 
322  for (unsigned int i = 0; i < rhs_size; i++)
323  _data[i] = rhs[i];
324 
325  return *this;
326 }
327 
328 template <typename T>
329 inline MooseArray<T> &
331 {
332  // mooseError("Shouldn't be doing this!");
333  resize(rhs._size);
334  // memcpy(_data,rhs._data,sizeof(T)*_size);
335 
336  for (unsigned int i = 0; i < _size; i++)
337  _data[i] = rhs._data[i];
338 
339  return *this;
340 }
341 
342 template <class T>
343 std::vector<T>
345 {
346  return std::vector<T>(_data, _data + _size);
347 }
348 
349 template <class T>
350 void
352 {
353  for (unsigned int i = 0; i < a.size(); i++)
354  a[i].release();
355  a.release();
356 }
MooseArray(const unsigned int size, const T &default_value)
Definition: MooseArray.h:39
~MooseArray()=default
MooseArray()
Default constructor.
Definition: MooseArray.h:25
void swap(std::vector< T > &data, const std::size_t idx0, const std::size_t idx1, const libMesh::Parallel::Communicator &comm)
Swap function for serial or distributed vector of data.
Definition: Shuffle.h:494
const T * data() const
Reference to first element of array.
Definition: MooseArray.h:180
void swap(MooseArray &rhs)
Swap memory in this object with the &#39;rhs&#39; object.
Definition: MooseArray.h:286
void shallowCopy(const MooseArray &rhs)
Doesn&#39;t actually make a copy of the data.
Definition: MooseArray.h:296
void setAllValues(const T &value)
Sets all values of the array to the passed in value.
Definition: MooseArray.h:200
void freeDoubleMooseArray(MooseArray< MooseArray< T >> &a)
Definition: MooseArray.h:351
MooseArray< T > & operator=(const std::vector< T > &rhs)
Actual operator=...
Definition: MooseArray.h:316
unsigned int _size
The current number of elements the array can hold.
Definition: MooseArray.h:192
unsigned int size() const
The number of elements that can currently be stored in the array.
Definition: MooseArray.h:259
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
unsigned int _allocated_size
Number of allocated memory positions for storage.
Definition: MooseArray.h:195
std::vector< T > stdVector() const
Extremely inefficient way to produce a std::vector from a MooseArray!
Definition: MooseArray.h:344
MooseArray(const MooseArray &rhs)
Definition: MooseArray.h:47
std::unique_ptr< T[]> _data_ptr
Smart pointer storage.
Definition: MooseArray.h:186
forward declarations
void release()
Manually deallocates the data pointer.
Definition: MooseArray.h:66
void resize(unsigned int size)
Change the number of elements the array can store.
Definition: MooseArray.h:216
T * data()
Definition: MooseArray.h:181
void clear()
Change the number of elements the array can store to zero.
Definition: MooseArray.h:208
T & operator[](const unsigned int i)
Get element i out of the array.
Definition: MooseArray.h:266
MooseArray(const unsigned int size)
Definition: MooseArray.h:30