Arcane  v3.16.0.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
MultiArray2.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 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/* Tableau 2D à taille multiple. */
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 Classe de base des tableau 2D à taille multiple.
31 *
32 * Cette classe gère les tableaux 2D dont le nombre d'éléments de la
33 * deuxième dimension est variable.
34 * Par exemple:
35 * \code
36 * UniqueArray<Int32> sizes(3); // Tableau avec 3 éléments
37 * sizes[0] = 1; sizes[1] = 2; sizes[2] = 4;
38 * // Construit le tableau avec sizes comme tailles
39 * MultiArray2<Int32> v(sizes);
40 * info() << " size=" << v.dim1Size(); // affiche 3
41 * info() << " size[0]=" << v[0].size(); // affiche 1
42 * info() << " size[1]=" << v[1].size(); // affiche 2
43 * info() << " size[2]=" << v[2].size(); // affiche 4
44 * \endcode
45 *
46 * \note Les indices sont conservés via le type Int32.
47 * Le nombre total d'éléments du tableau est donc limité à 2^31
48 *
49 * Il est possible de redimensionner (via la méthode resize()) le
50 * tableau tout en conservant ses valeurs mais pour des raisons de performance, ces
51 * redimensionnements se font sur tout le tableau (il n'est pas possible
52 * de redimensionner uniquement pour un seul élément, par exemple v[5].resize(3)).
53 *
54 * Comme pour Array et Array2, les instances de cette classe ne sont
55 * pas copiables ni assignables. Pour obtenir cette fonctionnalité, il faut
56 * utiliser la classe SharedMultiArray2 pour une sémantique par référence
57 * ou UniqueMultiArray2 pour une sémantique par valeur.
58 */
59template <typename DataType>
60class MultiArray2
61{
62 public:
63
64 using ConstReferenceType = typename UniqueArray<DataType>::ConstReferenceType;
65 using ThatClass = MultiArray2<DataType>;
66
67 public:
68
69 MultiArray2() = default;
70 // TODO: Rendre accessible uniquement à UniqueMultiArray2 ou SharedMultiArray2
71 explicit MultiArray2(ConstArrayView<Int32> sizes)
72 {
73 _resize(sizes);
74 }
75
76 public:
77
78 MultiArray2(const ThatClass& rhs) = delete;
79 ThatClass& operator=(const ThatClass& rhs) = delete;
80
81 protected:
82
83 /*!
84 * \brief Constructeur de recopie.
85 * Méthode temporaire à supprimer une fois le constructeur et opérateur de recopie
86 * supprimé.
87 */
88 MultiArray2(const MultiArray2<DataType>& rhs, bool do_clone)
89 : m_buffer(do_clone ? rhs.m_buffer.clone() : rhs.m_buffer)
90 , m_indexes(do_clone ? rhs.m_indexes.clone() : rhs.m_indexes)
91 , m_sizes(do_clone ? rhs.m_sizes.clone() : rhs.m_sizes)
92 {
93 }
95 : m_buffer(aview.m_buffer)
96 , m_indexes(aview.m_indexes)
97 , m_sizes(aview.m_sizes)
98 {
99 }
100 explicit MultiArray2(const MemoryAllocationOptions& allocation_options)
101 : m_buffer(allocation_options)
102 , m_indexes(allocation_options)
103 , m_sizes(allocation_options)
104 {}
105 // TODO: Rendre accessible uniquement à UniqueMultiArray2 ou SharedMultiArray2
106 MultiArray2(const MemoryAllocationOptions& allocation_options, ConstArrayView<Int32> sizes)
107 : MultiArray2(allocation_options)
108 {
109 _resize(sizes);
110 }
111
112 public:
113
114 ArrayView<DataType> operator[](Integer i)
115 {
116 return ArrayView<DataType>(m_sizes[i], m_buffer.data() + (m_indexes[i]));
117 }
118 ConstArrayView<DataType> operator[](Integer i) const
119 {
120 return ConstArrayView<DataType>(m_sizes[i], m_buffer.data() + (m_indexes[i]));
121 }
122
123 public:
124
125 //! Nombre total d'éléments
126 Int32 totalNbElement() const { return m_buffer.size(); }
127
128 //! Supprime les éléments du tableau.
129 void clear()
130 {
131 m_buffer.clear();
132 m_indexes.clear();
133 m_sizes.clear();
134 }
135 //! Remplit les éléments du tableau avec la valeur \a v
136 void fill(const DataType& v)
137 {
138 m_buffer.fill(v);
139 }
140 DataType& at(Integer i, Integer j)
141 {
142 return m_buffer[m_indexes[i] + j];
143 }
144 ConstReferenceType at(Integer i, Integer j) const
145 {
146 return m_buffer[m_indexes[i] + j];
147 }
148 void setAt(Integer i, Integer j, ConstReferenceType v)
149 {
150 return m_buffer.setAt(m_indexes[i] + j, v);
151 }
152
153 public:
154
155 //! Nombre d'éléments suivant la première dimension
156 Int32 dim1Size() const { return m_indexes.size(); }
157
158 //! Tableau du nombre d'éléments suivant la deuxième dimension
159 ConstArrayView<Int32> dim2Sizes() const { return m_sizes; }
160
161 //! Opérateur de conversion vers une vue modifiable
163 {
164 return view();
165 }
166
167 //! Opérateur de conversion vers une vue constante.
169 {
170 return constView();
171 }
172
173 //! Vue modifiable du tableau
175 {
176 return MultiArray2View<DataType>(m_buffer, m_indexes, m_sizes);
177 }
178
179 //! Vue constante du tableau
181 {
182 return ConstMultiArray2View<DataType>(m_buffer, m_indexes, m_sizes);
183 }
184
185 //! Vue modifiable du tableau
187 {
188 return { m_buffer.smallSpan(), m_indexes, m_sizes };
189 }
190
191 //! Vue constante du tableau
193 {
194 return { m_buffer, m_indexes, m_sizes };
195 }
196
197 //! Vue constante du tableau
199 {
200 return { m_buffer.constSmallSpan(), m_indexes, m_sizes };
201 }
202
203 //! Vue du tableau sous forme de tableau 1D
205 {
206 return m_buffer.view();
207 }
208
209 //! Vue du tableau sous forme de tableau 1D
211 {
212 return m_buffer.constView();
213 }
214
215 //! Retaille le tableau avec comme nouvelles tailles \a new_sizes
217 {
218 if (new_sizes.empty()) {
219 clear();
220 }
221 else
222 _resize(new_sizes);
223 }
224
225 protected:
226
227 ConstArrayView<DataType> _value(Integer i) const
228 {
229 return ConstArrayView<DataType>(m_sizes[i], m_buffer.data() + m_indexes[i]);
230 }
231
232 protected:
233
234 void _resize(ConstArrayView<Int32> ar)
235 {
236 Integer size1 = ar.size();
237 // Calcule le nombre d'éléments total
238 // TODO: Vérifier qu'on ne dépasse pas la valeur max d'un Int32
239 Integer total_size = 0;
240 for (Integer i = 0; i < size1; ++i)
241 total_size += ar[i];
242
243 // Si on ne change pas le nombre total d'éléments, vérifie
244 // si le resize est nécessaire
245 if (total_size == totalNbElement() && size1 == m_indexes.size()) {
246 bool is_same = true;
247 for (Integer i = 0; i < size1; ++i)
248 if (m_sizes[i] != ar[i]) {
249 is_same = false;
250 break;
251 }
252 if (is_same)
253 return;
254 }
255
256 Integer old_size1 = m_indexes.size();
257
258 SharedArray<DataType> new_buffer(m_buffer.allocationOptions(), total_size);
259
260 // Recopie dans le nouveau tableau les valeurs de l'ancien.
261 if (old_size1 > size1)
262 old_size1 = size1;
263 Integer index = 0;
264 for (Integer i = 0; i < old_size1; ++i) {
265 Integer size2 = ar[i];
266 Integer old_size2 = m_sizes[i];
267 if (old_size2 > size2)
268 old_size2 = size2;
269 ConstArrayView<DataType> cav(_value(i));
270 for (Integer j = 0; j < old_size2; ++j)
271 new_buffer[index + j] = cav[j];
272 index += size2;
273 }
274 m_buffer = new_buffer;
275
276 m_indexes.resize(size1);
277 m_sizes.resize(size1);
278 for (Integer i2 = 0, index2 = 0; i2 < size1; ++i2) {
279 Integer size2 = ar[i2];
280 m_indexes[i2] = index2;
281 m_sizes[i2] = size2;
282 index2 += size2;
283 }
284 }
285
286 protected:
287
288 void _copy(const MultiArray2<DataType>& rhs, bool do_clone)
289 {
290 m_buffer = do_clone ? rhs.m_buffer.clone() : rhs.m_buffer;
291 m_indexes = do_clone ? rhs.m_indexes.clone() : rhs.m_indexes;
292 m_sizes = do_clone ? rhs.m_sizes.clone() : rhs.m_sizes;
293 }
294 void _copy(ConstMultiArray2View<DataType> aview)
295 {
296 m_buffer = aview.m_buffer;
297 m_indexes = aview.m_indexes;
298 m_sizes = aview.m_sizes;
299 }
300
301 private:
302
303 //! Tableau des Valeurs
304 SharedArray<DataType> m_buffer;
305 //! Tableau des indices dans \a m_buffer du premièr élément de la deuxième dimension
306 SharedArray<Int32> m_indexes;
307 //! Tableau des tailles de la deuxième dimension
308 SharedArray<Int32> m_sizes;
309};
310
311/*---------------------------------------------------------------------------*/
312/*---------------------------------------------------------------------------*/
313/*!
314 * \ingroup Collection
315 * \brief Tableau 2D à taille multiple avec sémantique par référence.
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 //! Clone le tableau
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 Tableau 2D à taille multiple avec sémantique par valeur.
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: Vérifier que \a view n'est pas dans ce tableau
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 //! Clone le tableau
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
Nombre d'éléments du vecteur.
Vue modifiable d'un tableau d'un type T.
const T * data() const
Accès à la racine du tableau hors toute protection.
void setAt(Int64 i, ConstReferenceType value)
Positionne l'élément d'indice i. Vérifie toujours les débordements.
Vue constante d'un tableau de type T.
constexpr bool empty() const noexcept
true si le tableau est vide (size()==0)
Vue constante sur un MultiArray2.
Vue sur un MultiArray2.
Options pour configurer les allocations.
Vue modifiable sur un MultiArray2.
Classe de base des tableau 2D à taille multiple.
Definition MultiArray2.h:61
void clear()
Supprime les éléments du tableau.
void resize(ConstArrayView< Int32 > new_sizes)
Retaille le tableau avec comme nouvelles tailles new_sizes.
MultiArray2(const MultiArray2< DataType > &rhs, bool do_clone)
Constructeur de recopie. Méthode temporaire à supprimer une fois le constructeur et opérateur de reco...
Definition MultiArray2.h:88
void fill(const DataType &v)
Remplit les éléments du tableau avec la valeur v.
MultiArray2View< DataType > view()
Vue modifiable du tableau.
JaggedSmallSpan< const DataType > constSpan() const
Vue constante du tableau.
ConstArrayView< Int32 > dim2Sizes() const
Tableau du nombre d'éléments suivant la deuxième dimension.
JaggedSmallSpan< const DataType > span() const
Vue constante du tableau.
JaggedSmallSpan< DataType > span()
Vue modifiable du tableau.
ConstMultiArray2View< DataType > constView() const
Vue constante du tableau.
Int32 totalNbElement() const
Nombre total d'éléments.
Int32 dim1Size() const
Nombre d'éléments suivant la première dimension.
ConstArrayView< DataType > viewAsArray() const
Vue du tableau sous forme de tableau 1D.
ArrayView< DataType > viewAsArray()
Vue du tableau sous forme de tableau 1D.
Tableau 2D à taille multiple avec sémantique par référence.
SharedMultiArray2< DataType > clone() const
Clone le tableau.
Tableau 2D à taille multiple avec sémantique par valeur.
UniqueMultiArray2< DataType > clone() const
Clone le tableau.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int32 Integer
Type représentant un entier.
std::int32_t Int32
Type entier signé sur 32 bits.