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());
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 printInfos(std::ostream& o)
558 o <<
" Infos: size=" << m_md->size <<
" capacity=" << m_md->capacity <<
'\n';
575 Int64 s = m_md->size;
576 if ((s + n) > m_md->capacity)
578 for (
Int64 i = 0; i < n; ++i)
579 new (m_ptr + s + i) T(val);
587 const T* ptr = val.
data();
588 Int64 s = m_md->size;
589 if ((s + n) > m_md->capacity)
591 _createRange(s, s + n, ptr);
598 if (m_md->nb_ref == 0) {
605 _destroyRange(0, m_md->
size, IsPODType());
607 void _destroyRange(Int64, Int64, TrueType)
611 void _destroyRange(
Int64 abegin,
Int64 aend, FalseType)
615 for (
Int64 i = abegin; i < aend; ++i)
618 void _createRangeDefault(
Int64,
Int64, TrueType)
621 void _createRangeDefault(
Int64 abegin,
Int64 aend, FalseType)
625 for (
Int64 i = abegin; i < aend; ++i)
628 void _createRange(
Int64 abegin,
Int64 aend, ConstReferenceType value, TrueType)
632 for (
Int64 i = abegin; i < aend; ++i)
635 void _createRange(
Int64 abegin,
Int64 aend, ConstReferenceType value, FalseType)
639 for (
Int64 i = abegin; i < aend; ++i)
640 new (m_ptr + i) T(value);
642 void _createRange(
Int64 abegin,
Int64 aend,
const T* values)
646 for (
Int64 i = abegin; i < aend; ++i) {
647 new (m_ptr + i) T(*values);
651 void _fill(ConstReferenceType value)
653 for (
Int64 i = 0, n =
size(); i < n; ++i)
656 void _clone(
const ThatClassType& orig_array)
658 Int64 that_size = orig_array.size();
660 m_md->size = that_size;
661 m_md->dim1_size = orig_array.m_md->dim1_size;
662 m_md->dim2_size = orig_array.m_md->dim2_size;
663 _createRange(0, that_size, orig_array.m_ptr);
665 template <
typename PodType>
666 void _resizeHelper(
Int64 s, PodType pod_type, RunQueue* queue)
670 if (s > m_md->size) {
672 this->_createRangeDefault(m_md->size, s, pod_type);
675 this->_destroyRange(s, m_md->size, pod_type);
679 void _resize(
Int64 s)
686 _resizeHelper(s,
TrueType{}, queue);
690 this->_destroyRange(0, m_md->
size, IsPODType());
698 if (s > m_md->size) {
700 this->_createRange(m_md->size, s, value, IsPODType());
703 this->_destroyRange(s, m_md->size, IsPODType());
707 void _copy(
const T* rhs_begin,
TrueType)
709 _copyFromMemory(rhs_begin);
711 void _copy(
const T* rhs_begin, FalseType)
713 for (Int64 i = 0, n = m_md->
size; i < n; ++i)
714 m_ptr[i] = rhs_begin[i];
716 void _copy(
const T* rhs_begin)
718 _copy(rhs_begin, IsPODType());
731 const T* rhs_begin = rhs.
data();
733 const Int64 current_size = m_md->size;
736 if (abegin >= rhs_begin && abegin < (rhs_begin + rhs_size))
737 ArrayMetaData::overlapError(abegin, m_md->size, rhs_begin, rhs_size);
739 if (rhs_size > current_size) {
742 this->_createRange(m_md->size, rhs_size, rhs_begin + current_size);
745 m_md->size = rhs_size;
748 this->_destroyRange(rhs_size, current_size, IsPODType{});
749 m_md->size = rhs_size;
761 void _move(ThatClassType& rhs) ARCCORE_NOEXCEPT
785 void _swap(ThatClassType& rhs) ARCCORE_NOEXCEPT
787 std::swap(m_ptr, rhs.m_ptr);
797 void _shrink(Int64 new_capacity)
802 if (new_capacity > this->
capacity())
804 if (new_capacity < 4)
822 if (asize > max_size)
824 asize =
static_cast<Integer>(max_size);
833 Span<const T> rhs_span(rhs);
834 if (rhs.allocator() == this->allocator()) {
848 void _setMP(TrueImpl* new_mp)
853 void _setMP2(TrueImpl* new_mp, ArrayMetaData* new_md)
859 if (!m_md->is_allocated_by_new)
865 return m_ptr ==
nullptr;
870 void _setToSharedNull()
873 m_meta_data = ArrayMetaData();
876 void _setMPCast(
void* p)
878 _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(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.