Loading...
Searching...
No Matches
tf::IndexRange< T, N > Class Template Reference

class to create an N-dimensional index range of integral indices More...

#include <taskflow/utility/iterator.hpp>

Public Types

using index_type = T
 alias for the index type
 

Public Member Functions

 IndexRange ()=default
 constructs an N-dimensional index range without initialization
 
template<typename... Ranges>
requires (sizeof...(Ranges) == N) && (std::same_as<std::remove_cvref_t<Ranges>, IndexRange<T, 1>> && ...)
 IndexRange (Ranges &&... ranges)
 constructs an N-D index range from N 1D IndexRange<T, 1> objects
 
 IndexRange (const std::array< IndexRange< T, 1 >, N > &dims)
 constructs an N-D index range from an array of 1D ranges
 
const IndexRange< T, 1 > & dim (size_t d) const
 returns the 1D range for dimension d (read-only)
 
IndexRange< T, 1 > & dim (size_t d)
 returns the 1D range for dimension d (mutable)
 
const std::array< IndexRange< T, 1 >, N > & dims () const
 returns the underlying array of per-dimension ranges
 
size_t size (size_t d) const
 returns the number of iterations along dimension d
 
size_t size () const
 returns the total number of iterations across all dimensions
 
std::array< T, N > coords (size_t flat) const
 maps a zero-based flat index to its N-D index coordinates (row-major)
 
std::pair< IndexRange< T, N >, size_t > consume_chunk (size_t flat_beg, size_t requested_size) const
 consumes a linear chunk of the multidimensional space and returns the largest valid N-dimensional sub-box
 

Static Public Attributes

static constexpr size_t rank = N
 the number of dimensions
 

Detailed Description

template<std::integral T, size_t N>
class tf::IndexRange< T, N >

class to create an N-dimensional index range of integral indices

Template Parameters
Tthe integral type of the indices
Nthe number of dimensions (must be > 1; use IndexRange<T, 1> for 1D)

This class represents the Cartesian product of N independent 1D index ranges, each defined by a starting index, ending index, and step size. Iteration order is row-major: the last dimension varies fastest, matching the natural nesting of C-style for-loops.

// 3D range: i in [0,4), j in [0,6), k in [0,8), all step 1
);
printf("%zu\n", r.size()); // 4*6*8 = 192
class to create an N-dimensional index range of integral indices
Definition iterator.hpp:139
Attention
It is the user's responsibility to ensure each per-dimension range is valid.

Constructor & Destructor Documentation

◆ IndexRange()

template<std::integral T, size_t N>
template<typename... Ranges>
requires (sizeof...(Ranges) == N) && (std::same_as<std::remove_cvref_t<Ranges>, IndexRange<T, 1>> && ...)
tf::IndexRange< T, N >::IndexRange ( Ranges &&... ranges)
inlineexplicit

constructs an N-D index range from N 1D IndexRange<T, 1> objects

tf::IndexRange<int>(0, 10, 2), // dim 0: 0,2,4,6,8
tf::IndexRange<int>(0, 6, 3) // dim 1: 0,3
);

Member Function Documentation

◆ consume_chunk()

template<std::integral T, size_t N>
std::pair< IndexRange< T, N >, size_t > tf::IndexRange< T, N >::consume_chunk ( size_t flat_beg,
size_t requested_size ) const

consumes a linear chunk of the multidimensional space and returns the largest valid N-dimensional sub-box

Parameters
flat_begthe starting linear index (typically fetched from an atomic cursor)
requested_sizethe maximum number of elements allowed to consume (chunk size hint)
Returns
a pair containing the valid sub-box and the actual elements consumed

This function maps a linear index from a flat iteration space back into the multidimensional geometric space. To ensure the returned sub-box remains a valid, perfectly orthogonal hyper-rectangle, the function enforces a boundary constraint (the "trailing zeros" rule): a dimension can only grow if all dimensions inner to it are currently at coordinate 0.

Consequently, the actual number of elements consumed may be less than the requested_size if a geometric boundary is hit. This guarantees that workers never process discontiguous memory blocks or skip elements.

// 3D range: 4 x 5 x 10
);
// Scenario 1: flat_beg=0, requested=30
// Coords (0,0,0). inner_volume reaches 50 at dim-0 (first >= 30), so grow_dim=0,
// steps_to_take=1. The box overshoots to the next orthogonal boundary.
// box is [0,1) x [0,5) x [0,10), consumed=50
auto [box1, consumed1] = range.consume_chunk(0, 30);
// Scenario 2: flat_beg=30, requested=30
// Coords (0,3,0). coords[1]=3 != 0, so trailing-zeros fires at d=0.
// grow_dim=1, active=10. steps_left=2, steps_needed=3, steps_to_take=2.
// box is [0,1) x [3,5) x [0,10), consumed=20 (geometry-constrained, < requested)
auto [box2, consumed2] = range.consume_chunk(30, 30);
// Scenario 3: flat_beg=55, requested=30
// Coords (1,0,5). coords[2]=5 != 0, trailing-zeros fires at d=1.
// grow_dim=2, active=1. steps_left=5, steps_needed=30, steps_to_take=5.
// box is [1,2) x [0,1) x [5,10), consumed=5 (geometry-constrained, < requested)
auto [box3, consumed3] = range.consume_chunk(55, 30);
// Scenario 4: exact fit — requested equals a natural dimension boundary
// flat_beg=0, requested=10. inner_volume reaches 10 at d=1 (10>=10), stops there.
// grow_dim=1, active=10. steps_left=5, steps_needed=1, steps_to_take=1.
// box is [0,1) x [0,1) x [0,10), consumed=10 (no overshoot needed)
auto [box4, consumed4] = range.consume_chunk(0, 10);

◆ coords()

template<std::integral T, size_t N>
std::array< T, N > tf::IndexRange< T, N >::coords ( size_t flat) const

maps a zero-based flat index to its N-D index coordinates (row-major)

Parameters
flatzero-based flat index in [0, size())
Returns
array of N index values, one per dimension
tf::IndexRange<int>(0, 3, 1), // dim 0: 0, 1, 2
tf::IndexRange<int>(0, 4, 1) // dim 1: 0, 1, 2, 3
);
auto c = r.coords(5); // flat 5 -> row 1, col 1 -> {1, 1}

◆ size()

template<std::integral T, size_t N>
size_t tf::IndexRange< T, N >::size ( ) const

returns the total number of iterations across all dimensions

Equivalent to the product of each dimension's element count.

);
printf("%zu\n", r.size()); // 192

The documentation for this class was generated from the following file: