From 9233d6e7dd6fc84948cc892cf072edb6cc6ce3e1 Mon Sep 17 00:00:00 2001 From: Gilles Grospellier Date: Mon, 15 Nov 2021 18:51:40 +0100 Subject: [PATCH 1/5] =?UTF-8?q?[arccore,base]=20Ajoute=20fichier=20'ArrayV?= =?UTF-8?q?iewCommon.h'=20pour=20contenir=20les=20fonctions=20communes=20?= =?UTF-8?q?=C3=A0=20toutes=20les=20classes=20de=20vues.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ajoute implémentation commune pour ArrayView::subViewInterval(). --- arccore/src/base/arccore/base/ArrayView.h | 75 +++++++++++-------- .../src/base/arccore/base/ArrayViewCommon.h | 63 ++++++++++++++++ arccore/src/base/arccore/base/CMakeLists.txt | 1 + arccore/src/base/arccore/base/Span.h | 60 +++++++++++---- arccore/src/base/tests/TestArrayView.cc | 24 ++++++ 5 files changed, 175 insertions(+), 48 deletions(-) create mode 100644 arccore/src/base/arccore/base/ArrayViewCommon.h diff --git a/arccore/src/base/arccore/base/ArrayView.h b/arccore/src/base/arccore/base/ArrayView.h index c3eacea451..ed206f27fd 100644 --- a/arccore/src/base/arccore/base/ArrayView.h +++ b/arccore/src/base/arccore/base/ArrayView.h @@ -17,7 +17,7 @@ // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* ArrayView.h (C) 2000-2019 */ +/* ArrayView.h (C) 2000-2021 */ /* */ /* Types définissant les vues de tableaux C. */ /*---------------------------------------------------------------------------*/ @@ -27,8 +27,8 @@ /*---------------------------------------------------------------------------*/ #include "arccore/base/ArrayRange.h" +#include "arccore/base/ArrayViewCommon.h" -#include #include /*---------------------------------------------------------------------------*/ @@ -108,8 +108,11 @@ class ArrayView friend class Span; friend class SmallSpan; friend class SmallSpan; + public: + using ThatClass = ArrayView; + //! Type des éléments du tableau typedef T value_type; //! Type pointeur d'un élément du tableau @@ -137,22 +140,27 @@ class ArrayView typedef std::reverse_iterator reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; - public: - - public: //! Construit une vue vide. - ArrayView() : m_size(0), m_ptr(0) {} + ArrayView() : m_size(0), m_ptr(nullptr) {} //! Constructeur de recopie depuis une autre vue ArrayView(const ArrayView& from) : m_size(from.m_size), m_ptr(from.m_ptr) {} //! Construit une vue sur une zone mémoire commencant par \a ptr et // contenant \a asize éléments. - explicit ArrayView(Integer asize,T* ptr) : m_size(asize), m_ptr(ptr) {} + ArrayView(Integer asize,T* ptr) : m_size(asize), m_ptr(ptr) {} //! Opérateur de recopie - const ArrayView& operator=(const ArrayView& from) - { m_size=from.m_size; m_ptr=from.m_ptr; return *this; } + ArrayView& operator=(const ArrayView& from) = default; + + public: + + //! Construit une vue sur une zone mémoire commencant par \a ptr et + // contenant \a asize éléments. + static ThatClass create(T* ptr,Integer asize) + { + return ThatClass(asize,ptr); + } public: @@ -312,13 +320,7 @@ class ArrayView //! Sous-vue correspondant à l'interval \a index sur \a nb_interval ArrayView subViewInterval(Integer index,Integer nb_interval) { - Integer n = m_size; - Integer isize = n / nb_interval; - Integer ibegin = index * isize; - // Pour le dernier interval, prend les elements restants - if ((index+1)==nb_interval) - isize = n - ibegin; - return ArrayView(isize,m_ptr+ibegin); + return impl::subViewInterval(*this,index,nb_interval); } /*! @@ -475,6 +477,8 @@ class ConstArrayView public: + using ThatClass = ConstArrayView; + //! Type des éléments du tableau typedef T value_type; //! Type pointeur constant d'un élément du tableau @@ -488,6 +492,8 @@ class ConstArrayView //! Type d'une distance entre itérateur éléments du tableau typedef std::ptrdiff_t difference_type; + using const_value_type = typename std::add_const::type ; + //! Type d'un itérateur constant sur tout le tableau typedef ConstIterT< ConstArrayView > const_iter; @@ -505,7 +511,8 @@ class ConstArrayView */ ConstArrayView(const ConstArrayView& from) : m_size(from.m_size), m_ptr(from.m_ptr) {} - /*! \brief Constructeur par copie. + /*! + * \brief Constructeur par copie. * \warning Seul le pointeur est copié. Aucune copie mémoire n'est effectuée. */ ConstArrayView(const ArrayView& from) @@ -515,19 +522,27 @@ class ConstArrayView * \brief Opérateur de recopie. * \warning Seul le pointeur est copié. Aucune copie mémoire n'est effectuée. */ - const ConstArrayView& operator=(const ConstArrayView& from) - { m_size=from.m_size; m_ptr=from.m_ptr; return *this; } + ConstArrayView& operator=(const ConstArrayView& from) = default; /*! \brief Opérateur de recopie. * \warning Seul le pointeur est copié. Aucune copie mémoire n'est effectuée. */ - const ConstArrayView& operator=(const ArrayView& from) + ConstArrayView& operator=(const ArrayView& from) { m_size = from.size(); m_ptr = from.data(); return (*this); } + public: + + //! Construit une vue sur une zone mémoire commencant par \a ptr et + // contenant \a asize éléments. + static ThatClass create(const T* ptr,Integer asize) + { + return ThatClass(asize,ptr); + } + public: /*! @@ -558,16 +573,9 @@ class ConstArrayView } //! Sous-vue correspondant à l'interval \a index sur \a nb_interval - ArrayView subViewInterval(Integer index,Integer nb_interval) + ConstArrayView subViewInterval(Integer index,Integer nb_interval) const { - Integer n = m_size; - Integer isize = n / nb_interval; - Integer ibegin = index * isize; - // Pour le dernier interval, prend les elements restants - if ((index+1)==nb_interval) - isize = n - ibegin; - ARCCORE_CHECK_AT(ibegin+isize,n); - return ConstArrayView(isize,m_ptr+ibegin); + return impl::subViewInterval(*this,index,nb_interval); } //! Addresse du index-ème élément @@ -643,8 +651,11 @@ class ConstArrayView * operator[](): aucune vérification de dépassement n'est possible, * même en mode vérification. */ - const T* data() const - { return m_ptr; } + const_pointer data() const + { + return m_ptr; + } + //! Intervalle d'itération du premier au dernièr élément. ArrayRange range() const { @@ -654,7 +665,7 @@ class ConstArrayView private: Integer m_size; //!< Nombre d'éléments - const T* m_ptr; //!< Pointeur sur le début du tableau + const_pointer m_ptr; //!< Pointeur sur le début du tableau private: diff --git a/arccore/src/base/arccore/base/ArrayViewCommon.h b/arccore/src/base/arccore/base/ArrayViewCommon.h new file mode 100644 index 0000000000..2577185830 --- /dev/null +++ b/arccore/src/base/arccore/base/ArrayViewCommon.h @@ -0,0 +1,63 @@ +// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- +//----------------------------------------------------------------------------- +// Copyright 2000-2020 IFPEN-CEA +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 +//----------------------------------------------------------------------------- +/*---------------------------------------------------------------------------*/ +/* ArrayViewCommon.h (C) 2000-2021 */ +/* */ +/* Déclarations communes aux classes ArrayView, ConstArrayView et Span. */ +/*---------------------------------------------------------------------------*/ +#ifndef ARCCORE_BASE_ARRAYVIEWCOMMON_H +#define ARCCORE_BASE_ARRAYVIEWCOMMON_H +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#include "arccore/base/ArrayIterator.h" + +#include + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace Arccore::impl +{ + +//! Sous-vue correspondant à l'interval \a index sur \a nb_interval +template +auto subViewInterval(ViewType view, + typename ViewType::size_type index, + typename ViewType::size_type nb_interval) -> ViewType +{ + using size_type = typename ViewType::size_type; + size_type n = view.size(); + size_type isize = n / nb_interval; + size_type ibegin = index * isize; + // Pour le dernier interval, prend les elements restants + if ((index+1)==nb_interval) + isize = n - ibegin; + return ViewType::create(view.data()+ibegin,isize); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +} // End namespace Arccore::impl + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#endif diff --git a/arccore/src/base/arccore/base/CMakeLists.txt b/arccore/src/base/arccore/base/CMakeLists.txt index f3ea9e37e0..5b6cf5f090 100644 --- a/arccore/src/base/arccore/base/CMakeLists.txt +++ b/arccore/src/base/arccore/base/CMakeLists.txt @@ -6,6 +6,7 @@ set(SOURCES APReal.h ArrayIterator.h ArrayRange.h + ArrayViewCommon.h ArrayView.h ArrayView.cc Array2View.h diff --git a/arccore/src/base/arccore/base/Span.h b/arccore/src/base/arccore/base/Span.h index a060c9e47a..bc1bd5bd4c 100644 --- a/arccore/src/base/arccore/base/Span.h +++ b/arccore/src/base/arccore/base/Span.h @@ -74,6 +74,7 @@ class SpanImpl public: using ThatClass = SpanImpl; + using size_type = SizeType; using ElementType = T; using element_type = ElementType; using value_type = typename std::remove_cv::type; @@ -97,11 +98,20 @@ class SpanImpl template> > ARCCORE_HOST_DEVICE SpanImpl(const SpanImpl& from) : m_ptr(from.data()), m_size(from.size()) {} - //! Construit une vue sur une zone mémoire commencant par \a ptr et - // contenant \a asize éléments. + + //! Construit une vue sur une zone mémoire commencant par \a ptr et contenant \a asize éléments. ARCCORE_HOST_DEVICE SpanImpl(T* ptr,SizeType asize) : m_ptr(ptr), m_size(asize) {} + public: + + //! Construit une vue sur une zone mémoire commencant par \a ptr et + // contenant \a asize éléments. + static ThatClass create(pointer ptr,SizeType asize) + { + return ThatClass(ptr,asize); + } + public: /*! @@ -243,13 +253,7 @@ class SpanImpl //! Sous-vue correspondant à l'interval \a index sur \a nb_interval ThatClass subViewInterval(SizeType index,SizeType nb_interval) const { - SizeType n = m_size; - SizeType isize = n / nb_interval; - SizeType ibegin = index * isize; - // Pour le dernier interval, prend les elements restants - if ((index+1)==nb_interval) - isize = n - ibegin; - return {m_ptr+ibegin,isize}; + return impl::subViewInterval(*this,index,nb_interval); } /*! @@ -368,8 +372,11 @@ class Span { public: + using ThatClass = Span; using BaseClass = SpanImpl; + using size_type = Int64; using value_type = typename BaseClass::value_type; + using pointer = typename BaseClass::pointer; public: @@ -391,11 +398,20 @@ class Span : BaseClass(from) {} ARCCORE_HOST_DEVICE Span(const SpanImpl& from) : BaseClass(from.data(),from.size()) {} - //! Construit une vue sur une zone mémoire commencant par \a ptr et - // contenant \a asize éléments. + + //! Construit une vue sur une zone mémoire commencant par \a ptr et contenant \a asize éléments. ARCCORE_HOST_DEVICE Span(T* ptr,Int64 asize) : BaseClass(ptr,asize) {} + public: + + //! Construit une vue sur une zone mémoire commencant par \a ptr et + // contenant \a asize éléments. + static ThatClass create(pointer ptr,size_type asize) + { + return ThatClass(ptr,asize); + } + public: /*! @@ -425,7 +441,7 @@ class Span //! Sous-vue correspondant à l'interval \a index sur \a nb_interval ARCCORE_HOST_DEVICE Span subViewInterval(Int64 index,Int64 nb_interval) const { - return BaseClass::subViewInternal(index,nb_interval); + return impl::subViewInterval(*this,index,nb_interval); } }; @@ -450,8 +466,11 @@ class SmallSpan public: + using ThatClass = SmallSpan; using BaseClass = SpanImpl; + using size_type = Int32; using value_type = typename BaseClass::value_type; + using pointer = typename BaseClass::pointer; public: @@ -476,6 +495,15 @@ class SmallSpan ARCCORE_HOST_DEVICE SmallSpan(T* ptr,Int32 asize) : BaseClass(ptr,asize) {} + public: + + //! Construit une vue sur une zone mémoire commencant par \a ptr et + // contenant \a asize éléments. + static ThatClass create(pointer ptr,size_type asize) + { + return ThatClass(ptr,asize); + } + public: /*! @@ -485,7 +513,7 @@ class SmallSpan * Si `(abegin+asize` est supérieur à la taille du tableau, * la vue est tronquée à cette taille, retournant éventuellement une vue vide. */ - ARCCORE_HOST_DEVICE Span subspan(Int64 abegin,Int64 asize) const + ARCCORE_HOST_DEVICE SmallSpan subspan(Int32 abegin,Int32 asize) const { return BaseClass::subspan(abegin,asize); } @@ -497,15 +525,15 @@ class SmallSpan * Si `(abegin+asize)` est supérieur à la taille du tableau, * la vue est tronquée à cette taille, retournant éventuellement une vue vide. */ - ARCCORE_HOST_DEVICE Span subView(Int64 abegin,Int64 asize) const + ARCCORE_HOST_DEVICE SmallSpan subView(Int32 abegin,Int32 asize) const { return subspan(abegin,asize); } //! Sous-vue correspondant à l'interval \a index sur \a nb_interval - ARCCORE_HOST_DEVICE Span subViewInterval(Int64 index,Int64 nb_interval) const + ARCCORE_HOST_DEVICE SmallSpan subViewInterval(Int32 index,Int32 nb_interval) const { - return BaseClass::subViewInternal(index,nb_interval); + return impl::subViewInterval(*this,index,nb_interval); } }; diff --git a/arccore/src/base/tests/TestArrayView.cc b/arccore/src/base/tests/TestArrayView.cc index 6e10d842f5..a20baefdca 100644 --- a/arccore/src/base/tests/TestArrayView.cc +++ b/arccore/src/base/tests/TestArrayView.cc @@ -135,6 +135,9 @@ TEST(ArrayView,Iterator) _testIterator(values4); } +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + TEST(Span,Convert) { using namespace Arccore; @@ -173,3 +176,24 @@ TEST(Span,Convert) /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ + +namespace Arccore +{ +template class ArrayView; +template class ConstArrayView; +template class ArrayView; +template class ConstArrayView; + +template class Span; +template class Span; +template class Span; +template class Span; + +template class SmallSpan; +template class SmallSpan; +template class SmallSpan; +template class SmallSpan; +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ From b1d60e225c7a0813cf7bd1cf7e43b953858238c8 Mon Sep 17 00:00:00 2001 From: Gilles Grospellier Date: Mon, 15 Nov 2021 21:57:41 +0100 Subject: [PATCH 2/5] [arccore,base] Mutualise les fonctions 'dumpArray()' et 'operator==' des vues. --- arccore/src/base/arccore/base/ArrayView.h | 34 +---------- .../src/base/arccore/base/ArrayViewCommon.h | 57 +++++++++++++++++++ arccore/src/base/arccore/base/Span.h | 35 +----------- arccore/src/base/tests/TestArrayView.cc | 3 + 4 files changed, 65 insertions(+), 64 deletions(-) diff --git a/arccore/src/base/arccore/base/ArrayView.h b/arccore/src/base/arccore/base/ArrayView.h index ed206f27fd..3298efef34 100644 --- a/arccore/src/base/arccore/base/ArrayView.h +++ b/arccore/src/base/arccore/base/ArrayView.h @@ -681,16 +681,7 @@ class ConstArrayView template inline bool operator==(ConstArrayView rhs, ConstArrayView lhs) { - if (rhs.size()!=lhs.size()) - return false; - Integer s = rhs.size(); - for( Integer i=0; i inline bool @@ -714,7 +705,6 @@ operator!=(ArrayView rhs,ArrayView lhs) return !(rhs==lhs); } - /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /*! @@ -728,27 +718,7 @@ operator!=(ArrayView rhs,ArrayView lhs) template inline void dumpArray(std::ostream& o,ConstArrayView val,int max_print) { - Integer n = val.size(); - if (max_print>0 && n>max_print){ - // N'affiche que les (max_print/2) premiers et les (max_print/2) dernièrs - // sinon si le tableau est très grand cela peut générer des - // sorties listings énormes. - Integer z = (max_print/2); - Integer z2 = n - z; - o << "[0]=\"" << val[0] << '"'; - for( Integer i=1; i auto subViewInterval(ViewType view, @@ -52,6 +55,60 @@ auto subViewInterval(ViewType view, return ViewType::create(view.data()+ibegin,isize); } +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +/*! + * \brief Affiche les valeurs de la vue. + * + * Affiche sur le flot \a o les valeurs de \a val. + * Si \a max_print est supérieur à 0, indique le nombre maximum de valeurs + * à afficher. + */ +template inline void +dumpArray(std::ostream& o,ViewType val,int max_print) +{ + using size_type = typename ViewType::size_type; + size_type n = val.size(); + if (max_print>0 && n>max_print){ + // N'affiche que les (max_print/2) premiers et les (max_print/2) derniers + // sinon si le tableau est très grand cela peut générer des + // sorties listings énormes. + size_type z = (max_print/2); + size_type z2 = n - z; + o << "[0]=\"" << val[0] << '"'; + for( size_type i=1; i inline bool +areEqual(ViewType rhs, ViewType lhs) +{ + using size_type = typename ViewType::size_type; + if (rhs.size()!=lhs.size()) + return false; + size_type s = rhs.size(); + for( size_type i=0; i inline bool operator==(SpanImpl rhs, SpanImpl lhs) { - if (rhs.size()!=lhs.size()) - return false; - SizeType s = rhs.size(); - for( SizeType i=0; i inline bool @@ -613,27 +604,7 @@ operator!=(SmallSpan rhs, SmallSpan lhs) template inline void dumpArray(std::ostream& o,SpanImpl val,int max_print) { - SizeType n = val.size(); - if (max_print>0 && n>max_print){ - // N'affiche que les (max_print/2) premiers et les (max_print/2) derniers - // sinon si le tableau est très grand cela peut générer des - // sorties listings énormes. - SizeType z = (max_print/2); - SizeType z2 = n - z; - o << "[0]=\"" << val[0] << '"'; - for( SizeType i=1; i +#include /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -144,15 +145,30 @@ class ArrayView //! Construit une vue vide. constexpr ArrayView() noexcept : m_size(0), m_ptr(nullptr) {} + //! Constructeur de recopie depuis une autre vue constexpr ArrayView(const ArrayView& from) noexcept : m_size(from.m_size), m_ptr(from.m_ptr) {} + //! Construit une vue sur une zone mémoire commencant par \a ptr et // contenant \a asize éléments. constexpr ArrayView(Integer asize,pointer ptr) noexcept : m_size(asize), m_ptr(ptr) {} + + //! Construit une vue sur une zone mémoire commencant par \a ptr et contenant \a asize éléments. + template + constexpr ArrayView(std::array& v) noexcept : m_size(v.size()), m_ptr(v.data()) {} + //! Opérateur de recopie ArrayView& operator=(const ArrayView& from) = default; + template + constexpr ArrayView& operator=(std::array& from) noexcept + { + m_size = from.size(); + m_ptr = from.data(); + return (*this); + } + public: //! Construit une vue sur une zone mémoire commencant par \a ptr et @@ -492,7 +508,7 @@ class ConstArrayView //! Type d'une distance entre itérateur éléments du tableau typedef std::ptrdiff_t difference_type; - using const_value_type = typename std::add_const::type ; + using const_value_type = typename std::add_const_t; //! Type d'un itérateur constant sur tout le tableau typedef ConstIterT< ConstArrayView > const_iter; @@ -518,13 +534,19 @@ class ConstArrayView constexpr ConstArrayView(const ArrayView& from) noexcept : m_size(from.size()), m_ptr(from.data()) { } + //! Création depuis un std::array + template> > + constexpr ConstArrayView(const std::array& v) noexcept + : m_size(v.size()), m_ptr(v.data()) {} + /*! * \brief Opérateur de recopie. * \warning Seul le pointeur est copié. Aucune copie mémoire n'est effectuée. */ ConstArrayView& operator=(const ConstArrayView& from) = default; - /*! \brief Opérateur de recopie. + /*! + * \brief Opérateur de recopie. * \warning Seul le pointeur est copié. Aucune copie mémoire n'est effectuée. */ constexpr ConstArrayView& operator=(const ArrayView& from) @@ -534,6 +556,15 @@ class ConstArrayView return (*this); } + //! Opérateur de recopie + template> > + constexpr ConstArrayView& operator=(const std::array& from) noexcept + { + m_size = from.size(); + m_ptr = from.data(); + return (*this); + } + public: //! Construit une vue sur une zone mémoire commencant par \a ptr et diff --git a/arccore/src/base/arccore/base/Span.h b/arccore/src/base/arccore/base/Span.h index 1d9bc0d3de..dc91dc5e46 100644 --- a/arccore/src/base/arccore/base/Span.h +++ b/arccore/src/base/arccore/base/Span.h @@ -77,7 +77,8 @@ class SpanImpl using size_type = SizeType; using ElementType = T; using element_type = ElementType; - using value_type = typename std::remove_cv::type; + using value_type = typename std::remove_cv_t; + using const_value_type = typename std::add_const_t; using index_type = SizeType; using difference_type = SizeType; using pointer = ElementType*; @@ -90,6 +91,10 @@ class SpanImpl using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; + //! Indique si on peut convertir un 'X' ou 'const X' en un 'T' + template + using is_same_const_type = std::enable_if_t || std::is_same_v,T>>; + public: //! Construit une vue vide. @@ -105,6 +110,20 @@ class SpanImpl constexpr ARCCORE_HOST_DEVICE SpanImpl(pointer ptr,SizeType asize) noexcept : m_ptr(ptr), m_size(asize) {} + //! Construit une vue depuis un std::array + template > + constexpr ARCCORE_HOST_DEVICE SpanImpl(std::array& from) noexcept + : m_ptr(from.data()), m_size(from.size()) {} + + //! Opérateur de recopie + template > + constexpr ARCCORE_HOST_DEVICE ThatClass& operator=(std::array& from) noexcept + { + m_ptr = from.data(); + m_size = from.size(); + return (*this); + } + public: //! Construit une vue sur une zone mémoire commencant par \a ptr et @@ -379,6 +398,8 @@ class Span using size_type = Int64; using value_type = typename BaseClass::value_type; using pointer = typename BaseClass::pointer; + template + using is_same_const_type = std::enable_if_t || std::is_same_v,T>>; public: @@ -405,6 +426,19 @@ class Span constexpr ARCCORE_HOST_DEVICE Span(pointer ptr,Int64 asize) noexcept : BaseClass(ptr,asize) {} + //! Construit une vue à partir d'un std::array. + template > + constexpr ARCCORE_HOST_DEVICE Span(std::array& from) noexcept + : BaseClass(from) {} + + //! Opérateur de recopie + template > + constexpr ARCCORE_HOST_DEVICE ThatClass& operator=(std::array& from) noexcept + { + BaseClass::operator=(from); + return (*this); + } + public: //! Construit une vue sur une zone mémoire commencant par \a ptr et @@ -462,10 +496,6 @@ template class SmallSpan : public SpanImpl { - // Pour le cas où on ne supporte pas le C++14. - template< bool B, class XX = void > - using Span_enable_if_t = typename std::enable_if::type; - public: using ThatClass = SmallSpan; @@ -473,30 +503,48 @@ class SmallSpan using size_type = Int32; using value_type = typename BaseClass::value_type; using pointer = typename BaseClass::pointer; + template + using is_same_const_type = std::enable_if_t || std::is_same_v,T>>; public: //! Construit une vue vide. SmallSpan() = default; + //! Constructeur de recopie depuis une autre vue constexpr ARCCORE_HOST_DEVICE SmallSpan(const ArrayView& from) noexcept : BaseClass(from.m_ptr,from.m_size) {} + // Constructeur à partir d'un ConstArrayView. Cela n'est autorisé que // si T est const. - template::value> > + template::value> > constexpr ARCCORE_HOST_DEVICE SmallSpan(const ConstArrayView& from) noexcept : BaseClass(from.m_ptr,from.m_size) {} + // Pour un Span, on a le droit de construire depuis un Span - template::value> > + template::value> > constexpr ARCCORE_HOST_DEVICE SmallSpan(const SmallSpan& from) noexcept : BaseClass(from) {} + constexpr ARCCORE_HOST_DEVICE SmallSpan(const SpanImpl& from) noexcept : BaseClass(from) {} - //! Construit une vue sur une zone mémoire commencant par \a ptr et - // contenant \a asize éléments. + + //! Construit une vue sur une zone mémoire commencant par \a ptr et contenant \a asize éléments. constexpr ARCCORE_HOST_DEVICE SmallSpan(pointer ptr,Int32 asize) noexcept : BaseClass(ptr,asize) {} + template > + constexpr ARCCORE_HOST_DEVICE SmallSpan(std::array& from) noexcept + : BaseClass(from) {} + + //! Opérateur de recopie + template > + constexpr ARCCORE_HOST_DEVICE ThatClass& operator=(std::array& from) noexcept + { + BaseClass::operator=(from); + return (*this); + } + public: //! Construit une vue sur une zone mémoire commencant par \a ptr et diff --git a/arccore/src/base/tests/TestArrayView.cc b/arccore/src/base/tests/TestArrayView.cc index e53c3f85dd..1485d8aa20 100644 --- a/arccore/src/base/tests/TestArrayView.cc +++ b/arccore/src/base/tests/TestArrayView.cc @@ -177,6 +177,119 @@ TEST(Span,Convert) std::cout << "Span3=" << span3 << '\n'; } +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +// Vérifie que \a a1 et \a a2 sont identiques +template +void _checkSame(A1& a1,A2& a2,const char* message) +{ + ASSERT_EQ(a1.size(),a2.size()) << "Bad size " << message; + for( int i=0, n=a2.size(); i v0; + std::array v1 { 5, 7 }; + std::array v2 { 2, 4, -2 }; + std::array v3 { 9, 13, 32, 27 }; + + { + ArrayView view0 { v0 }; + _checkSame(view0,v0,"view0==v0"); + + ArrayView view1 { v1 }; + _checkSame(view1,v1,"view1==v1"); + + view0 = v2; + _checkSame(view0,v2,"view0==v2"); + } + + { + ConstArrayView view0 { v0 }; + _checkSame(view0,v0,"const view0==v0"); + + ConstArrayView view1 { v1 }; + _checkSame(view1,v1,"const view1==v1"); + + view0 = v2; + _checkSame(view0,v2,"const view0==v2"); + + ConstArrayView view2 { v3 }; + _checkSame(view2,v3,"const view2==v3"); + + view1 = v3; + _checkSame(view1,v3,"const view1==v3"); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template +void +_testSpanStdArray() +{ + using namespace Arccore; + std::array v0; + std::array v1 { 5, 7 }; + std::array v2 { 2, 4, -2 }; + std::array v3 { 9, 13, 32, 27 }; + + { + SpanType span0 { v0 }; + _checkSame(span0,v0,"span0==v0"); + + SpanType span1 { v1 }; + _checkSame(span1,v1,"span1==v1"); + + span0 = v2; + _checkSame(span0,v2,"span0==v2"); + } + + { + ConstSpanType span0 { v0 }; + _checkSame(span0,v0,"const span0==v0"); + + ConstSpanType span1 { v1 }; + _checkSame(span1,v1,"const span1==v1"); + + span0 = v2; + _checkSame(span0,v2,"const span0==v2"); + + ConstSpanType span2 { v3 }; + _checkSame(span2,v3,"const span2==v3"); + + span1 = v3; + _checkSame(span1,v3,"const span1==v3"); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +TEST(Span,StdArray) +{ + using namespace Arccore; + _testSpanStdArray,Span>(); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +TEST(SmallSpan,StdArray) +{ + using namespace Arccore; + _testSpanStdArray,SmallSpan>(); +} + + /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ From 8cab4cf9e72c4716ddef54d33e01b8961c85b2cf Mon Sep 17 00:00:00 2001 From: Gilles Grospellier Date: Tue, 16 Nov 2021 11:42:02 +0100 Subject: [PATCH 5/5] [arccore,base] Ajoute tests pour 'ArrayView::subViewInterval()'. --- .../src/base/arccore/base/ArrayViewCommon.h | 4 + arccore/src/base/tests/TestArrayView.cc | 74 ++++++++++++++++++- 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/arccore/src/base/arccore/base/ArrayViewCommon.h b/arccore/src/base/arccore/base/ArrayViewCommon.h index 0b13966a8b..3c79d7dffd 100644 --- a/arccore/src/base/arccore/base/ArrayViewCommon.h +++ b/arccore/src/base/arccore/base/ArrayViewCommon.h @@ -46,6 +46,10 @@ auto subViewInterval(ViewType view, typename ViewType::size_type nb_interval) -> ViewType { using size_type = typename ViewType::size_type; + if (nb_interval<=0) + return ViewType(); + if (index<0 || index>=nb_interval) + return ViewType(); size_type n = view.size(); size_type isize = n / nb_interval; size_type ibegin = index * isize; diff --git a/arccore/src/base/tests/TestArrayView.cc b/arccore/src/base/tests/TestArrayView.cc index 1485d8aa20..e56eb2d119 100644 --- a/arccore/src/base/tests/TestArrayView.cc +++ b/arccore/src/base/tests/TestArrayView.cc @@ -184,8 +184,9 @@ TEST(Span,Convert) template void _checkSame(A1& a1,A2& a2,const char* message) { + using size_type = typename A1::size_type; ASSERT_EQ(a1.size(),a2.size()) << "Bad size " << message; - for( int i=0, n=a2.size(); i,SmallSpan>(); } +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +template void +_testSubViewInterval() +{ + using namespace Arccore; + using size_type = typename ViewType::size_type; + + std::array vlist { 9, 13, 32, 27, 43, -5, 2, -7, 8, 11, 25, 48 }; + ViewType view{vlist}; + + { + ViewType null_view; + ViewType sub_view0{view.subViewInterval(1,0)}; + ViewType sub_view1{view.subViewInterval(-1,2)}; + ViewType sub_view2{view.subViewInterval(2,2)}; + ViewType sub_view3{view.subViewInterval(0,0)}; + std::cout << "SUBVIEW0=" << sub_view1 << '\n'; + _checkSame(sub_view0,null_view,"sub_view0_null"); + _checkSame(sub_view1,null_view,"sub_view1_null"); + _checkSame(sub_view2,null_view,"sub_view2_null"); + _checkSame(sub_view3,null_view,"sub_view3_null"); + } + + { + std::array vlist0 { 9, 13, 32, 27 }; + std::array vlist1 { 43, -5, 2, -7 }; + std::array vlist2 { 8, 11, 25, 48 }; + + ViewType sub_view0{view.subViewInterval(0,3)}; + ViewType sub_view1{view.subViewInterval(1,3)}; + ViewType sub_view2{view.subViewInterval(2,3)}; + std::cout << "SUBVIEW1=" << sub_view1 << '\n'; + _checkSame(sub_view0,vlist0,"sub_view0"); + _checkSame(sub_view1,vlist1,"sub_view1"); + _checkSame(sub_view2,vlist2,"sub_view2"); + } + + { + std::array vlist0 { 9, 13 }; + std::array vlist1 { 32, 27 }; + std::array vlist2 { 43, -5 }; + std::array vlist3 { 2, -7 }; + std::array vlist4 { 8, 11, 25, 48 }; + + ViewType sub_view0{view.subViewInterval(0,5)}; + ViewType sub_view1{view.subViewInterval(1,5)}; + ViewType sub_view2{view.subViewInterval(2,5)}; + ViewType sub_view3{view.subViewInterval(3,5)}; + ViewType sub_view4{view.subViewInterval(4,5)}; + std::cout << "SUBVIEW2=" << sub_view1 << '\n'; + _checkSame(sub_view0,vlist0,"sub_view0"); + _checkSame(sub_view1,vlist1,"sub_view1"); + _checkSame(sub_view2,vlist2,"sub_view2"); + _checkSame(sub_view3,vlist3,"sub_view3"); + _checkSame(sub_view4,vlist4,"sub_view4"); + } +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +TEST(ArrayView,SubViewInternval) +{ + using namespace Arccore; + _testSubViewInterval>(); + _testSubViewInterval>(); + _testSubViewInterval>(); + _testSubViewInterval>(); +} /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/