prefix sum array
uti::prefix_array
value_type range ( ssize_type x1, ssize_type x2 ) const noexcept
{
return x1 == 0 ? at( x1 )
: at( x1 )
- at( x0 - 1 ) ;
}
decltype( auto ) range ( ssize_type x1, ssize_type y1,
ssize_type x2, ssize_type y2 ) const noexcept
requires( is_2d_range_container_v< _self > )
{
return x1 == 0 ? at( x2 ).range( y1, y2 )
: at( x2 ).range( y1, y2 )
- at( x1 - 1 ).range( y1, y2 ) ;
}
decltype( auto ) range ( ssize_type x1, ssize_type y1, ssize_type z1,
ssize_type x2, ssize_type y2, ssize_type z2 ) const noexcept
requires( is_3d_range_container_v< _self > )
{
return x1 == 0 ? at( x2 ).range( y1, z1, y2, z2 )
: at( x2 ).range( y1, z1, y2, z2 )
- at( x1 - 1 ).range( y1, z1, y2, z2 ) ;
}
// need this cause the 'concept any' approach doesn't deduce lhs and rhs as expected
template< ssize_t >
struct index
{
ssize_t idx ;
template< ssize_t Idx_ >
constexpr index ( index< Idx_ > other ) : idx( other.idx ) {}
constexpr index ( ssize_t _idx_ ) : idx( _idx_ ) {}
constexpr operator ssize_t () const noexcept { return idx ; }
}
decltype( auto ) range ( auto&&... coords ) const noexcept
requires( sizeof...( coords ) % 2 == 0 &&
is_n_dimensional_container_v< _self, sizeof...( coords ) / 2 > )
{
constexpr auto Dim = sizeof...( coords ) / 2 ;
if constexpr( Dim == 1 )
{
return [ & ]( ssize_type x1, ssize_type x2 )
{
return x1 == 0 ? at( x2 )
: at( x2 )
- at( x1 - 1 ) ;
}( coords... ) ;
}
else
{
return [ & ]< ssize_type... Idxs >( uti::index_sequence< Idxs... > )
{
return [ & ]( ssize_type x1, index< Idxs >&&... lhs ,
ssize_type x2, index< Idxs >&&... rhs )
{
return x1 == 0 ? at( x2 ).range( lhs..., rhs... )
: at( x2 ).range( lhs..., rhs... )
- at( x1 - 1 ).range( lhs..., rhs... ) ;
}( coords... ) ;
}( uti::make_index_sequence< Dim - 1 >{} ) ;
}
}