{"id":6384,"date":"2022-06-16T20:10:47","date_gmt":"2022-06-16T20:10:47","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/ranges-improvements-with-c-23\/"},"modified":"2023-06-26T09:03:48","modified_gmt":"2023-06-26T09:03:48","slug":"ranges-improvements-with-c-23","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/ranges-improvements-with-c-23\/","title":{"rendered":"Ranges Improvements with C++23"},"content":{"rendered":"<p>Thanks to C++23, constructing containers will become more convenient. Additionally, the ranges library got more new views.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6382\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/06\/Cpp23.jpg\" alt=\"Cpp23\" width=\"400\" height=\"510\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/06\/Cpp23.jpg 467w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/06\/Cpp23-235x300.jpg 235w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<h2>Ranges<\/h2>\n<p>C++23 is not such a significant standard as C++11 or C++20. It&#8217;s more in the tradition of C++17. This is mainly due to COVID-19 because the annual four face-to-face meetings went online. Essentially, the ranges library is the exception to this rule. The ranges will get a few crucial additions.<\/p>\n<p>If you know more details about what you can expect about C++23 (before I write about it), study <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/compiler_support\">cppreference.com\/compiler_support<\/a>. Even better, read the excellent paper from Steve Downey (<a href=\"https:\/\/github.com\/steve-downey\/papers\/blob\/master\/wg21-status.org\">C++23 Status Report<\/a>).<\/p>\n<\/p>\n<h3>Constructing Containers<\/h3>\n<p>Constructing a container from a range was a complicated job. The following function range simulates python2&#8217;s range function. Python2&#8217;s range function is eager, and so is its range pendant: Additionally, Pythons range function returns a <code>list<\/code>, but mine a <code>std::vector<\/code>.<\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #555555;\">\/\/<\/span> <span style=\"color: #336666;\">range<\/span><span style=\"color: #555555;\">.<\/span>cpp\r\n\r\n<span style=\"color: #0099ff; font-style: italic;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #0099ff; font-style: italic;\">#include &lt;range\/v3\/all.hpp&gt;<\/span>\r\n<span style=\"color: #0099ff; font-style: italic;\">#include &lt;vector&gt;<\/span>\r\n\r\nstd::vector<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #336666;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> <span style=\"color: #336666;\">range<\/span>(<span style=\"color: #336666;\">int<\/span> begin, <span style=\"color: #336666;\">int<\/span> end, <span style=\"color: #336666;\">int<\/span> stepsize <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">1<\/span>) {\r\n    std::vector<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #336666;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> result{};\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span> (begin <span style=\"color: #555555;\">&lt;<\/span> end) {                                     <span style=\"color: #555555;\">\/\/<\/span> (<span style=\"color: #ff6600;\">5<\/span>)\r\n        auto boundary <span style=\"color: #555555;\">=<\/span> [end](<span style=\"color: #336666;\">int<\/span> i){ <span style=\"color: #006699; font-weight: bold;\">return<\/span> i <span style=\"color: #555555;\">&lt;<\/span> end; };\r\n        <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #336666;\">int<\/span> i: ranges::views::iota(begin) <span style=\"color: #555555;\">|<\/span> ranges::views::stride(stepsize) \r\n                                               <span style=\"color: #555555;\">|<\/span> ranges::views::take_while(boundary)) {\r\n            result<span style=\"color: #555555;\">.<\/span>push_back(i);\r\n        }\r\n    }\r\n    <span style=\"color: #006699; font-weight: bold;\">else<\/span> {                                                 <span style=\"color: #555555;\">\/\/<\/span> (<span style=\"color: #ff6600;\">6<\/span>)\r\n        begin<span style=\"color: #555555;\">++<\/span>;\r\n        end<span style=\"color: #555555;\">++<\/span>;\r\n        stepsize <span style=\"color: #555555;\">*=<\/span> <span style=\"color: #555555;\">-<\/span><span style=\"color: #ff6600;\">1<\/span>;\r\n        auto boundary <span style=\"color: #555555;\">=<\/span> [begin](<span style=\"color: #336666;\">int<\/span> i){ <span style=\"color: #006699; font-weight: bold;\">return<\/span> i <span style=\"color: #555555;\">&lt;<\/span> begin; };\r\n        <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #336666;\">int<\/span> i: ranges::views::iota(end) <span style=\"color: #555555;\">|<\/span> ranges::views::take_while(boundary) \r\n                                             <span style=\"color: #555555;\">|<\/span> ranges::views::reverse \r\n                                             <span style=\"color: #555555;\">|<\/span> ranges::views::stride(stepsize)) {\r\n            result<span style=\"color: #555555;\">.<\/span>push_back(i);\r\n        }\r\n    }\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> result;\r\n}<span style=\"color: #555555;\"><\/span><span style=\"color: #000000; font-weight: bold;\"><\/span><span style=\"color: #000000; font-weight: bold;\"><\/span><span style=\"color: #555555;\"><\/span><span style=\"color: #ff6600;\"><\/span><span style=\"color: #555555;\"><\/span><span style=\"color: #ff6600;\"><\/span>\r\n        \r\n<span style=\"color: #336666;\">int<\/span> main() {\r\n    \r\n    std::cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std::endl;\r\n\r\n    <span style=\"color: #555555;\">\/\/<\/span> <span style=\"color: #336666;\">range<\/span>(<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">50<\/span>)                                       <span style=\"color: #555555;\">\/\/<\/span> (<span style=\"color: #ff6600;\">1<\/span>)\r\n    auto res <span style=\"color: #555555;\">=<\/span> <span style=\"color: #336666;\">range<\/span>(<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">50<\/span>);\r\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (auto i: res) std::cout <span style=\"color: #555555;\">&lt;&lt;<\/span> i <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span>;\r\n    \r\n    std::cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"<\/span><span style=\"color: #cc3300; font-weight: bold;\">\\n\\n<\/span><span style=\"color: #cc3300;\">\"<\/span>;\r\n    \r\n    <span style=\"color: #555555;\">\/\/<\/span> <span style=\"color: #336666;\">range<\/span>(<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">50<\/span>, <span style=\"color: #ff6600;\">5<\/span>)                                    <span style=\"color: #555555;\">\/\/<\/span> (<span style=\"color: #ff6600;\">2<\/span>)\r\n    res <span style=\"color: #555555;\">=<\/span> <span style=\"color: #336666;\">range<\/span>(<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">50<\/span>, <span style=\"color: #ff6600;\">5<\/span>);\r\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (auto i: res) std::cout <span style=\"color: #555555;\">&lt;&lt;<\/span> i <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span>;\r\n    \r\n    std::cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"<\/span><span style=\"color: #cc3300; font-weight: bold;\">\\n\\n<\/span><span style=\"color: #cc3300;\">\"<\/span>;\r\n    \r\n    <span style=\"color: #555555;\">\/\/<\/span> <span style=\"color: #336666;\">range<\/span>(<span style=\"color: #ff6600;\">50<\/span>, <span style=\"color: #ff6600;\">10<\/span>, <span style=\"color: #555555;\">-<\/span><span style=\"color: #ff6600;\">1<\/span>)                                  <span style=\"color: #555555;\">\/\/<\/span> (<span style=\"color: #ff6600;\">3<\/span>)\r\n    res <span style=\"color: #555555;\">=<\/span> <span style=\"color: #336666;\">range<\/span>(<span style=\"color: #ff6600;\">50<\/span>, <span style=\"color: #ff6600;\">10<\/span>, <span style=\"color: #555555;\">-<\/span><span style=\"color: #ff6600;\">1<\/span>);\r\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (auto i: res) std::cout <span style=\"color: #555555;\">&lt;&lt;<\/span> i <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span>;\r\n    \r\n    std::cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"<\/span><span style=\"color: #cc3300; font-weight: bold;\">\\n\\n<\/span><span style=\"color: #cc3300;\">\"<\/span>;\r\n    \r\n    <span style=\"color: #555555;\">\/\/<\/span> <span style=\"color: #336666;\">range<\/span>(<span style=\"color: #ff6600;\">50<\/span>, <span style=\"color: #ff6600;\">10<\/span>, <span style=\"color: #555555;\">-<\/span><span style=\"color: #ff6600;\">5<\/span>)                                  <span style=\"color: #555555;\">\/\/<\/span> (<span style=\"color: #ff6600;\">4<\/span>)\r\n    res <span style=\"color: #555555;\">=<\/span> <span style=\"color: #336666;\">range<\/span>(<span style=\"color: #ff6600;\">50<\/span>, <span style=\"color: #ff6600;\">10<\/span>, <span style=\"color: #555555;\">-<\/span><span style=\"color: #ff6600;\">5<\/span>);\r\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (auto i: res) std::cout <span style=\"color: #555555;\">&lt;&lt;<\/span> i <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span>;\r\n    \r\n    std::cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"<\/span><span style=\"color: #cc3300; font-weight: bold;\">\\n\\n<\/span><span style=\"color: #cc3300;\">\"<\/span>;\r\n    \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The calls in lines (1) &#8211; (4) should be pretty easy to read when looking at the output.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5855\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/02\/range.png\" alt=\"range\" width=\"650\" height=\"279\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/02\/range.png 884w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/02\/range-300x129.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/02\/range-768x330.png 768w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<p>The first two arguments of the range call stand for the beginning and end of the created integers. The begin is included but not the end. The step size as the third parameter is, per default, 1. The step size should be negative when the interval [begin, end] decreases. If not, you get an empty <span style=\"font-family: courier new, courier;\">list<\/span> or an empty <span style=\"font-family: courier new, courier;\">std::vector&lt;int&gt;<\/span>.<\/p>\n<p>I cheat a little in my range implementation. I use the function <span style=\"font-family: courier new, courier;\">ranges::views::stride<\/span>, which is not part of C++20. <span style=\"font-family: courier new, courier;\">stride(n)<\/span> returns the n-th element of the given range. I assume that <code>std::views::stride<\/code> becomes part of C++23, but I&#8217;m not sure. Consequentially, I used the<a href=\"https:\/\/github.com\/ericniebler\/range-v3\"> ranges v3<\/a> implementation in my example but not the C++20 implementation of the ranges library.<\/p>\n<p>The if condition (<span style=\"font-family: courier new, courier;\">begin &lt; end<\/span>) of the range function in line (1) should be quite easy to read. Create all numbers starting with begin (<span style=\"font-family: courier new, courier;\">ranges::views::iota(begin)),<\/span> take each n-th element (<span style=\"font-family: courier new, courier;\">ranges::views::stride(stepsize<\/span>), and do it as long as the boundary condition holds (<span style=\"font-family: courier new, courier;\">ranges::views::take_while(boundar<\/span>y). Finally, push the integers on the <span style=\"font-family: courier new, courier;\">std::vector&lt;int&gt;. <\/span><\/p>\n<p>I use a little trick in the other case (line 2). I create the numbers <span style=\"font-family: courier new, courier;\">[end++, begin++[,<\/span> take them until the boundary condition is met, reverse them (<span style=\"font-family: courier new, courier;\">ranges::views::reverse<\/span>), and take each n-th element.<\/p>\n<p>Now, let&#8217;s assume that std::views::stride is part of C++23. Thanks to std::ranges::to, it&#8217;s pretty easy to construct a Container. Here is the C++23-based implementation of the previous <code>range<\/code> function.<\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\">std<span style=\"color: #555555;\">::<\/span>vector<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> range(<span style=\"color: #007788; font-weight: bold;\">int<\/span> begin, <span style=\"color: #007788; font-weight: bold;\">int<\/span> end, <span style=\"color: #007788; font-weight: bold;\">int<\/span> stepsize <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">1<\/span>) {\r\n    std<span style=\"color: #555555;\">::<\/span>vector<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span> result{};\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span> (begin <span style=\"color: #555555;\">&lt;<\/span> end) {                                    \r\n        <span style=\"color: #006699; font-weight: bold;\">auto<\/span> boundary <span style=\"color: #555555;\">=<\/span> [end](<span style=\"color: #007788; font-weight: bold;\">int<\/span> i){ <span style=\"color: #006699; font-weight: bold;\">return<\/span> i <span style=\"color: #555555;\">&lt;<\/span> end; };\r\n        result <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>ranges<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>iota(begin) <span style=\"color: #555555;\">|<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>stride(stepsize) \r\n                                                 <span style=\"color: #555555;\">|<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>take_while(boundary) \r\n                                                 <span style=\"color: #555555;\">|<\/span> std<span style=\"color: #555555;\">::<\/span>ranges<span style=\"color: #555555;\">::<\/span>to<span style=\"color: #555555;\">&lt;std::<\/span>vector<span style=\"color: #555555;\">&gt;<\/span>();\r\n    }\r\n    <span style=\"color: #006699; font-weight: bold;\">else<\/span> {                                                \r\n        begin<span style=\"color: #555555;\">++<\/span>;\r\n        end<span style=\"color: #555555;\">++<\/span>;\r\n        stepsize <span style=\"color: #555555;\">*=<\/span> <span style=\"color: #555555;\">-<\/span><span style=\"color: #ff6600;\">1<\/span>;\r\n        <span style=\"color: #006699; font-weight: bold;\">auto<\/span> boundary <span style=\"color: #555555;\">=<\/span> [begin](<span style=\"color: #007788; font-weight: bold;\">int<\/span> i){ <span style=\"color: #006699; font-weight: bold;\">return<\/span> i <span style=\"color: #555555;\">&lt;<\/span> begin; };\r\n        result <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>ranges<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>iota(end) <span style=\"color: #555555;\">|<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>take_while(boundary) \r\n                                               <span style=\"color: #555555;\">|<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>reverse \r\n                                               <span style=\"color: #555555;\">|<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>stride(stepsize) \r\n                                               <span style=\"color: #555555;\">|<\/span> std<span style=\"color: #555555;\">::<\/span>ranges<span style=\"color: #555555;\">::<\/span>to<span style=\"color: #555555;\">&lt;std::<\/span>vector<span style=\"color: #555555;\">&gt;<\/span>();\r\n    }\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> result;\r\n} \r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Essentially, I replaced the<code> push_back<\/code> operation on the <code>std::vector<\/code> with the new call <code>std::ranges::to&lt;std::vector&gt;, <\/code>and got rid of two lines of code. So far, no compiler supports this new convenient function to create a container. I created the new <code>range<\/code> function based on my interpretation of the specification. If there is an error included, I will fix it.<\/p>\n<h4>Existing Algorithms in C++20<\/h4>\n<p>Before I show you the new views in C++23, here are the already existing ones in C++20:<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6383\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/06\/viewNew.png\" alt=\"viewNew\" width=\"650\" height=\"876\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/06\/viewNew.png 1402w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/06\/viewNew-223x300.png 223w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/06\/viewNew-760x1024.png 760w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/06\/viewNew-768x1035.png 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/06\/viewNew-1139x1536.png 1139w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<h4>New Views in C++23<\/h4>\n<p>Now, I want to present to you the new views. If possible, I will provide you with a short code example.<\/p>\n<ul>\n<li><strong><code>std::ranges::views::zip_transform, <\/code>and <code>std::views::zip_transform<\/code><\/strong><\/li>\n<\/ul>\n<p>Creates a view that consists of tuples by applying a transformation function.<\/p>\n<p>Here is an excellent example from <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/ranges\/zip_transform_view\">cppreferene.com\/zip_transform_view<\/a>:<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #009999;\">#include &lt;list&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;array&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;ranges&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;vector&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n \r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">print<\/span>(<span style=\"color: #006699; font-weight: bold;\">auto<\/span> <span style=\"color: #006699; font-weight: bold;\">const<\/span> rem, <span style=\"color: #006699; font-weight: bold;\">auto<\/span> <span style=\"color: #006699; font-weight: bold;\">const<\/span><span style=\"color: #555555;\">&amp;<\/span> r) {\r\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> rem; <span style=\"color: #006699; font-weight: bold;\">auto<\/span> <span style=\"color: #006699; font-weight: bold;\">const<\/span><span style=\"color: #555555;\">&amp;<\/span> e <span style=\"color: #555555;\">:<\/span> r)\r\n        std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> e <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">' '<\/span>;\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n}\r\n \r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>() {\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> v1 <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>vector<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">float<\/span><span style=\"color: #555555;\">&gt;<\/span>{<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">2<\/span>, <span style=\"color: #ff6600;\">3<\/span>};\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> v2 <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>list<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">short<\/span><span style=\"color: #555555;\">&gt;<\/span>{<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">2<\/span>, <span style=\"color: #ff6600;\">3<\/span>, <span style=\"color: #ff6600;\">4<\/span>};\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> v3 <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>to_array({<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>});\r\n \r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> add <span style=\"color: #555555;\">=<\/span> [](<span style=\"color: #006699; font-weight: bold;\">auto<\/span> a, <span style=\"color: #006699; font-weight: bold;\">auto<\/span> b, <span style=\"color: #006699; font-weight: bold;\">auto<\/span> c) { <span style=\"color: #006699; font-weight: bold;\">return<\/span> a <span style=\"color: #555555;\">+<\/span> b <span style=\"color: #555555;\">+<\/span> c; };\r\n \r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> sum <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>zip_transform(add, v1, v2, v3);\r\n \r\n    print(<span style=\"color: #cc3300;\">\"v1:  \"<\/span>, v1);    <span style=\"color: #0099ff; font-style: italic;\">\/\/ 1 2 3<\/span>\r\n    print(<span style=\"color: #cc3300;\">\"v2:  \"<\/span>, v2);    <span style=\"color: #0099ff; font-style: italic;\">\/\/ 1 2 3 4<\/span>\r\n    print(<span style=\"color: #cc3300;\">\"v3:  \"<\/span>, v3);    <span style=\"color: #0099ff; font-style: italic;\">\/\/ 1 2 3 4 5<\/span>\r\n    print(<span style=\"color: #cc3300;\">\"sum: \"<\/span>, sum);   <span style=\"color: #0099ff; font-style: italic;\">\/\/ 3 6 9<\/span>\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>I added the output directly into the source code.<\/p>\n<ul>\n<li><strong><code>std::ranges::adjacent_view<\/code>, <\/strong><code><strong>std::views::adjacent_view, std::ranges::adjacent_transform_view, <\/strong><\/code>and <code><strong>std::views::adjacent_transform<\/strong><br \/><\/code><\/li>\n<\/ul>\n<p>Creates a view that consists of tuples of references to adjacent elements. Additionally, You can apply a transformation function.<\/p>\n<p>These examples are directly from the proposal <a href=\"https:\/\/wg21.link\/P2321R2\" rel=\"nofollow\" class=\"external text\">P2321R2<\/a>:<\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\">vector v <span style=\"color: #555555;\">=<\/span> {<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">2<\/span>, <span style=\"color: #ff6600;\">3<\/span>, <span style=\"color: #ff6600;\">4<\/span>};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">auto<\/span> i <span style=\"color: #555555;\">:<\/span> v <span style=\"color: #555555;\">|<\/span> views<span style=\"color: #555555;\">::<\/span>adjacent<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #ff6600;\">2<\/span><span style=\"color: #555555;\">&gt;<\/span>) {\r\n  cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'('<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> i.first <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #aa0000; background-color: #ffaaaa;\">'<\/span>, <span style=\"color: #aa0000; background-color: #ffaaaa;\">'<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> i.second <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\") \"<\/span>; <span style=\"color: #0099ff; font-style: italic;\">\/\/ prints: (1, 2) (2, 3) (3, 4)<\/span>\r\n}\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">auto<\/span> i <span style=\"color: #555555;\">:<\/span> v <span style=\"color: #555555;\">|<\/span> views<span style=\"color: #555555;\">::<\/span>adjacent_transform<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #ff6600;\">2<\/span><span style=\"color: #555555;\">&gt;<\/span>(std<span style=\"color: #555555;\">::<\/span>multiplies())) {\r\n  cout <span style=\"color: #555555;\">&lt;&lt;<\/span> i <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">' '<\/span>;  <span style=\"color: #0099ff; font-style: italic;\">\/\/ prints: 2 6 12<\/span>\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<ul>\n<li><code><strong>std::ranges::join_with, <\/strong><\/code><strong>and <\/strong><code><strong>std::views::join_with<\/strong><br \/><\/code><\/li>\n<\/ul>\n<p>Creates a view by flattening the input range. Puts a delimiter between elements.<\/p>\n<p><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/ranges\/join_with_view\">cppreference.com\/join_with_view<\/a> provides a nice example in which a space is the delimiter element.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;ranges&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;vector&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;string_view&gt;<\/span>\r\n \r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>() {\r\n    <span style=\"color: #006699; font-weight: bold;\">using<\/span> <span style=\"color: #006699; font-weight: bold;\">namespace<\/span> std<span style=\"color: #555555;\">::<\/span>literals;\r\n \r\n    std<span style=\"color: #555555;\">::<\/span>vector v{<span style=\"color: #cc3300;\">\"This\"<\/span>sv, <span style=\"color: #cc3300;\">\"is\"<\/span>sv, <span style=\"color: #cc3300;\">\"a\"<\/span>sv, <span style=\"color: #cc3300;\">\"test.\"<\/span>sv};\r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> joined <span style=\"color: #555555;\">=<\/span> v <span style=\"color: #555555;\">|<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>join_with(<span style=\"color: #cc3300;\">' '<\/span>);\r\n \r\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">auto<\/span> c <span style=\"color: #555555;\">:<\/span> joined) std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> c;\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<ul>\n<li><strong><code>std::views::chunk,<\/code> and<code> std::views::chunk_by<\/code><\/strong><\/li>\n<\/ul>\n<p>Creates a view by dividing a range R into non-overlapping N-sized chunks. Additionally, you can apply a predicate.<\/p>\n<p>The code snippets are from proposal <a href=\"https:\/\/wg21.link\/P2442R1\" rel=\"nofollow\" class=\"external text\">P2442R1<\/a> and proposal <a href=\"https:\/\/wg21.link\/P2443R1\" rel=\"nofollow\" class=\"external text\">P2443R1<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\">std<span style=\"color: #555555;\">::<\/span>vector v <span style=\"color: #555555;\">=<\/span> {<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>};\r\nfmt<span style=\"color: #555555;\">::<\/span>print(<span style=\"color: #cc3300;\">\"{}<\/span><span style=\"color: #cc3300; font-weight: bold;\">\\n<\/span><span style=\"color: #cc3300;\">\"<\/span>, v <span style=\"color: #555555;\">|<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>chunk(<span style=\"color: #ff6600;\">2<\/span>));   <span style=\"color: #0099ff; font-style: italic;\">\/\/ [[1, 2], [3, 4], [5]]<\/span>\r\nfmt<span style=\"color: #555555;\">::<\/span>print(<span style=\"color: #cc3300;\">\"{}<\/span><span style=\"color: #cc3300; font-weight: bold;\">\\n<\/span><span style=\"color: #cc3300;\">\"<\/span>, v <span style=\"color: #555555;\">|<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>slide(<span style=\"color: #ff6600;\">2<\/span>));   <span style=\"color: #0099ff; font-style: italic;\">\/\/ [[1, 2], [2, 3], [3, 4], [4, 5]]<\/span>\r\n\r\n\r\nstd<span style=\"color: #555555;\">::<\/span>vector v <span style=\"color: #555555;\">=<\/span> {<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">2<\/span>, <span style=\"color: #ff6600;\">2<\/span>, <span style=\"color: #ff6600;\">3<\/span>, <span style=\"color: #ff6600;\">0<\/span>, <span style=\"color: #ff6600;\">4<\/span>, <span style=\"color: #ff6600;\">5<\/span>, <span style=\"color: #ff6600;\">2<\/span>};\r\nfmt<span style=\"color: #555555;\">::<\/span>print(<span style=\"color: #cc3300;\">\"{}<\/span><span style=\"color: #cc3300; font-weight: bold;\">\\n<\/span><span style=\"color: #cc3300;\">\"<\/span>, v <span style=\"color: #555555;\">|<\/span> std<span style=\"color: #555555;\">::<\/span>views<span style=\"color: #555555;\">::<\/span>chunk_by(ranges<span style=\"color: #555555;\">::<\/span>less_equal{}));   <span style=\"color: #0099ff; font-style: italic;\">\/\/ [[1, 2, 2, 3], [0, 4, 5], [2]]<\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Both code snippets use the prototype library <a href=\"https:\/\/github.com\/fmtlib\/fmt\">fmt <\/a>for the format library in C++20. fmt has a convenience function <code>fmt::print<\/code> that may become part of C++23 as <code>std::print<\/code>.<\/p>\n<ul>\n<li><strong><code>std::views::slide<\/code><\/strong><\/li>\n<\/ul>\n<p>Creates a view of N-tuples by taking a view and a number N.<\/p>\n<p>The example is also from proposal <a href=\"https:\/\/wg21.link\/P2443R1\" rel=\"nofollow\" class=\"external text\">P2443R1<\/a>.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\">vector v <span style=\"color: #555555;\">=<\/span> {<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">2<\/span>, <span style=\"color: #ff6600;\">3<\/span>, <span style=\"color: #ff6600;\">4<\/span>};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">auto<\/span> i <span style=\"color: #555555;\">:<\/span> v <span style=\"color: #555555;\">|<\/span> views<span style=\"color: #555555;\">::<\/span>slide(<span style=\"color: #ff6600;\">2<\/span>)) {\r\n  cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'['<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> i[<span style=\"color: #ff6600;\">0<\/span>] <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #aa0000; background-color: #ffaaaa;\">'<\/span>, <span style=\"color: #aa0000; background-color: #ffaaaa;\">'<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> i[<span style=\"color: #ff6600;\">1<\/span>] <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"] \"<\/span>; <span style=\"color: #0099ff; font-style: italic;\">\/\/ prints: [1, 2] [2, 3] [3, 4]<\/span>\r\n}\r\n<\/pre>\n<\/div>\n<h2>What&#8217;s next?<\/h2>\n<p>Last week, I made a poll and asked: &#8220;Which mentoring program should I implement next?&#8221; Honestly, this result surprised me a lot. I taught Design Patterns from 2004 to 2008 and assumed that you already knew them, and C++20 or Clean Code with C++ would win the poll. Consequentially, I changed my plan for my upcoming posts. My next big topic will be &#8220;Design Pattern and Architectural Pattern in C++&#8221;. When I finish this big topic, I will return to C++20 and C++23.<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Thanks to C++23, constructing containers will become more convenient. Additionally, the ranges library got more new views.<\/p>\n","protected":false},"author":21,"featured_media":6382,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[378],"tags":[412,413],"class_list":["post-6384","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c-23","tag-python","tag-ranges"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6384","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=6384"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6384\/revisions"}],"predecessor-version":[{"id":6664,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6384\/revisions\/6664"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/6382"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=6384"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=6384"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=6384"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}