Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/container/mdspan"

From cppreference.com
< cpp‎ | container
m (Add std::mdspan::required_span_size() observer function)
m (Members objects: +"id=name" anchors. Should this section be "Data members", for unification?.)
 
(30 intermediate revisions by 7 users not shown)
Line 3: Line 3:
 
{{dcl begin}}
 
{{dcl begin}}
 
{{dcl header|mdspan}}
 
{{dcl header|mdspan}}
{{dcl | since=c++23 |1=
+
{{dcl|since=c++23|1=
 
template<
 
template<
 
     class T,
 
     class T,
Line 10: Line 10:
 
     class AccessorPolicy = std::default_accessor<T>
 
     class AccessorPolicy = std::default_accessor<T>
 
> class mdspan;
 
> class mdspan;
}}  
+
}}
 
{{dcl end}}
 
{{dcl end}}
  
{{tt|std::mdspan}} is a non-owning view into a contiguous sequence of objects that reinterprets it as a multidimensional array.
+
{{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 satisfies:
 +
:* {{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_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.
  
 
===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 }}
+
{{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===
 
{{dsc begin}}
 
{{dsc begin}}
{{dsc hitem | Member type | Definition}}
+
{{dsc hitem|Member type|Definition}}
{{dsc | {{tt|extents_type}} | {{tt|Extents}} }}
+
{{dsc|{{tt|extents_type}}|{{tt|Extents}}}}
{{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}} | {{tt|LayoutPolicy::mapping<Extents>}} }}
+
{{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}} | {{tt|std::remove_cv_t<T>}} }}
+
{{dsc|{{tt|value_type}}|{{c/core|std::remove_cv_t<T>}}}}
{{dsc | {{tt|index_type}} | {{tt|Extents::index_type}} }}
+
{{dsc|{{tt|index_type}}|{{c/core|Extents::index_type}}}}
{{dsc | {{tt|size_type}} | {{tt|Extents::size_type}} }}
+
{{dsc|{{tt|size_type}}|{{c/core|Extents::size_type}}}}
{{dsc | {{tt|rank_type}} | {{tt|Extents::rank_type}} }}
+
{{dsc|{{tt|rank_type}}|{{c/core|Extents::rank_type}}}}
{{dsc | {{tt|data_handle_type}} | {{tt|AccessorPolicy::data_handle_type}} }}
+
{{dsc|{{tt|data_handle_type}}|{{c/core|AccessorPolicy::data_handle_type}}}}
{{dsc | {{tt|reference}} | {{tt|AccessorPolicy::reference}} }}
+
{{dsc|{{tt|reference}}|{{c/core|AccessorPolicy::reference}}}}
 +
{{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}}
 
{{dsc end}}
  
 
===Member functions===
 
===Member functions===
 
{{dsc begin}}
 
{{dsc begin}}
{{dsc inc | cpp/container/mdspan/dsc constructor}}
+
{{dsc inc|cpp/container/mdspan/dsc constructor}}
{{dsc inc | cpp/container/mdspan/dsc operator{{=}}}}
+
{{dsc inc|cpp/container/mdspan/dsc operator{{=}}}}
  
{{dsc h2 | Element access}}
+
{{dsc h2|Element access}}
{{dsc inc | cpp/container/mdspan/dsc operator_at}}
+
{{dsc inc|cpp/container/mdspan/dsc operator_at}}
  
{{dsc h2 | Observers}}
+
{{dsc h2|Observers}}
{{dsc inc | cpp/container/mdspan/dsc size}}
+
{{dsc inc|cpp/container/mdspan/dsc rank}}
{{dsc inc | cpp/container/mdspan/dsc empty}}
+
{{dsc inc|cpp/container/mdspan/dsc rank_dynamic}}
{{dsc inc | cpp/container/mdspan/dsc stride}}
+
{{dsc inc|cpp/container/mdspan/dsc static_extent}}
{{dsc inc | cpp/container/mdspan/dsc extents_mfun}} <!-- dsc extents is for std::extents -->
+
{{dsc inc|cpp/container/mdspan/dsc extent}}
{{dsc inc | cpp/container/mdspan/dsc data_handle}}
+
{{dsc inc | cpp/container/mdspan/dsc mapping}}
+
{{dsc inc | cpp/container/mdspan/dsc accessor}}
+
  
