Nektar++
SharedArray.hpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File SharedArray.hpp
4 //
5 // For more information, please see: http://www.nektar.info
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Scientific Computing and Imaging Institute,
10 // University of Utah (USA) and Department of Aeronautics, Imperial
11 // College London (UK).
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining a
14 // copy of this software and associated documentation files (the "Software"),
15 // to deal in the Software without restriction, including without limitation
16 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 // and/or sell copies of the Software, and to permit persons to whom the
18 // Software is furnished to do so, subject to the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be included
21 // in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 // DEALINGS IN THE SOFTWARE.
30 //
31 // Description:
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
35 #ifndef NEKTAR_LIB_UTILITIES_BASIC_UTILS_SHARED_ARRAY_HPP
36 #define NEKTAR_LIB_UTILITIES_BASIC_UTILS_SHARED_ARRAY_HPP
37 
43 
44 #include <boost/core/ignore_unused.hpp>
45 #include <boost/multi_array.hpp>
46 
47 namespace Nektar
48 {
49  class LinearSystem;
50 
51  // Forward declaration for a ConstArray constructor.
52  template<typename Dim, typename DataType>
53  class Array;
54 
55  /// \brief 1D Array of constant elements with garbage collection and bounds checking.
56  template<typename DataType>
57  class Array<OneD, const DataType>
58  {
59 #ifdef WITH_PYTHON
60  struct PythonInfo {
61  void *m_pyObject; // Underlying PyObject pointer
62  void (*m_callback)(void *); // Callback
63  };
64 #endif
65  public:
66  typedef DataType* ArrayType;
67  typedef const DataType& const_reference;
68  typedef DataType& reference;
69 
70  typedef const DataType* const_iterator;
71  typedef DataType* iterator;
72 
73  typedef DataType element;
74  typedef size_t size_type;
75 
76 
77  public:
78  /// \brief Creates an empty array.
79  Array() :
80 #ifdef WITH_PYTHON
81  m_pythonInfo(nullptr),
82 #endif
83  m_size( 0 ),
84  m_capacity( 0 ),
85  m_data( nullptr ),
86  m_count( nullptr ),
87  m_offset( 0 )
88  {
89  CreateStorage(m_capacity);
90  }
91 
92  /// \brief Creates an array of size dim1Size.
93  ///
94  /// If DataType is a fundamental type (double, int, etc.), then the allocated array is
95  /// uninitialized. If it is any other type, each element is initialized with DataType's default
96  /// constructor.
97  explicit Array(size_t dim1Size) :
98 #ifdef WITH_PYTHON
99  m_pythonInfo(nullptr),
100 #endif
101  m_size( dim1Size ),
102  m_capacity( dim1Size ),
103  m_data( nullptr ),
104  m_count( nullptr ),
105  m_offset( 0 )
106  {
107  CreateStorage(m_capacity);
109  }
110 
111  /// \brief Creates a 1D array with each element
112  /// initialized to an initial value.
113  /// \param dim1Size The array's size.
114  /// \param initValue Each element's initial value.
115  ///
116  /// If DataType is a fundamental type (double, int, etc.),
117  /// then the initial value is copied directly into each
118  /// element. Otherwise, the DataType's copy constructor
119  /// is used to initialize each element.
120  Array(size_t dim1Size, const DataType& initValue) :
121 #ifdef WITH_PYTHON
122  m_pythonInfo(nullptr),
123 #endif
124  m_size( dim1Size ),
125  m_capacity( dim1Size ),
126  m_data( nullptr ),
127  m_count( nullptr ),
128  m_offset( 0 )
129  {
130  CreateStorage(m_capacity);
131  ArrayInitializationPolicy<DataType>::Initialize( m_data, m_capacity, initValue );
132  }
133 
134  /// \brief Creates a 1D array a copies data into it.
135  /// \param dim1Size the array's size.
136  /// \param data The data to copy.
137  ///
138  /// If DataType is a fundamental type (double, int, etc.), then data is copied
139  /// directly into the underlying storage. Otherwise, the DataType's copy constructor
140  /// is used to copy each element.
141  Array(size_t dim1Size, const DataType* data) :
142 #ifdef WITH_PYTHON
143  m_pythonInfo(nullptr),
144 #endif
145  m_size( dim1Size ),
146  m_capacity( dim1Size ),
147  m_data( nullptr ),
148  m_count( nullptr ),
149  m_offset( 0 )
150  {
151  CreateStorage(m_capacity);
152  ArrayInitializationPolicy<DataType>::Initialize( m_data, m_capacity, data );
153  }
154 
155  /// \brief Creates a 1D array that references rhs.
156  /// \param dim1Size The size of the array. This is useful
157  /// when you want this array to reference
158  /// a subset of the elements in rhs.
159  /// \param rhs Array to reference.
160  /// This constructor creates an array that references rhs.
161  /// Any changes to rhs will be reflected in this array.
162  /// The memory for the array will only be deallocated when
163  /// both rhs and this array have gone out of scope.
164  Array(size_t dim1Size, const Array<OneD, const DataType>& rhs) :
165 #ifdef WITH_PYTHON
166  m_pythonInfo(rhs.m_pythonInfo),
167 #endif
168  m_size(dim1Size),
169  m_capacity(rhs.m_capacity),
170  m_data(rhs.m_data),
171  m_count(rhs.m_count),
172  m_offset(rhs.m_offset)
173  {
174  *m_count += 1;
175  ASSERTL0(m_size <= rhs.num_elements(), "Requested size is larger than input array size.");
176  }
177 
178 #ifdef WITH_PYTHON
179  /// \brief Creates a 1D array a copies data into it.
180  /// \param dim1Size the array's size.
181  /// \param data The data to reference.
182  /// \param memory_pointer Pointer to the memory address of the array
183  /// \param python_decrement Pointer to decrementer
184  Array(size_t dim1Size, DataType* data, void* memory_pointer, void (*python_decrement)(void *)) :
185  m_size( dim1Size ),
186  m_capacity( dim1Size ),
187  m_data( data ),
188  m_count( nullptr ),
189  m_offset( 0 )
190  {
191  m_count = new size_t();
192  *m_count = 1;
193 
194  m_pythonInfo = new PythonInfo *();
195  *m_pythonInfo = new PythonInfo();
196  (*m_pythonInfo)->m_callback = python_decrement;
197  (*m_pythonInfo)->m_pyObject = memory_pointer;
198  }
199 #endif
200 
201  /// \brief Creates a reference to rhs.
203 #ifdef WITH_PYTHON
204  m_pythonInfo(rhs.m_pythonInfo),
205 #endif
206  m_size(rhs.m_size),
207  m_capacity(rhs.m_capacity),
208  m_data(rhs.m_data),
209  m_count(rhs.m_count),
210  m_offset(rhs.m_offset)
211  {
212  *m_count += 1;
213  }
214 
216  {
217  if( m_count == nullptr )
218  {
219  return;
220  }
221 
222  *m_count -= 1;
223  if( *m_count == 0 )
224  {
225 #ifdef WITH_PYTHON
226  if (*m_pythonInfo == nullptr)
227  {
228  ArrayDestructionPolicy<DataType>::Destroy( m_data, m_capacity );
229  MemoryManager<DataType>::RawDeallocate( m_data, m_capacity );
230  }
231  else
232  {
233  (*m_pythonInfo)->m_callback((*m_pythonInfo)->m_pyObject);
234  delete *m_pythonInfo;
235  }
236 
237  delete m_pythonInfo;
238 
239 #else
240 
241  ArrayDestructionPolicy<DataType>::Destroy( m_data, m_capacity );
242  MemoryManager<DataType>::RawDeallocate( m_data, m_capacity );
243 
244 #endif
245 
246  delete m_count; // Clean up the memory used for the reference count.
247  }
248  }
249 
250  /// \brief Creates a reference to rhs.
252  {
253  *m_count -= 1;
254  if( *m_count == 0 )
255  {
256 #ifdef WITH_PYTHON
257  if (*m_pythonInfo == nullptr)
258  {
259  ArrayDestructionPolicy<DataType>::Destroy( m_data, m_capacity );
260  MemoryManager<DataType>::RawDeallocate( m_data, m_capacity );
261  }
262  else if ((*rhs.m_pythonInfo) != nullptr && (*m_pythonInfo)->m_pyObject != (*rhs.m_pythonInfo)->m_pyObject)
263  {
264  (*m_pythonInfo)->m_callback((*m_pythonInfo)->m_pyObject);
265  delete *m_pythonInfo;
266  }
267 
268  delete m_pythonInfo;
269 #else
270 
271  ArrayDestructionPolicy<DataType>::Destroy( m_data, m_capacity );
272  MemoryManager<DataType>::RawDeallocate( m_data, m_capacity );
273 #endif
274  delete m_count; // Clean up the memory used for the reference count.
275  }
276 
277  m_data = rhs.m_data;
278  m_capacity = rhs.m_capacity;
279  m_count = rhs.m_count;
280  *m_count += 1;
281  m_offset = rhs.m_offset;
282  m_size = rhs.m_size;
283 #ifdef WITH_PYTHON
284  m_pythonInfo = rhs.m_pythonInfo;
285 #endif
286  return *this;
287  }
288 
289  const_iterator begin() const { return m_data + m_offset; }
290  const_iterator end() const { return m_data + m_offset + m_size; }
291 
292  const_reference operator[](size_t i) const
293  {
294  ASSERTL1(i < m_size,
295  std::string("Element ") + std::to_string(i) +
296  std::string(" requested in an array of size ") +
297  std::to_string(m_size));
298  return *( m_data + i + m_offset );
299  }
300 
301  /// \brief Returns a c-style pointer to the underlying array.
302  const element* get() const { return m_data + m_offset; }
303 
304  /// \brief Returns a c-style pointer to the underlying array.
305  const element* data() const { return m_data + m_offset; }
306 
307  /// \brief Returns 1.
308  size_t num_dimensions() const { return 1; }
309 
310  /// \brief Returns the array's size.
311  size_t num_elements() const { return m_size; }
312 
313  size_t capacity() const { return m_capacity; }
314 
315  /// \brief Returns the array's offset.
316  size_t GetOffset() const { return m_offset; }
317 
318  /// \brief Returns the array's reference counter.
319  size_t GetCount() const { return *m_count; }
320 
321  /// \brief Returns true is this array and rhs overlap.
323  {
324  const element* start = get();
325  const element* end = start + m_size;
326 
327  const element* rhs_start = rhs.get();
328  const element* rhs_end = rhs_start + rhs.num_elements();
329 
330  return (rhs_start >= start && rhs_start <= end) ||
331  (rhs_end >= start && rhs_end <= end);
332  }
333 
334 #ifdef WITH_PYTHON
335  bool IsPythonArray()
336  {
337  return *m_pythonInfo != nullptr;
338  }
339 
340  void ToPythonArray(void* memory_pointer, void (*python_decrement)(void *))
341  {
342  *m_pythonInfo = new PythonInfo();
343  (*m_pythonInfo)->m_callback = python_decrement;
344  (*m_pythonInfo)->m_pyObject = memory_pointer;
345  }
346 #endif
347 
348  template<typename T1, typename T2>
349  friend bool operator==(const Array<OneD, T1>&, const Array<OneD, T2>&);
352 
353  /// \brief Creates an array with a specified offset.
354  ///
355  /// The return value will reference the same array as lhs,
356  /// but with an offset.
357  ///
358  /// For example, in the following:
359  /// \code
360  /// Array<OneD, const double> result = anArray + 10;
361  /// \endcode
362  /// result[0] == anArray[10];
363  template<typename T>
364  friend Array<OneD, T> operator+(const Array<OneD, T>& lhs, size_t offset);
365 
366  template<typename T>
367  friend Array<OneD, T> operator+(unsigned int offset, const Array<OneD, T>& rhs);
368 
369  protected:
370 
371 #ifdef WITH_PYTHON
372  PythonInfo **m_pythonInfo;
373 #endif
374 
375  size_t m_size;
376  size_t m_capacity;
377  DataType* m_data;
378 
379  // m_count points to an integer used as a reference count to this array's data (m_data).
380  // Previously, the reference count was stored in the first 4 bytes of the m_data array.
381  size_t* m_count;
382 
383  size_t m_offset;
384 
385  private:
386  // struct DestroyArray
387  // {
388  // DestroyArray(unsigned int elements) :
389  // m_elements(elements) {}
390  //
391  // void operator()(DataType* p)
392  // {
393  // ArrayDestructionPolicy<DataType>::Destroy(p, m_elements);
394  // MemoryManager<DataType>::RawDeallocate(p, m_elements);
395  // }
396  // unsigned int m_elements;
397  // };
398  //
399  void
400  CreateStorage( size_t size )
401  {
402  DataType* storage = MemoryManager<DataType>::RawAllocate( size );
403  m_data = storage;
404 
405  // Allocate an integer to hold the reference count. Note 1, all arrays that share this array's
406  // data (ie, point to m_data) will also share the m_count data. Note 2, previously m_count
407  // pointed to "(unsigned int*)storage".
408  m_count = new size_t();
409  *m_count = 1;
410 #ifdef WITH_PYTHON
411  m_pythonInfo = new PythonInfo*();
412  *m_pythonInfo = nullptr;
413 #endif
414  }
415 
416  template<typename T>
417  static Array<OneD, T> CreateWithOffset(const Array<OneD, T>& rhs, size_t offset)
418  {
419  Array<OneD, T> result(rhs);
420  result.m_offset += offset;
421  result.m_size = rhs.m_size - offset;
422  return result;
423  }
424 
425  };
426 
427 
428  /// \brief 2D array with garbage collection and bounds checking.
429  template<typename DataType>
430  class Array<TwoD, const DataType>
431  {
432  public:
433  typedef boost::multi_array_ref<DataType, 2> ArrayType;
434  typedef typename ArrayType::const_reference const_reference;
435  typedef typename ArrayType::reference reference;
436 
437  typedef typename ArrayType::index index;
438  typedef typename ArrayType::const_iterator const_iterator;
439  typedef typename ArrayType::iterator iterator;
440 
441  typedef typename ArrayType::element element;
442  typedef typename ArrayType::size_type size_type;
443 
444 
445 
446  public:
447  Array() :
448  m_data(CreateStorage<DataType>(0, 0))
449  {
450  }
451 
452  /// \brief Constructs a 2 dimensional array. The elements of the array are not initialized.
453  Array(size_t dim1Size, size_t dim2Size) :
454  m_data(CreateStorage<DataType>(dim1Size, dim2Size))
455  {
456  ArrayInitializationPolicy<DataType>::Initialize(m_data->data(), m_data->num_elements());
457  }
458 
459  Array(size_t dim1Size, size_t dim2Size, const DataType& initValue) :
460  m_data(CreateStorage<DataType>(dim1Size, dim2Size))
461  {
462  ArrayInitializationPolicy<DataType>::Initialize(m_data->data(), m_data->num_elements(), initValue);
463  }
464 
465  Array(size_t dim1Size, size_t dim2Size, const DataType* data) :
466  m_data(CreateStorage<DataType>(dim1Size, dim2Size))
467  {
468  ArrayInitializationPolicy<DataType>::Initialize(m_data->data(), m_data->num_elements(), data);
469  }
470 
472  m_data(rhs.m_data)
473  {
474  }
475 
477  {
478  m_data = rhs.m_data;
479  return *this;
480  }
481 
482  template<typename T>
483  friend bool operator==(const Array<TwoD, T>&, const Array<TwoD, T>&);
486 
487  const_iterator begin() const { return m_data->begin(); }
488  const_iterator end() const { return m_data->end(); }
489  const_reference operator[](index i) const { return (*m_data)[i]; }
490  const element* get() const { return m_data->data(); }
491  const element* data() const { return m_data->data(); }
492  size_t num_dimensions() const { return m_data->num_dimensions(); }
493  const size_type* shape() const { return m_data->shape(); }
494  size_t num_elements() const { return m_data->num_elements(); }
495 
496  size_t GetRows() const { return m_data->shape()[0]; }
497  size_t GetColumns() const { return m_data->shape()[1]; }
498 
499  protected:
500  std::shared_ptr<ArrayType> m_data;
501 
502  private:
503 
504  };
505 
507  {
509  };
510 
511  /// \brief 1D Array
512  ///
513  /// \ref pageNekArrays
514  ///
515  /// Misc notes.
516  ///
517  /// Through out the 1D Array class you will see things like "using BaseType::begin" and
518  /// "using BaseType::end". This is necessary to bring the methods from the ConstArray
519  /// into scope in Array class. Typically this is not necessary, but since we have
520  /// method names which match those in the base class, the base class names are hidden.
521  /// Therefore, we have to explicitly bring them into scope to use them.
522  template<typename DataType>
523  class Array<OneD, DataType> : public Array<OneD, const DataType>
524  {
525  public:
527  typedef typename BaseType::iterator iterator;
528  typedef typename BaseType::reference reference;
529  typedef typename BaseType::size_type size_type;
530  typedef typename BaseType::element element;
531 
532  public:
533  Array() :
534  BaseType()
535  {
536  }
537 
538  explicit Array(size_t dim1Size) :
539  BaseType(dim1Size)
540  {
541  }
542 
543  Array(size_t dim1Size, const DataType& initValue) :
544  BaseType(dim1Size, initValue)
545  {
546  }
547 
548  Array(size_t dim1Size, const DataType* data) :
549  BaseType(dim1Size, data)
550  {
551  }
552 
553  Array(size_t dim1Size, const Array<OneD, DataType>& rhs) :
554  BaseType(dim1Size, rhs)
555  {
556  }
557 
558  Array(size_t dim1Size, const Array<OneD, const DataType>& rhs) :
559  BaseType(dim1Size, rhs.data())
560  {
561  }
562 
564  BaseType(rhs)
565  {
566  }
567 
569  BaseType(rhs.num_elements(), rhs.data())
570  {
571  }
572 
573 #ifdef WITH_PYTHON
574  Array(size_t dim1Size, DataType* data, void* memory_pointer, void (*python_decrement)(void *)) :
575  BaseType(dim1Size, data, memory_pointer, python_decrement)
576  {
577  }
578 
579  void ToPythonArray(void* memory_pointer, void (*python_decrement)(void *))
580  {
581  BaseType::ToPythonArray(memory_pointer, python_decrement);
582  }
583 #endif
584 
586  {
587  BaseType::operator=(rhs);
588  return *this;
589  }
590 
592  {
593  Array<OneD, DataType> result(rhs);
594  result.m_offset += offset;
595  result.m_size = rhs.m_size - offset;
596  return result;
597  }
598 
601  iterator begin() { return this->m_data + this->m_offset; }
602 
603  using BaseType::end;
604  iterator end() { return this->m_data + this->m_offset + this->m_size; }
605 
606  using BaseType::operator[];
607  reference operator[](size_t i)
608  {
609  ASSERTL1(static_cast<size_type>(i) < this->num_elements(),
610  std::string("Element ") + std::to_string(i) +
611  std::string(" requested in an array of size ") +
612  std::to_string(this->num_elements()));
613  return (get())[i];
614  }
615 
616 
617  using BaseType::get;
618  element* get() { return this->m_data + this->m_offset; }
619 
620  using BaseType::data;
621  element* data() { return this->m_data + this->m_offset; }
622 
623  template<typename T1>
624  friend class NekVector;
625 
626  template<typename T1, typename T3>
627  friend class NekMatrix;
628 
629  friend class LinearSystem;
630 
631  protected:
633  BaseType(rhs)
634  {
635  boost::ignore_unused(a);
636  }
637 
638  void ChangeSize(size_t newSize)
639  {
640  ASSERTL1(newSize <= this->m_capacity, "Can't change an array size to something larger than its capacity.");
641  this->m_size = newSize;
642  }
643 
644  private:
645 
646  };
647 
648  /// \brief A 2D array.
649  template<typename DataType>
650  class Array<TwoD, DataType> : public Array<TwoD, const DataType>
651  {
652  public:
654  typedef typename BaseType::iterator iterator;
655  typedef typename BaseType::reference reference;
656  typedef typename BaseType::index index;
657  typedef typename BaseType::size_type size_type;
658  typedef typename BaseType::element element;
659 
660  public:
661  Array() :
662  BaseType()
663  {
664  }
665 
666  Array(size_t dim1Size, size_t dim2Size) :
667  BaseType(dim1Size, dim2Size)
668  {
669  }
670 
671  Array(size_t dim1Size, size_t dim2Size, const DataType& initValue) :
672  BaseType(dim1Size, dim2Size, initValue)
673  {
674  }
675 
676  Array(size_t dim1Size, size_t dim2Size, const DataType* data) :
677  BaseType(dim1Size, dim2Size, data)
678  {
679  }
680 
682  BaseType(rhs)
683  {
684  }
685 
687  {
688  BaseType::operator=(rhs);
689  return *this;
690  }
691 
692  using BaseType::begin;
693  iterator begin() { return this->m_data->begin(); }
694 
695  using BaseType::end;
696  iterator end() { return this->m_data->end(); }
697 
698  using BaseType::operator[];
699  reference operator[](index i) { return (*this->m_data)[i]; }
700 
701  using BaseType::get;
702  element* get() { return this->m_data->data(); }
703 
704  using BaseType::data;
705  element* data() { return this->m_data->data(); }
706 
707  private:
708 
709  };
710 
715 
716  template<typename T1, typename T2>
717  bool operator==(const Array<OneD, T1>& lhs, const Array<OneD, T2>& rhs)
718  {
719  if( lhs.num_elements() != rhs.num_elements() )
720  {
721  return false;
722  }
723 
724  if( lhs.data() == rhs.data() )
725  {
726  return true;
727  }
728 
729  for(unsigned int i = 0; i < lhs.num_elements(); ++i)
730  {
731  if( lhs[i] != rhs[i] )
732  {
733  return false;
734  }
735  }
736 
737  return true;
738  }
739 
740  template<typename T1, typename T2>
741  bool operator!=(const Array<OneD, T1>& lhs, const Array<OneD, T2>& rhs)
742  {
743  return !(lhs == rhs);
744  }
745 
746  template<typename DataType>
748  {
750  }
751 
752  template<typename DataType>
754  {
756  }
757 
758 // template<typename DataType>
759 // Array<OneD, DataType> operator+(const Array<OneD, DataType>& lhs, size_t offset)
760 // {
761 // return Array<OneD, DataType>::CreateWithOffset(lhs, offset);
762 // }
763 
764  template<typename ConstDataType, typename DataType>
766  {
767  if( dest.num_elements() != source.num_elements() )
768  {
769  dest = Array<OneD, DataType>(source.num_elements());
770  }
771 
772  std::copy(source.data(), source.data() + source.num_elements(), dest.data());
773  }
774 
775  template<typename ConstDataType, typename DataType>
776  void CopyArrayN(const Array<OneD, ConstDataType>& source, Array<OneD, DataType>& dest, unsigned int n)
777  {
778  if( dest.num_elements() != n )
779  {
780  dest = Array<OneD, DataType>(n);
781  }
782 
783  std::copy(source.data(), source.data() + n, dest.data());
784  }
785 
789 
791  const Array<TwoD, const NekDouble>& rhs,
794 
795  template<typename DataType>
797  {
798  return *lhs.m_data == *rhs.m_data;
799  }
800 
801  template<typename DataType>
803  {
804  return !(lhs == rhs);
805  }
806 
807  namespace LibUtilities
808  {
809  static std::vector<NekDouble> NullNekDoubleVector;
810  static std::vector<unsigned int> NullUnsignedIntVector;
811  static std::vector<std::vector<NekDouble> > NullVectorNekDoubleVector
812  = { NullNekDoubleVector };
813  }
814 }
815 
816 #endif //NEKTAR_LIB_UTILITIES_BASIC_UTILS_SHARED_ARRAY_HPP
Array(size_t dim1Size, size_t dim2Size)
Array(size_t dim1Size, size_t dim2Size)
Constructs a 2 dimensional array. The elements of the array are not initialized.
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
std::shared_ptr< boost::multi_array_ref< DataType, Dim::Value > > CreateStorage(const ExtentListType &extent)
size_t GetCount() const
Returns the array&#39;s reference counter.
Array(const Array< TwoD, DataType > &rhs)
Array(size_t dim1Size, const DataType *data)
Creates a 1D array a copies data into it.
static Array< OneD, NekDouble > NullNekDouble1DArray
const element * get() const
Returns a c-style pointer to the underlying array.
Array(size_t dim1Size, size_t dim2Size, const DataType &initValue)
Array(const Array< OneD, DataType > &rhs)
Array(const Array< TwoD, const DataType > &rhs)
2D array with garbage collection and bounds checking.
Array(size_t dim1Size, size_t dim2Size, const DataType *data)
static void RawDeallocate(DataType *array, size_t NumberOfElements)
Deallocates memory allocated from RawAllocate.
Array()
Creates an empty array.
Definition: SharedArray.hpp:79
static DataType * RawAllocate(size_t NumberOfElements)
Allocates a chunk of raw, uninitialized memory, capable of holding NumberOfElements objects...
ArrayType::const_reference const_reference
Array< TwoD, DataType > & operator=(const Array< TwoD, DataType > &rhs)
Array(size_t dim1Size, const Array< OneD, DataType > &rhs)
Array(size_t dim1Size)
Creates an array of size dim1Size.
Definition: SharedArray.hpp:97
void ChangeSize(size_t newSize)
static Array< OneD, T > CreateWithOffset(const Array< OneD, T > &rhs, size_t offset)
def copy(self)
Definition: pycml.py:2663
bool operator==(const Array< OneD, NekDouble > &lhs, const Array< OneD, NekDouble > &rhs)
size_t GetOffset() const
Returns the array&#39;s offset.
bool Overlaps(const Array< OneD, const DataType > &rhs) const
Returns true is this array and rhs overlap.
size_t num_dimensions() const
Returns 1.
Array(const Array< OneD, const DataType > &rhs)
Array(size_t dim1Size, const DataType &initValue)
Creates a 1D array with each element initialized to an initial value.
StandardMatrixTag & lhs
BaseType::size_type size_type
const element * data() const
Returns a c-style pointer to the underlying array.
std::shared_ptr< ArrayType > m_data
Array(size_t dim1Size, const DataType &initValue)
static std::vector< NekDouble > NullNekDoubleVector
Array< TwoD, const DataType > & operator=(const Array< TwoD, const DataType > &rhs)
Array< OneD, const DataType > & operator=(const Array< OneD, const DataType > &rhs)
Creates a reference to rhs.
static const NekDouble kNekZeroTol
boost::multi_array_ref< DataType, 2 > ArrayType
Array(size_t dim1Size, size_t dim2Size, const DataType &initValue)
AllowWrappingOfConstArrays
const_reference operator[](index i) const
Array(const Array< OneD, const DataType > &rhs)
Creates a reference to rhs.
bool operator!=(const Array< OneD, T1 > &lhs, const Array< OneD, T2 > &rhs)
#define LIB_UTILITIES_EXPORT
void CopyArrayN(const Array< OneD, ConstDataType > &source, Array< OneD, DataType > &dest, unsigned int n)
static std::vector< std::vector< NekDouble > > NullVectorNekDoubleVector
static std::vector< unsigned int > NullUnsignedIntVector
Array< OneD, const DataType > BaseType
double NekDouble
static Array< OneD, DataType > CreateWithOffset(const Array< OneD, DataType > &rhs, unsigned int offset)
void CopyArray(const Array< OneD, ConstDataType > &source, Array< OneD, DataType > &dest)
Array(size_t dim1Size, const DataType *data)
BaseType::reference reference
BaseType::size_type size_type
Array(size_t dim1Size, const Array< OneD, const DataType > &rhs)
Creates a 1D array that references rhs.
const_reference operator[](size_t i) const
ArrayType::const_iterator const_iterator
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs
Array< OneD, const DataType >::const_iterator begin() const
BaseType::reference reference
size_t num_elements() const
Returns the array&#39;s size.
static Array< OneD, Array< OneD, NekDouble > > NullNekDoubleArrayofArray
static Array< OneD, int > NullInt1DArray
Array< OneD, DataType > & operator=(const Array< OneD, DataType > &rhs)
1D Array of constant elements with garbage collection and bounds checking.
Definition: SharedArray.hpp:57
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
Definition: ErrorUtil.hpp:250
Array(const Array< OneD, const DataType > &rhs, AllowWrappingOfConstArrays a)
Array< OneD, DataType > operator+(const Array< OneD, DataType > &lhs, size_t offset)
reference operator[](size_t i)
Array< TwoD, const DataType > BaseType
Array(size_t dim1Size, size_t dim2Size, const DataType *data)
Array(size_t dim1Size, const Array< OneD, const DataType > &rhs)
bool IsEqual(const Array< OneD, const NekDouble > &lhs, const Array< OneD, const NekDouble > &rhs, NekDouble tol)
const size_type * shape() const