Line data Source code
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 : 22 : /** 23 : * Default constructor. Doesn't initialize anything. 24 : */ 25 46403226 : MooseArray() : _data(nullptr), _size(0), _allocated_size(0) {} 26 : 27 : /** 28 : * @param size The initial size of the array. 29 : */ 30 620 : explicit MooseArray(const unsigned int size) : _data(nullptr), _size(0), _allocated_size(0) 31 : { 32 620 : resize(size); 33 620 : } 34 : 35 : /** 36 : * @param size The initial size of the array. 37 : * @param default_value The default value to set. 38 : */ 39 1731 : explicit MooseArray(const unsigned int size, const T & default_value) 40 1731 : : _data(nullptr), _size(0), _allocated_size(0) 41 : { 42 1731 : resize(size); 43 : 44 1731 : setAllValues(default_value); 45 1731 : } 46 : 47 44735 : explicit MooseArray(const MooseArray & rhs) : _data(nullptr), _size(0), _allocated_size(0) 48 : { 49 44735 : resize(rhs._size); 50 : 51 94693 : for (unsigned int i = 0; i < _size; i++) 52 49958 : _data[i] = rhs._data[i]; 53 44735 : } 54 : 55 43649150 : ~MooseArray() = default; 56 : 57 : /** 58 : * Sets all values of the array to the passed in value 59 : * @param value The value every entry of the array will be set to. 60 : */ 61 : void setAllValues(const T & value); 62 : 63 : /** 64 : * Manually deallocates the data pointer 65 : */ 66 1646163 : void release() 67 : { 68 1646163 : if (_data_ptr) 69 : { 70 799187 : _data_ptr.reset(); 71 799187 : _data = nullptr; 72 799187 : _allocated_size = _size = 0; 73 : } 74 1646163 : } 75 : 76 : /** 77 : * Change the number of elements the array can store to zero. 78 : * 79 : * Will destroy data currently in array! 80 : * 81 : * Note that this does _not_ free unused memory. 82 : * This is done for speed. 83 : */ 84 : void clear(); 85 : 86 : /** 87 : * Change the number of elements the array can store. 88 : * 89 : * Will allocate more memory if necessary. 90 : * 91 : * Can destroy data currently in array! 92 : * Basically, data retention not guaranteed. 93 : * 94 : * Note that this does _not_ free unused memory. 95 : * This is done for speed. 96 : * 97 : * @param size The new size of the array 98 : * @tparam value_initialize Whether to perform value initialization of the array instead of 99 : * default initialization 100 : */ 101 : template <bool value_initialize = false> 102 : void resize(unsigned int size); 103 : 104 : /** 105 : * Change the number of elements the array can store. 106 : * 107 : * Will allocate more memory if necessary. 108 : * 109 : * Can destroy data currently in array! 110 : * Basically, data retention not guaranteed. 111 : * 112 : * Note that this does _not_ free unused memory. 113 : * This is done for speed. 114 : * 115 : * Also note that default_value is only applied to NEW entries. 116 : */ 117 : void resize(unsigned int size, const T & default_value); 118 : 119 : /** 120 : * The number of elements that can currently 121 : * be stored in the array. 122 : */ 123 : unsigned int size() const; 124 : 125 : /** 126 : * Get element i out of the array. 127 : */ 128 : T & operator[](const unsigned int i); 129 : 130 : /** 131 : * Get element i out of the array. 132 : */ 133 : const T & operator[](const unsigned int i) const; 134 : 135 : /** 136 : * Swap memory in this object with the 'rhs' object 137 : * @param rhs The object we are swapping with 138 : */ 139 : void swap(MooseArray & rhs); 140 : 141 : /** 142 : * Doesn't actually make a copy of the data. 143 : * 144 : * Just makes _this_ object operate on the same data. 145 : */ 146 : void shallowCopy(const MooseArray & rhs); 147 : 148 : /** 149 : * Doesn't actually make a copy of the data. 150 : * 151 : * Just makes _this_ object operate on the same data. 152 : */ 153 : void shallowCopy(std::vector<T> & rhs); 154 : 155 : /** 156 : * Actual operator=... really does make a copy of the data 157 : * 158 : * If you don't want a copy use shallowCopy() 159 : */ 160 : MooseArray<T> & operator=(const std::vector<T> & rhs); 161 : 162 : /** 163 : * Actual operator=... really does make a copy of the data 164 : * 165 : * If you don't want a copy use shallowCopy() 166 : */ 167 : MooseArray<T> & operator=(const MooseArray<T> & rhs); 168 : 169 : /** 170 : * Extremely inefficient way to produce a std::vector from a MooseArray! 171 : * 172 : * @return A _copy_ of the MooseArray contents. 173 : */ 174 : std::vector<T> stdVector() const; 175 : 176 : ///@{ 177 : /** 178 : * Reference to first element of array 179 : */ 180 0 : const T * data() const { return _data; } 181 : T * data() { return _data; } 182 : ///@} 183 : 184 : private: 185 : /// Smart pointer storage 186 : std::unique_ptr<T[]> _data_ptr; 187 : 188 : // Actual data pointer (from inside of the smart pointer). 189 : T * _data; 190 : 191 : /// The current number of elements the array can hold. 192 : unsigned int _size; 193 : 194 : /// Number of allocated memory positions for storage. 195 : unsigned int _allocated_size; 196 : }; 197 : 198 : template <typename T> 199 : inline void 200 1732 : MooseArray<T>::setAllValues(const T & value) 201 : { 202 1690486 : for (unsigned int i = 0; i < _size; i++) 203 1688754 : _data[i] = value; 204 1732 : } 205 : 206 : template <typename T> 207 : inline void 208 804912 : MooseArray<T>::clear() 209 : { 210 804912 : _size = 0; 211 804912 : } 212 : 213 : template <typename T> 214 : template <bool value_initialize> 215 : inline void 216 5697309611 : MooseArray<T>::resize(unsigned int size) 217 : { 218 5697309611 : if (size > _allocated_size) 219 : { 220 : if constexpr (value_initialize) 221 11516299 : _data_ptr.reset(new T[size]()); 222 : else 223 2680010 : _data_ptr = std::make_unique<T[]>(size); 224 : mooseAssert(_data_ptr, "Failed to allocate MooseArray memory!"); 225 : 226 3243305 : _data = _data_ptr.get(); 227 3243305 : _allocated_size = size; 228 : } 229 : 230 5697309611 : _size = size; 231 5697309611 : } 232 : 233 : template <typename T> 234 : inline void 235 1563661 : MooseArray<T>::resize(unsigned int size, const T & default_value) 236 : { 237 1563661 : if (size > _allocated_size) 238 : { 239 726227 : auto new_pointer = std::make_unique<T[]>(size); 240 : mooseAssert(new_pointer, "Failed to allocate MooseArray memory!"); 241 : 242 726227 : if (_data) 243 1049 : for (unsigned int i = 0; i < _size; i++) 244 839 : new_pointer[i] = _data[i]; 245 : 246 726227 : _data_ptr = std::move(new_pointer); 247 726227 : _data = _data_ptr.get(); 248 726227 : _allocated_size = size; 249 726227 : } 250 : 251 8194023 : for (unsigned int i = _size; i < size; i++) 252 6630362 : _data[i] = default_value; 253 : 254 1563661 : _size = size; 255 1563661 : } 256 : 257 : template <typename T> 258 : inline unsigned int 259 8787514342 : MooseArray<T>::size() const 260 : { 261 8787514342 : return _size; 262 : } 263 : 264 : template <typename T> 265 : inline T & 266 56493641904 : 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 56493641904 : return _data[i]; 272 : } 273 : 274 : template <typename T> 275 : inline const T & 276 >17659*10^7 : 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 >17659*10^7 : return _data[i]; 282 : } 283 : 284 : template <typename T> 285 : inline void 286 32934719 : MooseArray<T>::swap(MooseArray & rhs) 287 : { 288 32934719 : _data_ptr.swap(rhs._data_ptr); 289 32934719 : std::swap(_data, rhs._data); 290 32934719 : std::swap(_size, rhs._size); 291 32934719 : std::swap(_allocated_size, rhs._allocated_size); 292 32934719 : } 293 : 294 : template <typename T> 295 : inline void 296 264463436 : MooseArray<T>::shallowCopy(const MooseArray & rhs) 297 : { 298 264463436 : _data_ptr.reset(); 299 264463436 : _data = rhs._data; 300 264463436 : _size = rhs._size; 301 264463436 : _allocated_size = rhs._allocated_size; 302 264463436 : } 303 : 304 : template <typename T> 305 : inline void 306 1913441207 : MooseArray<T>::shallowCopy(std::vector<T> & rhs) 307 : { 308 1913441207 : _data_ptr.reset(); 309 1913441207 : _data = &rhs[0]; 310 1913441207 : _size = rhs.size(); 311 1913441207 : _allocated_size = rhs.size(); 312 1913441207 : } 313 : 314 : template <typename T> 315 : inline MooseArray<T> & 316 518213 : MooseArray<T>::operator=(const std::vector<T> & rhs) 317 : { 318 518213 : unsigned int rhs_size = rhs.size(); 319 : 320 518213 : resize(rhs_size); 321 : 322 1045068 : for (unsigned int i = 0; i < rhs_size; i++) 323 526855 : _data[i] = rhs[i]; 324 : 325 518213 : return *this; 326 : } 327 : 328 : template <typename T> 329 : inline MooseArray<T> & 330 0 : MooseArray<T>::operator=(const MooseArray<T> & rhs) 331 : { 332 : // mooseError("Shouldn't be doing this!"); 333 0 : resize(rhs._size); 334 : // memcpy(_data,rhs._data,sizeof(T)*_size); 335 : 336 0 : for (unsigned int i = 0; i < _size; i++) 337 0 : _data[i] = rhs._data[i]; 338 : 339 0 : return *this; 340 : } 341 : 342 : template <class T> 343 : std::vector<T> 344 3811888 : MooseArray<T>::stdVector() const 345 : { 346 3811888 : return std::vector<T>(_data, _data + _size); 347 : } 348 : 349 : template <class T> 350 : void 351 : freeDoubleMooseArray(MooseArray<MooseArray<T>> & a) 352 : { 353 : for (unsigned int i = 0; i < a.size(); i++) 354 : a[i].release(); 355 : a.release(); 356 : }