Arcane  4.1.12.0
User documentation
Loading...
Searching...
No Matches
MultiArray2.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* MultiArray2.h (C) 2000-2025 */
9/* */
10/* Multi-sized 2D Array. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_UTILS_MULTIARRAY2_H
13#define ARCANE_UTILS_MULTIARRAY2_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arcane/utils/Array.h"
18#include "arcane/utils/MultiArray2View.h"
19
20/*---------------------------------------------------------------------------*/
21/*---------------------------------------------------------------------------*/
22
23namespace Arcane
24{
25
26/*---------------------------------------------------------------------------*/
27/*---------------------------------------------------------------------------*/
28/*!
29 * \ingroup Collection
30 * \brief Base class for multi-sized 2D arrays.
31 *
32 * This class manages 2D arrays where the number of elements in the
33 * second dimension is variable.
34 * For example:
35 * \code
36 * UniqueArray<Int32> sizes(3); // Array with 3 elements
37 * sizes[0] = 1; sizes[1] = 2; sizes[2] = 4;
38 * // Constructs the array with sizes as dimensions
39 * MultiArray2<Int32> v(sizes);
40 * info() << " size=" << v.dim1Size(); // displays 3
41 * info() << " size[0]=" << v[0].size(); // displays 1
42 * info() << " size[1]=" << v[1].size(); // displays 2
43 * info() << " size[2]=" << v[2].size(); // displays 4
44 * \endcode
45 *
46 * \note Indices are stored using the Int32 type.
47 * The total number of elements in the array is therefore limited to 2^31
48 *
49 * It is possible to resize (via the resize() method) the
50 * array while keeping its values, but for performance reasons, these
51 * resizes apply to the entire array (it is not possible
52 * to resize only a single element, for example v[5].resize(3)).
53 *
54 * Like Array and Array2, instances of this class are not copyable or assignable. To get this functionality, you must
55 * use the SharedMultiArray2 class for reference semantics
56 * or UniqueMultiArray2 for value semantics.
57 */
58template <typename DataType>
59class MultiArray2
60{
61 public:
62
63 using ConstReferenceType = typename UniqueArray<DataType>::ConstReferenceType;
64 using ThatClass = MultiArray2<DataType>;
65
66 public:
67
68 MultiArray2() = default;
69 // TODO: Make accessible only to UniqueMultiArray2 or SharedMultiArray2
70 explicit MultiArray2(ConstArrayView<Int32> sizes)
71 {
72 _resize(sizes);
73 }
74
75 public:
76
77 MultiArray2(const ThatClass& rhs) = delete;
78 ThatClass& operator=(const ThatClass& rhs) = delete;
79
80 protected:
81
82 /*!
83 * \brief Copy constructor.
84 * Temporary method to be removed once the copy constructor and copy operator
85 * are deleted.
86 */
87 MultiArray2(const MultiArray2<DataType>& rhs, bool do_clone)
88 : m_buffer(do_clone ? rhs.m_buffer.clone() : rhs.m_buffer)
89 , m_indexes(do_clone ? rhs.m_indexes.clone() : rhs.m_indexes)
90 , m_sizes(do_clone ? rhs.m_sizes.clone() : rhs.m_sizes)
91 {
92 }
94 : m_buffer(aview.m_buffer)
95 , m_indexes(aview.m_indexes)
96 , m_sizes(aview.m_sizes)
97 {
98 }
99 explicit MultiArray2(const MemoryAllocationOptions& allocation_options)
100 : m_buffer(allocation_options)
101 , m_indexes(allocation_options)
102 , m_sizes(allocation_options)
103 {}
104 // TODO: Make accessible only to UniqueMultiArray2 or SharedMultiArray2
105 MultiArray2(const MemoryAllocationOptions& allocation_options, ConstArrayView<Int32> sizes)
106 : MultiArray2(allocation_options)
107 {
108 _resize(sizes);
109 }
110
111 public:
112
113 ArrayView<DataType> operator[](Integer i)
114 {
115 return ArrayView<DataType>(m_sizes[i], m_buffer.data() + (m_indexes[i]));
116 }
117 ConstArrayView<DataType> operator[](Integer i) const
118 {
119 return ConstArrayView<DataType>(m_sizes[i], m_buffer.data() + (m_indexes[i]));
120 }
121
122 public:
123
124 //! Total number of elements
125 Int32 totalNbElement() const { return m_buffer.size(); }
126
127 //! Clears the array elements.
128 void clear()
129 {
130 m_buffer.clear();
131 m_indexes.clear();
132 m_sizes.clear();
133 }
134 //! Fills the array elements with the value \a v
135 void fill(const DataType& v)
136 {
137 m_buffer.fill(v);
138 }
139 DataType& at(Integer i, Integer j)
140 {
141 return m_buffer[m_indexes[i] + j];
142 }
143 ConstReferenceType at(Integer i, Integer j) const
144 {
145 return m_buffer[m_indexes[i] + j];
146 }
147 void setAt(Integer i, Integer j, ConstReferenceType v)
148 {
149 return m_buffer.setAt(m_indexes[i] + j, v);
150 }
151
152 public:
153
154 //! Number of elements following the first dimension
155 Int32 dim1Size() const { return m_indexes.size(); }
156
157 //! Array of the number of elements following the second dimension
158 ConstArrayView<Int32> dim2Sizes() const { return m_sizes; }
159
160 //! Conversion operator to a mutable view
162 {
163 return view();
164 }
165
166 //! Conversion operator to a constant view.
168 {
169 return constView();
170 }
171
172 //! Mutable view of the array
174 {
175 return MultiArray2View<DataType>(m_buffer, m_indexes, m_sizes);
176 }
177
178 //! Constant view of the array
180 {
181 return ConstMultiArray2View<DataType>(m_buffer, m_indexes, m_sizes);
182 }
183
184 //! Mutable view of the array
186 {
187 return { m_buffer.smallSpan(), m_indexes, m_sizes };
188 }
189
190 //! Constant view of the array
192 {
193 return { m_buffer, m_indexes, m_sizes };
194 }
195
196 //! Constant view of the array
198 {
199 return { m_buffer.constSmallSpan(), m_indexes, m_sizes };
200 }
201
202 //! View of the array as a 1D array
204 {
205 return m_buffer.view();
206 }
207
208 //! View of the array as a 1D array
210 {
211 return m_buffer.constView();
212 }
213
214 //! Resizes the array with new sizes \a new_sizes
216 {
217 if (new_sizes.empty()) {
218 clear();
219 }
220 else
221 _resize(new_sizes);
222 }
223
224 protected:
225
226 ConstArrayView<DataType> _value(Integer i) const
227 {
228 return ConstArrayView<DataType>(m_sizes[i], m_buffer.data() + m_indexes[i]);
229 }
230
231 protected:
232
233 void _resize(ConstArrayView<Int32> ar)
234 {
235 Integer size1 = ar.size();
236 // Calculates the total number of elements
237 // TODO: Check that we do not exceed the max value of an Int32
238 Integer total_size = 0;
239 for (Integer i = 0; i < size1; ++i)
240 total_size += ar[i];
241
242 // If the total number of elements does not change, check
243 // if the resize is necessary
244 if (total_size == totalNbElement() && size1 == m_indexes.size()) {
245 bool is_same = true;
246 for (Integer i = 0; i < size1; ++i)
247 if (m_sizes[i] != ar[i]) {
248 is_same = false;
249 break;
250 }
251 if (is_same)
252 return;
253 }
254
255 Integer old_size1 = m_indexes.size();
256
257 SharedArray<DataType> new_buffer(m_buffer.allocationOptions(), total_size);
258
259 // Copies the values from the old array to the new one.
260 if (old_size1 > size1)
261 old_size1 = size1;
262 Integer index = 0;
263 for (Integer i = 0; i < old_size1; ++i) {
264 Integer size2 = ar[i];
265 Integer old_size2 = m_sizes[i];
266 if (old_size2 > size2)
267 old_size2 = size2;
268 ConstArrayView<DataType> cav(_value(i));
269 for (Integer j = 0; j < old_size2; ++j)
270 new_buffer[index + j] = cav[j];
271 index += size2;
272 }
273 m_buffer = new_buffer;
274
275 m_indexes.resize(size1);
276 m_sizes.resize(size1);
277 for (Integer i2 = 0, index2 = 0; i2 < size1; ++i2) {
278 Integer size2 = ar[i2];
279 m_indexes[i2] = index2;
280 m_sizes[i2] = size2;
281 index2 += size2;
282 }
283 }
284
285 protected:
286
287 void _copy(const MultiArray2<DataType>& rhs, bool do_clone)
288 {
289 m_buffer = do_clone ? rhs.m_buffer.clone() : rhs.m_buffer;
290 m_indexes = do_clone ? rhs.m_indexes.clone() : rhs.m_indexes;
291 m_sizes = do_clone ? rhs.m_sizes.clone() : rhs.m_sizes;
292 }
293 void _copy(ConstMultiArray2View<DataType> aview)
294 {
295 m_buffer = aview.m_buffer;
296 m_indexes = aview.m_indexes;
297 m_sizes = aview.m_sizes;
298 }
299
300 private:
301
302 //! Array of Values
303 SharedArray<DataType> m_buffer;
304 //! Array of indices in \a m_buffer of the first element of the second dimension
305 SharedArray<Int32> m_indexes;
306 //! Array of sizes of the second dimension
307 SharedArray<Int32> m_sizes;
308};
309
310/*---------------------------------------------------------------------------*/
311/*---------------------------------------------------------------------------*/
312
313/*!
314 * \ingroup Collection
315 * \brief Multi-sized 2D array with reference semantics.
316 */
317template <typename DataType>
318class SharedMultiArray2
319: public MultiArray2<DataType>
320{
321 public:
322
323 using ThatClass = SharedMultiArray2<DataType>;
324
325 public:
326
327 SharedMultiArray2() = default;
328 explicit SharedMultiArray2(ConstArrayView<Int32> sizes)
329 : MultiArray2<DataType>(sizes)
330 {}
331 SharedMultiArray2(ConstMultiArray2View<DataType> view)
332 : MultiArray2<DataType>(view)
333 {}
334 SharedMultiArray2(const SharedMultiArray2<DataType>& rhs)
335 : MultiArray2<DataType>(rhs, false)
336 {}
337 SharedMultiArray2(const UniqueMultiArray2<DataType>& rhs);
338
339 public:
340
341 ThatClass& operator=(const ThatClass& rhs)
342 {
343 if (&rhs != this)
344 this->_copy(rhs, false);
345 return (*this);
346 }
348 {
349 this->_copy(view);
350 }
351 ThatClass& operator=(const UniqueMultiArray2<DataType>& rhs);
352 void operator=(const MultiArray2<DataType>& rhs) = delete;
353
354 public:
355
356 //! Clones the array
357 SharedMultiArray2<DataType> clone() const
358 {
359 return SharedMultiArray2<DataType>(this->constView());
360 }
361
362 private:
363};
364
365/*---------------------------------------------------------------------------*/
366/*---------------------------------------------------------------------------*/
367
368/*!
369 * \ingroup Collection
370 * \brief Multi-sized 2D array with value semantics.
371 */
372template <typename DataType>
373class UniqueMultiArray2
374: public MultiArray2<DataType>
375{
376 public:
377
378 using ThatClass = UniqueMultiArray2<DataType>;
379
380 public:
381
382 UniqueMultiArray2() = default;
383 explicit UniqueMultiArray2(ConstArrayView<Int32> sizes)
384 : MultiArray2<DataType>(sizes)
385 {}
386 explicit UniqueMultiArray2(IMemoryAllocator* allocator)
387 : UniqueMultiArray2(MemoryAllocationOptions(allocator))
388 {}
389 explicit UniqueMultiArray2(const MemoryAllocationOptions& allocation_options)
390 : MultiArray2<DataType>(allocation_options)
391 {}
392 UniqueMultiArray2(const MemoryAllocationOptions& allocation_options,
394 : MultiArray2<DataType>(allocation_options, sizes)
395 {}
396 UniqueMultiArray2(ConstMultiArray2View<DataType> view)
397 : MultiArray2<DataType>(view)
398 {}
399 UniqueMultiArray2(const SharedMultiArray2<DataType>& rhs)
400 : MultiArray2<DataType>(rhs, true)
401 {}
402 UniqueMultiArray2(const UniqueMultiArray2<DataType>& rhs)
403 : MultiArray2<DataType>(rhs, true)
404 {}
405
406 public:
407
408 ThatClass& operator=(const SharedMultiArray2<DataType>& rhs)
409 {
410 this->_copy(rhs, true);
411 return (*this);
412 }
413 ThatClass& operator=(ConstMultiArray2View<DataType> view)
414 {
415 // TODO: Check that \a view is not in this array
416 this->_copy(view);
417 return (*this);
418 }
419 ThatClass& operator=(const UniqueMultiArray2<DataType>& rhs)
420 {
421 if (&rhs != this)
422 this->_copy(rhs, true);
423 return (*this);
424 }
425 ThatClass& operator=(const MultiArray2<DataType>& rhs) = delete;
426
427 public:
428
429 //! Clones the array
430 UniqueMultiArray2<DataType> clone() const
431 {
432 return UniqueMultiArray2<DataType>(this->constView());
433 }
434};
435
436/*---------------------------------------------------------------------------*/
437/*---------------------------------------------------------------------------*/
438
439template <typename DataType> SharedMultiArray2<DataType>::
440SharedMultiArray2(const UniqueMultiArray2<DataType>& rhs)
441: MultiArray2<DataType>(rhs, true)
442{}
443
444/*---------------------------------------------------------------------------*/
445/*---------------------------------------------------------------------------*/
446
449{
450 this->_copy(rhs, true);
451 return (*this);
452}
453
454/*---------------------------------------------------------------------------*/
455/*---------------------------------------------------------------------------*/
456
457} // namespace Arcane
458
459/*---------------------------------------------------------------------------*/
460/*---------------------------------------------------------------------------*/
461
462#endif
Integer size() const
Number of elements in the vector.
Modifiable view of an array of type T.
const T * data() const
Access to the root of the array without any protection.
void setAt(Int64 i, ConstReferenceType value)
Sets the element at index i. Always checks for overflows.
Constant view of an array of type T.
constexpr bool empty() const noexcept
true if the array is empty (size()==0)
Constant view on a MultiArray2.
View on a MultiArray2.
Modifiable view on a MultiArray2.
Base class for multi-sized 2D arrays.
Definition MultiArray2.h:60
void clear()
Clears the array elements.
void resize(ConstArrayView< Int32 > new_sizes)
Resizes the array with new sizes new_sizes.
MultiArray2(const MultiArray2< DataType > &rhs, bool do_clone)
Copy constructor. Temporary method to be removed once the copy constructor and copy operator are dele...
Definition MultiArray2.h:87
void fill(const DataType &v)
Fills the array elements with the value v.
MultiArray2View< DataType > view()
Mutable view of the array.
JaggedSmallSpan< const DataType > constSpan() const
Constant view of the array.
ConstArrayView< Int32 > dim2Sizes() const
Array of the number of elements following the second dimension.
JaggedSmallSpan< const DataType > span() const
Constant view of the array.
JaggedSmallSpan< DataType > span()
Mutable view of the array.
ConstMultiArray2View< DataType > constView() const
Constant view of the array.
Int32 totalNbElement() const
Total number of elements.
Int32 dim1Size() const
Number of elements following the first dimension.
ConstArrayView< DataType > viewAsArray() const
View of the array as a 1D array.
ArrayView< DataType > viewAsArray()
View of the array as a 1D array.
Multi-sized 2D array with reference semantics.
SharedMultiArray2< DataType > clone() const
Clones the array.
Multi-sized 2D array with value semantics.
UniqueMultiArray2< DataType > clone() const
Clones the array.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type representing an integer.
std::int32_t Int32
Signed integer type of 32 bits.