{"id":9992,"date":"2024-09-09T10:18:04","date_gmt":"2024-09-09T10:18:04","guid":{"rendered":"https:\/\/www.modernescpp.com\/?p=9992"},"modified":"2025-07-03T15:54:21","modified_gmt":"2025-07-03T15:54:21","slug":"an-overview-of-c26-the-library-math","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/an-overview-of-c26-the-library-math\/","title":{"rendered":"An Overview Of C++26: The Library &#8211; Math"},"content":{"rendered":"\n<p>The most interesting feature of the new C++26 standard library is its improved math support.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1030\" height=\"450\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/08\/TimelineCpp26Library-1-1030x450.png\" alt=\"\" class=\"wp-image-9949\" style=\"width:746px;height:auto\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/08\/TimelineCpp26Library-1-1030x450.png 1030w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/08\/TimelineCpp26Library-1-300x131.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/08\/TimelineCpp26Library-1-768x335.png 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/08\/TimelineCpp26Library-1-705x308.png 705w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2024\/08\/TimelineCpp26Library-1.png 1180w\" sizes=\"auto, (max-width: 1030px) 100vw, 1030px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><code>std::submdspan<\/code><\/h2>\n\n\n\n<p><code>std::submdspan<\/code> is a subspan of an existing span std::mdspan (C++23). The subspan was not included in C++23 and was added with C++26.<\/p>\n\n\n\n<p>Before I continue with C++26, I need to make a brief detour to C++23. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">std::mdspan<\/h2>\n\n\n\n<p>A <code>std::mdspan<\/code> is a non-owning multidimensional view of a contiguous sequence of objects. The contiguous sequence of objects can be a plain C-array, a pointer with a size, a <code>std::array<\/code>, a <code>std::vector<\/code>, or a <code>std::string<\/code>. Often, this multidimensional view is referred to as a multidimensional array.<\/p>\n\n\n\n<p>The number of dimensions and the size of each dimension determine the shape of the multidimensional array. The number of dimensions is called rank, and the size of each dimension extension. The size of the <code>std::mdspan<\/code> is the product of all dimensions that are not 0. You can access the elements of a <code>std::mdspan<\/code> using the multidimensional index operator <code>[]<\/code>.<\/p>\n\n\n\n<p>Each dimension of a <code>std::mdspan<\/code> can have a <em>static <\/em>or <em>dynamic extent<\/em>. <em>static extent<\/em> means that its length is specified at compile time; <em>dynamic extent<\/em> means that its length is specified at run time. <\/p>\n\n\n\n<p>Thanks to class template argument deduction (CTAG) in C++17, the compiler can often automatically deduce the template arguments from the types of initializers:<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto;gray;border-width:.1em .1em .1em .8em\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #0099FF; font-style: italic\">\/\/ mdspan.cpp<\/span>\n\n<span style=\"color: #009999\">#include &lt;mdspan&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;iostream&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;vector&gt;<\/span>\n\n<span style=\"color: #007788; font-weight: bold\">int<\/span> <span style=\"color: #CC00FF\">main<\/span>() {\n    \n    std<span style=\"color: #555555\">::<\/span>vector myVec{<span style=\"color: #FF6600\">1<\/span>, <span style=\"color: #FF6600\">2<\/span>, <span style=\"color: #FF6600\">3<\/span>, <span style=\"color: #FF6600\">4<\/span>, <span style=\"color: #FF6600\">5<\/span>, <span style=\"color: #FF6600\">6<\/span>, <span style=\"color: #FF6600\">7<\/span>, <span style=\"color: #FF6600\">8<\/span>};          <span style=\"color: #0099FF; font-style: italic\">\/\/ (1)<\/span>\n\n    std<span style=\"color: #555555\">::<\/span>mdspan m{myVec.data(), <span style=\"color: #FF6600\">2<\/span>, <span style=\"color: #FF6600\">4<\/span>};                  <span style=\"color: #0099FF; font-style: italic\">\/\/ (2)<\/span>\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&quot;m.rank(): &quot;<\/span> <span style=\"color: #555555\">&lt;&lt;<\/span> m.rank() <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;      <span style=\"color: #0099FF; font-style: italic\">\/\/ (4)<\/span>\n\n    <span style=\"color: #006699; font-weight: bold\">for<\/span> (std<span style=\"color: #555555\">::<\/span><span style=\"color: #007788; font-weight: bold\">size_t<\/span> i <span style=\"color: #555555\">=<\/span> <span style=\"color: #FF6600\">0<\/span>; i <span style=\"color: #555555\">&lt;<\/span> m.extent(<span style=\"color: #FF6600\">0<\/span>); <span style=\"color: #555555\">++<\/span>i) {     <span style=\"color: #0099FF; font-style: italic\">\/\/ (6)<\/span>\n        <span style=\"color: #006699; font-weight: bold\">for<\/span> (std<span style=\"color: #555555\">::<\/span><span style=\"color: #007788; font-weight: bold\">size_t<\/span> j <span style=\"color: #555555\">=<\/span> <span style=\"color: #FF6600\">0<\/span>; j <span style=\"color: #555555\">&lt;<\/span> m.extent(<span style=\"color: #FF6600\">1<\/span>); <span style=\"color: #555555\">++<\/span>j) { <span style=\"color: #0099FF; font-style: italic\">\/\/ (7)<\/span>\n            std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> m[i, j] <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39; &#39;<\/span>;                <span style=\"color: #0099FF; font-style: italic\">\/\/ (8)<\/span>\n        }\n        std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n    }\n\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n\n    std<span style=\"color: #555555\">::<\/span>mdspan m2{myVec.data(), <span style=\"color: #FF6600\">4<\/span>, <span style=\"color: #FF6600\">2<\/span>};                 <span style=\"color: #0099FF; font-style: italic\">\/\/ (3)<\/span>\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&quot;m2.rank(): &quot;<\/span> <span style=\"color: #555555\">&lt;&lt;<\/span> m2.rank() <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;    <span style=\"color: #0099FF; font-style: italic\">\/\/ (5)<\/span>\n\n    <span style=\"color: #006699; font-weight: bold\">for<\/span> (std<span style=\"color: #555555\">::<\/span><span style=\"color: #007788; font-weight: bold\">size_t<\/span> i <span style=\"color: #555555\">=<\/span> <span style=\"color: #FF6600\">0<\/span>; i <span style=\"color: #555555\">&lt;<\/span> m2.extent(<span style=\"color: #FF6600\">0<\/span>); <span style=\"color: #555555\">++<\/span>i) {\n        <span style=\"color: #006699; font-weight: bold\">for<\/span> (std<span style=\"color: #555555\">::<\/span><span style=\"color: #007788; font-weight: bold\">size_t<\/span> j <span style=\"color: #555555\">=<\/span> <span style=\"color: #FF6600\">0<\/span>; j <span style=\"color: #555555\">&lt;<\/span> m2.extent(<span style=\"color: #FF6600\">1<\/span>); <span style=\"color: #555555\">++<\/span>j) {\n        std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> m2[i, j] <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39; &#39;<\/span>;  \n    }\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>;\n  }\n\n}\n<\/pre><\/div>\n\n\n\n<p>I apply class template argument deduction three times in this example. Line (1) uses it for a<code> std::vector<\/code>, and lines (2) and (3) for a<code> std::mdspan<\/code>. The first 2-dimensional array <code>m <\/code>has a shape of (2, 4), the second one <code>m2 <\/code>a shape of (4, 2). Lines (4) and (5) display the ranks of both <code>std::mdspan<\/code>. Thanks to the extent of each dimension (lines 6 and 7) and the index operator in line (8), it is straightforward to iterate through multidimensional arrays.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"170\" height=\"231\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2023\/09\/mdspan.png\" alt=\"\" class=\"wp-image-8213\"\/><\/figure>\n\n\n\n<p>Here ends my detour, and I continue with <code>std::submdspan.<\/code><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">std::submdspan<\/h2>\n\n\n\n<p>This function was considered critical for the overall functionality of <code>mdspan<\/code>. However, due to review time constraints, it was removed in order for <code>mdspan<\/code> to be included in C++23.<\/p>\n\n\n\n<p>Creating a <code>std::submdspan<\/code> is straightforward. Its first parameter is an <code>mdspan<\/code> <code>x<\/code>. The remaining <code>x.rank()<\/code> parameters are slice specifiers, one for each dimension of <code>x<\/code>. The slice specifiers describe which elements of the range [0,<code>x.extent(d)<\/code>) are part of the multidimensional index space of the returned <code>mdspan<\/code>.<\/p>\n\n\n\n<p>This leads to the following fundamental signature:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><a href=\"https:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2023\/p2630r4.html#cb2-1\"><\/a>template&lt;class T, class E, class L, class A,\n<a href=\"https:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2023\/p2630r4.html#cb2-2\"><\/a>         class ... SliceArgs)\n<a href=\"https:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2023\/p2630r4.html#cb2-3\"><\/a>auto submdspan(mdspan&lt;T,E,L,A&gt; x, SliceArgs ... args);<\/code><\/pre>\n\n\n\n<p>where <code>E.rank()<\/code> must be equal to <code>sizeof...(SliceArgs)<\/code>.<\/p>\n\n\n\n<p>Proposal P2630R4 provides, in addition to the definition of a <code>std::submdspan<\/code>, a few examples for a rank-1 <code>mdspan<\/code>.<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto;gray;border-width:.1em .1em .1em .8em\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #007788; font-weight: bold\">int<\/span><span style=\"color: #555555\">*<\/span> ptr <span style=\"color: #555555\">=<\/span> ...;\n<span style=\"color: #007788; font-weight: bold\">int<\/span> N <span style=\"color: #555555\">=<\/span> ...;\nmdspan <span style=\"color: #CC00FF\">a<\/span>(ptr, N);\n\n<span style=\"color: #0099FF; font-style: italic\">\/\/ subspan of a single element<\/span>\n<span style=\"color: #006699; font-weight: bold\">auto<\/span> a_sub1 <span style=\"color: #555555\">=<\/span> submdspan(a, <span style=\"color: #FF6600\">1<\/span>);\nstatic_assert(decltype(a_sub1)<span style=\"color: #555555\">::<\/span>rank() <span style=\"color: #555555\">==<\/span> <span style=\"color: #FF6600\">0<\/span>);\nassert(<span style=\"color: #555555\">&amp;<\/span>a_sub1() <span style=\"color: #555555\">==<\/span> <span style=\"color: #555555\">&amp;<\/span>a(<span style=\"color: #FF6600\">1<\/span>));\n\n<span style=\"color: #0099FF; font-style: italic\">\/\/ subrange<\/span>\n<span style=\"color: #006699; font-weight: bold\">auto<\/span> a_sub2 <span style=\"color: #555555\">=<\/span> submdspan(a, tuple{<span style=\"color: #FF6600\">1<\/span>, <span style=\"color: #FF6600\">4<\/span>});\nstatic_assert(decltype(a_sub2)<span style=\"color: #555555\">::<\/span>rank() <span style=\"color: #555555\">==<\/span> <span style=\"color: #FF6600\">1<\/span>);\nassert(<span style=\"color: #555555\">&amp;<\/span>a_sub2(<span style=\"color: #FF6600\">0<\/span>) <span style=\"color: #555555\">==<\/span> <span style=\"color: #555555\">&amp;<\/span>a(<span style=\"color: #FF6600\">1<\/span>));\nassert(a_sub2.extent(<span style=\"color: #FF6600\">0<\/span>) <span style=\"color: #555555\">==<\/span> <span style=\"color: #FF6600\">3<\/span>);\n\n<span style=\"color: #0099FF; font-style: italic\">\/\/ subrange with stride<\/span>\n<span style=\"color: #006699; font-weight: bold\">auto<\/span> a_sub3 <span style=\"color: #555555\">=<\/span> submdspan(a, strided_slice{<span style=\"color: #FF6600\">1<\/span>, <span style=\"color: #FF6600\">7<\/span>, <span style=\"color: #FF6600\">2<\/span>});\nstatic_assert(decltype(a_sub3)<span style=\"color: #555555\">::<\/span>rank() <span style=\"color: #555555\">==<\/span> <span style=\"color: #FF6600\">1<\/span>);\nassert(<span style=\"color: #555555\">&amp;<\/span>a_sub3(<span style=\"color: #FF6600\">0<\/span>) <span style=\"color: #555555\">==<\/span> <span style=\"color: #555555\">&amp;<\/span>a(<span style=\"color: #FF6600\">1<\/span>));\nassert(<span style=\"color: #555555\">&amp;<\/span>a_sub3(<span style=\"color: #FF6600\">3<\/span>) <span style=\"color: #555555\">==<\/span> <span style=\"color: #555555\">&amp;<\/span>a(<span style=\"color: #FF6600\">7<\/span>));\nassert(a_sub3.extent(<span style=\"color: #FF6600\">0<\/span>) <span style=\"color: #555555\">==<\/span> <span style=\"color: #FF6600\">4<\/span>);\n\n<span style=\"color: #0099FF; font-style: italic\">\/\/ full range<\/span>\n<span style=\"color: #006699; font-weight: bold\">auto<\/span> a_sub4 <span style=\"color: #555555\">=<\/span> submdspan(a, full_extent);\nstatic_assert(decltype(a_sub4)<span style=\"color: #555555\">::<\/span>rank() <span style=\"color: #555555\">==<\/span> <span style=\"color: #FF6600\">1<\/span>);\nassert(a_sub4(<span style=\"color: #FF6600\">0<\/span>) <span style=\"color: #555555\">==<\/span> a(<span style=\"color: #FF6600\">0<\/span>));\nassert(a_sub4.extent(<span style=\"color: #FF6600\">0<\/span>) <span style=\"color: #555555\">==<\/span> a.extent(<span style=\"color: #FF6600\">0<\/span>));\n<\/pre><\/div>\n\n\n\n<p> The same rules apply to the multi-dimensional use case.<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto;gray;border-width:.1em .1em .1em .8em\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #007788; font-weight: bold\">int<\/span><span style=\"color: #555555\">*<\/span> ptr <span style=\"color: #555555\">=<\/span> ...;\n<span style=\"color: #007788; font-weight: bold\">int<\/span> N0 <span style=\"color: #555555\">=<\/span> ..., N1 <span style=\"color: #555555\">=<\/span> ..., N2 <span style=\"color: #555555\">=<\/span> ..., N3 <span style=\"color: #555555\">=<\/span> ..., N4 <span style=\"color: #555555\">=<\/span> ...;\nmdspan <span style=\"color: #CC00FF\">a<\/span>(ptr, N0, N1, N2, N3, N4);\n\n<span style=\"color: #006699; font-weight: bold\">auto<\/span> a_sub <span style=\"color: #555555\">=<\/span> submdspan(a,<span style=\"color: #007788; font-weight: bold\">full_extent_t<\/span>(), <span style=\"color: #FF6600\">3<\/span>, strided_slice{<span style=\"color: #FF6600\">2<\/span>,N2<span style=\"color: #555555\">-<\/span><span style=\"color: #FF6600\">5<\/span>, <span style=\"color: #FF6600\">2<\/span>}, <span style=\"color: #FF6600\">4<\/span>, tuple{<span style=\"color: #FF6600\">3<\/span>, N5<span style=\"color: #555555\">-<\/span><span style=\"color: #FF6600\">5<\/span>});\n\n<span style=\"color: #0099FF; font-style: italic\">\/\/ two integral specifiers so the rank is reduced by 2<\/span>\nstatic_assert(decltype(a_sub) <span style=\"color: #555555\">==<\/span> <span style=\"color: #FF6600\">3<\/span>);\n<span style=\"color: #0099FF; font-style: italic\">\/\/ 1st dimension is taking the whole extent<\/span>\nassert(a_sub.extent(<span style=\"color: #FF6600\">0<\/span>) <span style=\"color: #555555\">==<\/span> a.extent(<span style=\"color: #FF6600\">0<\/span>));\n<span style=\"color: #0099FF; font-style: italic\">\/\/ the new 2nd dimension corresponds to the old 3rd dimension<\/span>\nassert(a_sub.extent(<span style=\"color: #FF6600\">1<\/span>) <span style=\"color: #555555\">==<\/span> (a.extent(<span style=\"color: #FF6600\">2<\/span>) <span style=\"color: #555555\">-<\/span> <span style=\"color: #FF6600\">5<\/span>)<span style=\"color: #555555\">\/<\/span><span style=\"color: #FF6600\">2<\/span>);\nassert(a_sub.stride(<span style=\"color: #FF6600\">1<\/span>) <span style=\"color: #555555\">==<\/span> a.stride(<span style=\"color: #FF6600\">2<\/span>)<span style=\"color: #555555\">*<\/span><span style=\"color: #FF6600\">2<\/span>);\n<span style=\"color: #0099FF; font-style: italic\">\/\/ the new 3rd dimension corresponds to the old 5th dimension<\/span>\nassert(a_sub.extent(<span style=\"color: #FF6600\">2<\/span>) <span style=\"color: #555555\">==<\/span> a.extent(<span style=\"color: #FF6600\">4<\/span>)<span style=\"color: #555555\">-<\/span><span style=\"color: #FF6600\">8<\/span>);\n\nassert(<span style=\"color: #555555\">&amp;<\/span>a_sub(<span style=\"color: #FF6600\">1<\/span>,<span style=\"color: #FF6600\">5<\/span>,<span style=\"color: #FF6600\">7<\/span>) <span style=\"color: #555555\">==<\/span> <span style=\"color: #555555\">&amp;<\/span>a(<span style=\"color: #FF6600\">1<\/span>, <span style=\"color: #FF6600\">3<\/span>, <span style=\"color: #FF6600\">2<\/span><span style=\"color: #555555\">+<\/span><span style=\"color: #FF6600\">5<\/span><span style=\"color: #555555\">*<\/span><span style=\"color: #FF6600\">2<\/span>, <span style=\"color: #FF6600\">4<\/span>, <span style=\"color: #FF6600\">3<\/span><span style=\"color: #555555\">+<\/span><span style=\"color: #FF6600\">7<\/span>));\n<\/pre><\/div>\n\n\n\n<p> This is not the end of the support is C++26.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">&lt;linalg&gt;: <\/h2>\n\n\n\n<p><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/header\/linalg\">&lt;linalg&gt;<\/a> is a free function linear algebra interface based on the BLAS.<\/p>\n\n\n\n<p>BLAS: <strong>Basic Linear Algebra Subprograms<\/strong> (<strong>BLAS<\/strong>) is a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Specification_(technical_standard)\">specification<\/a> that prescribes a set of low-level routines for performing common <a href=\"https:\/\/en.wikipedia.org\/wiki\/Linear_algebra\">linear algebra<\/a> operations such as <a href=\"https:\/\/en.wikipedia.org\/wiki\/Vector_space\">vector<\/a> addition, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Scalar_multiplication\">scalar multiplication<\/a>, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Dot_product\">dot products<\/a>, linear combinations, and <a href=\"https:\/\/en.wikipedia.org\/wiki\/Matrix_multiplication\">matrix multiplication<\/a>. They are the <em><a href=\"https:\/\/en.wikipedia.org\/wiki\/De_facto\">de facto<\/a><\/em> standard low-level routines for linear algebra libraries &#8230; .(<a href=\"https:\/\/en.wikipedia.org\/wiki\/Basic_Linear_Algebra_Subprograms\">https:\/\/en.wikipedia.org\/wiki\/Basic_Linear_Algebra_Subprograms<\/a>)<\/p>\n\n\n\n<p>Proposal <a href=\"https:\/\/wg21.link\/P1673R13\">P1673R13<\/a> proposes a C++ Standard Library dense linear algebra interface based on the dense Basic Linear Algebra Subroutines (BLAS). This corresponds to a subset of the <a href=\"http:\/\/www.netlib.org\/blas\/blast-forum\/blas-report.pdf\">BLAS Standard<\/a>. <\/p>\n\n\n\n<p>Linear algebra was long missed in the C++ community. According to the proposal, the following code snippet is the hello world of linear algebra. It scales the elements of a 1-D <code>mdspan<\/code> by a constant factor, first sequentially, then in parallel.<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto;gray;border-width:.1em .1em .1em .8em\"><pre style=\"margin: 0; line-height: 125%\">  constexpr <span style=\"color: #007788; font-weight: bold\">size_t<\/span> N <span style=\"color: #555555\">=<\/span> <span style=\"color: #FF6600\">40<\/span>;\n  std<span style=\"color: #555555\">::<\/span>vector<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">double<\/span><span style=\"color: #555555\">&gt;<\/span> x_vec(N);\n\n  mdspan <span style=\"color: #CC00FF\">x<\/span>(x_vec.data(), N);\n  <span style=\"color: #006699; font-weight: bold\">for<\/span>(<span style=\"color: #007788; font-weight: bold\">size_t<\/span> i <span style=\"color: #555555\">=<\/span> <span style=\"color: #FF6600\">0<\/span>; i <span style=\"color: #555555\">&lt;<\/span> N; <span style=\"color: #555555\">++<\/span>i) {\n    x[i] <span style=\"color: #555555\">=<\/span> <span style=\"color: #007788; font-weight: bold\">double<\/span>(i);\n  }\n\n  linalg<span style=\"color: #555555\">::<\/span>scale(<span style=\"color: #FF6600\">2.0<\/span>, x); <span style=\"color: #0099FF; font-style: italic\">\/\/ x = 2.0 * x<\/span>\n  linalg<span style=\"color: #555555\">::<\/span>scale(std<span style=\"color: #555555\">::<\/span>execution<span style=\"color: #555555\">::<\/span>par_unseq, <span style=\"color: #FF6600\">3.0<\/span>, x);\n  <span style=\"color: #006699; font-weight: bold\">for<\/span>(<span style=\"color: #007788; font-weight: bold\">size_t<\/span> i <span style=\"color: #555555\">=<\/span> <span style=\"color: #FF6600\">0<\/span>; i <span style=\"color: #555555\">&lt;<\/span> N; <span style=\"color: #555555\">++<\/span>i) {\n    assert(x[i] <span style=\"color: #555555\">==<\/span> <span style=\"color: #FF6600\">6.0<\/span> <span style=\"color: #555555\">*<\/span> <span style=\"color: #007788; font-weight: bold\">double<\/span>(i));\n  }\n<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"> What&#8217;s next?<\/h2>\n\n\n\n<p>I&#8217;m still not done with C++26. In my next post, I will discuss saturation arithmetic and the concurrency support in C++26.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The most interesting feature of the new C++26 standard library is its improved math support. std::submdspan std::submdspan is a subspan of an existing span std::mdspan (C++23). The subspan was not included in C++23 and was added with C++26. Before I continue with C++26, I need to make a brief detour to C++23. std::mdspan A std::mdspan [&hellip;]<\/p>\n","protected":false},"author":21,"featured_media":10028,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[559],"tags":[],"class_list":["post-9992","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c26-blog"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/9992","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=9992"}],"version-history":[{"count":18,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/9992\/revisions"}],"predecessor-version":[{"id":10849,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/9992\/revisions\/10849"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/10028"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=9992"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=9992"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=9992"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}