12#ifndef ARCCORE_COMMON_ABSTRACTARRAY_H
13#define ARCCORE_COMMON_ABSTRACTARRAY_H
19#include "arccore/common/ArrayTraits.h"
20#include "arccore/common/ArrayMetaData.h"
46class ARCCORE_COMMON_EXPORT AbstractArrayBase
54 virtual ~AbstractArrayBase() =
default;
60 return m_md->allocation_options.allocator();
64 return m_md->allocation_options;
100 std::swap(m_md, rhs.m_md);
101 std::swap(m_meta_data, rhs.m_meta_data);
102 _checkSetUseOwnMetaData();
103 rhs._checkSetUseOwnMetaData();
106 void _copyMetaData(
const AbstractArrayBase& rhs)
111 m_meta_data = rhs.m_meta_data;
113 _checkSetUseOwnMetaData();
116 void _allocateMetaData()
120 ArrayMetaData::throwNullExpected();
122 if (_isUseOwnMetaData()) {
123 m_meta_data = ArrayMetaData();
127 m_md =
new ArrayMetaData();
133 void _deallocateMetaData(ArrayMetaData* md)
135 if (md->is_allocated_by_new)
138 *md = ArrayMetaData();
141 void _checkValidSharedArray()
145 ArrayMetaData::throwInvalidMetaDataForSharedArray();
151 void _checkSetUseOwnMetaData()
169:
public AbstractArrayBase
173 typedef typename ArrayTraits<T>::ConstReferenceType ConstReferenceType;
174 typedef typename ArrayTraits<T>::IsPODType IsPODType;
199 typedef std::reverse_iterator<iterator> reverse_iterator;
200 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
229 static constexpr Int64 typeSize() {
return static_cast<Int64
>(
sizeof(T)); }
230 AllocatedMemoryInfo _currentMemoryInfo()
const
232 return AllocatedMemoryInfo(m_ptr, m_md->size * typeSize(), m_md->capacity * typeSize());
247 _createRange(0, asize, view.
data());
262 void* pre_allocated_buffer =
nullptr)
274 _internalDeallocate();
278 if (options.allocator() != m_md->_allocator())
289 operator Span<const T>()
const
291 return Span<const T>(m_ptr, m_md->
size);
293 operator SmallSpan<const T>()
const
295 return SmallSpan<const T>(m_ptr, ARCCORE_CAST_SMALL_SIZE(
size()));
301 Integer size()
const {
return ARCCORE_CAST_SMALL_SIZE(m_md->size); }
313 bool empty()
const {
return m_md->size == 0; }
317 const T* ptr = m_ptr;
318 for (
Int64 i = 0, n = m_md->size; i < n; ++i) {
330 ARCCORE_CHECK_AT(i, m_md->size);
336 ARCCORE_CHECK_AT(i, m_md->size);
345 m_md->_setMemoryLocationHint(new_hint, m_ptr,
sizeof(T));
356 m_md->_setHostDeviceMemoryLocation(location);
362 return m_md->allocation_options.hostDeviceMemoryLocation();
374 return !(rhs == lhs);
377 friend bool operator==(
const AbstractArray<T>& rhs,
const Span<const T>& lhs)
379 return operator==(Span<const T>(rhs), lhs);
382 friend bool operator!=(
const AbstractArray<T>& rhs,
const Span<const T>& lhs)
384 return !(rhs == lhs);
387 friend bool operator==(
const Span<const T>& rhs,
const AbstractArray<T>& lhs)
389 return operator==(rhs, Span<const T>(lhs));
392 friend bool operator!=(
const Span<const T>& rhs,
const AbstractArray<T>& lhs)
394 return !(rhs == lhs);
397 friend std::ostream& operator<<(std::ostream& o,
const AbstractArray<T>& val)
399 o << Span<const T>(val);
405 using AbstractArrayBase::m_meta_data;
428 template <
typename PodType>
431 if (_isSharedNull()) {
432 if (new_capacity != 0)
433 _internalAllocate(new_capacity, queue);
437 Int64 acapacity = new_capacity;
438 if (compute_capacity) {
439 acapacity = m_md->capacity;
441 while (new_capacity > acapacity)
442 acapacity = (acapacity == 0) ? 4 : (acapacity + 1 + acapacity / 2);
460 Int64 old_capacity = m_md->capacity;
461 _directReAllocate(new_capacity, queue);
462 bool update = (new_capacity < old_capacity) || (m_ptr != old_ptr);
474 Int64 old_size = m_md->size;
475 _directAllocate(new_capacity, queue);
476 if (m_ptr != old_ptr) {
477 for (
Int64 i = 0; i < old_size; ++i) {
478 new (m_ptr + i) T(old_ptr[i]);
481 m_md->nb_ref = old_md->
nb_ref;
482 m_md->_deallocate(old_mem_info, queue);
487 void _internalDeallocate(
RunQueue* queue =
nullptr)
489 if (!_isSharedNull())
490 m_md->_deallocate(_currentMemoryInfo(), queue);
492 _deallocateMetaData(m_md);
494 void _internalAllocate(Int64 new_capacity, RunQueue* queue)
496 _directAllocate(new_capacity, queue);
501 void _copyFromMemory(
const T* source)
503 m_md->_copyFromMemory(m_ptr, source,
sizeof(T),
_nullRunQueue());
517 void* pre_allocated_buffer =
nullptr)
520 if (!wanted_allocator) {
521 wanted_allocator = ArrayMetaData::_defaultAllocator();
522 options.setAllocator(wanted_allocator);
525 m_md->allocation_options = options;
526 if (new_capacity > 0) {
527 if (!pre_allocated_buffer)
528 _allocateMP(new_capacity, options.runQueue());
530 _setMPCast(pre_allocated_buffer);
541 _allocateMP(new_capacity, queue);
544 void _allocateMP(Int64 new_capacity, RunQueue* queue)
546 _setMPCast(m_md->_allocate(new_capacity, typeSize(), queue));
549 void _directReAllocate(
Int64 new_capacity, RunQueue* queue)
551 _setMPCast(m_md->_reallocate(_currentMemoryInfo(), new_capacity, typeSize(), queue));
556 void changeAllocator(
const MemoryAllocationOptions& options, RunQueue* queue)
558 _setMPCast(m_md->_changeAllocator(options, _currentMemoryInfo(), typeSize(), queue));
562 void changeAllocator(
const MemoryAllocationOptions& options)
564 _setMPCast(m_md->_changeAllocator(options, _currentMemoryInfo(), typeSize(),
_nullRunQueue()));
570 void printInfos(std::ostream& o)
572 o <<
" Infos: size=" << m_md->size <<
" capacity=" << m_md->capacity <<
'\n';
589 Int64 s = m_md->size;
590 if ((s + n) > m_md->capacity)
592 for (
Int64 i = 0; i < n; ++i)
593 new (m_ptr + s + i) T(val);
601 const T* ptr = val.
data();
602 Int64 s = m_md->size;
603 if ((s + n) > m_md->capacity)
605 _createRange(s, s + n, ptr);
612 if (m_md->nb_ref == 0) {
619 _destroyRange(0, m_md->
size, IsPODType());
621 void _destroyRange(Int64, Int64, TrueType)
625 void _destroyRange(
Int64 abegin,
Int64 aend, FalseType)
629 for (
Int64 i = abegin; i < aend; ++i)
632 void _createRangeDefault(
Int64,
Int64, TrueType)
635 void _createRangeDefault(
Int64 abegin,
Int64 aend, FalseType)
639 for (
Int64 i = abegin; i < aend; ++i)
642 void _createRange(
Int64 abegin,
Int64 aend, ConstReferenceType value, TrueType)
646 for (
Int64 i = abegin; i < aend; ++i)
649 void _createRange(
Int64 abegin,
Int64 aend, ConstReferenceType value, FalseType)
653 for (
Int64 i = abegin; i < aend; ++i)
654 new (m_ptr + i) T(value);
656 void _createRange(
Int64 abegin,
Int64 aend,
const T* values)
660 for (
Int64 i = abegin; i < aend; ++i) {
661 new (m_ptr + i) T(*values);
665 void _fill(ConstReferenceType value)
667 for (
Int64 i = 0, n =
size(); i < n; ++i)
670 void _clone(
const ThatClassType& orig_array)
672 Int64 that_size = orig_array.size();
674 m_md->size = that_size;
675 m_md->dim1_size = orig_array.m_md->dim1_size;
676 m_md->dim2_size = orig_array.m_md->dim2_size;
677 _createRange(0, that_size, orig_array.m_ptr);
679 template <
typename PodType>
680 void _resizeHelper(
Int64 s, PodType pod_type, RunQueue* queue)
684 if (s > m_md->size) {
686 this->_createRangeDefault(m_md->size, s, pod_type);
689 this->_destroyRange(s, m_md->size, pod_type);
693 void _resize(
Int64 s)
700 _resizeHelper(s,
TrueType{}, queue);
704 this->_destroyRange(0, m_md->
size, IsPODType());
712 if (s > m_md->size) {
714 this->_createRange(m_md->size, s, value, IsPODType());
717 this->_destroyRange(s, m_md->size, IsPODType());
721 void _copy(
const T* rhs_begin,
TrueType)
723 _copyFromMemory(rhs_begin);
725 void _copy(
const T* rhs_begin, FalseType)
727 for (Int64 i = 0, n = m_md->
size; i < n; ++i)
728 m_ptr[i] = rhs_begin[i];
730 void _copy(
const T* rhs_begin)
732 _copy(rhs_begin, IsPODType());
745 const T* rhs_begin = rhs.
data();
747 const Int64 current_size = m_md->size;
750 if (abegin >= rhs_begin && abegin < (rhs_begin + rhs_size))
751 ArrayMetaData::overlapError(abegin, m_md->size, rhs_begin, rhs_size);
753 if (rhs_size > current_size) {
756 this->_createRange(m_md->size, rhs_size, rhs_begin + current_size);
759 m_md->size = rhs_size;
762 this->_destroyRange(rhs_size, current_size, IsPODType{});
763 m_md->size = rhs_size;
775 void _move(ThatClassType& rhs) ARCCORE_NOEXCEPT
799 void _swap(ThatClassType& rhs) ARCCORE_NOEXCEPT
801 std::swap(m_ptr, rhs.m_ptr);
811 void _shrink(Int64 new_capacity)
816 if (new_capacity > this->
capacity())
818 if (new_capacity < 4)
836 if (asize > max_size)
838 asize =
static_cast<Integer>(max_size);
847 Span<const T> rhs_span(rhs);
848 if (rhs.allocator() == this->allocator()) {
862 void _setMP(TrueImpl* new_mp)
867 void _setMP2(TrueImpl* new_mp, ArrayMetaData* new_md)
873 if (!m_md->is_allocated_by_new)
879 return m_ptr ==
nullptr;
884 void _setToSharedNull()
887 m_meta_data = ArrayMetaData();
890 void _setMPCast(
void* p)
892 _setMP(
reinterpret_cast<TrueImpl*
>(p));
Types et fonctions associés aux classes SpanImpl, SmallSpan and Span.
Classe de base interne pour les tableaux.
static constexpr RunQueue * _nullRunQueue()
Méthode explicite pour une RunQueue nulle.
virtual bool _isUseOwnMetaData() const
Indique si m_md fait référence à m_meta_data.
Classe abstraite de base d'un vecteur.
void _addRange(ConstReferenceType val, Int64 n)
Ajoute n élément de valeur val à la fin du tableau.
Integer capacity() const
Capacité (nombre d'éléments alloués) du vecteur.
void _addRange(Span< const T > val)
Ajoute n élément de valeur val à la fin du tableau.
void _internalSetHostDeviceMemoryLocation(eHostDeviceMemoryLocation location)
Positionne l'emplacement physique de la zone mémoire.
virtual void _updateReferences()
Mise à jour des références.
const value_type * const_pointer
void _checkFreeMemory()
Détruit l'instance si plus personne ne la référence.
ConstReferenceType operator[](Int64 i) const
Elément d'indice i.
void dispose()
Libère la mémoire utilisée par le tableau.
AbstractArray()
Construit un vecteur vide avec l'allocateur par défaut.
Integer size() const
Nombre d'éléments du vecteur.
void _initFromSpan(const Span< const T > &view)
Initialise le tableau avec la vue view.
void _move(ThatClassType &rhs) ARCCORE_NOEXCEPT
Implémente l'opérateur d'assignement par déplacement.
void _initFromAllocator(MemoryAllocationOptions o, Int64 acapacity, void *pre_allocated_buffer=nullptr)
Construit un vecteur vide avec un allocateur spécifique a.
ArrayIterator< pointer > iterator
void _resize(Int64 s, ConstReferenceType value)
Redimensionne et remplit les nouvelles valeurs avec value.
void setMemoryLocationHint(eMemoryLocationHint new_hint)
Modifie les informations sur la localisation mémoire.
void _internalReallocate(Int64 new_capacity, FalseType, RunQueue *queue)
Réallocation pour un type complexe (non POD)
bool empty() const
Capacité (nombre d'éléments alloués) du vecteur.
eHostDeviceMemoryLocation hostDeviceMemoryLocation() const
Positionne l'emplacement physique de la zone mémoire.
ptrdiff_t difference_type
Int64 largeSize() const
Nombre d'éléments du vecteur (en 64 bits)
bool contains(ConstReferenceType v) const
Vrai si le tableau contient l'élément de valeur v.
Int64 largeCapacity() const
Capacité (nombre d'éléments alloués) du vecteur (en 64 bits)
Int64 largeLength() const
Nombre d'éléments du vecteur (en 64 bits)
void _directFirstAllocateWithAllocator(Int64 new_capacity, MemoryAllocationOptions options, void *pre_allocated_buffer=nullptr)
Effectue la première allocation.
void _reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
void _resizeAndCopyView(Span< const T > rhs)
Redimensionne l'instance et recopie les valeurs de rhs.
virtual Integer _getNbRef()
Mise à jour des références.
ConstReferenceType const_reference
ArrayIterator< const_pointer > const_iterator
void _resizeNoInit(Int64 s, RunQueue *queue=nullptr)
Redimensionne sans initialiser les nouvelles valeurs.
AbstractArray(ThatClassType &&rhs) ARCCORE_NOEXCEPT
Constructeur par déplacement. Ne doit être utilisé que par UniqueArray.
void _internalRealloc(Int64 new_capacity, bool compute_capacity, PodType pod_type, RunQueue *queue=nullptr)
Réalloue le tableau pour une nouvelle capacité égale à new_capacity.
void _swap(ThatClassType &rhs) ARCCORE_NOEXCEPT
Échange les valeurs de l'instance avec celles de rhs.
ConstReferenceType operator()(Int64 i) const
Elément d'indice i.
void _reset()
Réinitialise le tableau à un tableau vide.
void _internalReallocate(Int64 new_capacity, TrueType, RunQueue *queue)
Réallocation pour un type POD.
Integer length() const
Nombre d'éléments du vecteur.
File d'exécution pour un accélérateur.
Informations sur une zone mémoire allouée.
void setDebugName(const String &name)
Itérateur sur les classes tableau de Arccore.
Vue constante d'un tableau de type T.
Interface d'un allocateur pour la mémoire.
Options pour configurer les allocations.
constexpr __host__ __device__ pointer data() const noexcept
Pointeur sur le début de la vue.
constexpr __host__ __device__ SizeType size() const noexcept
Retourne la taille du tableau.
Vue d'un tableau d'éléments de type T.
Chaîne de caractères unicode.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
eMemoryLocationHint
Indices sur la localisation mémoire attendue.
eHostDeviceMemoryLocation
Localisation physique d'une adresse mémoire.
std::int32_t Int32
Type entier signé sur 32 bits.
Structure équivalente à la valeur booléenne vrai.
Structure équivalente à la valeur booléenne vrai.