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/multi_array.hpp>
45
46namespace Nektar
47{
48class LinearSystem;
49
50// Forward declaration for a ConstArray constructor.
51template <typename Dim, typename DataType> class Array;
52
53/// \brief 1D Array of constant elements with garbage collection and bounds
54/// checking.
55template <typename DataType> class Array<OneD, const DataType>
56{
57#ifdef WITH_PYTHON
58 struct PythonInfo
59 {
60 void *m_pyObject; // Underlying PyObject pointer
61 void (*m_callback)(void *); // Callback
62 };
63#endif
64public:
65 typedef DataType *ArrayType;
66
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
76public:
77 /// \brief Creates an empty array.
79 :
80#ifdef WITH_PYTHON
81 m_pythonInfo(nullptr),
82#endif
83 m_size(0), m_capacity(0), m_data(nullptr), m_count(nullptr),
84 m_offset(0)
85 {
86 CreateStorage(m_capacity);
87 }
88
89 /// \brief Creates an array of size dim1Size.
90 ///
91 /// If DataType is a fundamental type (double, int, etc.), then the
92 /// allocated array is uninitialized. If it is any other type, each element
93 /// is initialized with DataType's default constructor.
94 explicit Array(size_type dim1Size)
95 :
96#ifdef WITH_PYTHON
97 m_pythonInfo(nullptr),
98#endif
99 m_size(dim1Size), m_capacity(dim1Size), m_data(nullptr),
100 m_count(nullptr), m_offset(0)
101 {
102 CreateStorage(m_capacity);
104 }
105
106 /// \brief Creates a 1D array with each element
107 /// initialized to an initial value.
108 /// \param dim1Size The array's size.
109 /// \param initValue Each element's initial value.
110 ///
111 /// If DataType is a fundamental type (double, int, etc.),
112 /// then the initial value is copied directly into each
113 /// element. Otherwise, the DataType's copy constructor
114 /// is used to initialize each element.
115 Array(size_type dim1Size, const DataType &initValue)
116 :
117#ifdef WITH_PYTHON
118 m_pythonInfo(nullptr),
119#endif
120 m_size(dim1Size), m_capacity(dim1Size), m_data(nullptr),
121 m_count(nullptr), m_offset(0)
122 {
123 CreateStorage(m_capacity);
125 initValue);
126 }
127
128 /// \brief Creates a 1D array a copies data into it.
129 /// \param dim1Size the array's size.
130 /// \param data The data to copy.
131 ///
132 /// If DataType is a fundamental type (double, int, etc.), then data is
133 /// copied directly into the underlying storage. Otherwise, the DataType's
134 /// copy constructor is used to copy each element.
135 Array(size_type dim1Size, const DataType *data)
136 :
137#ifdef WITH_PYTHON
138 m_pythonInfo(nullptr),
139#endif
140 m_size(dim1Size), m_capacity(dim1Size), m_data(nullptr),
141 m_count(nullptr), m_offset(0)
142 {
143 CreateStorage(m_capacity);
145 data);
146 }
147
148 /// \brief Creates a 1D array that references rhs.
149 /// \param dim1Size The size of the array. This is useful
150 /// when you want this array to reference
151 /// a subset of the elements in rhs.
152 /// \param rhs Array to reference.
153 /// This constructor creates an array that references rhs.
154 /// Any changes to rhs will be reflected in this array.
155 /// The memory for the array will only be deallocated when
156 /// both rhs and this array have gone out of scope.
158 :
159#ifdef WITH_PYTHON
160 m_pythonInfo(rhs.m_pythonInfo),
161#endif
162 m_size(dim1Size), m_capacity(rhs.m_capacity), m_data(rhs.m_data),
163 m_count(rhs.m_count), m_offset(rhs.m_offset)
164 {
165 *m_count += 1;
166 ASSERTL0(m_size <= rhs.size(), "Requested size is \
167 larger than input array size.");
168 }
169
170#ifdef WITH_PYTHON
171 /// \brief Creates a 1D array a copies data into it.
172 /// \param dim1Size the array's size.
173 /// \param data The data to reference.
174 /// \param memory_pointer Pointer to the memory address of the array
175 /// \param python_decrement Pointer to decrementer
176 Array(size_type dim1Size, DataType *data, void *memory_pointer,
177 void (*python_decrement)(void *))
178 : m_size(dim1Size), m_capacity(dim1Size), m_data(data),
179 m_count(nullptr), m_offset(0)
180 {
181 m_count = new size_type();
182 *m_count = 1;
183
184 m_pythonInfo = new PythonInfo *();
185 *m_pythonInfo = new PythonInfo();
186 (*m_pythonInfo)->m_callback = python_decrement;
187 (*m_pythonInfo)->m_pyObject = memory_pointer;
188 }
189#endif
190
191 /// \brief Creates a reference to rhs.
193 :
194#ifdef WITH_PYTHON
195 m_pythonInfo(rhs.m_pythonInfo),
196#endif
197 m_size(rhs.m_size), m_capacity(rhs.m_capacity), m_data(rhs.m_data),
198 m_count(rhs.m_count), m_offset(rhs.m_offset)
199 {
200 *m_count += 1;
201 }
202
203// Disable use-after-free warning with these two functions as it appears to be
204// incorrectly triggered in GCC 12.2.
205#if __GNUC__ == 12 && __GNUC_MINOR__ == 2
206#pragma GCC diagnostic push
207#pragma GCC diagnostic ignored "-Wuse-after-free"
208#endif
210 {
211 if (m_count == nullptr)
212 {
213 return;
214 }
215
216 *m_count -= 1;
217 if (*m_count == 0)
218 {
219#ifdef WITH_PYTHON
220 if (*m_pythonInfo == nullptr)
221 {
223 MemoryManager<DataType>::RawDeallocate(m_data, m_capacity);
224 }
225 else
226 {
227 (*m_pythonInfo)->m_callback((*m_pythonInfo)->m_pyObject);
228 delete *m_pythonInfo;
229 }
230
231 delete m_pythonInfo;
232 m_pythonInfo = nullptr;
233#else
234
236 MemoryManager<DataType>::RawDeallocate(m_data, m_capacity);
237
238#endif
239
240 delete m_count; // Clean up the memory used for the reference count.
241 m_count = nullptr;
242 }
243 }
244
245 /// \brief Creates a reference to rhs.
248 {
249 *m_count -= 1;
250 if (*m_count == 0)
251 {
252#ifdef WITH_PYTHON
253 if (*m_pythonInfo == nullptr)
254 {
256 MemoryManager<DataType>::RawDeallocate(m_data, m_capacity);
257 }
258 else if ((*rhs.m_pythonInfo) != nullptr &&
259 (*m_pythonInfo)->m_pyObject !=
260 (*rhs.m_pythonInfo)->m_pyObject)
261 {
262 (*m_pythonInfo)->m_callback((*m_pythonInfo)->m_pyObject);
263 delete *m_pythonInfo;
264 }
265
266 delete m_pythonInfo;
267 m_pythonInfo = nullptr;
268#else
269
271 MemoryManager<DataType>::RawDeallocate(m_data, m_capacity);
272#endif
273 delete m_count; // Clean up the memory used for the reference count.
274 m_count = nullptr;
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#if __GNUC__ == 12 && __GNUC_MINOR__ == 2
289#pragma GCC diagnostic pop
290#endif
291
293 {
294 return m_data + m_offset;
295 }
297 {
298 return m_data + m_offset + m_size;
299 }
300
302 {
303 ASSERTL1(i < m_size,
304 std::string("Element ") + std::to_string(i) +
305 std::string(" requested in an array of size ") +
306 std::to_string(m_size));
307 return *(m_data + i + m_offset);
308 }
309
310 /// \brief Returns a c-style pointer to the underlying array.
311 const element *get() const
312 {
313 return m_data + m_offset;
314 }
315
316 /// \brief Returns a c-style pointer to the underlying array.
317 const element *data() const
318 {
319 return m_data + m_offset;
320 }
321
322 /// \brief Returns 1.
324 {
325 return 1;
326 }
327
328 /// \brief Returns the array's size.
330 {
331 return m_size;
332 }
333
334 /// \brief Returns the array's size.
335 /// Deprecated
336 [[deprecated("since 5.1.0, use size() instead")]] size_type num_elements()
337 const
338 {
339 WARNINGL1(false, "member function num_elements() is deprecated, "
340 "use size() instead.");
341 return m_size;
342 }
343
344 /// \brief Returns the array's capacity.
346 {
347 return m_capacity;
348 }
349
350 /// \brief Returns the array's offset.
352 {
353 return m_offset;
354 }
355
356 /// \brief Returns the array's reference counter.
358 {
359 return *m_count;
360 }
361
362 /// \brief Returns true is this array and rhs overlap.
364 {
365 const element *start = get();
366 const element *end = start + m_size;
367
368 const element *rhs_start = rhs.get();
369 const element *rhs_end = rhs_start + rhs.size();
370
371 return (rhs_start >= start && rhs_start <= end) ||
372 (rhs_end >= start && rhs_end <= end);
373 }
374
375#ifdef WITH_PYTHON
376 bool IsPythonArray()
377 {
378 return *m_pythonInfo != nullptr;
379 }
380
381 void ToPythonArray(void *memory_pointer, void (*python_decrement)(void *))
382 {
383 *m_pythonInfo = new PythonInfo();
384 (*m_pythonInfo)->m_callback = python_decrement;
385 (*m_pythonInfo)->m_pyObject = memory_pointer;
386 }
387#endif
388
389 /// \brief Creates an array with a specified offset.
390 ///
391 /// The return value will reference the same array as lhs,
392 /// but with an offset.
393 ///
394 /// For example, in the following:
395 /// \code
396 /// Array<OneD, const double> result = anArray + 10;
397 /// \endcode
398 /// result[0] == anArray[10];
399 template <typename T>
401 typename Array<OneD, T>::size_type offset);
402
403 template <typename T>
405 const Array<OneD, T> &rhs);
406
407protected:
408#ifdef WITH_PYTHON
409 PythonInfo **m_pythonInfo;
410#endif
411
414 DataType *m_data;
415
416 // m_count points to an integer used as a reference count to this array's
417 // data (m_data). Previously, the reference count was stored in the first 4
418 // bytes of the m_data array.
420
422
423private:
425 {
426 DataType *storage = MemoryManager<DataType>::RawAllocate(size);
427 m_data = storage;
428
429 // Allocate an integer to hold the reference count. Note 1, all arrays
430 // that share this array's data (ie, point to m_data) will also share
431 // the m_count data. Note 2, previously m_count pointed to "(unsigned
432 // int*)storage".
433 m_count = new size_type();
434 *m_count = 1;
435#ifdef WITH_PYTHON
436 m_pythonInfo = new PythonInfo *();
437 *m_pythonInfo = nullptr;
438#endif
439 }
440
441 template <typename T>
443 size_type offset)
444 {
445 Array<OneD, T> result(rhs);
446 result.m_offset += offset;
447 result.m_size = rhs.m_size - offset;
448 return result;
449 }
450};
451
452/// \brief 2D array with garbage collection and bounds checking.
453template <typename DataType> class Array<TwoD, const DataType>
454{
455public:
456 typedef boost::multi_array_ref<DataType, 2> ArrayType;
457
458 typedef typename ArrayType::const_reference const_reference;
459 typedef typename ArrayType::reference reference;
460
461 typedef typename ArrayType::index index;
462 typedef typename ArrayType::const_iterator const_iterator;
463 typedef typename ArrayType::iterator iterator;
464
465 typedef typename ArrayType::element element;
466 typedef typename ArrayType::size_type size_type;
467
468public:
469 Array() : m_data(CreateStorage<DataType>(0, 0))
470 {
471 }
472
473 /// \brief Constructs a 2 dimensional array. The elements of the array are
474 /// not initialized.
475 Array(size_type dim1Size, size_type dim2Size)
476 : m_data(CreateStorage<DataType>(dim1Size, dim2Size))
477 {
479 m_data->num_elements());
480 }
481
482 Array(size_type dim1Size, size_type dim2Size, const DataType &initValue)
483 : m_data(CreateStorage<DataType>(dim1Size, dim2Size))
484 {
486 m_data->data(), m_data->num_elements(), initValue);
487 }
488
489 Array(size_type dim1Size, size_type dim2Size, const DataType *data)
490 : m_data(CreateStorage<DataType>(dim1Size, dim2Size))
491 {
493 m_data->data(), m_data->num_elements(), data);
494 }
495
496 Array(const Array<TwoD, const DataType> &rhs) : m_data(rhs.m_data)
497 {
498 }
499
502 {
503 m_data = rhs.m_data;
504 return *this;
505 }
506
508 {
509 return m_data->begin();
510 }
512 {
513 return m_data->end();
514 }
516 {
517 return (*m_data)[i];
518 }
519 const element *get() const
520 {
521 return m_data->data();
522 }
523 const element *data() const
524 {
525 return m_data->data();
526 }
528 {
529 return m_data->num_dimensions();
530 }
531 const size_type *shape() const
532 {
533 return m_data->shape();
534 }
535 // m_data is a shared_ptr to a boost::multi_array_ref
537 {
538 return m_data->num_elements();
539 }
540 // deprecated interface
541 [[deprecated("since 5.1.0, use size() instead")]] size_type num_elements()
542 const
543 {
544 WARNINGL1(false, "member function num_elements() is deprecated, "
545 "use size() instead.");
546 return m_data->num_elements();
547 }
548
550 {
551 return m_data->shape()[0];
552 }
554 {
555 return m_data->shape()[1];
556 }
557
558protected:
559 std::shared_ptr<ArrayType> m_data;
560
561private:
562};
563
565{
568
569/// \brief 1D Array
570///
571/// \ref pageNekArrays
572///
573/// Misc notes.
574///
575/// Through out the 1D Array class you will see things like "using
576/// BaseType::begin" and "using BaseType::end". This is necessary to bring the
577/// methods from the ConstArray into scope in Array class. Typically this is
578/// not necessary, but since we have method names which match those in the base
579/// class, the base class names are hidden. Therefore, we have to explicitly
580/// bring them into scope to use them.
581template <typename DataType>
582class Array<OneD, DataType> : public Array<OneD, const DataType>
583{
584public:
586 typedef typename BaseType::iterator iterator;
589 typedef typename BaseType::element element;
590
591public:
593 {
594 }
595
596 explicit Array(size_type dim1Size) : BaseType(dim1Size)
597 {
598 }
599
600 Array(size_type dim1Size, const DataType &initValue)
601 : BaseType(dim1Size, initValue)
602 {
603 }
604
605 Array(size_type dim1Size, const DataType *data) : BaseType(dim1Size, data)
606 {
607 }
608
609 Array(size_type dim1Size, DataType *data, bool WrapArray)
610 : BaseType(dim1Size, data, WrapArray)
611 {
612 }
613
615 : BaseType(dim1Size, rhs)
616 {
617 }
618
620 : BaseType(dim1Size, rhs.data())
621 {
622 }
623
625 {
626 }
627
629 : BaseType(rhs.size(), rhs.data())
630 {
631 }
632
633#ifdef WITH_PYTHON
634 Array(size_type dim1Size, DataType *data, void *memory_pointer,
635 void (*python_decrement)(void *))
636 : BaseType(dim1Size, data, memory_pointer, python_decrement)
637 {
638 }
639
640 void ToPythonArray(void *memory_pointer, void (*python_decrement)(void *))
641 {
642 BaseType::ToPythonArray(memory_pointer, python_decrement);
643 }
644#endif
645
647 {
648 BaseType::operator=(rhs);
649 return *this;
650 }
651
653 const Array<OneD, DataType> &rhs, unsigned int offset)
654 {
655 Array<OneD, DataType> result(rhs);
656 result.m_offset += offset;
657 result.m_size = rhs.m_size - offset;
658 return result;
659 }
660
662 {
664 }
666 {
667 return this->m_data + this->m_offset;
668 }
669
670 using BaseType::end;
672 {
673 return this->m_data + this->m_offset + this->m_size;
674 }
675
676 using BaseType::operator[];
678 {
679 ASSERTL1(static_cast<size_type>(i) < this->size(),
680 std::string("Element ") + std::to_string(i) +
681 std::string(" requested in an array of size ") +
682 std::to_string(this->size()));
683 return (get())[i];
684 }
685
686 using BaseType::get;
688 {
689 return this->m_data + this->m_offset;
690 }
691
692 using BaseType::data;
694 {
695 return this->m_data + this->m_offset;
696 }
697
698 template <typename T1> friend class NekVector;
699
700 template <typename T1, typename T3> friend class NekMatrix;
701
702 friend class LinearSystem;
703
704protected:
706 [[maybe_unused]] AllowWrappingOfConstArrays a)
707 : BaseType(rhs)
708 {
709 }
710
711 void ChangeSize(size_type newSize)
712 {
713 ASSERTL1(newSize <= this->m_capacity,
714 "Can't change an array size to something larger than its "
715 "capacity.");
716 this->m_size = newSize;
717 }
718
719private:
720};
721
722/// \brief A 2D array.
723template <typename DataType>
724class Array<TwoD, DataType> : public Array<TwoD, const DataType>
725{
726public:
728 typedef typename BaseType::iterator iterator;
730 typedef typename BaseType::index index;
732 typedef typename BaseType::element element;
733
734public:
736 {
737 }
738
739 Array(size_type dim1Size, size_type dim2Size) : BaseType(dim1Size, dim2Size)
740 {
741 }
742
743 Array(size_type dim1Size, size_type dim2Size, const DataType &initValue)
744 : BaseType(dim1Size, dim2Size, initValue)
745 {
746 }
747
748 Array(size_type dim1Size, size_type dim2Size, const DataType *data)
749 : BaseType(dim1Size, dim2Size, data)
750 {
751 }
752
754 {
755 }
756
758 {
759 BaseType::operator=(rhs);
760 return *this;
761 }
762
763 using BaseType::begin;
765 {
766 return this->m_data->begin();
767 }
768
769 using BaseType::end;
771 {
772 return this->m_data->end();
773 }
774
775 using BaseType::operator[];
777 {
778 return (*this->m_data)[i];
779 }
780
781 using BaseType::get;
783 {
784 return this->m_data->data();
785 }
786
787 using BaseType::data;
789 {
790 return this->m_data->data();
791 }
792
793private:
794};
795
796// compare whatever
797template <typename T>
798inline bool IsEqualImpl(const T &lhs, const T &rhs, std::false_type)
799{
800 return lhs == rhs;
801}
802
803// compare floating point value
804template <typename T>
805inline bool IsEqualImpl(const T &lhs, const T &rhs, std::true_type)
806{
807 return LibUtilities::IsRealEqual(lhs, rhs);
808}
809
810template <typename T> inline bool IsEqual(const T &lhs, const T &rhs)
811{
812 return IsEqualImpl(lhs, rhs, std::is_floating_point<T>());
813}
814
815template <typename T1, typename T2>
816bool operator==(const Array<OneD, T1> &lhs, const Array<OneD, T2> &rhs)
817{
818 if (lhs.size() != rhs.size())
819 {
820 return false;
821 }
822
823 if (lhs.data() == rhs.data())
824 {
825 return true;
826 }
827
828 typename Array<OneD, T1>::size_type size_value(lhs.size());
829 for (typename Array<OneD, T1>::size_type i = 0; i < size_value; ++i)
830 {
831 if (!IsEqual(lhs[i], rhs[i]))
832 {
833 return false;
834 }
835 }
836
837 return true;
838}
839
840template <typename T1, typename T2>
841bool operator!=(const Array<OneD, T1> &lhs, const Array<OneD, T2> &rhs)
842{
843 return !(lhs == rhs);
844}
845
846template <typename DataType>
848 const Array<OneD, DataType> &lhs,
849 typename Array<OneD, DataType>::size_type offset)
850{
852}
853
854template <typename DataType>
856 typename Array<OneD, DataType>::size_type offset,
857 const Array<OneD, DataType> &rhs)
858{
860}
861
862template <typename ConstDataType, typename DataType>
865{
866 if (dest.size() != source.size())
867 {
868 dest = Array<OneD, DataType>(source.size());
869 }
870
871 std::copy(source.data(), source.data() + source.size(), dest.data());
872}
873
874template <typename ConstDataType, typename DataType>
878{
879 if (dest.size() != n)
880 {
881 dest = Array<OneD, DataType>(n);
882 }
883
884 std::copy(source.data(), source.data() + n, dest.data());
885}
886
892
893// Temporary alias for 2D nested array.
894template <class T> using TensorOfArray2D = Array<OneD, Array<OneD, T>>;
895// Temporary alias for 3D nested array. Please note that the inner arrays
896// are not const declared. It is therefore suggested to use this alias with
897// caution.
898template <class T>
900// Temporary alias for 4D nested array. Please note that the inner arrays
901// are not const declared. It is therefore suggested to use this alias with
902// caution.
903template <class T>
905// Temporary alias for 5D nested array. Please note that the inner arrays
906// are not const declared. It is therefore suggested to use this alias with
907// caution.
908template <class T>
911
912template <typename T1, typename T2>
913bool operator==(const Array<TwoD, T1> &lhs, const Array<TwoD, T2> &rhs)
914{
915 if ((lhs.GetRows() != rhs.GetRows()) ||
916 (lhs.GetColumns() != rhs.GetColumns()))
917 {
918 return false;
919 }
920
921 if (lhs.data() == rhs.data())
922 {
923 return true;
924 }
925
926 for (typename Array<OneD, T1>::size_type i = 0; i < lhs.GetRows(); ++i)
927 {
928 for (typename Array<OneD, T1>::size_type j = 0; j < lhs.GetColumns();
929 ++j)
930 {
931 if (!IsEqual(lhs[i][j], rhs[i][j]))
932 {
933 return false;
934 }
935 }
936 }
937
938 return true;
939}
940
941template <typename T1, typename T2>
942bool operator!=(const Array<TwoD, T1> &lhs, const Array<TwoD, T2> &rhs)
943{
944 return !(lhs == rhs);
945}
946
947namespace LibUtilities
948{
949static std::vector<NekDouble> NullNekDoubleVector;
950static std::vector<unsigned int> NullUnsignedIntVector;
951static std::vector<std::vector<NekDouble>> NullVectorNekDoubleVector = {
953} // namespace LibUtilities
954} // namespace Nektar
955
956#endif // NEKTAR_LIB_UTILITIES_BASIC_UTILS_SHARED_ARRAY_HPP
#define WARNINGL1(condition, msg)
Definition: ErrorUtil.hpp:243
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:208
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:242
reference operator[](size_type i)
Array(size_type dim1Size, const Array< OneD, DataType > &rhs)
BaseType::reference reference
Array(size_type dim1Size, const DataType *data)
Array(const Array< OneD, const DataType > &rhs)
static Array< OneD, DataType > CreateWithOffset(const Array< OneD, DataType > &rhs, unsigned int offset)
Array(size_type dim1Size, DataType *data, bool WrapArray)
Array(const Array< OneD, const DataType > &rhs, AllowWrappingOfConstArrays a)
Array< OneD, constDataType >::const_iterator begin() const
BaseType::size_type size_type
Array(const Array< OneD, DataType > &rhs)
Array< OneD, const DataType > BaseType
Array(size_type dim1Size, const DataType &initValue)
Array(size_type dim1Size, const Array< OneD, const DataType > &rhs)
Array< OneD, DataType > & operator=(const Array< OneD, DataType > &rhs)
void ChangeSize(size_type newSize)
1D Array of constant elements with garbage collection and bounds checking.
Definition: SharedArray.hpp:56
friend Array< OneD, T > operator+(const Array< OneD, T > &lhs, typename Array< OneD, T >::size_type offset)
Creates an array with a specified offset.
Array(size_type dim1Size, const Array< OneD, const DataType > &rhs)
Creates a 1D array that references rhs.
size_type GetCount() const
Returns the array's reference counter.
Array(size_type dim1Size, const DataType *data)
Creates a 1D array a copies data into it.
Array()
Creates an empty array.
Definition: SharedArray.hpp:78
bool Overlaps(const Array< OneD, const DataType > &rhs) const
Returns true is this array and rhs overlap.
Array(size_type dim1Size)
Creates an array of size dim1Size.
Definition: SharedArray.hpp:94
size_type num_elements() const
Returns the array's size. Deprecated.
friend Array< OneD, T > operator+(typename Array< OneD, T >::size_type offset, const Array< OneD, T > &rhs)
const_reference operator[](size_type i) const
Array< OneD, const DataType > & operator=(const Array< OneD, const DataType > &rhs)
Creates a reference to rhs.
const element * get() const
Returns a c-style pointer to the underlying array.
size_type capacity() const
Returns the array's capacity.
Array(const Array< OneD, const DataType > &rhs)
Creates a reference to rhs.
size_type size() const
Returns the array's size.
size_type num_dimensions() const
Returns 1.
static Array< OneD, T > CreateWithOffset(const Array< OneD, T > &rhs, size_type offset)
size_type GetOffset() const
Returns the array's offset.
Array(size_type dim1Size, const DataType &initValue)
Creates a 1D array with each element initialized to an initial value.
const element * data() const
Returns a c-style pointer to the underlying array.
Array(const Array< TwoD, DataType > &rhs)
Array(size_type dim1Size, size_type dim2Size, const DataType *data)
BaseType::reference reference
Array(size_type dim1Size, size_type dim2Size)
Array(size_type dim1Size, size_type dim2Size, const DataType &initValue)
BaseType::size_type size_type
Array< TwoD, DataType > & operator=(const Array< TwoD, DataType > &rhs)
Array< TwoD, const DataType > BaseType
2D array with garbage collection and bounds checking.
Array< TwoD, const DataType > & operator=(const Array< TwoD, const DataType > &rhs)
Array(size_type dim1Size, size_type dim2Size, const DataType &initValue)
Array(size_type dim1Size, size_type dim2Size, const DataType *data)
ArrayType::const_reference const_reference
const size_type * shape() const
Array(size_type dim1Size, size_type dim2Size)
Constructs a 2 dimensional array. The elements of the array are not initialized.
std::shared_ptr< ArrayType > m_data
ArrayType::const_iterator const_iterator
boost::multi_array_ref< DataType, 2 > ArrayType
Array(const Array< TwoD, const DataType > &rhs)
const_reference operator[](index i) const
static DataType * RawAllocate(size_t NumberOfElements)
Allocates a chunk of raw, uninitialized memory, capable of holding NumberOfElements objects.
static void RawDeallocate(DataType *array, size_t NumberOfElements)
Deallocates memory allocated from RawAllocate.
def copy(self)
Definition: pycml.py:2663
static std::vector< unsigned int > NullUnsignedIntVector
static std::vector< std::vector< NekDouble > > NullVectorNekDoubleVector
static std::vector< NekDouble > NullNekDoubleVector
bool IsRealEqual(T1 &&lhs, T2 &&rhs, const unsigned int factor=NekConstants::kNekFloatCompFact)
compare reals of same type with relative tolerance
bool operator==(const Array< OneD, T1 > &lhs, const Array< OneD, T2 > &rhs)
AllowWrappingOfConstArrays
@ eVECTOR_WRAPPER
static Array< OneD, int > NullInt1DArray
Array< OneD, DataType > operator+(const Array< OneD, DataType > &lhs, typename Array< OneD, DataType >::size_type offset)
static Array< OneD, Array< OneD, NekDouble > > NullNekDoubleArrayOfArray
bool IsEqual(const T &lhs, const T &rhs)
static Array< OneD, Array< OneD, Array< OneD, NekDouble > > > NullNekDoubleTensorOfArray3D
bool IsEqualImpl(const T &lhs, const T &rhs, std::false_type)
void CopyArrayN(const Array< OneD, ConstDataType > &source, Array< OneD, DataType > &dest, typename Array< OneD, DataType >::size_type n)
static Array< OneD, NekDouble > NullNekDouble1DArray
std::shared_ptr< boost::multi_array_ref< DataType, Dim::Value > > CreateStorage(const ExtentListType &extent)
bool operator!=(const Array< OneD, T1 > &lhs, const Array< OneD, T2 > &rhs)
void CopyArray(const Array< OneD, ConstDataType > &source, Array< OneD, DataType > &dest)