12#ifndef ARCCORE_COMMON_ABSTRACTARRAY_H
13#define ARCCORE_COMMON_ABSTRACTARRAY_H
17#include "arccore/base/Span.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());
273 void* pre_allocated_buffer =
nullptr)
285 _internalDeallocate();
289 if (options.allocator() != m_md->_allocator())
300 operator Span<const T>()
const
302 return Span<const T>(m_ptr, m_md->
size);
304 operator SmallSpan<const T>()
const
306 return SmallSpan<const T>(m_ptr, ARCCORE_CAST_SMALL_SIZE(
size()));
312 Integer size()
const {
return ARCCORE_CAST_SMALL_SIZE(m_md->size); }
324 bool empty()
const {
return m_md->size == 0; }
328 const T* ptr = m_ptr;
329 for (
Int64 i = 0, n = m_md->size; i < n; ++i) {
341 ARCCORE_CHECK_AT(i, m_md->size);
347 ARCCORE_CHECK_AT(i, m_md->size);
356 m_md->_setMemoryLocationHint(new_hint, m_ptr,
sizeof(T));
367 m_md->_setHostDeviceMemoryLocation(location);
373 return m_md->allocation_options.hostDeviceMemoryLocation();
385 return !(rhs == lhs);
388 friend bool operator==(
const AbstractArray<T>& rhs,
const Span<const T>& lhs)
390 return operator==(Span<const T>(rhs), lhs);
393 friend bool operator!=(
const AbstractArray<T>& rhs,
const Span<const T>& lhs)
395 return !(rhs == lhs);
398 friend bool operator==(
const Span<const T>& rhs,
const AbstractArray<T>& lhs)
400 return operator==(rhs, Span<const T>(lhs));
403 friend bool operator!=(
const Span<const T>& rhs,
const AbstractArray<T>& lhs)
405 return !(rhs == lhs);
408 friend std::ostream& operator<<(std::ostream& o,
const AbstractArray<T>& val)
410 o << Span<const T>(val);
416 using AbstractArrayBase::m_meta_data;
439 template <
typename PodType>
442 if (_isSharedNull()) {
443 if (new_capacity != 0)
444 _internalAllocate(new_capacity, queue);
448 Int64 acapacity = new_capacity;
449 if (compute_capacity) {
450 acapacity = m_md->capacity;
452 while (new_capacity > acapacity)
453 acapacity = (acapacity == 0) ? 4 : (acapacity + 1 + acapacity / 2);
471 Int64 old_capacity = m_md->capacity;
472 _directReAllocate(new_capacity, queue);
473 bool update = (new_capacity < old_capacity) || (m_ptr != old_ptr);
485 Int64 old_size = m_md->size;
486 _directAllocate(new_capacity, queue);
487 if (m_ptr != old_ptr) {
488 for (
Int64 i = 0; i < old_size; ++i) {
489 new (m_ptr + i) T(old_ptr[i]);
492 m_md->nb_ref = old_md->
nb_ref;
493 m_md->_deallocate(old_mem_info, queue);
498 void _internalDeallocate(
RunQueue* queue =
nullptr)
500 if (!_isSharedNull())
501 m_md->_deallocate(_currentMemoryInfo(), queue);
503 _deallocateMetaData(m_md);
505 void _internalAllocate(Int64 new_capacity, RunQueue* queue)
507 _directAllocate(new_capacity, queue);
512 void _copyFromMemory(
const T* source)
514 m_md->_copyFromMemory(m_ptr, source,
sizeof(T),
_nullRunQueue());
528 void* pre_allocated_buffer =
nullptr)
531 if (!wanted_allocator) {
532 wanted_allocator = ArrayMetaData::_defaultAllocator();
533 options.setAllocator(wanted_allocator);
536 m_md->allocation_options = options;
537 if (new_capacity > 0) {
538 if (!pre_allocated_buffer)
539 _allocateMP(new_capacity, options.runQueue());
541 _setMPCast(pre_allocated_buffer);
552 _allocateMP(new_capacity, queue);
555 void _allocateMP(Int64 new_capacity, RunQueue* queue)
557 _setMPCast(m_md->_allocate(new_capacity, typeSize(), queue));
560 void _directReAllocate(
Int64 new_capacity, RunQueue* queue)
562 _setMPCast(m_md->_reallocate(_currentMemoryInfo(), new_capacity, typeSize(), queue));
567 void printInfos(std::ostream& o)
569 o <<
" Infos: size=" << m_md->size <<
" capacity=" << m_md->capacity <<
'\n';
586 Int64 s = m_md->size;
587 if ((s + n) > m_md->capacity)
589 for (
Int64 i = 0; i < n; ++i)
590 new (m_ptr + s + i) T(val);
598 const T* ptr = val.
data();
599 Int64 s = m_md->size;
600 if ((s + n) > m_md->capacity)
602 _createRange(s, s + n, ptr);
609 if (m_md->nb_ref == 0) {
616 _destroyRange(0, m_md->
size, IsPODType());
618 void _destroyRange(Int64, Int64, TrueType)
622 void _destroyRange(
Int64 abegin,
Int64 aend, FalseType)
626 for (
Int64 i = abegin; i < aend; ++i)
629 void _createRangeDefault(
Int64,
Int64, TrueType)
632 void _createRangeDefault(
Int64 abegin,
Int64 aend, FalseType)
636 for (
Int64 i = abegin; i < aend; ++i)
639 void _createRange(
Int64 abegin,
Int64 aend, ConstReferenceType value, TrueType)
643 for (
Int64 i = abegin; i < aend; ++i)
646 void _createRange(
Int64 abegin,
Int64 aend, ConstReferenceType value, FalseType)
650 for (
Int64 i = abegin; i < aend; ++i)
651 new (m_ptr + i) T(value);
653 void _createRange(
Int64 abegin,
Int64 aend,
const T* values)
657 for (
Int64 i = abegin; i < aend; ++i) {
658 new (m_ptr + i) T(*values);
662 void _fill(ConstReferenceType value)
664 for (
Int64 i = 0, n =
size(); i < n; ++i)
667 void _clone(
const ThatClassType& orig_array)
669 Int64 that_size = orig_array.size();
671 m_md->size = that_size;
672 m_md->dim1_size = orig_array.m_md->dim1_size;
673 m_md->dim2_size = orig_array.m_md->dim2_size;
674 _createRange(0, that_size, orig_array.m_ptr);
676 template <
typename PodType>
677 void _resizeHelper(
Int64 s, PodType pod_type, RunQueue* queue)
681 if (s > m_md->size) {
683 this->_createRangeDefault(m_md->size, s, pod_type);
686 this->_destroyRange(s, m_md->size, pod_type);
690 void _resize(
Int64 s)
697 _resizeHelper(s,
TrueType{}, queue);
701 this->_destroyRange(0, m_md->
size, IsPODType());
709 if (s > m_md->size) {
711 this->_createRange(m_md->size, s, value, IsPODType());
714 this->_destroyRange(s, m_md->size, IsPODType());
718 void _copy(
const T* rhs_begin,
TrueType)
720 _copyFromMemory(rhs_begin);
722 void _copy(
const T* rhs_begin, FalseType)
724 for (Int64 i = 0, n = m_md->
size; i < n; ++i)
725 m_ptr[i] = rhs_begin[i];
727 void _copy(
const T* rhs_begin)
729 _copy(rhs_begin, IsPODType());
742 const T* rhs_begin = rhs.
data();
744 const Int64 current_size = m_md->size;
747 if (abegin >= rhs_begin && abegin < (rhs_begin + rhs_size))
748 ArrayMetaData::overlapError(abegin, m_md->size, rhs_begin, rhs_size);
750 if (rhs_size > current_size) {
753 this->_createRange(m_md->size, rhs_size, rhs_begin + current_size);
756 m_md->size = rhs_size;
759 this->_destroyRange(rhs_size, current_size, IsPODType{});
760 m_md->size = rhs_size;
772 void _move(ThatClassType& rhs) ARCCORE_NOEXCEPT
796 void _swap(ThatClassType& rhs) ARCCORE_NOEXCEPT
798 std::swap(m_ptr, rhs.m_ptr);
808 void _shrink(Int64 new_capacity)
813 if (new_capacity > this->
capacity())
815 if (new_capacity < 4)
833 if (asize > max_size)
835 asize =
static_cast<Integer>(max_size);
844 Span<const T> rhs_span(rhs);
845 if (rhs.allocator() == this->allocator()) {
859 void _setMP(TrueImpl* new_mp)
864 void _setMP2(TrueImpl* new_mp, ArrayMetaData* new_md)
870 if (!m_md->is_allocated_by_new)
876 return m_ptr ==
nullptr;
881 void _setToSharedNull()
884 m_meta_data = ArrayMetaData();
887 void _setMPCast(
void* p)
889 _setMP(
reinterpret_cast<TrueImpl*
>(p));
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(IMemoryAllocator *a, Int64 acapacity)
Construit un tableau avec un allocateur spécifique a.
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.