LCOV - code coverage report
Current view: top level - src/Index - Index.h (source / functions) Coverage Total Hit
Test: report.info Lines: 100.0 % 3 3
Test Date: 2025-05-21 10:57:37 Functions: 100.0 % 1 1

            Line data    Source code
       1              : //
       2              : // Class Index
       3              : //   Define a slice in an array.
       4              : //
       5              : //   This essentially defines a list of evenly spaced numbers.
       6              : //   Most commonly this list will be increasing (positive stride)
       7              : //   but it can also have negative stride and be decreasing.
       8              : //
       9              : //   Index()      --> A null interval with no elements.
      10              : //   Index(n)     --> make an Index on [0..n-1]
      11              : //   Index(a,b)   --> make an Index on [a..b]
      12              : //   Index(a,b,s) --> make an Index on [a..b] with stride s
      13              : //
      14              : //   Example1:
      15              : //   --------
      16              : //   Index I(10);           --> Index on [0..9]
      17              : //   Index Low(5);          --> Index on [0..4]
      18              : //   Index High(5,9);       --> Index on [5..9]
      19              : //   Index IOdd(1,9,2);     --> Index on [1..9] stride 2
      20              : //   Index IEven(0,9,2);    --> Index on [0..9] stride 2
      21              : //
      22              : //   Given an Index I(a,n,s), and an integer j you can do the following:
      23              : //
      24              : //   I+j  : a+j+i*s        for i in [0..n-1]
      25              : //   j-I  : j-a-i*s
      26              : //   j*I  : j*a + i*j*s
      27              : //   I/j  : a/j + i*s/j
      28              : //
      29              : //   j/I we don't do because it is not a uniform stride, and we don't
      30              : //   allow strides that are fractions.
      31              : //
      32              : #ifndef IPPL_INDEX_H
      33              : #define IPPL_INDEX_H
      34              : 
      35              : #include <Kokkos_Core.hpp>
      36              : 
      37              : #include <iostream>
      38              : 
      39              : namespace ippl {
      40              :     class Index {
      41              :     public:
      42              :         class iterator {
      43              :         public:
      44              :             iterator()
      45              :                 : current_m(0)
      46              :                 , stride_m(0) {}
      47              : 
      48              :             iterator(int current, int stride = 1)
      49              :                 : current_m(current)
      50              :                 , stride_m(stride) {}
      51              : 
      52              :             int operator*() { return current_m; }
      53              : 
      54              :             iterator operator--(int) {
      55              :                 iterator tmp = *this;
      56              :                 current_m -= stride_m;  // Post decrement
      57              :                 return tmp;
      58              :             }
      59              : 
      60              :             iterator& operator--() {
      61              :                 current_m -= stride_m;
      62              :                 return (*this);
      63              :             }
      64              : 
      65              :             iterator operator++(int) {
      66              :                 iterator tmp = *this;
      67              :                 current_m += stride_m;  // Post increment
      68              :                 return tmp;
      69              :             }
      70              : 
      71              :             iterator& operator++() {
      72              :                 current_m += stride_m;
      73              :                 return (*this);
      74              :             }
      75              : 
      76              :             iterator& operator+=(int i) {
      77              :                 current_m += (stride_m * i);
      78              :                 return *this;
      79              :             }
      80              : 
      81              :             iterator& operator-=(int i) {
      82              :                 current_m -= (stride_m * i);
      83              :                 return *this;
      84              :             }
      85              : 
      86              :             iterator operator+(int i) const { return iterator(current_m + i * stride_m, stride_m); }
      87              : 
      88              :             iterator operator-(int i) const { return iterator(current_m - i * stride_m, stride_m); }
      89              : 
      90              :             int operator[](int i) const { return current_m + i * stride_m; }
      91              : 
      92              :             bool operator==(const iterator& y) const {
      93              :                 return (current_m == y.current_m) && (stride_m == y.stride_m);
      94              :             }
      95              : 
      96              :             bool operator<(const iterator& y) const {
      97              :                 return (current_m < y.current_m)
      98              :                        || ((current_m == y.current_m) && (stride_m < y.stride_m));
      99              :             }
     100              : 
     101              :             bool operator!=(const iterator& y) const { return !((*this) == y); }
     102              : 
     103              :             bool operator>(const iterator& y) const { return y < (*this); }
     104              : 
     105              :             bool operator<=(const iterator& y) const { return !(y < (*this)); }
     106              : 
     107              :             bool operator>=(const iterator& y) const { return !((*this) < y); }
     108              : 
     109              :         private:
     110              :             int current_m;
     111              :             int stride_m;
     112              :         };
     113              : 
     114              :         /*!
     115              :          * Instantiate Index without any range.
     116              :          */
     117              :         KOKKOS_INLINE_FUNCTION Index();
     118              : 
     119              :         /*!
     120              :          * Instantiate Index with range [0, ..., n-1]
     121              :          * @param n number of elements
     122              :          */
     123              :         KOKKOS_INLINE_FUNCTION Index(size_t n);
     124              : 
     125              :         /*!
     126              :          * Instantiate Index with user-defined lower and upper
     127              :          * bound [f, ..., l].
     128              :          * @param f first element
     129              :          * @param l last element
     130              :          */
     131              :         KOKKOS_INLINE_FUNCTION Index(int f, int l);
     132              : 
     133              :         /*!
     134              :          * First to Last using Step.
     135              :          * @param f first element
     136              :          * @param l last element
     137              :          * @param s step
     138              :          */
     139              :         KOKKOS_INLINE_FUNCTION Index(int f, int l, int s);
     140              : 
     141              :         KOKKOS_DEFAULTED_FUNCTION
     142              :         ~Index() = default;
     143              : 
     144              :         /*!
     145              :          * @returns the smallest element
     146              :          */
     147              :         KOKKOS_INLINE_FUNCTION int min() const noexcept;
     148              : 
     149              :         /*!
     150              :          * @returns the largest element
     151              :          */
     152              :         KOKKOS_INLINE_FUNCTION int max() const noexcept;
     153              : 
     154              :         /*!
     155              :          * @returns the number of elements
     156              :          */
     157              :         KOKKOS_INLINE_FUNCTION size_t length() const noexcept;
     158              : 
     159              :         /*!
     160              :          * @returns the stride
     161              :          */
     162              :         KOKKOS_INLINE_FUNCTION int stride() const noexcept;
     163              : 
     164              :         /*!
     165              :          * @returns the first element
     166              :          */
     167              :         KOKKOS_INLINE_FUNCTION int first() const noexcept;
     168              : 
     169              :         /*!
     170              :          * @returns the last element
     171              :          */
     172              :         KOKKOS_INLINE_FUNCTION int last() const noexcept;
     173              : 
     174              :         /*!
     175              :          * @returns true if empty, otherwise false
     176              :          */
     177              :         KOKKOS_INLINE_FUNCTION bool empty() const noexcept;
     178              : 
     179              :         KOKKOS_INLINE_FUNCTION Index& operator+=(int);
     180              : 
     181              :         KOKKOS_INLINE_FUNCTION Index& operator-=(int);
     182              : 
     183              :         // Additive operations.
     184              :         KOKKOS_INLINE_FUNCTION friend Index operator+(const Index&, int);
     185              : 
     186              :         KOKKOS_INLINE_FUNCTION friend Index operator+(int, const Index&);
     187              : 
     188              :         KOKKOS_INLINE_FUNCTION friend Index operator-(const Index&, int);
     189              : 
     190              :         KOKKOS_INLINE_FUNCTION friend Index operator-(int, const Index&);
     191              : 
     192              :         // Multipplicative operations.
     193              :         KOKKOS_INLINE_FUNCTION friend Index operator-(const Index&);
     194              : 
     195              :         KOKKOS_INLINE_FUNCTION friend Index operator*(const Index&, int);
     196              : 
     197              :         KOKKOS_INLINE_FUNCTION friend Index operator*(int, const Index&);
     198              : 
     199              :         KOKKOS_INLINE_FUNCTION friend Index operator/(const Index&, int);
     200              : 
     201              :         // Intersect with another Index.
     202              :         KOKKOS_INLINE_FUNCTION Index intersect(const Index&) const;
     203              : 
     204              :         // Intersect with another Index.
     205              :         KOKKOS_INLINE_FUNCTION Index grow(int ncells) const;
     206              : 
     207              :         // Test to see if there is any overlap between two Indexes.
     208              :         KOKKOS_INLINE_FUNCTION bool touches(const Index& a) const;
     209              :         // Test to see if one contains another (endpoints only)
     210              :         KOKKOS_INLINE_FUNCTION bool contains(const Index& a) const;
     211              :         // Split one into two.
     212              :         KOKKOS_INLINE_FUNCTION bool split(Index& l, Index& r) const;
     213              :         // Split one into two at index i.
     214              :         KOKKOS_INLINE_FUNCTION bool split(Index& l, Index& r, int i) const;
     215              :         // Split index into two with a ratio between 0 and 1.
     216              :         KOKKOS_INLINE_FUNCTION bool split(Index& l, Index& r, double a) const;
     217              : 
     218              :         // iterator begin
     219              :         iterator begin() { return iterator(first_m, stride_m); }
     220              :         // iterator end
     221              :         iterator end() { return iterator(first_m + stride_m * length_m, stride_m); }
     222              : 
     223              :         // An operator< so we can impose some sort of ordering.
     224              :         KOKKOS_INLINE_FUNCTION bool operator<(const Index& r) const {
     225              :             return (
     226              :                 (length_m < r.length_m)
     227              :                 || ((length_m == r.length_m)
     228              :                     && ((first_m < r.first_m)
     229              :                         || ((first_m == r.first_m) && (length_m > 0) && (stride_m < r.stride_m)))));
     230              :         }
     231              :         // Test for equality.
     232              :         KOKKOS_INLINE_FUNCTION bool operator==(const Index& r) const noexcept {
     233              :             return (length_m == r.length_m) && (first_m == r.first_m) && (stride_m == r.stride_m);
     234              :         }
     235              : 
     236              :     private:
     237              :         int first_m;  /// First index element
     238              :         int stride_m;
     239              :         size_t length_m;  /// The number of elements
     240              : 
     241              :         // Make an Index that interally counts the other direction.
     242              :         KOKKOS_INLINE_FUNCTION Index reverse() const;
     243              : 
     244              :         // Construct with a given base. This is private because
     245              :         // the interface shouldn't depend on how this is done.
     246              : 
     247              :         KOKKOS_INLINE_FUNCTION Index(int m, int a, const Index& b);
     248              : 
     249              :         KOKKOS_INLINE_FUNCTION Index(int f, int s, const Index* b);
     250              : 
     251              :         // Do a general intersect if the strides are not both 1.
     252              :         KOKKOS_INLINE_FUNCTION Index general_intersect(const Index&) const;
     253              :     };
     254              : 
     255           42 :     inline std::ostream& operator<<(std::ostream& out, const Index& I) {
     256           42 :         out << '[' << I.first() << ':' << I.last() << ':' << I.stride() << ']';
     257           42 :         return out;
     258              :     }
     259              : }  // namespace ippl
     260              : 
     261              : #include "Index/Index.hpp"
     262              : 
     263              : #endif
        

Generated by: LCOV version 2.0-1