std::strided_slice(3)

NAME
std::strided_slice - std::strided_slice

Synopsis
   Defined in header <mdspan>
   template< class OffsetType, class ExtentType, class StrideType > (since C++26)
   struct strided_slice;
   An instance of every specialization of strided_slice is a slice specifier used in
   std::submdspan to select a subset of elements using a set of regularly spaced
   indices at a specified dimension in std::mdspan. It provides three values: the
   offset index, the extent, and the stride.
   Given that stride is greater than zero, let N be the number of selected indices
   which is determined by 1 + (extent - 1) / stride if extent is nonzero, otherwise 0.
   The indices are selected from half-open interval [offset, offset + extent). Hence,
   the selected indices are offset, ..., offset + (N - 1) * stride.
   This class template has no base classes or declared members other than those shown
   below.

Template parameters
   OffsetType the types of offset, extent, and stride,
   ExtentType - respectively.
   StrideType

Type requirements
   -
   All template parameters must be unsigned or signed integer types or must satisfy
   integral-constant-like
   The program is ill-formed if the type requirement is not satisfied.

Member types
   Member type Definition
   offset_type OffsetType
   extent_type ExtentType
   stride_type StrideType
   Data members
   Member name Definition
   offset a starting index of type offset_type
               (public member object)
               a value of type extent_type added to offset used to define the upper
   extent bound of indices
               (public member object)
               an increment value of type stride_type which is equivalent to the
   stride distance between two indices
               (public member object)
   All these members are declared with [[no_unique_address]] attribute and have default
   member initializers where each data member is value initialized.

Notes
   Every specialization of strided_slice is an aggregate class which allows aggregate
   initialization (including designated initialization) of data members (for instance,
   std::strided_slice { .offset = 2, .extent = 10, .stride = 3 }).
   The slice specification of strided_slice takes advantage of the data member extent,
   as opposed to other slice specifications that use end to indicate the upper bound
   value. This is because it can directly generate a static extent for subview of
   std::mdspan if both extent and stride are of types that satisfy
   integral-constant-like. This enables efficient extraction of subviews with static
   extents by mixing compile time values with a runtime value of offset.

Example
// Run this code
 #include <mdspan>
 #include <print>
 template <typename View, typename O = int, typename E = int, typename S = int>
     requires (View::extents_type::rank() == 1)
 void print_sliced_view(View v, std::strided_slice<O, E, S> s)
 {
     using index_type = View::index_type;
     auto subview = std::submdspan(v, s);
     const auto& submap = subview.mapping();
     std::print("[");
     bool uses_comma = false;
     for (index_type i = 0; i < subview.extent(0); ++i)
     {
         if (uses_comma)
             std::print(", ");
         std::print("{}", subview[i]);
         uses_comma = true;
     }
     uses_comma = false;
     std::print("] extracted from indices [");
     for (index_type i = 0; i < subview.extent(0); ++i)
     {
         if (uses_comma)
             std::print(", ");
         std::print("{}", submap(i) + s.offset);
         uses_comma = true;
     }
     std::println("]");
 }
 int main()
 {
     static constexpr char letters [] {
         'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
         'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
         'U', 'V', 'W', 'X', 'Y', 'Z'
     };
     constexpr std::mdspan md (letters, 26);
     print_sliced_view(md, {.offset = 0, .extent = 10, .stride = 1});
     print_sliced_view(md, {.offset = 2, .extent = 10, .stride = 1});
     print_sliced_view(md, {.offset = 0, .extent = 5, .stride = 1});
     print_sliced_view(md, {.offset = 2, .extent = 5, .stride = 1});
     print_sliced_view(md, {.offset = 0, .extent = 10, .stride = 2});
     print_sliced_view(md, {.offset = 2, .extent = 10, .stride = 3});
     print_sliced_view(md, {.offset = 0, .extent = 15, .stride = 5});
     print_sliced_view(md, {.offset = 6, .extent = 15, .stride = 5});
 }

Output:
 [A, B, C, D, E, F, G, H, I, J] extracted from indices [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
 [C, D, E, F, G, H, I, J, K, L] extracted from indices [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
 [A, B, C, D, E] extracted from indices [0, 1, 2, 3, 4]
 [C, D, E, F, G] extracted from indices [2, 3, 4, 5, 6]
 [A, C, E, G, I] extracted from indices [0, 2, 4, 6, 8]
 [C, F, I, L] extracted from indices [2, 5, 8, 11]
 [A, F, K] extracted from indices [0, 5, 10]
 [G, L, Q] extracted from indices [6, 11, 16]

See also
   slice BLAS-like slice of a valarray: starting index, length, stride
             (class)
   submdspan returns a view of a subset of an existing mdspan
   (C++26) (function template)