LCOV - code coverage report
Current view: top level - include/utils - int_range.h (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 21 23 91.3 %
Date: 2025-08-19 19:27:09 Functions: 89 121 73.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // The libMesh Finite Element Library.
       2             : // Copyright (C) 2002-2025 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   455029514 :     iterator (T i) : _i(i) {}
      65             : 
      66  1050058509 :     T operator* () const { return _i; }
      67             : 
      68  1041723276 :     const iterator & operator++ ()
      69             :     {
      70 >15526*10^7 :       ++_i;
      71 >14328*10^7 :       return *this;
      72             :     }
      73             : 
      74             :     iterator operator++ (int)
      75             :     {
      76             :       iterator returnval(*this);
      77             :       ++_i;
      78             :       return returnval;
      79             :     }
      80             : 
      81  1269238033 :     bool operator== (const iterator & j) const
      82             :     {
      83  1269238033 :       return ( _i == j._i );
      84             :     }
      85             : 
      86  1269238033 :     bool operator!= (const iterator & j) const
      87             :     {
      88  1269238033 :       return !(*this == j);
      89             :     }
      90             : 
      91             :   private:
      92             :     T _i;
      93             :   };
      94             : 
      95             :   template <typename U, typename V>
      96   252265623 :   IntRange(U begin, V end) :
      97    62268264 :     _begin(cast_int<T>(begin)),
      98   252265623 :     _end(cast_int<T>(end))
      99   252265623 :   {}
     100             : 
     101   227514757 :   iterator begin() const { return _begin; }
     102             : 
     103   227514757 :   iterator end () const { return _end; }
     104             : 
     105             : private:
     106             :   iterator _begin, _end;
     107             : };
     108             : 
     109             : 
     110             : 
     111             : /**
     112             :  * Helper function that returns an IntRange<std::size_t> representing
     113             :  * all the indices of the passed-in vector-like object (i.e. any type that
     114             :  * has a size() member).
     115             :  */
     116             : template <typename T>
     117   221361097 : auto index_range(const T & sizable)
     118             : {
     119   545246962 :   return IntRange<decltype(sizable.size())>(0, sizable.size());
     120             : }
     121             : 
     122             : 
     123             : /**
     124             :  * Same thing but for NumericVector. Returns a range (first_local_index, last_local_index).
     125             :  */
     126             : template <typename T>
     127           0 : IntRange<numeric_index_type> index_range(const NumericVector<T> & vec)
     128             : {
     129           0 :   return {vec.first_local_index(), vec.last_local_index()};
     130             : }
     131             : 
     132             : 
     133             : 
     134             : /**
     135             :  * The 2-parameter make_range() helper function returns an IntRange<T>
     136             :  * when both input parameters are of type T. This saves a bit of
     137             :  * typing over calling the IntRange<T> constructor directly.
     138             :  */
     139             : template <typename T>
     140     3976884 : IntRange<T> make_range(T beg, T end)
     141             : {
     142     3976884 :   return {beg, end};
     143             : }
     144             : 
     145             : 
     146             : 
     147             : /**
     148             :  * The 1-parameter version of make_range() saves even more typing in
     149             :  * the common case of a 0 starting point. Example usage:
     150             :  *
     151             :  * for (auto i : make_range(10))
     152             :  *
     153             :  * will loop from 0 to 9. In more realistic cases such as:
     154             :  *
     155             :  * for (auto i : make_range(foo()))
     156             :  *
     157             :  * this construction guarantees that the function foo() is called
     158             :  * exactly once rather than once per loop iteration.
     159             :  */
     160             : template <typename T>
     161   150787225 : IntRange<T> make_range(T end)
     162             : {
     163   150787225 :   return {T(0), end};
     164             : }
     165             : 
     166             : } // namespace libMesh
     167             : 
     168             : #endif // LIBMESH_INT_RANGE_H

Generated by: LCOV version 1.14