1. Introduction
[P0009R11] proposes adding non-owning multidimensional span abstractions
to the C++ Standard Library;
, which is fully generic and
can represent any kind of multidimensional data, and
, a
convenience template alias for simpler use cases.
template < class ElementType , class Extents , class LayoutPolicy = layout_right , class AccessorPolicy = accessor_basic < ElementType >> struct basic_mdspan ; template < class ElementType , size_t ... Extents > using mdspan = basic_mdspan < ElementType , extents < Extents ... >> ;
In the
/
interface, extents can be either static, e.g.
expressed at compile time:
mdspan < double , 64 , 64 > a ( data );
or dynamic, e.g. expressed at run time:
mdspan < double , dynamic_extent , dynamic_extent > a ( data , 64 , 64 );
You can also use a mix of the two styles:
mdspan < double , 64 , dynamic_extent > a ( data , 64 );
While
and
are powerful, the spelling of instantiations
can be verbose, especially for the common case where all extents are dynamic.
Using class template argument deduction (introduced in C++17) and alias
template argument deduction (introduced in C++20), we can make it a easier to
use
with all dynamic extents:
Before | After |
---|---|
|
|
To make this work, we need to add a deduction guide for
.
Through the power of alias template argument deduction,
will be
able to use said deduction guide as well.
Here’s an example implementation of such a
deduction guide for
.
In earlier versions of this paper, it was unclear whether such a deduction
guide would work for the alias template
, as attempts to construct
one that functioned as intended had failed.
However, we have since learned that the this is due to bugs in the two
implementations that currently support alias template deduction, MSVC
and GCC.
Those bugs have been reported to the respective compilers and hopefully
will be fixed soon.
Here’s an example of the current
implementation bugs that prevent the deduction guide from working for
.
2. Wording
The following changes are relative to the
proposal ([P0009R11]).
The � character is used to denote a placeholder number which shall be selected by the editor.
Modify the header synopsis for
in [mdspan.syn] as follows:
22.7.� Headersynopsis [mdspan.syn]
< mdspan >
namespace std { // [mdspan.extents], class template extents template class extents ; // [mdspan.layout], Layout mapping policies class layout_left ; class layout_right ; class layout_stride ; // [mdspan.accessor.basic] template < class ElementType > class default_accessor ; // [mdspan.basic], class template mdspan template < class ElementType , class Extents , class LayoutPolicy = layout_right , class AccessorPolicy = default_accessor < ElementType >> class basic_mdspan ; template < class ElementType , class ... IndexTypes > explicit basic_mdspan ( ElementType * , IndexTypes ...) -> basic_mdspan < ElementType , extents < [] ( auto ) constexpr { return dynamic_extent ; } ( identity < IndexTypes > {})... >> ; template < class T , size_t ... Extents > using mdspan = basic_mdspan < T , extents < Extents ... >> ; // [mdspan.submdspan] template < class ElementType , class Extents , class LayoutPolicy , class AccessorPolicy , class ... SliceSpecifiers > constexpr basic_mdspan < see below > submdspan ( const basic_mdspan < ElementType , Extents , LayoutPolicy , AccessorPolicy >& m , SliceSpecifiers ... specs ) noexcept ; // tag supporting submdspan struct full_extent_t { explicit full_extent_t () = default ; }; inline constexpr full_extent_t full_extent = full_extent_t {}; }