{{dsc inc | cpp/container/mdspan/dsc is_unique}}
+
{{dsc inc|cpp/container/mdspan/dsc size}}
{{dsc inc | cpp/container/mdspan/dsc is_exhaustive}}
+
{{dsc inc|cpp/container/mdspan/dsc empty}}
{{dsc inc | cpp/container/mdspan/dsc is_strided}}
+
{{dsc inc|cpp/container/mdspan/dsc stride}}
{{dsc inc | cpp/container/mdspan/dsc is_always_unique}}
+
{{dsc inc|cpp/container/mdspan/dsc extents_mfun}}<!--dsc extents is for std::extents-->
{{dsc inc | cpp/container/mdspan/dsc is_always_exhaustive}}
+
{{dsc inc|cpp/container/mdspan/dsc data_handle}}
{{dsc inc | cpp/container/mdspan/dsc is_always_strided}}
+
{{dsc inc|cpp/container/mdspan/dsc mapping}}
{{dsc inc | cpp/container/mdspan/dsc required_span_size}}
+
{{dsc inc|cpp/container/mdspan/dsc accessor}}
 +
 
 +
{{dsc inc|cpp/container/mdspan/dsc is_unique}}
 +
{{dsc inc|cpp/container/mdspan/dsc is_exhaustive}}
 +
{{dsc inc|cpp/container/mdspan/dsc is_strided}}
 +
{{dsc inc|cpp/container/mdspan/dsc is_always_unique}}
 +
{{dsc inc|cpp/container/mdspan/dsc is_always_exhaustive}}
 +
{{dsc inc|cpp/container/mdspan/dsc is_always_strided}}
 
{{dsc end}}
 
{{dsc end}}
  
 
===Non-member functions===
 
===Non-member functions===
 
{{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}}
  
 
===Helper types and templates===
 
===Helper types and templates===
 
{{dsc begin}}
 
{{dsc begin}}
{{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 layout_right}}
+
{{dsc inc|cpp/container/mdspan/dsc default_accessor}}
{{dsc inc | cpp/container/mdspan/dsc layout_left}}
+
{{dsc h2|Layout mapping policies}}
{{dsc inc | cpp/container/mdspan/dsc layout_stride}}
+
{{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_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 82: Line 111:
  
 
===Notes===
 
===Notes===
 
+
{{ftm begin|sort=yes}}
{{feature test macro|__cpp_lib_mdspan|std=C++23|value=202207L|{{tt|std::mdspan}}}}
+
{{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 at https://godbolt.org/z/PK7bccGr3
+
|Can be previewed on [https://godbolt.org/z/6WqGonPTn Compiler Explorer].
| code=
+
|code=
#include <vector>
+
#include <cstddef>
 
#include <mdspan>
 
#include <mdspan>
 
#include <print>
 
#include <print>
 +
#include <vector>
  
 
int main()
 
int main()
 
{
 
{
  std::vector v = {1,2,3,4,5,6,7,8,9,10,11,12};
+
    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
  auto ms2 = std::mdspan(v.data(), 2, 6);
+
    auto ms2 = std::mdspan(v.data(), 2, 6);
  // View the same data as a 3D array 2 x 3 x 2
+
    // View the same data as a 3D array 2 x 3 x 2
  auto ms3 = std::mdspan(v.data(), 2, 3, 2);
+
    auto ms3 = std::mdspan(v.data(), 2, 3, 2);
  
  // write data using 2D view
+
    // 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
+
    // 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);
+
    for(size_t j=0; j != ms3.extent(1); j++)
+
 
     {
 
     {
      for(size_t k=0; k != ms3.extent(2); k++)
+
        std::println("slice @ i = {}", i);
        std::print("{} ", ms3[i, j, k]);
+
        for (std::size_t j = 0; j != ms3.extent(1); j++)
      std::println("");
+
        {
 +
            for (std::size_t k = 0; k != ms3.extent(2); k++)
 +
                std::print("{} ", ms3[i, j, k]);
 +
            std::println("");
 +
        }
 
     }
 
     }
  }
 
 
}
 
}
| output=
+
|output=
 
slice @ i = 0
 
slice @ i = 0
0 1  
+
0 1
2 3  
+
2 3
4 5  
+
4 5
 
slice @ i = 1
 
slice @ i = 1
1000 1001  
+
1000 1001
1002 1003  
+
1002 1003
1004 1005  
+
1004 1005
 
}}
 
}}
  
 
===See also===
 
