LCOV - code coverage report
Current view: top level - core/include/scipp/core - element_array_view.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 41 41 100.0 %
Date: 2024-04-28 01:25:40 Functions: 470 935 50.3 %

          Line data    Source code
       1             : // SPDX-License-Identifier: BSD-3-Clause
       2             : // Copyright (c) 2023 Scipp contributors (https://github.com/scipp)
       3             : /// @file
       4             : /// @author Simon Heybrock
       5             : #pragma once
       6             : 
       7             : #include <algorithm>
       8             : 
       9             : #include <boost/iterator/iterator_facade.hpp>
      10             : 
      11             : #include "scipp/core/dimensions.h"
      12             : #include "scipp/core/sizes.h"
      13             : #include "scipp/core/strides.h"
      14             : #include "scipp/core/view_index.h"
      15             : 
      16             : namespace scipp::core {
      17             : 
      18             : struct SCIPP_CORE_EXPORT BucketParams {
      19     5235681 :   explicit operator bool() const noexcept { return dim != Dim::Invalid; }
      20             :   Dim dim{Dim::Invalid};
      21             :   Dimensions dims{};
      22             :   Strides strides{};
      23             :   const std::pair<scipp::index, scipp::index> *indices{nullptr};
      24             : };
      25             : 
      26             : template <class T>
      27             : class ElementArrayViewParams_iterator
      28             :     : public boost::iterator_facade<ElementArrayViewParams_iterator<T>, T,
      29             :                                     boost::random_access_traversal_tag> {
      30             : public:
      31     2322437 :   ElementArrayViewParams_iterator(T *variable,
      32             :                                   const Dimensions &targetDimensions,
      33             :                                   const Strides &strides,
      34             :                                   const scipp::index index)
      35     2322437 :       : m_variable(variable), m_index(targetDimensions, strides) {
      36     2322437 :     m_index.set_index(index);
      37     2322437 :   }
      38             : 
      39             : private:
      40             :   friend class boost::iterator_core_access;
      41             : 
      42    11664651 :   bool equal(const ElementArrayViewParams_iterator &other) const {
      43    11664651 :     return m_index == other.m_index;
      44             :   }
      45    22686268 :   constexpr void increment() noexcept { m_index.increment(); }
      46    22783829 :   auto &dereference() const { return m_variable[m_index.get()]; }
      47             :   void decrement() { m_index.set_index(m_index.index() - 1); }
      48       95525 :   void advance(int64_t delta) {
      49       95525 :     if (delta == 1)
      50        1232 :       increment();
      51             :     else
      52       94293 :       m_index.set_index(m_index.index() + delta);
      53       95525 :   }
      54     1052768 :   int64_t distance_to(const ElementArrayViewParams_iterator &other) const {
      55     1052768 :     return static_cast<int64_t>(other.m_index.index()) -
      56     1052768 :            static_cast<int64_t>(m_index.index());
      57             :   }
      58             : 
      59             :   T *m_variable;
      60             :   ViewIndex m_index;
      61             : };
      62             : 
      63             : /// Base class for ElementArrayView<T> with functionality independent of T.
      64             : class SCIPP_CORE_EXPORT ElementArrayViewParams {
      65             : public:
      66             :   ElementArrayViewParams(scipp::index offset, const Dimensions &iter_dims,
      67             :                          const Strides &strides,
      68             :                          const BucketParams &bucket_params);
      69             :   ElementArrayViewParams(const ElementArrayViewParams &other,
      70             :                          const Dimensions &iterDims);
      71             : 
      72     3066846 :   [[nodiscard]] scipp::index size() const { return m_iterDims.volume(); }
      73             :   [[nodiscard]] constexpr scipp::index offset() const noexcept {
      74             :     return m_offset;
      75             :   }
      76     2040640 :   [[nodiscard]] constexpr const Dimensions &dims() const noexcept {
      77     2040640 :     return m_iterDims;
      78             :   }
      79     4880674 :   [[nodiscard]] const Strides &strides() const noexcept { return m_strides; }
      80     5392670 :   [[nodiscard]] constexpr const BucketParams &bucketParams() const noexcept {
      81     5392670 :     return m_bucketParams;
      82             :   }
      83             : 
      84             :   [[nodiscard]] bool overlaps(const ElementArrayViewParams &other) const;
      85             : 
      86             : protected:
      87             :   void requireContiguous() const;
      88             :   scipp::index m_offset{0};
      89             :   Dimensions m_iterDims;
      90             :   Strides m_strides;
      91             :   BucketParams m_bucketParams{};
      92             : };
      93             : 
      94             : /// A view into multi-dimensional data, supporting slicing, index reordering,
      95             : /// and broadcasting.
      96             : template <class T> class ElementArrayView : public ElementArrayViewParams {
      97             : public:
      98             :   using element_type = T;
      99             :   using value_type = std::remove_cv_t<T>;
     100             :   using iterator = ElementArrayViewParams_iterator<T>;
     101             : 
     102             :   /// Construct an ElementArrayView over given buffer.
     103             :   ElementArrayView(T *buffer, const scipp::index offset,
     104             :                    const Dimensions &iterDims, const Strides &strides,
     105             :                    const BucketParams &bucketParams = BucketParams{})
     106             :       : ElementArrayViewParams(offset, iterDims, strides, bucketParams),
     107             :         m_buffer(buffer) {}
     108             : 
     109             :   /// Construct an ElementArrayView over given buffer.
     110     7940837 :   ElementArrayView(const ElementArrayViewParams &base, T *buffer)
     111     7940837 :       : ElementArrayViewParams(base), m_buffer(buffer) {}
     112             : 
     113             :   /// Construct a ElementArrayView from another ElementArrayView, with different
     114             :   /// iteration dimensions.
     115             :   template <class Other>
     116     3416897 :   ElementArrayView(const Other &other, const Dimensions &iterDims)
     117     3416897 :       : ElementArrayViewParams(other, iterDims), m_buffer(other.buffer()) {}
     118             : 
     119     1209012 :   iterator begin() const {
     120     1209012 :     return {m_buffer + m_offset, m_iterDims, m_strides, 0};
     121             :   }
     122     1113425 :   iterator end() const {
     123     1113425 :     return {m_buffer + m_offset, m_iterDims, m_strides, size()};
     124             :   }
     125       94215 :   auto &operator[](const scipp::index i) const { return *(begin() + i); }
     126             : 
     127             :   auto &front() const { return *begin(); }
     128             :   auto &back() const { return *(begin() + (size() - 1)); }
     129             : 
     130             :   const T *data() const { return m_buffer + m_offset; }
     131  1349787383 :   T *data() { return m_buffer + m_offset; }
     132             : 
     133             :   auto as_span() const {
     134             :     requireContiguous();
     135             :     return scipp::span(data(), data() + size());
     136             :   }
     137             : 
     138       75969 :   auto as_span() {
     139       75969 :     requireContiguous();
     140       75969 :     return scipp::span(data(), data() + size());
     141             :   }
     142             : 
     143             :   bool operator==(const ElementArrayView<T> &other) const {
     144             :     if (dims() != other.dims())
     145             :       return false;
     146             :     return std::equal(begin(), end(), other.begin());
     147             :   }
     148             : 
     149      511401 :   template <class T2> bool overlaps(const ElementArrayView<T2> &other) const {
     150      511401 :     if (buffer() && buffer() == other.buffer())
     151         488 :       return ElementArrayViewParams::overlaps(other);
     152      510913 :     return false;
     153             :   }
     154             : 
     155     4940320 :   constexpr T *buffer() const noexcept { return m_buffer; }
     156             : 
     157             : private:
     158             :   T *m_buffer;
     159             : };
     160             : 
     161             : } // namespace scipp::core
     162             : 
     163             : namespace scipp {
     164             : using core::ElementArrayView;
     165             : }
     166             : 
     167             : // Specializations of ElementArrayView:
     168             : #include "scipp/core/bucket_array_view.h"

Generated by: LCOV version 1.14