LCOV - code coverage report
Current view: top level - include/utils - int_range.h (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4476 (4beb67) with base a68cc6 Lines: 24 37 64.9 %
Date: 2026-06-03 20:22:46 Functions: 91 127 71.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // The libMesh Finite Element Library.
       2             : // Copyright (C) 2002-2026 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
       3             : 
       4             : // This library is free software; you can redistribute it and/or
       5             : // modify it under the terms of the GNU Lesser General Public
       6             : // License as published by the Free Software Foundation; either
       7             : // version 2.1 of the License, or (at your option) any later version.
       8             : 
       9             : // This library is distributed in the hope that it will be useful,
      10             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12             : // Lesser General Public License for more details.
      13             : 
      14             : // You should have received a copy of the GNU Lesser General Public
      15             : // License along with this library; if not, write to the Free Software
      16             : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      17             : 
      18             : 
      19             : 
      20             : #ifndef LIBMESH_INT_RANGE_H
      21             : #define LIBMESH_INT_RANGE_H
      22             : 
      23             : #include "libmesh/libmesh_common.h" // cast_int
      24             : 
      25             : // C++ includes
      26             : #include <vector>
      27             : 
      28             : namespace libMesh
      29             : {
      30             : 
      31             : // Forward declarations
      32             : template <typename T> class DenseSubVector;
      33             : template <typename T> class DenseVector;
      34             : template <typename T> class NumericVector;
      35             : 
      36             : /**
      37             :  * The \p IntRange templated class is intended to make it easy to
      38             :  * loop over integers which are indices of a container.
      39             :  *
      40             :  * In cases where such a range is defined by the result of a virtual
      41             :  * function call, this allows range-based for loops to be easily
      42             :  * written which make only a single such call, rather than a new call
      43             :  * for each iteration.
      44             :  *
      45             :  * We perform a cast_int operation (no-op in opt mode, test+assert in
      46             :  * debug) at construction time to make sure that the given range
      47             :  * bounds are representable by the given range type.
      48             :  *
      49             :  * \author  Roy H. Stogner
      50             :  */
      51             : 
      52             : template <typename T>
      53             : class IntRange
      54             : {
      55             : public:
      56             :   class iterator {
      57             :   public:
      58             :     using iterator_category = std::input_iterator_tag;
      59             :     using value_type = T;
      60             :     using difference_type = T;
      61             :     using pointer = T;
      62             :     using reference = T&;
      63             : 
      64   472222164 :     explicit iterator (T i) : _i(i) {}
      65             : 
      66  1121266994 :     T operator* () const { return _i; }
      67             : 
      68  1112529148 :     const iterator & operator++ ()
      69             :     {
      70 92397435498 :       ++_i;
      71 86277290189 :       return *this;
      72             :     }
      73             : 
      74             :     iterator operator++ (int)
      75             :     {
      76             :       iterator returnval(*this);
      77             :       ++_i;
      78             :       return returnval;
      79             :     }
      80             : 
      81             :     template <typename T2>
      82           0 :     void operator+= (T2 n)
      83             :     {
      84           0 :       _i += cast_int<T>(n);
      85           0 :     }
      86             : 
      87             :     template <typename T2>
      88           0 :     iterator operator+ (T2 n) const
      89             :     {
      90           0 :       iterator returnval(_i);
      91           0 :       returnval += n;
      92           0 :       return returnval;
      93             :     }
      94             : 
      95  1348640230 :     bool operator== (const iterator & j) const
      96             :     {
      97  1348640230 :       return ( _i == j._i );
      98             :     }
      99             : 
     100  1348640230 :     bool operator!= (const iterator & j) const
     101             :     {
     102  1348640230 :       return !(*this == j);
     103             :     }
     104             : 
     105             :   private:
     106             :     T _i;
     107             :   };
     108             : 
     109             :   typedef typename IntRange<T>::iterator const_iterator;
     110             : 
     111             :   template <typename U, typename V>
     112   260733772 :   IntRange(U begin, V end) :
     113    60850560 :     _begin(cast_int<T>(begin)),
     114   260733772 :     _end(cast_int<T>(end))
     115   260733772 :   {}
     116             : 
     117             :   // Signature needed for use in threads_pthread.h
     118           0 :   IntRange(const IntRange &,
     119             :            const const_iterator & begin,
     120             :            const const_iterator & end) :
     121           0 :     _begin(begin),
     122           0 :     _end(end)
     123           0 :   {}
     124             : 
     125   236112876 :   iterator begin() const { return _begin; }
     126             : 
     127   236112876 :   iterator end () const { return _end; }
     128             : 
     129          70 :   std::size_t size () const
     130        1934 :   { return *_end - *_begin; }
     131             : 
     132             :   // For thread splitting control
     133        1934 :   std::size_t grainsize () const { return libMesh::default_grainsize(); }
     134             : 
     135             : private:
     136             :   iterator _begin, _end;
     137             : };
     138             : 
     139             : 
     140             : template <typename T, typename T2>
     141             : typename IntRange<T>::iterator operator+ (T2 n, typename IntRange<T>::iterator i)
     142             : {
     143             :   return i + n;
     144             : }
     145             : 
     146             : 
     147             : /**
     148             :  * Helper function that returns an IntRange<std::size_t> representing
     149             :  * all the indices of the passed-in vector-like object (i.e. any type that
     150             :  * has a size() member).
     151             :  */
     152             : template <typename T>
     153   236151575 : auto index_range(const T & sizable)
     154             : {
     155   575711681 :   return IntRange<decltype(sizable.size())>(0, sizable.size());
     156             : }
     157             : 
     158             : 
     159             : /**
     160             :  * Same thing but for NumericVector. Returns a range (first_local_index, last_local_index).
     161             :  */
     162             : template <typename T>
     163           0 : IntRange<numeric_index_type> index_range(const NumericVector<T> & vec)
     164             : {
     165           0 :   return {vec.first_local_index(), vec.last_local_index()};
     166             : }
     167             : 
     168             : 
     169             : 
     170             : /**
     171             :  * The 2-parameter make_range() helper function returns an IntRange<T>
     172             :  * when both input parameters are of type T. This saves a bit of
     173             :  * typing over calling the IntRange<T> constructor directly.
     174             :  */
     175             : template <typename T>
     176     3804111 : IntRange<T> make_range(T beg, T end)
     177             : {
     178     3804111 :   return {beg, end};
     179             : }
     180             : 
     181             : 
     182             : 
     183             : /**
     184             :  * The 1-parameter version of make_range() saves even more typing in
     185             :  * the common case of a 0 starting point. Example usage:
     186             :  *
     187             :  * for (auto i : make_range(10))
     188             :  *
     189             :  * will loop from 0 to 9. In more realistic cases such as:
     190             :  *
     191             :  * for (auto i : make_range(foo()))
     192             :  *
     193             :  * this construction guarantees that the function foo() is called
     194             :  * exactly once rather than once per loop iteration.
     195             :  */
     196             : template <typename T>
     197   145298899 : IntRange<T> make_range(T end)
     198             : {
     199   145298899 :   return {T(0), end};
     200             : }
     201             : 
     202             : } // namespace libMesh
     203             : 
     204             : #endif // LIBMESH_INT_RANGE_H

Generated by: LCOV version 1.14