std::strided_slice(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

Hey bestie πŸ’– welcome to the std::strided_slice(3) page from the C++ Standard Libary. This is your main-character manual for a slice specifier that lowkey does the most in std::mdspan, and we’re gonna cover every single detail. No cap, periodt.

πŸ’… NAME πŸ’…

std::strided_slice - std::strided_slice

Okay so the name is literally the name. Iconic minimalism, honestly.

✨ Synopsis ✨

Defined in header <mdspan>. (since C++26) β€” here’s the template flex, bestie:

template< class OffsetType, class ExtentType, class StrideType >
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. It’s giving clean minimalism.

🌸 Template parameters 🌸

  • OffsetType, ExtentType, StrideType β€” the types of offset, extent, and stride, respectively.

πŸ’– 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.
Bestie, that β€œill-formed” part is not a vibe-check suggestion. It means the program is invalid if the requirement isn’t met. πŸ’€

πŸ¦‹ Member types πŸ¦‹

  • offset_type β€” OffsetType
  • extent_type β€” ExtentType
  • stride_type β€” StrideType

πŸŽ€ Data members πŸŽ€

  • offset β€” a starting index of type offset_type (public member object)
  • extent β€” a value of type extent_type added to offset used to define the upper bound of indices (public member object)
  • stride β€” an increment value of type stride_type which is equivalent to the 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 }). Obsessed with a designated-initializer moment.

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 (C++26) β€” returns a view of a subset of an existing mdspan (function template)

xoxo, sourced from http://cppreference.com, version/date 2024.06.10 β€” std::strided_slice(3) out πŸ’…βœ¨

πŸ“¦ where this page comes from