From 4fac083be18406fc55ec27ffcb486e87de9cd978 Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Tue, 23 Jan 2024 09:58:26 -0700 Subject: [PATCH] Make some parts of VectorizedArray infrastructure 'constexpr'. --- include/deal.II/base/vectorization.h | 63 ++++++++++++++-------------- 1 file changed, 31 insertions(+), 32 deletions(-) diff --git a/include/deal.II/base/vectorization.h b/include/deal.II/base/vectorization.h index ea0bb552bc..95d78681b0 100644 --- a/include/deal.II/base/vectorization.h +++ b/include/deal.II/base/vectorization.h @@ -105,7 +105,7 @@ public: * @param data The actual VectorizedArray. * @param lane A pointer to the current lane. */ - VectorizedArrayIterator(T &data, const std::size_t lane) + constexpr VectorizedArrayIterator(T &data, const std::size_t lane) : data(&data) , lane(lane) {} @@ -113,7 +113,7 @@ public: /** * Compare for equality. */ - bool + constexpr bool operator==(const VectorizedArrayIterator &other) const { Assert(this->data == other.data, @@ -125,7 +125,7 @@ public: /** * Compare for inequality. */ - bool + constexpr bool operator!=(const VectorizedArrayIterator &other) const { Assert(this->data == other.data, @@ -137,14 +137,14 @@ public: /** * Copy assignment. */ - VectorizedArrayIterator & + constexpr VectorizedArrayIterator & operator=(const VectorizedArrayIterator &other) = default; /** * Dereferencing operator (const version): returns the value of the current * lane. */ - const typename T::value_type & + constexpr const typename T::value_type & operator*() const { AssertIndexRange(lane, T::size()); @@ -157,7 +157,8 @@ public: * current lane. */ template - std::enable_if_t, typename T::value_type> & + constexpr std::enable_if_t, + typename T::value_type> & operator*() { AssertIndexRange(lane, T::size()); @@ -169,7 +170,7 @@ public: * the iterator to the next lane and returns a reference to * *this. */ - VectorizedArrayIterator & + constexpr VectorizedArrayIterator & operator++() { AssertIndexRange(lane + 1, T::size() + 1); @@ -181,7 +182,7 @@ public: * This operator advances the iterator by @p offset lanes and returns a * reference to *this. */ - VectorizedArrayIterator & + constexpr VectorizedArrayIterator & operator+=(const std::size_t offset) { AssertIndexRange(lane + offset, T::size() + 1); @@ -194,7 +195,7 @@ public: * the iterator to the previous lane and returns a reference to * *this. */ - VectorizedArrayIterator & + constexpr VectorizedArrayIterator & operator--() { Assert( @@ -208,7 +209,7 @@ public: /** * Create new iterator, which is shifted by @p offset. */ - VectorizedArrayIterator + constexpr VectorizedArrayIterator operator+(const std::size_t &offset) const { AssertIndexRange(lane + offset, T::size() + 1); @@ -218,7 +219,7 @@ public: /** * Compute distance between this iterator and iterator @p other. */ - std::ptrdiff_t + constexpr std::ptrdiff_t operator-(const VectorizedArrayIterator &other) const { return static_cast(lane) - @@ -255,31 +256,29 @@ public: /** * Default constructor. */ - VectorizedArrayBase() = default; + constexpr VectorizedArrayBase() = default; /** * Construct an array with the given initializer list. + * + * The initializer list must have at most as many elements as the + * vector length. Elements not listed in the initializer list are + * zero-initialized. */ template - VectorizedArrayBase(const std::initializer_list &list) + constexpr VectorizedArrayBase(const std::initializer_list &list) { - auto i0 = this->begin(); - auto i1 = list.begin(); - - for (; i1 != list.end(); ++i0, ++i1) - { - Assert( - i0 != this->end(), - ExcMessage( - "Initializer list exceeds size of this VectorizedArray object.")); + const unsigned int n_initializers = list.size(); + Assert(n_initializers <= size(), + ExcMessage("The initializer list must have at most " + "as many elements as the vector length.")); - *i0 = *i1; - } + // Copy what's in the list. + std::copy_n(list.begin(), n_initializers, this->begin()); - for (; i0 != this->end(); ++i0) - { - *i0 = 0.0; - } + // Then add zero padding where necessary. + if (n_initializers < size()) + std::fill(this->begin() + n_initializers, this->end(), 0.0); } /** @@ -294,7 +293,7 @@ public: /** * @return An iterator pointing to the beginning of the underlying data. */ - VectorizedArrayIterator + constexpr VectorizedArrayIterator begin() { return VectorizedArrayIterator(static_cast(*this), 0); @@ -304,7 +303,7 @@ public: * @return An iterator pointing to the beginning of the underlying data (`const` * version). */ - VectorizedArrayIterator + constexpr VectorizedArrayIterator begin() const { return VectorizedArrayIterator(static_cast(*this), 0); @@ -313,7 +312,7 @@ public: /** * @return An iterator pointing to the end of the underlying data. */ - VectorizedArrayIterator + constexpr VectorizedArrayIterator end() { return VectorizedArrayIterator(static_cast(*this), width); @@ -323,7 +322,7 @@ public: * @return An iterator pointing to the end of the underlying data (`const` * version). */ - VectorizedArrayIterator + constexpr VectorizedArrayIterator end() const { return VectorizedArrayIterator(static_cast(*this), -- 2.39.5