===See also===
 
{{dsc begin}}
 
{{dsc begin}}
{{dsc inc | cpp/container/dsc span}}
+
{{dsc inc|cpp/container/dsc span}}
{{dsc inc | cpp/numeric/dsc valarray}}
+
{{dsc inc|cpp/numeric/dsc valarray}}
 
{{dsc end}}
 
{{dsc end}}
  
 
{{langlinks|de|es|ja|ru|zh}}
 
{{langlinks|de|es|ja|ru|zh}}

Latest revision as of 14:53, 18 October 2024

 
 
 
 
Defined in header <mdspan>
template<

    class T,
    class Extents,
    class LayoutPolicy = std::layout_right,
    class AccessorPolicy = std::default_accessor<T>

> class mdspan;
(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:

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) [edit]
assigns an mdspan
(public member function) [edit]
Element access
accesses an element at the specified multidimensional index
(public member function) [edit]
Observers
[static]
returns the rank of a mdspan
(public static member function) [edit]
returns the dynamic rank of a mdspan
(public static member function) [edit]
returns the static extent size of a mdspan at a given rank index
(public static member function) [edit]
returns the extent of a mdspan at a given rank index
(public member function) [edit]
returns the size of the multidimensional index space
(public member function) [edit]
checks if the size of the index space is zero
(public member function) [edit]
obtains the stride along the specified dimension
(public member function) [edit]
obtains the extents object
(public member function) [edit]
obtains the pointer to the underlying 1D sequence
(public member function) [edit]
obtains the mapping object
(public member function) [edit]
obtains the accessor policy object
(public member function) [edit]
determines if this mdspan's mapping is unique (every combination of indices maps to a different underlying element)
(public member function) [edit]
determines if this mdspan's mapping is exhaustive (every underlying element can be accessed with some combination of indices)
(public member function) [edit]
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) [edit]
determines if this mdspan's layout mapping is always unique
(public static member function) [edit]
determines if this mdspan's layout mapping is always exhaustive
(public static member function) [edit]
determines if this mdspan's layout mapping is always strided
(public static member function) [edit]

[edit] Non-member functions

specializes the std::swap algorithm for mdspan
(function template) [edit]
Subviews
(C++26)
returns a view of a subset of an existing mdspan
(function template) [edit]
creates new extents from the existing extents and slice specifiers
(function template) [edit]

[edit] Helper types and templates

(C++23)
a descriptor of a multidimensional index space of some rank
(class template) [edit]
(C++23)(C++26)
convenience alias template for an all-dynamic std::extents
(alias template)[edit]
a type for indexed access to elements of mdspan
(class template) [edit]
Layout mapping policies
column-major multidimensional array layout mapping policy; leftmost extent has stride 1
(class) [edit]
row-major multidimensional array layout mapping policy; rightmost extent has stride 1
(class) [edit]
a layout mapping policy with user-defined strides
(class) [edit]
column-major layout mapping policy with padding stride that can be greater than or equal to the leftmost extent
(class template) [edit]
row-major layout mapping policy with padding stride that can be greater than or equal to the rightmost extent
(class template) [edit]
Subviews helpers
a slice specifier tag describing full range of indices in the specified extent
(tag)[edit]
a slice specifier representing a set of regularly spaced indices as indicated by an offset, an extent, and a stride
(class template) [edit]
a return type of the overloads of submdspan_mapping
(class template) [edit]

[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.

#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) [edit]
numeric arrays, array masks and array slices
(class template) [edit]