Difference between revisions of "cpp/container/mdspan"
From cppreference.com
m (add default_accessor) |
m (→Members objects: +"id=name" anchors. Should this section be "Data members", for unification?.) |
||
(20 intermediate revisions by 6 users not shown) | |||
Line 13: | Line 13: | ||
{{dcl end}} | {{dcl end}} | ||
− | {{tt|std::mdspan}} is a | + | {{tt|std::mdspan}} is a view into a contiguous sequence of objects that reinterprets it as a multidimensional array. |
− | Each specialization {{tt|MDS}} of {{tt|mdspan}} models {{lconcept|copyable}} and: | + | Each specialization {{tt|MDS}} of {{tt|mdspan}} models {{lconcept|copyable}} and satisfies: |
:* {{c|std::is_nothrow_move_constructible_v<MDS>}} is {{c|true}}, | :* {{c|std::is_nothrow_move_constructible_v<MDS>}} is {{c|true}}, | ||
:* {{c|std::is_nothrow_move_assignable_v<MDS>}} is {{c|true}}, and | :* {{c|std::is_nothrow_move_assignable_v<MDS>}} is {{c|true}}, and | ||
− | :* {{c|std::is_nothrow_swappable_v<MDS>}} is {{c|true}} | + | :* {{c|std::is_nothrow_swappable_v<MDS>}} is {{c|true}}. |
A specialization of {{tt|mdspan}} is a {{named req|TriviallyCopyable}} type if its {{tt|accessor_type}}, {{tt|mapping_type}} and {{tt|data_handle_type}} are {{named req|TriviallyCopyable}} types. | A specialization of {{tt|mdspan}} is a {{named req|TriviallyCopyable}} type if its {{tt|accessor_type}}, {{tt|mapping_type}} and {{tt|data_handle_type}} are {{named req|TriviallyCopyable}} types. | ||
===Template parameters=== | ===Template parameters=== | ||
{{par begin}} | {{par begin}} | ||
− | {{par|T|element type; a complete object type that is neither an abstract class type nor an array type | + | {{par|T|element type; a complete object type that is neither an abstract class type nor an array type.}} |
− | {{par|Extents|specifies number of dimensions, their sizes, and which are known at compile time. Must be a specialization of {{lc|std::extents}} | + | {{par|Extents|specifies number of dimensions, their sizes, and which are known at compile time. Must be a specialization of {{lc|std::extents}}.}} |
− | {{par|LayoutPolicy|specifies how to convert multidimensional index to underlying 1D index (column-major 3D array, symmetric triangular 2D matrix, etc).}} | + | {{par|LayoutPolicy|specifies how to convert multidimensional index to underlying 1D index (column-major 3D array, symmetric triangular 2D matrix, etc). Must satisfy the requirements of {{named req|LayoutMappingPolicy}}.}} |
− | {{par|AccessorPolicy|specifies how to convert underlying 1D index to a reference to T. Must satisfy the constraint that {{c|std::is_same_v<T, typename AccessorPolicy::element_type>}} is {{c|true}}.}} | + | {{par|AccessorPolicy|specifies how to convert underlying 1D index to a reference to T. Must satisfy the constraint that {{c|std::is_same_v<T, typename AccessorPolicy::element_type>}} is {{c|true}}. Must satisfy the requirements of {{named req|AccessorPolicy}}.}} |
{{par end}} | {{par end}} | ||
− | |||
− | |||
===Member types=== | ===Member types=== | ||
Line 37: | Line 35: | ||
{{dsc|{{tt|layout_type}}|{{tt|LayoutPolicy}}}} | {{dsc|{{tt|layout_type}}|{{tt|LayoutPolicy}}}} | ||
{{dsc|{{tt|accessor_type}}|{{tt|AccessorPolicy}}}} | {{dsc|{{tt|accessor_type}}|{{tt|AccessorPolicy}}}} | ||
− | {{dsc|{{tt|mapping_type}}|{{ | + | {{dsc|{{tt|mapping_type}}|{{c/core|LayoutPolicy::mapping<Extents>}}}} |
{{dsc|{{tt|element_type}}|{{tt|T}}}} | {{dsc|{{tt|element_type}}|{{tt|T}}}} | ||
− | {{dsc|{{tt|value_type}}|{{ | + | {{dsc|{{tt|value_type}}|{{c/core|std::remove_cv_t<T>}}}} |
− | {{dsc|{{tt|index_type}}|{{ | + | {{dsc|{{tt|index_type}}|{{c/core|Extents::index_type}}}} |
− | {{dsc|{{tt|size_type}}|{{ | + | {{dsc|{{tt|size_type}}|{{c/core|Extents::size_type}}}} |
− | {{dsc|{{tt|rank_type}}|{{ | + | {{dsc|{{tt|rank_type}}|{{c/core|Extents::rank_type}}}} |
− | {{dsc|{{tt|data_handle_type}}|{{ | + | {{dsc|{{tt|data_handle_type}}|{{c/core|AccessorPolicy::data_handle_type}}}} |
− | {{dsc|{{tt|reference}}|{{ | + | {{dsc|{{tt|reference}}|{{c/core|AccessorPolicy::reference}}}} |
{{dsc end}} | {{dsc end}} | ||
− | === | + | ===Member objects=== |
− | + | {{dsc begin}} | |
− | + | {{dsc hitem|Name|Definition}} | |
− | + | {{dsc expos mem obj|acc_|id=acc|private=yes|The accessor of type {{tt|accessor_type}}}} | |
− | + | {{dsc expos mem obj|map_|id=map|private=yes|The layout mapping of type {{tt|mapping_type}}}} | |
− | + | {{dsc expos mem obj|ptr_|id=ptr|private=yes|The underlying data handle of type {{tt|data_handle_type}}}} | |
+ | {{dsc end}} | ||
===Member functions=== | ===Member functions=== | ||
Line 63: | Line 62: | ||
{{dsc h2|Observers}} | {{dsc h2|Observers}} | ||
+ | {{dsc inc|cpp/container/mdspan/dsc rank}} | ||
+ | {{dsc inc|cpp/container/mdspan/dsc rank_dynamic}} | ||
+ | {{dsc inc|cpp/container/mdspan/dsc static_extent}} | ||
+ | {{dsc inc|cpp/container/mdspan/dsc extent}} | ||
+ | |||
{{dsc inc|cpp/container/mdspan/dsc size}} | {{dsc inc|cpp/container/mdspan/dsc size}} | ||
{{dsc inc|cpp/container/mdspan/dsc empty}} | {{dsc inc|cpp/container/mdspan/dsc empty}} | ||
{{dsc inc|cpp/container/mdspan/dsc stride}} | {{dsc inc|cpp/container/mdspan/dsc stride}} | ||
− | {{dsc inc|cpp/container/mdspan/dsc extents_mfun}} <!-- dsc extents is for std::extents --> | + | {{dsc inc|cpp/container/mdspan/dsc extents_mfun}}<!--dsc extents is for std::extents--> |
{{dsc inc|cpp/container/mdspan/dsc data_handle}} | {{dsc inc|cpp/container/mdspan/dsc data_handle}} | ||
{{dsc inc|cpp/container/mdspan/dsc mapping}} | {{dsc inc|cpp/container/mdspan/dsc mapping}} | ||
Line 82: | Line 86: | ||
{{dsc begin}} | {{dsc begin}} | ||
{{dsc inc|cpp/container/mdspan/dsc swap}} | {{dsc inc|cpp/container/mdspan/dsc swap}} | ||
+ | {{dsc h2|Subviews}} | ||
+ | {{dsc inc|cpp/container/mdspan/dsc submdspan}} | ||
+ | {{dsc inc|cpp/container/mdspan/dsc submdspan_extents}} | ||
{{dsc end}} | {{dsc end}} | ||
Line 88: | Line 95: | ||
{{dsc inc|cpp/container/mdspan/dsc extents}} | {{dsc inc|cpp/container/mdspan/dsc extents}} | ||
{{dsc inc|cpp/container/mdspan/dsc dextents}} | {{dsc inc|cpp/container/mdspan/dsc dextents}} | ||
− | {{dsc inc|cpp/container/mdspan/dsc | + | {{dsc inc|cpp/container/mdspan/dsc default_accessor}} |
+ | {{dsc h2|Layout mapping policies}} | ||
{{dsc inc|cpp/container/mdspan/dsc layout_left}} | {{dsc inc|cpp/container/mdspan/dsc layout_left}} | ||
+ | {{dsc inc|cpp/container/mdspan/dsc layout_right}} | ||
{{dsc inc|cpp/container/mdspan/dsc layout_stride}} | {{dsc inc|cpp/container/mdspan/dsc layout_stride}} | ||
− | {{dsc inc|cpp/container/mdspan/dsc | + | {{dsc inc|cpp/container/mdspan/dsc layout_left_padded}} |
+ | {{dsc inc|cpp/container/mdspan/dsc layout_right_padded}} | ||
+ | {{dsc h2|Subviews helpers}} | ||
+ | {{dsc inc|cpp/container/mdspan/dsc full_extent}} | ||
+ | {{dsc inc|cpp/container/mdspan/dsc strided_slice}} | ||
+ | {{dsc inc|cpp/container/mdspan/dsc submdspan_mapping_result}} | ||
{{dsc end}} | {{dsc end}} | ||
Line 97: | Line 111: | ||
===Notes=== | ===Notes=== | ||
− | + | {{ftm begin|sort=yes}} | |
− | {{ | + | {{ftm|value=202207L|std=C++23|__cpp_lib_mdspan|{{tt|std::mdspan}}}} |
+ | {{ftm|value=202306L|std=C++26|__cpp_lib_submdspan|rowspan="2"|{{lc|std::submdspan}}}} | ||
+ | {{ftm|value=202403L|std=C++26|-|{{tt|std::mdspan}} padded layouts}} | ||
+ | {{ftm end}} | ||
===Example=== | ===Example=== | ||
{{example | {{example | ||
− | | | + | |Can be previewed on [https://godbolt.org/z/6WqGonPTn Compiler Explorer]. |
|code= | |code= | ||
+ | #include <cstddef> | ||
#include <mdspan> | #include <mdspan> | ||
#include <print> | #include <print> | ||
Line 110: | Line 128: | ||
int main() | int main() | ||
{ | { | ||
− | std::vector v | + | std::vector v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; |
// View data as contiguous memory representing 2 rows of 6 ints each | // View data as contiguous memory representing 2 rows of 6 ints each | ||
Line 117: | Line 135: | ||
auto ms3 = std::mdspan(v.data(), 2, 3, 2); | auto ms3 = std::mdspan(v.data(), 2, 3, 2); | ||
− | // | + | // Write data using 2D view |
− | for (size_t i = 0; i != ms2.extent(0); i++) | + | for (std::size_t i = 0; i != ms2.extent(0); i++) |
− | for (size_t j = 0; j != ms2.extent(1); j++) | + | for (std::size_t j = 0; j != ms2.extent(1); j++) |
ms2[i, j] = i * 1000 + j; | ms2[i, j] = i * 1000 + j; | ||
− | // | + | // Read back using 3D view |
− | for (size_t i = 0; i != ms3.extent(0); i++) | + | for (std::size_t i = 0; i != ms3.extent(0); i++) |
{ | { | ||
std::println("slice @ i = {}", i); | std::println("slice @ i = {}", i); | ||
− | for (size_t j = 0; j != ms3.extent(1); j++) | + | for (std::size_t j = 0; j != ms3.extent(1); j++) |
{ | { | ||
− | for (size_t k = 0; k != ms3.extent(2); k++) | + | for (std::size_t k = 0; k != ms3.extent(2); k++) |
std::print("{} ", ms3[i, j, k]); | std::print("{} ", ms3[i, j, k]); | ||
std::println(""); | std::println(""); |
Latest revision as of 14:53, 18 October 2024
Defined in header <mdspan>
|
||
template< class T, |
(since C++23) | |
std::mdspan
is a view into a contiguous sequence of objects that reinterprets it as a multidimensional array.
Each specialization MDS
of mdspan
models copyable
and satisfies:
- std::is_nothrow_move_constructible_v<MDS> is true,
- std::is_nothrow_move_assignable_v<MDS> is true, and
- std::is_nothrow_swappable_v<MDS> is true.
A specialization of mdspan
is a TriviallyCopyable type if its accessor_type
, mapping_type
and data_handle_type
are TriviallyCopyable types.
Contents |
[edit] Template parameters
T | - | element type; a complete object type that is neither an abstract class type nor an array type. |
Extents | - | specifies number of dimensions, their sizes, and which are known at compile time. Must be a specialization of std::extents. |
LayoutPolicy | - | specifies how to convert multidimensional index to underlying 1D index (column-major 3D array, symmetric triangular 2D matrix, etc). Must satisfy the requirements of LayoutMappingPolicy. |
AccessorPolicy | - | specifies how to convert underlying 1D index to a reference to T. Must satisfy the constraint that std::is_same_v<T, typename AccessorPolicy::element_type> is true. Must satisfy the requirements of AccessorPolicy. |
[edit] Member types
Member type | Definition |
extents_type
|
Extents
|
layout_type
|
LayoutPolicy
|
accessor_type
|
AccessorPolicy
|
mapping_type
|
LayoutPolicy::mapping<Extents> |
element_type
|
T
|
value_type
|
std::remove_cv_t<T> |
index_type
|
Extents::index_type |
size_type
|
Extents::size_type |
rank_type
|
Extents::rank_type |
data_handle_type
|
AccessorPolicy::data_handle_type |
reference
|
AccessorPolicy::reference |
[edit] Member objects
Name | Definition |
acc_ (private)
|
The accessor of type accessor_type (exposition-only member object*) |
map_ (private)
|
The layout mapping of type mapping_type (exposition-only member object*) |
ptr_ (private)
|
The underlying data handle of type data_handle_type (exposition-only member object*) |
[edit] Member functions
constructs an mdspan (public member function) | |
assigns an mdspan (public member function) | |
Element access | |
accesses an element at the specified multidimensional index (public member function) | |
Observers | |
[static] |
returns the rank of a mdspan (public static member function) |
[static] |
returns the dynamic rank of a mdspan (public static member function) |
[static] |
returns the static extent size of a mdspan at a given rank index (public static member function) |
returns the extent of a mdspan at a given rank index (public member function) | |
returns the size of the multidimensional index space (public member function) | |
checks if the size of the index space is zero (public member function) | |
obtains the stride along the specified dimension (public member function) | |
obtains the extents object (public member function) | |
obtains the pointer to the underlying 1D sequence (public member function) | |
obtains the mapping object (public member function) | |
obtains the accessor policy object (public member function) | |
determines if this mdspan's mapping is unique (every combination of indices maps to a different underlying element) (public member function) | |
determines if this mdspan's mapping is exhaustive (every underlying element can be accessed with some combination of indices) (public member function) | |
determines if this mdspan's mapping is strided (in each dimension, incrementing an index jumps over the same number of underlying elements every time) (public member function) | |
[static] |
determines if this mdspan's layout mapping is always unique (public static member function) |
[static] |
determines if this mdspan's layout mapping is always exhaustive (public static member function) |
[static] |
determines if this mdspan's layout mapping is always strided (public static member function) |
[edit] Non-member functions
(C++23) |
specializes the std::swap algorithm for mdspan (function template) |
Subviews | |
(C++26) |
returns a view of a subset of an existing mdspan (function template) |
(C++26) |
creates new extents from the existing extents and slice specifiers (function template) |
[edit] Helper types and templates
(C++23) |
a descriptor of a multidimensional index space of some rank (class template) |
(C++23)(C++26) |
convenience alias template for an all-dynamic std::extents (alias template) |
(C++23) |
a type for indexed access to elements of mdspan (class template) |
Layout mapping policies | |
(C++23) |
column-major multidimensional array layout mapping policy; leftmost extent has stride 1 (class) |
(C++23) |
row-major multidimensional array layout mapping policy; rightmost extent has stride 1 (class) |
(C++23) |
a layout mapping policy with user-defined strides (class) |
(C++26) |
column-major layout mapping policy with padding stride that can be greater than or equal to the leftmost extent (class template) |
(C++26) |
row-major layout mapping policy with padding stride that can be greater than or equal to the rightmost extent (class template) |
Subviews helpers | |
(C++26) |
a slice specifier tag describing full range of indices in the specified extent (tag) |
(C++26) |
a slice specifier representing a set of regularly spaced indices as indicated by an offset, an extent, and a stride (class template) |
(C++26) |
a return type of the overloads of submdspan_mapping (class template) |
[edit] Deduction guides
[edit] Notes
Feature-test macro | Value | Std | Feature |
---|---|---|---|
__cpp_lib_mdspan |
202207L | (C++23) | std::mdspan
|
__cpp_lib_submdspan |
202306L | (C++26) | std::submdspan |
202403L | (C++26) | std::mdspan padded layouts
|
[edit] Example
Can be previewed on Compiler Explorer.
Run this code
#include <cstddef> #include <mdspan> #include <print> #include <vector> int main() { std::vector v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; // View data as contiguous memory representing 2 rows of 6 ints each auto ms2 = std::mdspan(v.data(), 2, 6); // View the same data as a 3D array 2 x 3 x 2 auto ms3 = std::mdspan(v.data(), 2, 3, 2); // Write data using 2D view for (std::size_t i = 0; i != ms2.extent(0); i++) for (std::size_t j = 0; j != ms2.extent(1); j++) ms2[i, j] = i * 1000 + j; // Read back using 3D view for (std::size_t i = 0; i != ms3.extent(0); i++) { std::println("slice @ i = {}", i); for (std::size_t j = 0; j != ms3.extent(1); j++) { for (std::size_t k = 0; k != ms3.extent(2); k++) std::print("{} ", ms3[i, j, k]); std::println(""); } } }
Output:
slice @ i = 0 0 1 2 3 4 5 slice @ i = 1 1000 1001 1002 1003 1004 1005
[edit] See also
(C++20) |
a non-owning view over a contiguous sequence of objects (class template) |
numeric arrays, array masks and array slices (class template) |