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
44
45#include <boost/core/ignore_unused.hpp>
46#include <boost/multi_array.hpp>
47
48namespace Nektar
49{
50class LinearSystem;
51
52// Forward declaration for a ConstArray constructor.
53template <typename Dim, typename DataType> class Array;
54
55/// \brief 1D Array of constant elements with garbage collection and bounds
56/// checking.
57template <typename DataType> class Array<OneD, const DataType>
58{
59#ifdef WITH_PYTHON
60 struct PythonInfo
61 {
62 void *m_pyObject; // Underlying PyObject pointer
63 void (*m_callback)(void *); // Callback
64 };
65#endif
66public:
67 typedef DataType *ArrayType;
68
69 typedef const DataType &const_reference;
70 typedef DataType &reference;
71
72 typedef const DataType *const_iterator;
73 typedef DataType *iterator;
74
75 typedef DataType element;
76 typedef size_t size_type;
77
78public:
79 /// \brief Creates an empty array.
81 :
82#ifdef WITH_PYTHON
83 m_pythonInfo(nullptr),
84#endif
85 m_size(0), m_capacity(0), m_data(nullptr), m_count(nullptr),
86 m_offset(0)
87 {
88 CreateStorage(m_capacity);
89 }
90
91 /// \brief Creates an array of size dim1Size.
92 ///
93 /// If DataType is a fundamental type (double, int, etc.), then the
94 /// allocated array is uninitialized. If it is any other type, each element
95 /// is initialized with DataType's default constructor.
96 explicit Array(size_type dim1Size)
97 :
98#ifdef WITH_PYTHON
99 m_pythonInfo(nullptr),
100#endif
101 m_size(dim1Size), m_capacity(dim1Size), m_data(nullptr),
102 m_count(nullptr), m_offset(0)
103 {
104 CreateStorage(m_capacity);
106 }
107
108 /// \brief Creates a 1D array with each element
109 /// initialized to an initial value.
110 /// \param dim1Size The array's size.
111 /// \param initValue Each element's initial value.
112 ///
113 /// If DataType is a fundamental type (double, int, etc.),
114 /// then the initial value is copied directly into each
115 /// element. Otherwise, the DataType's copy constructor
116 /// is used to initialize each element.
117 Array(size_type dim1Size, const DataType &initValue)
118 :
119#ifdef WITH_PYTHON
120 m_pythonInfo(nullptr),
121#endif
122 m_size(dim1Size), m_capacity(dim1Size), m_data(nullptr),
123 m_count(nullptr), m_offset(0)
124 {
125 CreateStorage(m_capacity);
127 initValue);
128 }
129
130 /// \brief Creates a 1D array a copies data into it.
131 /// \param dim1Size the array's size.
132 /// \param data The data to copy.
133 ///
134 /// If DataType is a fundamental type (double, int, etc.), then data is
135 /// copied directly into the underlying storage. Otherwise, the DataType's
136 /// copy constructor is used to copy each element.
137 Array(size_type dim1Size, const DataType *data)
138 :
139#ifdef WITH_PYTHON
140 m_pythonInfo(nullptr),
141#endif
142 m_size(dim1Size), m_capacity(dim1Size), m_data(nullptr),
143 m_count(nullptr), m_offset(0)
144 {
145 CreateStorage(m_capacity);
147 data);
148 }
149
150 /// \brief Creates a 1D array that references rhs.
151 /// \param dim1Size The size of the array. This is useful
152 /// when you want this array to reference
153 /// a subset of the elements in rhs.
154 /// \param rhs Array to reference.
155 /// This constructor creates an array that references rhs.
156 /// Any changes to rhs will be reflected in this array.
157 /// The memory for the array will only be deallocated when
158 /// both rhs and this array have gone out of scope.
160 :
161#ifdef WITH_PYTHON
162 m_pythonInfo(rhs.m_pythonInfo),
163#endif
164 m_size(dim1Size), m_capacity(rhs.m_capacity), m_data(rhs.m_data),
165 m_count(rhs.m_count), m_offset(rhs.m_offset)
166 {
167 *m_count += 1;
168 ASSERTL0(m_size <= rhs.size(), "Requested size is \
169 larger than input array size.");
170 }
171
172#ifdef WITH_PYTHON
173 /// \brief Creates a 1D array a copies data into it.
174 /// \param dim1Size the array's size.
175 /// \param data The data to reference.
176 /// \param memory_pointer Pointer to the memory address of the array
177 /// \param python_decrement Pointer to decrementer
178 Array(size_type dim1Size, DataType *data, void *memory_pointer,
179 void (*python_decrement)(void *))
180 : m_size(dim1Size), m_capacity(dim1Size), m_data(data),
181 m_count(nullptr), m_offset(0)
182 {
183 m_count = new size_type();
184 *m_count = 1;
185
186 m_pythonInfo = new PythonInfo *();
187 *m_pythonInfo = new PythonInfo();
188 (*m_pythonInfo)->m_callback = python_decrement;
189 (*m_pythonInfo)->m_pyObject = memory_pointer;
190 }
191#endif
192
193 /// \brief Creates a reference to rhs.
195 :
196#ifdef WITH_PYTHON
197 m_pythonInfo(rhs.m_pythonInfo),
198#endif
199 m_size(rhs.m_size), m_capacity(rhs.m_capacity), m_data(rhs.m_data),
200 m_count(rhs.m_count), m_offset(rhs.m_offset)
201 {
202 *m_count += 1;
203 }
204
205// Disable use-after-free warning with these two functions as it appears to be
206// incorrectly triggered in GCC 12.2.
207#if __GNUC__ == 12 && __GNUC_MINOR__ == 2
208#pragma GCC diagnostic push
209#pragma GCC diagnostic ignored "-Wuse-after-free"
210#endif
212 {
213 if (m_count == nullptr)
214 {
215 return;
216 }
217
218 *m_count -= 1;
219 if (*m_count == 0)
220 {
221#ifdef WITH_PYTHON
222 if (*m_pythonInfo == nullptr)
223 {
225 MemoryManager<DataType>::RawDeallocate(m_data, m_capacity);
226 }
227 else
228 {
229 (*m_pythonInfo)->m_callback((*m_pythonInfo)->m_pyObject);
230 delete *m_pythonInfo;
231 }
232
233 delete m_pythonInfo;
234 m_pythonInfo = nullptr;
235#else
236
238 MemoryManager<DataType>::RawDeallocate(m_data, m_capacity);
239
240#endif
241
242 delete m_count; // Clean up the memory used for the reference count.
243 m_count = nullptr;
244 }
245 }
246
247 /// \brief Creates a reference to rhs.
250 {
251 *m_count -= 1;
252 if (*m_count == 0)
253 {
254#ifdef WITH_PYTHON
255 if (*m_pythonInfo == nullptr)
256 {
258 MemoryManager<DataType>::RawDeallocate(m_data, m_capacity);
259 }
260 else if ((*rhs.m_pythonInfo) != nullptr &&
261 (*m_pythonInfo)->m_pyObject !=
262 (*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 m_pythonInfo = nullptr;
270#else
271
273 MemoryManager<DataType>::RawDeallocate(m_data, m_capacity);
274#endif
275 delete m_count; // Clean up the memory used for the reference count.
276 m_count = nullptr;
277 }
278
279 m_data = rhs.m_data;
280 m_capacity = rhs.m_capacity;
281 m_count = rhs.m_count;
282 *m_count += 1;
283 m_offset = rhs.m_offset;
284 m_size = rhs.m_size;
285#ifdef WITH_PYTHON
286 m_pythonInfo = rhs.m_pythonInfo;
287#endif
288 return *this;
289 }
290#if __GNUC__ == 12 && __GNUC_MINOR__ == 2
291#pragma GCC diagnostic pop
292#endif
293
295 {
296 return m_data + m_offset;
297 }
299 {
300 return m_data + m_offset + m_size;
301 }
302
304 {
305 ASSERTL1(i < m_size,
306 std::string("Element ") + std::to_string(i) +
307 std::string(" requested in an array of size ") +
308 std::to_string(m_size));
309 return *(m_data + i + m_offset);
310 }
311
312 /// \brief Returns a c-style pointer to the underlying array.
313 const element *get() const
314 {
315 return m_data + m_offset;
316 }
317
318 /// \brief Returns a c-style pointer to the underlying array.
319 const element *data() const
320 {
321 return m_data + m_offset;
322 }
323
324 /// \brief Returns 1.
326 {
327 return 1;
328 }
329
330 /// \brief Returns the array's size.
332 {
333 return m_size;
334 }
335
336 /// \brief Returns the array's size.
337 /// Deprecated
338 DEPRECATED(5.1.0, size) size_type num_elements() const
339 {
340 WARNINGL1(false, "member function num_elements() is deprecated, "
341 "use size() instead.");
342 return m_size;
343 }
344
345 /// \brief Returns the array's capacity.
347 {
348 return m_capacity;
349 }
350
351 /// \brief Returns the array's offset.
353 {
354 return m_offset;
355 }
356
357 /// \brief Returns the array's reference counter.
359 {
360 return *m_count;
361 }
362
363 /// \brief Returns true is this array and rhs overlap.
365 {
366 const element *start = get();
367 const element *end = start + m_size;
368
369 const element *rhs_start = rhs.get();
370 const element *rhs_end = rhs_start + rhs.size();
371
372 return (rhs_start >= start && rhs_start <= end) ||
373 (rhs_end >= start && rhs_end <= end);
374 }
375
376#ifdef WITH_PYTHON
377 bool IsPythonArray()
378 {
379 return *m_pythonInfo != nullptr;
380 }
381
382 void ToPythonArray(void *memory_pointer, void (*python_decrement)(void *))
383 {
384 *m_pythonInfo = new PythonInfo();
385 (*m_pythonInfo)->m_callback = python_decrement;
386 (*m_pythonInfo)->m_pyObject = memory_pointer;
387 }
388#endif
389
390 /// \brief Creates an array with a specified offset.
391 ///
392 /// The return value will reference the same array as lhs,
393 /// but with an offset.
394 ///
395 /// For example, in the following:
396 /// \code
397 /// Array<OneD, const double> result = anArray + 10;
398 /// \endcode
399 /// result[0] == anArray[10];
400 template <typename T>
402 typename Array<OneD, T>::size_type offset);
403
404 template <typename T>
406 const Array<OneD, T> &rhs);
407
408protected:
409#ifdef WITH_PYTHON
410 PythonInfo **m_pythonInfo;
411#endif
412
415 DataType *m_data;
416
417 // m_count points to an integer used as a reference count to this array's
418 // data (m_data). Previously, the reference count was stored in the first 4
419 // bytes of the m_data array.
421
423
424private:
426 {
427 DataType *storage = MemoryManager<DataType>::RawAllocate(size);
428 m_data = storage;
429
430 // Allocate an integer to hold the reference count. Note 1, all arrays
431 // that share this array's data (ie, point to m_data) will also share
432 // the m_count data. Note 2, previously m_count pointed to "(unsigned
433 // int*)storage".
434 m_count = new size_type();
435 *m_count = 1;
436#ifdef WITH_PYTHON
437 m_pythonInfo = new PythonInfo *();
438 *m_pythonInfo = nullptr;
439#endif
440 }
441
442 template <typename T>
444 size_type offset)
445 {
446 Array<OneD, T> result(rhs);
447 result.m_offset += offset;
448 result.m_size = rhs.m_size - offset;
449 return result;
450 }
451};
452
453/// \brief 2D array with garbage collection and bounds checking.
454template <typename DataType> class Array<TwoD, const DataType>
455{
456public:
457 typedef boost::multi_array_ref<DataType, 2> ArrayType;
458
459 typedef typename ArrayType::const_reference const_reference;
460 typedef typename ArrayType::reference reference;
461
462 typedef typename ArrayType::index index;
463 typedef typename ArrayType::const_iterator const_iterator;
464 typedef typename ArrayType::iterator iterator;
465
466 typedef typename ArrayType::element element;
467 typedef typename ArrayType::size_type size_type;
468
469public:
470 Array() : m_data(CreateStorage<DataType>(0, 0))
471 {
472 }
473
474 /// \brief Constructs a 2 dimensional array. The elements of the array are
475 /// not initialized.
476 Array(size_type dim1Size, size_type dim2Size)
477 : m_data(CreateStorage<DataType>(dim1Size, dim2Size))
478 {
480 m_data->num_elements());
481 }
482
483 Array(size_type dim1Size, size_type dim2Size, const DataType &initValue)
484 : m_data(CreateStorage<DataType>(dim1Size, dim2Size))
485 {
487 m_data->data(), m_data->num_elements(), initValue);
488 }
489
490 Array(size_type dim1Size, size_type dim2Size, const DataType *data)
491 : m_data(CreateStorage<DataType>(dim1Size, dim2Size))
492 {
494 m_data->data(), m_data->num_elements(), data);
495 }
496
497 Array(const Array<TwoD, const DataType> &rhs) : m_data(rhs.m_data)
498 {
499 }
500
503 {
504 m_data = rhs.m_data;
505 return *this;
506 }
507
509 {
510 return m_data->begin();
511 }
513 {
514 return m_data->end();
515 }
517 {
518 return (*m_data)[i];
519 }
520 const element *get() const
521 {
522 return m_data->data();
523 }
524 const element *data() const
525 {
526 return m_data->data();
527 }
529 {
530 return m_data->num_dimensions();
531 }
532 const size_type *shape() const
533 {
534 return m_data->shape();
535 }
536 // m_data is a shared_ptr to a boost::multi_array_ref
538 {
539 return m_data->num_elements();
540 }
541 // deprecated interface
542 DEPRECATED(5.1.0, size) size_type num_elements() 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 : BaseType(rhs)
707 {
708 boost::ignore_unused(a);
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:250
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:249
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:58
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:80
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:96
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.
DEPRECATED(5.1.0, size) size_type num_elements() const
Returns the array's size. Deprecated.
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)
DEPRECATED(5.1.0, size) size_type num_elements() const
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
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
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)