<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
<title>nor&#x27;s blog - c++</title>
<link>https://nor-blog.pages.dev/tags/c%2B%2B/</link>
<description>nor&#x27;s blog</description>
<lastBuildDate>Tue, 05 Mar 2024 00:00:00 +0000</lastBuildDate>
<atom:link href="https://nor-blog.pages.dev/tags/c%2B%2B/index.xml" rel="self" type="application/rss+xml"/>
<item>
<title>Convenient and near-optimal binary search on floating point numbers</title>
<link>https://nor-blog.pages.dev/posts/2024-03-05-floating-point-binsearch/</link>
<guid>https://nor-blog.pages.dev/posts/2024-03-05-floating-point-binsearch/</guid>
<pubDate>Tue, 05 Mar 2024 00:00:00 +0000</pubDate>
<description>A near-optimal floating-point binary search template that searches representable values via bit-casts instead of hard-coded iteration counts.</description>
<content:encoded><![CDATA[<h2 id="tldr">TL;DR</h2>
<p>Use the following template (C++20) for efficient and near-optimal binary search (in terms of number of queries) on floating point numbers.</p>
<details>
<summary>Template</summary>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="bu">std::</span>size_t N_BITS<span class="op">&gt;</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="kw">using</span> <span class="dt">int_least_t</span> <span class="op">=</span> <span class="bu">std::</span>conditional_t<span class="op">&lt;</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>    N_BITS <span class="op">&lt;=</span> <span class="dv">8</span><span class="op">,</span> <span class="bu">std::</span>uint8_t<span class="op">,</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>    <span class="bu">std::</span>conditional_t<span class="op">&lt;</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>        N_BITS <span class="op">&lt;=</span> <span class="dv">16</span><span class="op">,</span> <span class="bu">std::</span>uint16_t<span class="op">,</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>        <span class="bu">std::</span>conditional_t<span class="op">&lt;</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>            N_BITS <span class="op">&lt;=</span> <span class="dv">32</span><span class="op">,</span> <span class="bu">std::</span>uint32_t<span class="op">,</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>            <span class="bu">std::</span>conditional_t<span class="op">&lt;</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>                N_BITS <span class="op">&lt;=</span> <span class="dv">64</span><span class="op">,</span> <span class="bu">std::</span>uint64_t<span class="op">,</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>                <span class="bu">std::</span>conditional_t<span class="op">&lt;</span>N_BITS <span class="op">&lt;=</span> <span class="dv">128</span><span class="op">,</span> __uint128_t<span class="op">,</span> <span class="dt">void</span><span class="op">&gt;&gt;&gt;&gt;&gt;;</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a><span class="co">// this should work for float and doubles, but for long doubles, std::bit_cast will fail on most systems due to being 80 bits wide.</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a><span class="co">// to handle this, consider using doubles instead or std::bit_cast the long double to an 80-bit bitset and convert it to a 128 bit integer using to_ullong.</span></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a><span class="co">/*</span></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a><span class="co">   * returns first x in [a, b] such that predicate(x) is false, conditioned on</span></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a><span class="co">   * logical_predicate(a) &amp;&amp; !logical_predicate(b) &amp;&amp; logical_predicate(-inf) &amp;&amp;</span></span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a><span class="co">   * !logical_predicate(inf)</span></span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a><span class="co">   * here logical_predicate is the mathematical value of the predicate, not the</span></span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a><span class="co">   * machine value of the predicate</span></span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a><span class="co">   * it is guaranteed that non-nan, non-inf inputs are passed into the predicate</span></span>
<span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-26"><a href="#cb1-26" aria-hidden="true" tabindex="-1"></a><span class="co">   * if NaNs or infinities are passed to this function as argument, then the</span></span>
<span id="cb1-27"><a href="#cb1-27" aria-hidden="true" tabindex="-1"></a><span class="co">   * inputs to the predicate will start from smallest/largest representable</span></span>
<span id="cb1-28"><a href="#cb1-28" aria-hidden="true" tabindex="-1"></a><span class="co">   * floating point numbers of the input type - this can be a source of errors</span></span>
<span id="cb1-29"><a href="#cb1-29" aria-hidden="true" tabindex="-1"></a><span class="co">   * if you multiply the input by something &gt; 1 for example</span></span>
<span id="cb1-30"><a href="#cb1-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-31"><a href="#cb1-31" aria-hidden="true" tabindex="-1"></a><span class="co">   * strictly speaking, the predicate should also be perfectly monotonic, but if</span></span>
<span id="cb1-32"><a href="#cb1-32" aria-hidden="true" tabindex="-1"></a><span class="co">   * it gives out-of-order booleans in some small range [a, a + eps] (and the</span></span>
<span id="cb1-33"><a href="#cb1-33" aria-hidden="true" tabindex="-1"></a><span class="co">   * correct order elsewhere), then the answer will be somewhere in between</span></span>
<span id="cb1-34"><a href="#cb1-34" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-35"><a href="#cb1-35" aria-hidden="true" tabindex="-1"></a><span class="co">   * the same holds for how denormals are handled by this code</span></span>
<span id="cb1-36"><a href="#cb1-36" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-37"><a href="#cb1-37" aria-hidden="true" tabindex="-1"></a><span class="co">   */</span></span>
<span id="cb1-38"><a href="#cb1-38" aria-hidden="true" tabindex="-1"></a><span class="co">//</span></span>
<span id="cb1-39"><a href="#cb1-39" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="dt">bool</span> check_infinities <span class="op">=</span> <span class="kw">false</span><span class="op">,</span></span>
<span id="cb1-40"><a href="#cb1-40" aria-hidden="true" tabindex="-1"></a>          <span class="dt">bool</span> distinguish_plus_minus_zero <span class="op">=</span> <span class="kw">false</span><span class="op">,</span></span>
<span id="cb1-41"><a href="#cb1-41" aria-hidden="true" tabindex="-1"></a>          <span class="dt">bool</span> deal_with_nans_and_infs <span class="op">=</span> <span class="kw">false</span><span class="op">,</span> <span class="bu">std::</span>floating_point T<span class="op">&gt;</span></span>
<span id="cb1-42"><a href="#cb1-42" aria-hidden="true" tabindex="-1"></a>T partition_point_fp<span class="op">(</span>T a<span class="op">,</span> T b<span class="op">,</span> <span class="kw">auto</span><span class="op">&amp;&amp;</span> predicate<span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-43"><a href="#cb1-43" aria-hidden="true" tabindex="-1"></a>    <span class="at">static</span> <span class="kw">constexpr</span> <span class="bu">std::</span>size_t T_WIDTH <span class="op">=</span> <span class="kw">sizeof</span><span class="op">(</span>T<span class="op">)</span> <span class="op">*</span> CHAR_BIT<span class="op">;</span></span>
<span id="cb1-44"><a href="#cb1-44" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> Int <span class="op">=</span> <span class="dt">int_least_t</span><span class="op">&lt;</span>T_WIDTH<span class="op">&gt;;</span></span>
<span id="cb1-45"><a href="#cb1-45" aria-hidden="true" tabindex="-1"></a>    <span class="at">static</span> <span class="kw">constexpr</span> <span class="kw">auto</span> is_negative <span class="op">=</span> <span class="op">[](</span>T x<span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-46"><a href="#cb1-46" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="kw">static_cast</span><span class="op">&lt;</span><span class="dt">bool</span><span class="op">&gt;((</span><span class="bu">std::</span>bit_cast<span class="op">&lt;</span>Int<span class="op">&gt;(</span>x<span class="op">)</span> <span class="op">&gt;&gt;</span> <span class="op">(</span>T_WIDTH <span class="op">-</span> <span class="dv">1</span><span class="op">))</span> <span class="op">&amp;</span> <span class="dv">1</span><span class="op">);</span></span>
<span id="cb1-47"><a href="#cb1-47" aria-hidden="true" tabindex="-1"></a>    <span class="op">};</span></span>
<span id="cb1-48"><a href="#cb1-48" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="kw">constexpr</span> <span class="op">(</span>distinguish_plus_minus_zero<span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-49"><a href="#cb1-49" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(</span>a <span class="op">==</span> T<span class="op">(</span><span class="fl">0.0</span><span class="op">)</span> <span class="op">&amp;&amp;</span> b <span class="op">==</span> T<span class="op">(</span><span class="fl">0.0</span><span class="op">)</span> <span class="op">&amp;&amp;</span> is_negative<span class="op">(</span>a<span class="op">)</span> <span class="op">&amp;&amp;</span> <span class="op">!</span>is_negative<span class="op">(</span>b<span class="op">))</span> <span class="op">{</span></span>
<span id="cb1-50"><a href="#cb1-50" aria-hidden="true" tabindex="-1"></a>            <span class="cf">if</span> <span class="op">(!</span>predicate<span class="op">(-</span>T<span class="op">(</span><span class="fl">0.0</span><span class="op">)))</span> <span class="op">{</span></span>
<span id="cb1-51"><a href="#cb1-51" aria-hidden="true" tabindex="-1"></a>                <span class="cf">return</span> <span class="op">-</span>T<span class="op">(</span><span class="fl">0.0</span><span class="op">);</span></span>
<span id="cb1-52"><a href="#cb1-52" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb1-53"><a href="#cb1-53" aria-hidden="true" tabindex="-1"></a>                <span class="co">// predicate(0.0) is guaranteed to be true because b = 0.0</span></span>
<span id="cb1-54"><a href="#cb1-54" aria-hidden="true" tabindex="-1"></a>                <span class="cf">return</span> T<span class="op">(</span><span class="fl">0.0</span><span class="op">);</span></span>
<span id="cb1-55"><a href="#cb1-55" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="cb1-56"><a href="#cb1-56" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb1-57"><a href="#cb1-57" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-58"><a href="#cb1-58" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-59"><a href="#cb1-59" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="op">(</span>a <span class="op">&gt;=</span> b<span class="op">)</span> <span class="cf">return</span> NAN<span class="op">;</span></span>
<span id="cb1-60"><a href="#cb1-60" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-61"><a href="#cb1-61" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="kw">constexpr</span> <span class="op">(</span>deal_with_nans_and_infs<span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-62"><a href="#cb1-62" aria-hidden="true" tabindex="-1"></a>        <span class="co">// get rid of NaNs as soon as possible</span></span>
<span id="cb1-63"><a href="#cb1-63" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(</span><span class="bu">std::</span>isnan<span class="op">(</span>a<span class="op">))</span> a <span class="op">=</span> <span class="op">-</span><span class="bu">std::</span>numeric_limits<span class="op">&lt;</span>T<span class="op">&gt;::</span>infinity<span class="op">();</span></span>
<span id="cb1-64"><a href="#cb1-64" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(</span><span class="bu">std::</span>isnan<span class="op">(</span>b<span class="op">))</span> b <span class="op">=</span> <span class="bu">std::</span>numeric_limits<span class="op">&lt;</span>T<span class="op">&gt;::</span>infinity<span class="op">();</span></span>
<span id="cb1-65"><a href="#cb1-65" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-66"><a href="#cb1-66" aria-hidden="true" tabindex="-1"></a>        <span class="co">// deal with infinities</span></span>
<span id="cb1-67"><a href="#cb1-67" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(</span>a <span class="op">==</span> <span class="op">-</span><span class="bu">std::</span>numeric_limits<span class="op">&lt;</span>T<span class="op">&gt;::</span>infinity<span class="op">())</span> <span class="op">{</span></span>
<span id="cb1-68"><a href="#cb1-68" aria-hidden="true" tabindex="-1"></a>            <span class="cf">if</span> <span class="kw">constexpr</span> <span class="op">(</span>check_infinities<span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-69"><a href="#cb1-69" aria-hidden="true" tabindex="-1"></a>                <span class="cf">if</span> <span class="op">(</span>predicate<span class="op">(-</span><span class="bu">std::</span>numeric_limits<span class="op">&lt;</span>T<span class="op">&gt;::</span>max<span class="op">()))</span> <span class="op">{</span></span>
<span id="cb1-70"><a href="#cb1-70" aria-hidden="true" tabindex="-1"></a>                    a <span class="op">=</span> <span class="op">-</span><span class="bu">std::</span>numeric_limits<span class="op">&lt;</span>T<span class="op">&gt;::</span>max<span class="op">();</span></span>
<span id="cb1-71"><a href="#cb1-71" aria-hidden="true" tabindex="-1"></a>                <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb1-72"><a href="#cb1-72" aria-hidden="true" tabindex="-1"></a>                    <span class="cf">return</span> <span class="op">-</span><span class="bu">std::</span>numeric_limits<span class="op">&lt;</span>T<span class="op">&gt;::</span>max<span class="op">();</span></span>
<span id="cb1-73"><a href="#cb1-73" aria-hidden="true" tabindex="-1"></a>                <span class="op">}</span></span>
<span id="cb1-74"><a href="#cb1-74" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb1-75"><a href="#cb1-75" aria-hidden="true" tabindex="-1"></a>                a <span class="op">=</span> <span class="op">-</span><span class="bu">std::</span>numeric_limits<span class="op">&lt;</span>T<span class="op">&gt;::</span>max<span class="op">();</span></span>
<span id="cb1-76"><a href="#cb1-76" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="cb1-77"><a href="#cb1-77" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb1-78"><a href="#cb1-78" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(</span>b <span class="op">==</span> <span class="bu">std::</span>numeric_limits<span class="op">&lt;</span>T<span class="op">&gt;::</span>infinity<span class="op">())</span> <span class="op">{</span></span>
<span id="cb1-79"><a href="#cb1-79" aria-hidden="true" tabindex="-1"></a>            <span class="cf">if</span> <span class="kw">constexpr</span> <span class="op">(</span>check_infinities<span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-80"><a href="#cb1-80" aria-hidden="true" tabindex="-1"></a>                <span class="cf">if</span> <span class="op">(!</span>predicate<span class="op">(</span><span class="bu">std::</span>numeric_limits<span class="op">&lt;</span>T<span class="op">&gt;::</span>max<span class="op">()))</span> <span class="op">{</span></span>
<span id="cb1-81"><a href="#cb1-81" aria-hidden="true" tabindex="-1"></a>                    b <span class="op">=</span> <span class="bu">std::</span>numeric_limits<span class="op">&lt;</span>T<span class="op">&gt;::</span>max<span class="op">();</span></span>
<span id="cb1-82"><a href="#cb1-82" aria-hidden="true" tabindex="-1"></a>                <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb1-83"><a href="#cb1-83" aria-hidden="true" tabindex="-1"></a>                    <span class="cf">return</span> <span class="bu">std::</span>numeric_limits<span class="op">&lt;</span>T<span class="op">&gt;::</span>infinity<span class="op">();</span></span>
<span id="cb1-84"><a href="#cb1-84" aria-hidden="true" tabindex="-1"></a>                <span class="op">}</span></span>
<span id="cb1-85"><a href="#cb1-85" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb1-86"><a href="#cb1-86" aria-hidden="true" tabindex="-1"></a>                b <span class="op">=</span> <span class="bu">std::</span>numeric_limits<span class="op">&lt;</span>T<span class="op">&gt;::</span>max<span class="op">();</span></span>
<span id="cb1-87"><a href="#cb1-87" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="cb1-88"><a href="#cb1-88" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb1-89"><a href="#cb1-89" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-90"><a href="#cb1-90" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-91"><a href="#cb1-91" aria-hidden="true" tabindex="-1"></a>    <span class="co">// now a and b are both finite - deal with differently signed a and b</span></span>
<span id="cb1-92"><a href="#cb1-92" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="op">(</span>is_negative<span class="op">(</span>a<span class="op">)</span> <span class="op">&amp;&amp;</span> <span class="op">!</span>is_negative<span class="op">(</span>b<span class="op">))</span> <span class="op">{</span></span>
<span id="cb1-93"><a href="#cb1-93" aria-hidden="true" tabindex="-1"></a>        <span class="co">// check 0 once</span></span>
<span id="cb1-94"><a href="#cb1-94" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="kw">constexpr</span> <span class="op">(</span>distinguish_plus_minus_zero<span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-95"><a href="#cb1-95" aria-hidden="true" tabindex="-1"></a>            <span class="cf">if</span> <span class="op">(!</span>predicate<span class="op">(-</span>T<span class="op">(</span><span class="fl">0.0</span><span class="op">)))</span> <span class="op">{</span></span>
<span id="cb1-96"><a href="#cb1-96" aria-hidden="true" tabindex="-1"></a>                b <span class="op">=</span> <span class="op">-</span>T<span class="op">(</span><span class="fl">0.0</span><span class="op">);</span></span>
<span id="cb1-97"><a href="#cb1-97" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span> <span class="cf">else</span> <span class="cf">if</span> <span class="op">(</span>predicate<span class="op">(</span>T<span class="op">(</span><span class="fl">0.0</span><span class="op">)))</span> <span class="op">{</span></span>
<span id="cb1-98"><a href="#cb1-98" aria-hidden="true" tabindex="-1"></a>                a <span class="op">=</span> T<span class="op">(</span><span class="fl">0.0</span><span class="op">);</span></span>
<span id="cb1-99"><a href="#cb1-99" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb1-100"><a href="#cb1-100" aria-hidden="true" tabindex="-1"></a>                <span class="cf">return</span> T<span class="op">(</span><span class="fl">0.0</span><span class="op">);</span></span>
<span id="cb1-101"><a href="#cb1-101" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="cb1-102"><a href="#cb1-102" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb1-103"><a href="#cb1-103" aria-hidden="true" tabindex="-1"></a>            <span class="cf">if</span> <span class="op">(!</span>predicate<span class="op">(</span>T<span class="op">(</span><span class="fl">0.0</span><span class="op">)))</span> <span class="op">{</span></span>
<span id="cb1-104"><a href="#cb1-104" aria-hidden="true" tabindex="-1"></a>                b <span class="op">=</span> <span class="op">-</span>T<span class="op">(</span><span class="fl">0.0</span><span class="op">);</span></span>
<span id="cb1-105"><a href="#cb1-105" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb1-106"><a href="#cb1-106" aria-hidden="true" tabindex="-1"></a>                a <span class="op">=</span> T<span class="op">(</span><span class="fl">0.0</span><span class="op">);</span></span>
<span id="cb1-107"><a href="#cb1-107" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="cb1-108"><a href="#cb1-108" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb1-109"><a href="#cb1-109" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-110"><a href="#cb1-110" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-111"><a href="#cb1-111" aria-hidden="true" tabindex="-1"></a>    <span class="co">// in the case a and b are both 0 after the above check, return 0</span></span>
<span id="cb1-112"><a href="#cb1-112" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="op">(</span>a <span class="op">==</span> b<span class="op">)</span> <span class="cf">return</span> T<span class="op">(</span><span class="fl">0.0</span><span class="op">);</span></span>
<span id="cb1-113"><a href="#cb1-113" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-114"><a href="#cb1-114" aria-hidden="true" tabindex="-1"></a>    <span class="co">// start actual binary search</span></span>
<span id="cb1-115"><a href="#cb1-115" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> get_int <span class="op">=</span> <span class="op">[](</span>T x<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> <span class="bu">std::</span>bit_cast<span class="op">&lt;</span>Int<span class="op">,</span> T<span class="op">&gt;(</span>x<span class="op">);</span> <span class="op">};</span></span>
<span id="cb1-116"><a href="#cb1-116" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> get_float <span class="op">=</span> <span class="op">[](</span>Int x<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> <span class="bu">std::</span>bit_cast<span class="op">&lt;</span>T<span class="op">,</span> Int<span class="op">&gt;(</span>x<span class="op">);</span> <span class="op">};</span></span>
<span id="cb1-117"><a href="#cb1-117" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="op">(</span>b <span class="op">&gt;</span> <span class="dv">0</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-118"><a href="#cb1-118" aria-hidden="true" tabindex="-1"></a>        <span class="cf">while</span> <span class="op">(</span>get_int<span class="op">(</span>a<span class="op">)</span> <span class="op">+</span> <span class="dv">1</span> <span class="op">&lt;</span> get_int<span class="op">(</span>b<span class="op">))</span> <span class="op">{</span></span>
<span id="cb1-119"><a href="#cb1-119" aria-hidden="true" tabindex="-1"></a>            <span class="kw">auto</span> m <span class="op">=</span> <span class="bu">std::</span>midpoint<span class="op">(</span>get_int<span class="op">(</span>a<span class="op">),</span> get_int<span class="op">(</span>b<span class="op">));</span></span>
<span id="cb1-120"><a href="#cb1-120" aria-hidden="true" tabindex="-1"></a>            <span class="cf">if</span> <span class="op">(</span>predicate<span class="op">(</span>get_float<span class="op">(</span>m<span class="op">)))</span> <span class="op">{</span></span>
<span id="cb1-121"><a href="#cb1-121" aria-hidden="true" tabindex="-1"></a>                a <span class="op">=</span> get_float<span class="op">(</span>m<span class="op">);</span></span>
<span id="cb1-122"><a href="#cb1-122" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb1-123"><a href="#cb1-123" aria-hidden="true" tabindex="-1"></a>                b <span class="op">=</span> get_float<span class="op">(</span>m<span class="op">);</span></span>
<span id="cb1-124"><a href="#cb1-124" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="cb1-125"><a href="#cb1-125" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb1-126"><a href="#cb1-126" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb1-127"><a href="#cb1-127" aria-hidden="true" tabindex="-1"></a>        <span class="cf">while</span> <span class="op">(</span>get_int<span class="op">(-</span>b<span class="op">)</span> <span class="op">+</span> <span class="dv">1</span> <span class="op">&lt;</span> get_int<span class="op">(-</span>a<span class="op">))</span> <span class="op">{</span></span>
<span id="cb1-128"><a href="#cb1-128" aria-hidden="true" tabindex="-1"></a>            <span class="kw">auto</span> m <span class="op">=</span> <span class="bu">std::</span>midpoint<span class="op">(</span>get_int<span class="op">(-</span>b<span class="op">),</span> get_int<span class="op">(-</span>a<span class="op">));</span></span>
<span id="cb1-129"><a href="#cb1-129" aria-hidden="true" tabindex="-1"></a>            <span class="cf">if</span> <span class="op">(</span>predicate<span class="op">(-</span>get_float<span class="op">(</span>m<span class="op">)))</span> <span class="op">{</span></span>
<span id="cb1-130"><a href="#cb1-130" aria-hidden="true" tabindex="-1"></a>                a <span class="op">=</span> <span class="op">-</span>get_float<span class="op">(</span>m<span class="op">);</span></span>
<span id="cb1-131"><a href="#cb1-131" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb1-132"><a href="#cb1-132" aria-hidden="true" tabindex="-1"></a>                b <span class="op">=</span> <span class="op">-</span>get_float<span class="op">(</span>m<span class="op">);</span></span>
<span id="cb1-133"><a href="#cb1-133" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="cb1-134"><a href="#cb1-134" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb1-135"><a href="#cb1-135" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-136"><a href="#cb1-136" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> b<span class="op">;</span></span>
<span id="cb1-137"><a href="#cb1-137" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</details>
<p>It is also possible to extend this to breaking early when a custom closeness predicate is true (for example, min(absolute error, relative error) &lt; 1e-9 and so on), but for the sake of simplicity, this template does not do so.</p>
<h2 id="introduction">Introduction</h2>
<p>It is well known that writing the condition for continuation of the binary search as anything like <code>while (r - l &gt; 1)</code> or <code>while (l &lt; r)</code> is bug-prone on floating point integers, so people tend to write a binary search by fixing the number of iterations. However, this is usually not the best method --- you need <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>O</mi><mo stretchy="false" form="prefix">(</mo><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>L</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">O(\log L)</annotation></semantics></math> iterations where <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>L</mi><annotation encoding="application/x-tex">L</annotation></semantics></math> is the length of the range, and the range of floating point numbers is very large.</p>
<p>So, I came up with a way to binary search on (IEEE754, i.e., practically all implementations of) floating point numbers that takes <code>bit_width(floating_type) + O(1)</code> calls to the predicate for binary search. I am pretty sure that this method has been explored before (feel free to drop references in the comments if you find them). Regardless of whether this is a novel algorithm or not, I wanted to share this since it teaches you a lot about floating points, and it also has the following advantages:</p>
<ul>
<li>No need to hard-code the number of iterations.</li>
<li>It avoids issues that you get in other implementations (for example, using sqrt, you end up with a ton of cases with 0, negatives and so on).</li>
<li>It is efficient (sqrt is expensive, and so is dealing with a lot of cases).</li>
</ul>
<h2 id="arriving-at-the-algorithm">Arriving at the algorithm</h2>
<p>I started out by thinking about this: floating point numbers have a very large range. Can we do better than <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>O</mi><mo stretchy="false" form="prefix">(</mo><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>L</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">O(\log L)</annotation></semantics></math> where <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>L</mi><annotation encoding="application/x-tex">L</annotation></semantics></math> is the length of the range? Recall that floating point numbers also have a fixed width that is much smaller than the log of the range they represent, and between two consecutive representable floating point numbers, it is their ratio that is nicely bounded (ignoring the boundary of 0 and inf and nans) instead of their difference. Now since it is <a href="https://codeforces.com/blog/entry/49189">well-known</a> that for getting to a certain relative-error, it is optimal to use <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><msqrt><mrow><mi>l</mi><mi>r</mi></mrow></msqrt><annotation encoding="application/x-tex">\sqrt{lr}</annotation></semantics></math> instead of <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mfrac><mrow><mi>l</mi><mo>+</mo><mi>r</mi></mrow><mn>2</mn></mfrac><annotation encoding="application/x-tex">\frac{l + r}{2}</annotation></semantics></math> in binary search.</p>
<p>So the first idea that comes to mind is to use sqrt instead of midpoint in the usual binary search. However, it has a lot of issues --- for example, if <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>l</mi><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">l = 0</annotation></semantics></math>, then you never progress in the binary search (this is fixable by doing a midpoint search on 0 to 1 and sqrt search on 1 to <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>r</mi><annotation encoding="application/x-tex">r</annotation></semantics></math>). One more issue is how to deal with negatives (this is again doable by splitting the input range into multiple ranges where sqrt works) and with overflows/underflows. And the main issue with this approach is that sqrt is expensive --- if you are doing a problem where the predicate is pretty fast and you need to do a lot of binary searches, most of your computation time would be due to sqrt.</p>
<p>Inspired by these, we decide to try to approximate sqrt in a way that preserves monotonicity. Here comes the main point --- note that the IEEE754 implementation of floating point numbers separates the mantissa from the exponent, and the exponent part of <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><msqrt><mrow><mi>l</mi><mi>r</mi></mrow></msqrt><annotation encoding="application/x-tex">\sqrt{lr}</annotation></semantics></math> is roughly the mean of that of <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>l</mi><annotation encoding="application/x-tex">l</annotation></semantics></math> and <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>r</mi><annotation encoding="application/x-tex">r</annotation></semantics></math>. Since these are the top few bits (excluding the sign bit), we can just do the following (for positive floating point numbers at least): read the floating point representation as an integer (this can be done in a type-safe manner by using <code>std::bit_cast</code>), take the midpoint of these integers, and convert it back to a floating point number. This clearly preserves monotonicity --- this can be verified easily by hand. Note that this same thing works for when both range endpoints are negative numbers too --- for this we simply invert the sign bit. The case where both are of opposite signs is also simple (if you disregard the fact that +0 and -0 are equal but have distinct representations and reciprocals) --- check the predicate on <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mn>0</mn><annotation encoding="application/x-tex">0</annotation></semantics></math> (both the zeroes if it matters for your predicate).</p>
<p>Now if we want to do some more handling (infinities, NaNs, denormals), we can do it as we wish. In the implementation in the TL;DR above, we decide to replace NaNs with the infinity in the correct direction, and since there can be many infinities, we try to bring down the range endpoint to the largest representable floating point instead.</p>
<h2 id="analysis">Analysis</h2>
<p>In all, there are at most <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>w</mi><mo>+</mo><mi>O</mi><mo stretchy="false" form="prefix">(</mo><mn>1</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">w + O(1)</annotation></semantics></math> calls to the predicate, where <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>w</mi><annotation encoding="application/x-tex">w</annotation></semantics></math> is the length of the complement of the longest common prefix of the floating point representations of endpoints.</p>
<p>This implementation is also robust to predicates which are noisy near the boundary (i.e., near the boundary, there is a small range where the true values of the predicate can come after the false values) --- in this case the algorithm returns something in this range near the boundary.</p>
<p>Note that we did not need to hardcode the number of iterations, nor did we require some carefully-written predicate for loop termination.</p>
<p>Also, since <code>std::bit_cast</code> is practically free compared to <code>std::sqrt</code>, it is much faster in cases where you need to do a lot of binary searches.</p>
<p>As a usage example, <a href="https://codeforces.com/contest/1059/submission/249782522">this submission</a> uses the usual binary search with fixed number of iterations, and <a href="https://codeforces.com/contest/1059/submission/249779467">this submission</a> uses the template above.</p>
<h2 id="some-problems">Some problems</h2>
<p>The following are some problems that use binary search on floating points, and should be solvable using this template. If you encounter any bugs in the template while solving these problems, do let me know in the comments below. Thanks to <a href="https://codeforces.com/profile/jeroenodb">jeroenodb</a> and <a href="https://codeforces.com/profile/PurpleCrayon">PurpleCrayon</a> for problem suggestions.</p>
<details>
<summary>Spoiler alert</summary>
<ul>
<li><a href="https://codeforces.com/contest/1059/problem/D">1059D</a></li>
<li><a href="https://codeforces.com/contest/1446/problem/F">1446F</a></li>
<li><a href="https://codeforces.com/contest/595/problem/D">595D</a></li>
<li><a href="https://codeforces.com/contest/1359/problem/F">1359F</a></li>
<li><a href="https://open.kattis.com/problems/cameramakers">Kattis --- Association of Camera Makers</a></li>
<li><a href="https://open.kattis.com/problems/pickingupsteam">Kattis --- Picking Up Steam</a></li>
</ul>
</details>
<details>
<summary>Cite this post</summary>
<div class="sourceCode" id="cb2"><pre class="sourceCode bibtex"><code class="sourceCode bibtex"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="va">@online</span>{<span class="ot">floating</span>-<span class="ot">point</span>-<span class="ot">binsearch</span>-<span class="ot">2024</span>,</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">author</span>    = {nor},</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">title</span>     = {Convenient and near-optimal binary search on floating point numbers},</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">year</span>      = {2024},</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>  <span class="dt">month</span>     = {03},</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">day</span>       = {05},</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>  <span class="dt">url</span>       = {https://nor-blog.pages.dev/posts/2024-03-05-floating-point-binsearch},</span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
</details>]]></content:encoded>
</item><item>
<title>Write recursive DP without thinking about memoization</title>
<link>https://nor-blog.pages.dev/posts/2024-01-14-easy-recursive-dp-template/</link>
<guid>https://nor-blog.pages.dev/posts/2024-01-14-easy-recursive-dp-template/</guid>
<pubDate>Sun, 14 Jan 2024 00:00:00 +0000</pubDate>
<description>A C++ template for recursive DP with automatic memoization, built from recursive lambdas, generalized hashing, and policy-based hash tables.</description>
<content:encoded><![CDATA[<p><a href="https://codeforces.com/blog/entry/122881?#comment-1106739">Someone asked me</a> about my template that used a "cache wrapper" for lambdas, so I decided to write a post explaining how it works. For reference, <a href="https://codeforces.com/contest/1400/submission/134333870">here</a> is a submission of mine from 2021 that uses that template.</p>
<p>Here's what you will find implementations for in this post:</p>
<ul>
<li>Generalized hashing (for tuple types, sequence types and basic types)</li>
<li>Convenient aliases for policy based data structures</li>
<li>Wrappers for recursive (or otherwise) lambdas that automatically do caching (memoization) for you.</li>
</ul>
<p>Jump to the <strong>Usage</strong> section if you only care about the template, though I would strongly recommend reading the rest of the post too since it has a lot of cool/useful things in my opinion.</p>
<details>
<summary>If you know how to implement recursive lambdas</summary>
<p>You will notice that the implementation in this post uses the <code>self</code> pattern (non-standard terminology, just what I like to call it), just like the <code>y_combinator</code> pattern uses it.</p>
<details>
<summary>If you know functional programming</summary>
<p>This should remind you of the <a href="https://en.wikipedia.org/wiki/Continuation-passing_style">Continuation-passing style</a>, and the cache implementation is like a monad that does this for you, but for this specific case.</p>
</details>
</details>
<h2 id="motivation">Motivation</h2>
<p>There are two major ways in which dynamic programming is implemented --- recursive and iterative.</p>
<p>Recursive DP has the following advantages:</p>
<ul>
<li>It is (arguably) the cleaner way for beginners, and is often easier to reason about mathematically.</li>
<li>It is needed in problems where you want to only traverse the states required for computing your answer and no others.</li>
</ul>
<p>However, people switch to iterative DP as their default DP implementation, because of the following reasons:</p>
<ul>
<li>Recursive DP is sometimes slower compared to iterative DP when they compute the same number of states.</li>
<li>It is much easier to do push DP iteratively.</li>
<li>Recursive DP takes more boilerplate to write (something along the lines of "if computed already, return the stored value; otherwise, do the following").</li>
</ul>
<p>The template talked about in the above comment aims to tackle the third point by reducing boilerplate code --- it does this by automatically managing memoization for you.</p>
<h2 id="implementation">Implementation</h2>
<p>In Python, you have nice things called decorators. For example, the <code>functools.cache</code> decorator is precisely what we would use for such a purpose:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> functools <span class="im">import</span> cache</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="at">@cache</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> factorial(n):</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> n <span class="op">*</span> factorial(n <span class="op">-</span> <span class="dv">1</span>) <span class="cf">if</span> n <span class="cf">else</span> <span class="dv">1</span></span></code></pre></div>
<p>If you call <code>factorial(10)</code>, then the internal cache will be populated with the results of all the recursive calls that were required to compute <code>factorial(10)</code>. As a result, you can call <code>factorial(5)</code> and it will just look it up in the internal cache and return the value to you without calling the function body.</p>
<p>So I thought, why not try to do the same thing in C++?</p>
<p>Let's get a couple of things out of the way first:</p>
<ul>
<li>Note that Python dictionaries support heterogeneous types, but you can't do this without type erasure (in C++ or otherwise). So I decided to keep types homogeneous, i.e., the internal cache has keys of the same type. This was done to avoid performance hits, and it made sense because in competitive programming, people don't really use DP states that have heterogeneous types.</li>
<li>Functions in C++ can take arguments by value or by reference. But in Python, arguments are taken by name. For the purposes of DP, since it doesn't really make sense to make states mutable, we decide that we will pass everything by value (there are a few pointers in the Caveats section if you are worried about performance implications due to copying a lot, but these are often not important since DP states tend to be integers/small types most of the time).</li>
</ul>
<p>So let's start out by trying to design it.</p>
<p>We need the following two parts:</p>
<ol type="1">
<li>A wrapper around a function that is able to store calls to the function and their results.</li>
<li>Generalized hashing, to be able to store results.</li>
</ol>
<p>Let's solve the first problem first. Hashing arbitrary structs in C++ is quite hard (not impossible, though). But what you can always do (for structs whose intent is to just store elements) is to supply a function that makes them tuples (i.e., provide a type conversion operator). For our problem, we identify the most important types that we will ever need to hash:</p>
<ul>
<li>Native integral types (including characters)</li>
<li>Sequence types (vectors, sets, maps)</li>
<li>Tuple types (tuples, pairs)</li>
</ul>
<p>The last two are uniformly recursive on their inputs (except for <code>vector&lt;bool&gt;</code>, but our implementation doesn't need to treat it separately), so we can do recursive metaprogramming to be able to hash such types.</p>
<p>All in all, we need a hashing function that hashes the "base case" and a hash combination function that aggregates over the sequence/tuple types.</p>
<p>The implementation becomes something like this:</p>
<details>
<summary>Spoiler</summary>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">namespace</span> hashing <span class="op">{</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> i64 <span class="op">=</span> <span class="bu">std::</span>int64_t<span class="op">;</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> u64 <span class="op">=</span> <span class="bu">std::</span>uint64_t<span class="op">;</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>    <span class="at">static</span> <span class="at">const</span> u64 FIXED_RANDOM <span class="op">=</span> <span class="bu">std::</span>chrono::steady_clock::now<span class="op">().</span>time_since_epoch<span class="op">().</span>count<span class="op">();</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a><span class="pp">#if USE_AES</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>    <span class="bu">std::</span>mt19937 rd<span class="op">(</span>FIXED_RANDOM<span class="op">);</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>    <span class="at">const</span> __m128i KEY1<span class="op">{(</span>i64<span class="op">)</span>rd<span class="op">(),</span> <span class="op">(</span>i64<span class="op">)</span>rd<span class="op">()};</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>    <span class="at">const</span> __m128i KEY2<span class="op">{(</span>i64<span class="op">)</span>rd<span class="op">(),</span> <span class="op">(</span>i64<span class="op">)</span>rd<span class="op">()};</span></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a><span class="pp">#endif</span></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">,</span> <span class="kw">class</span> D <span class="op">=</span> <span class="dt">void</span><span class="op">&gt;</span></span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">struct</span> custom_hash <span class="op">{};</span></span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true" tabindex="-1"></a>    <span class="co">// https://www.boost.org/doc/libs/1_55_0/doc/html/hash/combine.html</span></span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb2-17"><a href="#cb2-17" aria-hidden="true" tabindex="-1"></a>    <span class="kw">inline</span> <span class="dt">void</span> hash_combine<span class="op">(</span>u64<span class="op">&amp;</span> seed<span class="op">,</span> <span class="at">const</span> T<span class="op">&amp;</span> v<span class="op">)</span> <span class="op">{</span></span>
<span id="cb2-18"><a href="#cb2-18" aria-hidden="true" tabindex="-1"></a>        custom_hash<span class="op">&lt;</span>T<span class="op">&gt;</span> hasher<span class="op">;</span></span>
<span id="cb2-19"><a href="#cb2-19" aria-hidden="true" tabindex="-1"></a>        seed <span class="op">^=</span> hasher<span class="op">(</span>v<span class="op">)</span> <span class="op">+</span> <span class="bn">0x9e3779b97f4a7c15</span> <span class="op">+</span> <span class="op">(</span>seed <span class="op">&lt;&lt;</span> <span class="dv">12</span><span class="op">)</span> <span class="op">+</span> <span class="op">(</span>seed <span class="op">&gt;&gt;</span> <span class="dv">4</span><span class="op">);</span></span>
<span id="cb2-20"><a href="#cb2-20" aria-hidden="true" tabindex="-1"></a>    <span class="op">};</span></span>
<span id="cb2-21"><a href="#cb2-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-22"><a href="#cb2-22" aria-hidden="true" tabindex="-1"></a>    <span class="co">// http://xorshift.di.unimi.it/splitmix64.c</span></span>
<span id="cb2-23"><a href="#cb2-23" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb2-24"><a href="#cb2-24" aria-hidden="true" tabindex="-1"></a>    <span class="kw">struct</span> custom_hash<span class="op">&lt;</span>T<span class="op">,</span> <span class="kw">typename</span> <span class="bu">std::</span>enable_if<span class="op">&lt;</span><span class="bu">std::</span>is_integral<span class="op">&lt;</span>T<span class="op">&gt;::</span>value<span class="op">&gt;::</span>type<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb2-25"><a href="#cb2-25" aria-hidden="true" tabindex="-1"></a>        u64 <span class="kw">operator</span><span class="op">()(</span>T _x<span class="op">)</span> <span class="at">const</span> <span class="op">{</span></span>
<span id="cb2-26"><a href="#cb2-26" aria-hidden="true" tabindex="-1"></a>            u64 x <span class="op">=</span> _x<span class="op">;</span></span>
<span id="cb2-27"><a href="#cb2-27" aria-hidden="true" tabindex="-1"></a><span class="pp">#if USE_AES</span></span>
<span id="cb2-28"><a href="#cb2-28" aria-hidden="true" tabindex="-1"></a>            <span class="co">// implementation defined till C++17, defined from C++20</span></span>
<span id="cb2-29"><a href="#cb2-29" aria-hidden="true" tabindex="-1"></a>            __m128i m<span class="op">{</span>i64<span class="op">(</span>u64<span class="op">(</span>x<span class="op">)</span> <span class="op">*</span> <span class="bn">0xbf58476d1ce4e5b9</span><span class="er">u64</span><span class="op">),</span> <span class="op">(</span>i64<span class="op">)</span>FIXED_RANDOM<span class="op">};</span></span>
<span id="cb2-30"><a href="#cb2-30" aria-hidden="true" tabindex="-1"></a>            __m128i y <span class="op">=</span> _mm_aesenc_si128<span class="op">(</span>m<span class="op">,</span> KEY1<span class="op">);</span></span>
<span id="cb2-31"><a href="#cb2-31" aria-hidden="true" tabindex="-1"></a>            __m128i z <span class="op">=</span> _mm_aesenc_si128<span class="op">(</span>y<span class="op">,</span> KEY2<span class="op">);</span></span>
<span id="cb2-32"><a href="#cb2-32" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> z<span class="op">[</span><span class="dv">0</span><span class="op">];</span></span>
<span id="cb2-33"><a href="#cb2-33" aria-hidden="true" tabindex="-1"></a><span class="pp">#else</span></span>
<span id="cb2-34"><a href="#cb2-34" aria-hidden="true" tabindex="-1"></a>            x <span class="op">+=</span> <span class="bn">0x9e3779b97f4a7c15</span> <span class="op">+</span> FIXED_RANDOM<span class="op">;</span></span>
<span id="cb2-35"><a href="#cb2-35" aria-hidden="true" tabindex="-1"></a>            x <span class="op">=</span> <span class="op">(</span>x <span class="op">^</span> <span class="op">(</span>x <span class="op">&gt;&gt;</span> <span class="dv">30</span><span class="op">))</span> <span class="op">*</span> <span class="bn">0xbf58476d1ce4e5b9</span><span class="op">;</span></span>
<span id="cb2-36"><a href="#cb2-36" aria-hidden="true" tabindex="-1"></a>            x <span class="op">=</span> <span class="op">(</span>x <span class="op">^</span> <span class="op">(</span>x <span class="op">&gt;&gt;</span> <span class="dv">27</span><span class="op">))</span> <span class="op">*</span> <span class="bn">0x94d049bb133111eb</span><span class="op">;</span></span>
<span id="cb2-37"><a href="#cb2-37" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> x <span class="op">^</span> <span class="op">(</span>x <span class="op">&gt;&gt;</span> <span class="dv">31</span><span class="op">);</span></span>
<span id="cb2-38"><a href="#cb2-38" aria-hidden="true" tabindex="-1"></a><span class="pp">#endif</span></span>
<span id="cb2-39"><a href="#cb2-39" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb2-40"><a href="#cb2-40" aria-hidden="true" tabindex="-1"></a>    <span class="op">};</span></span>
<span id="cb2-41"><a href="#cb2-41" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-42"><a href="#cb2-42" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb2-43"><a href="#cb2-43" aria-hidden="true" tabindex="-1"></a>    <span class="kw">struct</span> custom_hash<span class="op">&lt;</span>T<span class="op">,</span> <span class="bu">std::</span>void_t<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(</span><span class="bu">std::</span>begin<span class="op">(</span><span class="bu">std::</span>declval<span class="op">&lt;</span>T<span class="op">&gt;()))&gt;&gt;</span> <span class="op">{</span></span>
<span id="cb2-44"><a href="#cb2-44" aria-hidden="true" tabindex="-1"></a>        u64 <span class="kw">operator</span><span class="op">()(</span><span class="at">const</span> T<span class="op">&amp;</span> a<span class="op">)</span> <span class="at">const</span> <span class="op">{</span></span>
<span id="cb2-45"><a href="#cb2-45" aria-hidden="true" tabindex="-1"></a>            u64 value <span class="op">=</span> FIXED_RANDOM<span class="op">;</span></span>
<span id="cb2-46"><a href="#cb2-46" aria-hidden="true" tabindex="-1"></a>            <span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span><span class="op">&amp;</span> x <span class="op">:</span> a<span class="op">)</span> hash_combine<span class="op">(</span>value<span class="op">,</span> x<span class="op">);</span></span>
<span id="cb2-47"><a href="#cb2-47" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> value<span class="op">;</span></span>
<span id="cb2-48"><a href="#cb2-48" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb2-49"><a href="#cb2-49" aria-hidden="true" tabindex="-1"></a>    <span class="op">};</span></span>
<span id="cb2-50"><a href="#cb2-50" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-51"><a href="#cb2-51" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> T<span class="op">&gt;</span></span>
<span id="cb2-52"><a href="#cb2-52" aria-hidden="true" tabindex="-1"></a>    <span class="kw">struct</span> custom_hash<span class="op">&lt;</span><span class="bu">std::</span>tuple<span class="op">&lt;</span>T<span class="op">...&gt;&gt;</span> <span class="op">{</span></span>
<span id="cb2-53"><a href="#cb2-53" aria-hidden="true" tabindex="-1"></a>        u64 <span class="kw">operator</span><span class="op">()(</span><span class="at">const</span> <span class="bu">std::</span>tuple<span class="op">&lt;</span>T<span class="op">...&gt;&amp;</span> a<span class="op">)</span> <span class="at">const</span> <span class="op">{</span></span>
<span id="cb2-54"><a href="#cb2-54" aria-hidden="true" tabindex="-1"></a>            u64 value <span class="op">=</span> FIXED_RANDOM<span class="op">;</span></span>
<span id="cb2-55"><a href="#cb2-55" aria-hidden="true" tabindex="-1"></a>            <span class="bu">std::</span>apply<span class="op">([&amp;</span>value<span class="op">](</span>T <span class="at">const</span><span class="op">&amp;...</span> args<span class="op">)</span> <span class="op">{</span> <span class="op">(</span>hash_combine<span class="op">(</span>value<span class="op">,</span> args<span class="op">),</span> <span class="op">...);</span> <span class="op">},</span> a<span class="op">);</span></span>
<span id="cb2-56"><a href="#cb2-56" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> value<span class="op">;</span></span>
<span id="cb2-57"><a href="#cb2-57" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb2-58"><a href="#cb2-58" aria-hidden="true" tabindex="-1"></a>    <span class="op">};</span></span>
<span id="cb2-59"><a href="#cb2-59" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-60"><a href="#cb2-60" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">,</span> <span class="kw">class</span> U<span class="op">&gt;</span></span>
<span id="cb2-61"><a href="#cb2-61" aria-hidden="true" tabindex="-1"></a>    <span class="kw">struct</span> custom_hash<span class="op">&lt;</span><span class="bu">std::</span>pair<span class="op">&lt;</span>T<span class="op">,</span> U<span class="op">&gt;&gt;</span> <span class="op">{</span></span>
<span id="cb2-62"><a href="#cb2-62" aria-hidden="true" tabindex="-1"></a>        u64 <span class="kw">operator</span><span class="op">()(</span><span class="at">const</span> <span class="bu">std::</span>pair<span class="op">&lt;</span>T<span class="op">,</span> U<span class="op">&gt;&amp;</span> a<span class="op">)</span> <span class="at">const</span> <span class="op">{</span></span>
<span id="cb2-63"><a href="#cb2-63" aria-hidden="true" tabindex="-1"></a>            u64 value <span class="op">=</span> FIXED_RANDOM<span class="op">;</span></span>
<span id="cb2-64"><a href="#cb2-64" aria-hidden="true" tabindex="-1"></a>            hash_combine<span class="op">(</span>value<span class="op">,</span> a<span class="op">.</span>first<span class="op">);</span></span>
<span id="cb2-65"><a href="#cb2-65" aria-hidden="true" tabindex="-1"></a>            hash_combine<span class="op">(</span>value<span class="op">,</span> a<span class="op">.</span>second<span class="op">);</span></span>
<span id="cb2-66"><a href="#cb2-66" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> value<span class="op">;</span></span>
<span id="cb2-67"><a href="#cb2-67" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb2-68"><a href="#cb2-68" aria-hidden="true" tabindex="-1"></a>    <span class="op">};</span></span>
<span id="cb2-69"><a href="#cb2-69" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-70"><a href="#cb2-70" aria-hidden="true" tabindex="-1"></a><span class="op">};</span>  <span class="co">// namespace hashing</span></span></code></pre></div>
</details>
<p>Now for the hash table, we could just use <code>std::unordered_map</code>. However, it often turns out to be slower than the GNU policy based data structure <code>gp_hash_table</code>, so we also define some aliases that are helpful.</p>
<details>
<summary>Spoiler</summary>
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&quot;ext/pb_ds/assoc_container.hpp&quot;</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&quot;ext/pb_ds/tree_policy.hpp&quot;</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="kw">namespace</span> pbds <span class="op">{</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> <span class="kw">namespace</span> __gnu_pbds<span class="op">;</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a><span class="pp">#ifdef PB_DS_ASSOC_CNTNR_HPP</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> Key<span class="op">,</span> <span class="kw">class</span> Value<span class="op">,</span> <span class="kw">class</span> Hash<span class="op">&gt;</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> unordered_map <span class="op">=</span> gp_hash_table<span class="op">&lt;</span>Key<span class="op">,</span> Value<span class="op">,</span> Hash<span class="op">,</span> <span class="bu">std::</span>equal_to<span class="op">&lt;</span>Key<span class="op">&gt;,</span> direct_mask_range_hashing<span class="op">&lt;&gt;,</span> linear_probe_fn<span class="op">&lt;&gt;,</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>                                        hash_standard_resize_policy<span class="op">&lt;</span>hash_exponential_size_policy<span class="op">&lt;&gt;,</span> hash_load_check_resize_trigger<span class="op">&lt;&gt;,</span> <span class="kw">true</span><span class="op">&gt;&gt;;</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> Key<span class="op">,</span> <span class="kw">class</span> Hash<span class="op">&gt;</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> unordered_set <span class="op">=</span> pbds<span class="op">::</span>unordered_map<span class="op">&lt;</span>Key<span class="op">,</span> <span class="dt">null_type</span><span class="op">,</span> Hash<span class="op">&gt;;</span></span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a><span class="pp">#endif</span></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a><span class="pp">#ifdef PB_DS_TREE_POLICY_HPP</span></span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> ordered_set <span class="op">=</span> tree<span class="op">&lt;</span>T<span class="op">,</span> <span class="dt">null_type</span><span class="op">,</span> <span class="bu">std::</span>less<span class="op">&lt;</span>T<span class="op">&gt;,</span> rb_tree_tag<span class="op">,</span> tree_order_statistics_node_update<span class="op">&gt;;</span></span>
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb3-17"><a href="#cb3-17" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> ordered_multiset <span class="op">=</span> tree<span class="op">&lt;</span>T<span class="op">,</span> <span class="dt">null_type</span><span class="op">,</span> <span class="bu">std::</span>less_equal<span class="op">&lt;</span>T<span class="op">&gt;,</span> rb_tree_tag<span class="op">,</span> tree_order_statistics_node_update<span class="op">&gt;;</span></span>
<span id="cb3-18"><a href="#cb3-18" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> Key<span class="op">,</span> <span class="kw">class</span> Value<span class="op">,</span> <span class="kw">class</span> Compare <span class="op">=</span> <span class="bu">std::</span>less<span class="op">&lt;</span>Key<span class="op">&gt;&gt;</span></span>
<span id="cb3-19"><a href="#cb3-19" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> ordered_map <span class="op">=</span> tree<span class="op">&lt;</span>Key<span class="op">,</span> Value<span class="op">,</span> Compare<span class="op">,</span> rb_tree_tag<span class="op">,</span> tree_order_statistics_node_update<span class="op">&gt;;</span></span>
<span id="cb3-20"><a href="#cb3-20" aria-hidden="true" tabindex="-1"></a><span class="pp">#endif</span></span>
<span id="cb3-21"><a href="#cb3-21" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>  <span class="co">// namespace pbds</span></span></code></pre></div>
</details>
<p>Now the only thing that remains is to actually decide the design of the wrapper.</p>
<p>We make the following choices:</p>
<ul>
<li>As mentioned above, we won't support reference semantics for now.</li>
<li>We can choose to use either lambdas or plain old functions. Functions can't "capture" any state, and thus you need to make things global for using them with functions (or pass them as references, which we already disallowed). Hence, we will support lambdas and not functions for the sake of generality.</li>
<li>We will choose to implement the wrapper as a struct that stores the lambda as well as the cache (hash table mapping tuples of input arguments to return values) inside it, and has its own <code>operator()</code> (call operator) that looks into the cache and returns the answer if found, else calls the lambda recursively and updates the cache (both recursively and for the current call).</li>
</ul>
<p>This is done as follows:</p>
<details>
<summary>Spoiler</summary>
<div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Signature<span class="op">,</span> <span class="kw">typename</span> Lambda<span class="op">&gt;</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Cache<span class="op">;</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> ReturnType<span class="op">,</span> <span class="kw">typename</span><span class="op">...</span> Args<span class="op">,</span> <span class="kw">typename</span> Lambda<span class="op">&gt;</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Cache<span class="op">&lt;</span>ReturnType<span class="op">(</span>Args<span class="op">...),</span> Lambda<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span><span class="op">...</span> DummyArgs<span class="op">&gt;</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>    ReturnType <span class="kw">operator</span><span class="op">()(</span>DummyArgs<span class="op">&amp;&amp;...</span> args<span class="op">)</span> <span class="op">{</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>        <span class="kw">auto</span> tied_args <span class="op">=</span> <span class="bu">std::</span>tie<span class="op">(</span>args<span class="op">...);</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a>        <span class="kw">auto</span> it <span class="op">=</span> memo<span class="op">.</span>find<span class="op">(</span>tied_args<span class="op">);</span></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(</span>it <span class="op">==</span> memo<span class="op">.</span>end<span class="op">())</span> <span class="op">{</span></span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a>            <span class="kw">auto</span><span class="op">&amp;&amp;</span> ans <span class="op">=</span> f<span class="op">(*</span><span class="kw">this</span><span class="op">,</span> <span class="bu">std::</span>forward<span class="op">&lt;</span>DummyArgs<span class="op">&gt;(</span>args<span class="op">)...);</span></span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a>            memo<span class="op">[</span>tied_args<span class="op">]</span> <span class="op">=</span> ans<span class="op">;</span></span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> ans<span class="op">;</span></span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> it<span class="op">-&gt;</span>second<span class="op">;</span></span>
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb4-18"><a href="#cb4-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-19"><a href="#cb4-19" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> _Lambda<span class="op">&gt;</span></span>
<span id="cb4-20"><a href="#cb4-20" aria-hidden="true" tabindex="-1"></a>    Cache<span class="op">(</span><span class="bu">std::</span>tuple<span class="op">&lt;&gt;,</span> _Lambda<span class="op">&amp;&amp;</span> _f<span class="op">)</span> <span class="op">:</span> f<span class="op">(</span><span class="bu">std::</span>forward<span class="op">&lt;</span>_Lambda<span class="op">&gt;(</span>_f<span class="op">))</span> <span class="op">{}</span></span>
<span id="cb4-21"><a href="#cb4-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-22"><a href="#cb4-22" aria-hidden="true" tabindex="-1"></a>    Lambda f<span class="op">;</span></span>
<span id="cb4-23"><a href="#cb4-23" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> TiedArgs <span class="op">=</span> <span class="bu">std::</span>tuple<span class="op">&lt;</span><span class="bu">std::</span>decay_t<span class="op">&lt;</span>Args<span class="op">&gt;...&gt;;</span></span>
<span id="cb4-24"><a href="#cb4-24" aria-hidden="true" tabindex="-1"></a>    pbds<span class="op">::</span>unordered_map<span class="op">&lt;</span>TiedArgs<span class="op">,</span> ReturnType<span class="op">,</span> hashing<span class="op">::</span>custom_hash<span class="op">&lt;</span>TiedArgs<span class="op">&gt;&gt;</span> memo<span class="op">;</span></span>
<span id="cb4-25"><a href="#cb4-25" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb4-26"><a href="#cb4-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-27"><a href="#cb4-27" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> Signature<span class="op">,</span> <span class="kw">class</span> Lambda<span class="op">&gt;</span></span>
<span id="cb4-28"><a href="#cb4-28" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> use_cache<span class="op">(</span>Lambda<span class="op">&amp;&amp;</span> f<span class="op">)</span> <span class="op">{</span></span>
<span id="cb4-29"><a href="#cb4-29" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> Cache<span class="op">&lt;</span>Signature<span class="op">,</span> Lambda<span class="op">&gt;(</span><span class="bu">std::</span>tuple<span class="op">{},</span> <span class="bu">std::</span>forward<span class="op">&lt;</span>Lambda<span class="op">&gt;(</span>f<span class="op">));</span></span>
<span id="cb4-30"><a href="#cb4-30" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</details>
<h2 id="usage">Usage</h2>
<p>The usage is very simple.</p>
<p>Here's the whole template for reference:</p>
<details>
<summary>Template</summary>
<div class="sourceCode" id="cb5"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">namespace</span> hashing <span class="op">{</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> i64 <span class="op">=</span> <span class="bu">std::</span>int64_t<span class="op">;</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> u64 <span class="op">=</span> <span class="bu">std::</span>uint64_t<span class="op">;</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>    <span class="at">static</span> <span class="at">const</span> u64 FIXED_RANDOM <span class="op">=</span> <span class="bu">std::</span>chrono::steady_clock::now<span class="op">().</span>time_since_epoch<span class="op">().</span>count<span class="op">();</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a><span class="pp">#if USE_AES</span></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>    <span class="bu">std::</span>mt19937 rd<span class="op">(</span>FIXED_RANDOM<span class="op">);</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>    <span class="at">const</span> __m128i KEY1<span class="op">{(</span>i64<span class="op">)</span>rd<span class="op">(),</span> <span class="op">(</span>i64<span class="op">)</span>rd<span class="op">()};</span></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a>    <span class="at">const</span> __m128i KEY2<span class="op">{(</span>i64<span class="op">)</span>rd<span class="op">(),</span> <span class="op">(</span>i64<span class="op">)</span>rd<span class="op">()};</span></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a><span class="pp">#endif</span></span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">,</span> <span class="kw">class</span> D <span class="op">=</span> <span class="dt">void</span><span class="op">&gt;</span></span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">struct</span> custom_hash <span class="op">{};</span></span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true" tabindex="-1"></a>    <span class="co">// https://www.boost.org/doc/libs/1_55_0/doc/html/hash/combine.html</span></span>
<span id="cb5-16"><a href="#cb5-16" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb5-17"><a href="#cb5-17" aria-hidden="true" tabindex="-1"></a>    <span class="kw">inline</span> <span class="dt">void</span> hash_combine<span class="op">(</span>u64<span class="op">&amp;</span> seed<span class="op">,</span> <span class="at">const</span> T<span class="op">&amp;</span> v<span class="op">)</span> <span class="op">{</span></span>
<span id="cb5-18"><a href="#cb5-18" aria-hidden="true" tabindex="-1"></a>        custom_hash<span class="op">&lt;</span>T<span class="op">&gt;</span> hasher<span class="op">;</span></span>
<span id="cb5-19"><a href="#cb5-19" aria-hidden="true" tabindex="-1"></a>        seed <span class="op">^=</span> hasher<span class="op">(</span>v<span class="op">)</span> <span class="op">+</span> <span class="bn">0x9e3779b97f4a7c15</span> <span class="op">+</span> <span class="op">(</span>seed <span class="op">&lt;&lt;</span> <span class="dv">12</span><span class="op">)</span> <span class="op">+</span> <span class="op">(</span>seed <span class="op">&gt;&gt;</span> <span class="dv">4</span><span class="op">);</span></span>
<span id="cb5-20"><a href="#cb5-20" aria-hidden="true" tabindex="-1"></a>    <span class="op">};</span></span>
<span id="cb5-21"><a href="#cb5-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-22"><a href="#cb5-22" aria-hidden="true" tabindex="-1"></a>    <span class="co">// http://xorshift.di.unimi.it/splitmix64.c</span></span>
<span id="cb5-23"><a href="#cb5-23" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb5-24"><a href="#cb5-24" aria-hidden="true" tabindex="-1"></a>    <span class="kw">struct</span> custom_hash<span class="op">&lt;</span>T<span class="op">,</span> <span class="kw">typename</span> <span class="bu">std::</span>enable_if<span class="op">&lt;</span><span class="bu">std::</span>is_integral<span class="op">&lt;</span>T<span class="op">&gt;::</span>value<span class="op">&gt;::</span>type<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb5-25"><a href="#cb5-25" aria-hidden="true" tabindex="-1"></a>        u64 <span class="kw">operator</span><span class="op">()(</span>T _x<span class="op">)</span> <span class="at">const</span> <span class="op">{</span></span>
<span id="cb5-26"><a href="#cb5-26" aria-hidden="true" tabindex="-1"></a>            u64 x <span class="op">=</span> _x<span class="op">;</span></span>
<span id="cb5-27"><a href="#cb5-27" aria-hidden="true" tabindex="-1"></a><span class="pp">#if USE_AES</span></span>
<span id="cb5-28"><a href="#cb5-28" aria-hidden="true" tabindex="-1"></a>            <span class="co">// implementation defined till C++17, defined from C++20</span></span>
<span id="cb5-29"><a href="#cb5-29" aria-hidden="true" tabindex="-1"></a>            __m128i m<span class="op">{</span>i64<span class="op">(</span>u64<span class="op">(</span>x<span class="op">)</span> <span class="op">*</span> <span class="bn">0xbf58476d1ce4e5b9</span><span class="er">u64</span><span class="op">),</span> <span class="op">(</span>i64<span class="op">)</span>FIXED_RANDOM<span class="op">};</span></span>
<span id="cb5-30"><a href="#cb5-30" aria-hidden="true" tabindex="-1"></a>            __m128i y <span class="op">=</span> _mm_aesenc_si128<span class="op">(</span>m<span class="op">,</span> KEY1<span class="op">);</span></span>
<span id="cb5-31"><a href="#cb5-31" aria-hidden="true" tabindex="-1"></a>            __m128i z <span class="op">=</span> _mm_aesenc_si128<span class="op">(</span>y<span class="op">,</span> KEY2<span class="op">);</span></span>
<span id="cb5-32"><a href="#cb5-32" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> z<span class="op">[</span><span class="dv">0</span><span class="op">];</span></span>
<span id="cb5-33"><a href="#cb5-33" aria-hidden="true" tabindex="-1"></a><span class="pp">#else</span></span>
<span id="cb5-34"><a href="#cb5-34" aria-hidden="true" tabindex="-1"></a>            x <span class="op">+=</span> <span class="bn">0x9e3779b97f4a7c15</span> <span class="op">+</span> FIXED_RANDOM<span class="op">;</span></span>
<span id="cb5-35"><a href="#cb5-35" aria-hidden="true" tabindex="-1"></a>            x <span class="op">=</span> <span class="op">(</span>x <span class="op">^</span> <span class="op">(</span>x <span class="op">&gt;&gt;</span> <span class="dv">30</span><span class="op">))</span> <span class="op">*</span> <span class="bn">0xbf58476d1ce4e5b9</span><span class="op">;</span></span>
<span id="cb5-36"><a href="#cb5-36" aria-hidden="true" tabindex="-1"></a>            x <span class="op">=</span> <span class="op">(</span>x <span class="op">^</span> <span class="op">(</span>x <span class="op">&gt;&gt;</span> <span class="dv">27</span><span class="op">))</span> <span class="op">*</span> <span class="bn">0x94d049bb133111eb</span><span class="op">;</span></span>
<span id="cb5-37"><a href="#cb5-37" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> x <span class="op">^</span> <span class="op">(</span>x <span class="op">&gt;&gt;</span> <span class="dv">31</span><span class="op">);</span></span>
<span id="cb5-38"><a href="#cb5-38" aria-hidden="true" tabindex="-1"></a><span class="pp">#endif</span></span>
<span id="cb5-39"><a href="#cb5-39" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb5-40"><a href="#cb5-40" aria-hidden="true" tabindex="-1"></a>    <span class="op">};</span></span>
<span id="cb5-41"><a href="#cb5-41" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-42"><a href="#cb5-42" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb5-43"><a href="#cb5-43" aria-hidden="true" tabindex="-1"></a>    <span class="kw">struct</span> custom_hash<span class="op">&lt;</span>T<span class="op">,</span> <span class="bu">std::</span>void_t<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(</span><span class="bu">std::</span>begin<span class="op">(</span><span class="bu">std::</span>declval<span class="op">&lt;</span>T<span class="op">&gt;()))&gt;&gt;</span> <span class="op">{</span></span>
<span id="cb5-44"><a href="#cb5-44" aria-hidden="true" tabindex="-1"></a>        u64 <span class="kw">operator</span><span class="op">()(</span><span class="at">const</span> T<span class="op">&amp;</span> a<span class="op">)</span> <span class="at">const</span> <span class="op">{</span></span>
<span id="cb5-45"><a href="#cb5-45" aria-hidden="true" tabindex="-1"></a>            u64 value <span class="op">=</span> FIXED_RANDOM<span class="op">;</span></span>
<span id="cb5-46"><a href="#cb5-46" aria-hidden="true" tabindex="-1"></a>            <span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span><span class="op">&amp;</span> x <span class="op">:</span> a<span class="op">)</span> hash_combine<span class="op">(</span>value<span class="op">,</span> x<span class="op">);</span></span>
<span id="cb5-47"><a href="#cb5-47" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> value<span class="op">;</span></span>
<span id="cb5-48"><a href="#cb5-48" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb5-49"><a href="#cb5-49" aria-hidden="true" tabindex="-1"></a>    <span class="op">};</span></span>
<span id="cb5-50"><a href="#cb5-50" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-51"><a href="#cb5-51" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span><span class="op">...</span> T<span class="op">&gt;</span></span>
<span id="cb5-52"><a href="#cb5-52" aria-hidden="true" tabindex="-1"></a>    <span class="kw">struct</span> custom_hash<span class="op">&lt;</span><span class="bu">std::</span>tuple<span class="op">&lt;</span>T<span class="op">...&gt;&gt;</span> <span class="op">{</span></span>
<span id="cb5-53"><a href="#cb5-53" aria-hidden="true" tabindex="-1"></a>        u64 <span class="kw">operator</span><span class="op">()(</span><span class="at">const</span> <span class="bu">std::</span>tuple<span class="op">&lt;</span>T<span class="op">...&gt;&amp;</span> a<span class="op">)</span> <span class="at">const</span> <span class="op">{</span></span>
<span id="cb5-54"><a href="#cb5-54" aria-hidden="true" tabindex="-1"></a>            u64 value <span class="op">=</span> FIXED_RANDOM<span class="op">;</span></span>
<span id="cb5-55"><a href="#cb5-55" aria-hidden="true" tabindex="-1"></a>            <span class="bu">std::</span>apply<span class="op">([&amp;</span>value<span class="op">](</span>T <span class="at">const</span><span class="op">&amp;...</span> args<span class="op">)</span> <span class="op">{</span> <span class="op">(</span>hash_combine<span class="op">(</span>value<span class="op">,</span> args<span class="op">),</span> <span class="op">...);</span> <span class="op">},</span> a<span class="op">);</span></span>
<span id="cb5-56"><a href="#cb5-56" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> value<span class="op">;</span></span>
<span id="cb5-57"><a href="#cb5-57" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb5-58"><a href="#cb5-58" aria-hidden="true" tabindex="-1"></a>    <span class="op">};</span></span>
<span id="cb5-59"><a href="#cb5-59" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-60"><a href="#cb5-60" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> T<span class="op">,</span> <span class="kw">class</span> U<span class="op">&gt;</span></span>
<span id="cb5-61"><a href="#cb5-61" aria-hidden="true" tabindex="-1"></a>    <span class="kw">struct</span> custom_hash<span class="op">&lt;</span><span class="bu">std::</span>pair<span class="op">&lt;</span>T<span class="op">,</span> U<span class="op">&gt;&gt;</span> <span class="op">{</span></span>
<span id="cb5-62"><a href="#cb5-62" aria-hidden="true" tabindex="-1"></a>        u64 <span class="kw">operator</span><span class="op">()(</span><span class="at">const</span> <span class="bu">std::</span>pair<span class="op">&lt;</span>T<span class="op">,</span> U<span class="op">&gt;&amp;</span> a<span class="op">)</span> <span class="at">const</span> <span class="op">{</span></span>
<span id="cb5-63"><a href="#cb5-63" aria-hidden="true" tabindex="-1"></a>            u64 value <span class="op">=</span> FIXED_RANDOM<span class="op">;</span></span>
<span id="cb5-64"><a href="#cb5-64" aria-hidden="true" tabindex="-1"></a>            hash_combine<span class="op">(</span>value<span class="op">,</span> a<span class="op">.</span>first<span class="op">);</span></span>
<span id="cb5-65"><a href="#cb5-65" aria-hidden="true" tabindex="-1"></a>            hash_combine<span class="op">(</span>value<span class="op">,</span> a<span class="op">.</span>second<span class="op">);</span></span>
<span id="cb5-66"><a href="#cb5-66" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> value<span class="op">;</span></span>
<span id="cb5-67"><a href="#cb5-67" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb5-68"><a href="#cb5-68" aria-hidden="true" tabindex="-1"></a>    <span class="op">};</span></span>
<span id="cb5-69"><a href="#cb5-69" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-70"><a href="#cb5-70" aria-hidden="true" tabindex="-1"></a><span class="op">};</span>  <span class="co">// namespace hashing</span></span>
<span id="cb5-71"><a href="#cb5-71" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-72"><a href="#cb5-72" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&quot;ext/pb_ds/assoc_container.hpp&quot;</span></span>
<span id="cb5-73"><a href="#cb5-73" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&quot;ext/pb_ds/tree_policy.hpp&quot;</span></span>
<span id="cb5-74"><a href="#cb5-74" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-75"><a href="#cb5-75" aria-hidden="true" tabindex="-1"></a><span class="kw">namespace</span> pbds <span class="op">{</span></span>
<span id="cb5-76"><a href="#cb5-76" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> <span class="kw">namespace</span> __gnu_pbds<span class="op">;</span></span>
<span id="cb5-77"><a href="#cb5-77" aria-hidden="true" tabindex="-1"></a><span class="pp">#ifdef PB_DS_ASSOC_CNTNR_HPP</span></span>
<span id="cb5-78"><a href="#cb5-78" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> Key<span class="op">,</span> <span class="kw">class</span> Value<span class="op">,</span> <span class="kw">class</span> Hash<span class="op">&gt;</span></span>
<span id="cb5-79"><a href="#cb5-79" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> unordered_map <span class="op">=</span> gp_hash_table<span class="op">&lt;</span>Key<span class="op">,</span> Value<span class="op">,</span> Hash<span class="op">,</span> <span class="bu">std::</span>equal_to<span class="op">&lt;</span>Key<span class="op">&gt;,</span> direct_mask_range_hashing<span class="op">&lt;&gt;,</span> linear_probe_fn<span class="op">&lt;&gt;,</span></span>
<span id="cb5-80"><a href="#cb5-80" aria-hidden="true" tabindex="-1"></a>                                        hash_standard_resize_policy<span class="op">&lt;</span>hash_exponential_size_policy<span class="op">&lt;&gt;,</span> hash_load_check_resize_trigger<span class="op">&lt;&gt;,</span> <span class="kw">true</span><span class="op">&gt;&gt;;</span></span>
<span id="cb5-81"><a href="#cb5-81" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> Key<span class="op">,</span> <span class="kw">class</span> Hash<span class="op">&gt;</span></span>
<span id="cb5-82"><a href="#cb5-82" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> unordered_set <span class="op">=</span> pbds<span class="op">::</span>unordered_map<span class="op">&lt;</span>Key<span class="op">,</span> <span class="dt">null_type</span><span class="op">,</span> Hash<span class="op">&gt;;</span></span>
<span id="cb5-83"><a href="#cb5-83" aria-hidden="true" tabindex="-1"></a><span class="pp">#endif</span></span>
<span id="cb5-84"><a href="#cb5-84" aria-hidden="true" tabindex="-1"></a><span class="pp">#ifdef PB_DS_TREE_POLICY_HPP</span></span>
<span id="cb5-85"><a href="#cb5-85" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb5-86"><a href="#cb5-86" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> ordered_set <span class="op">=</span> tree<span class="op">&lt;</span>T<span class="op">,</span> <span class="dt">null_type</span><span class="op">,</span> <span class="bu">std::</span>less<span class="op">&lt;</span>T<span class="op">&gt;,</span> rb_tree_tag<span class="op">,</span> tree_order_statistics_node_update<span class="op">&gt;;</span></span>
<span id="cb5-87"><a href="#cb5-87" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb5-88"><a href="#cb5-88" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> ordered_multiset <span class="op">=</span> tree<span class="op">&lt;</span>T<span class="op">,</span> <span class="dt">null_type</span><span class="op">,</span> <span class="bu">std::</span>less_equal<span class="op">&lt;</span>T<span class="op">&gt;,</span> rb_tree_tag<span class="op">,</span> tree_order_statistics_node_update<span class="op">&gt;;</span></span>
<span id="cb5-89"><a href="#cb5-89" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> Key<span class="op">,</span> <span class="kw">class</span> Value<span class="op">,</span> <span class="kw">class</span> Compare <span class="op">=</span> <span class="bu">std::</span>less<span class="op">&lt;</span>Key<span class="op">&gt;&gt;</span></span>
<span id="cb5-90"><a href="#cb5-90" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> ordered_map <span class="op">=</span> tree<span class="op">&lt;</span>Key<span class="op">,</span> Value<span class="op">,</span> Compare<span class="op">,</span> rb_tree_tag<span class="op">,</span> tree_order_statistics_node_update<span class="op">&gt;;</span></span>
<span id="cb5-91"><a href="#cb5-91" aria-hidden="true" tabindex="-1"></a><span class="pp">#endif</span></span>
<span id="cb5-92"><a href="#cb5-92" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>  <span class="co">// namespace pbds</span></span>
<span id="cb5-93"><a href="#cb5-93" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-94"><a href="#cb5-94" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Signature<span class="op">,</span> <span class="kw">typename</span> Lambda<span class="op">&gt;</span></span>
<span id="cb5-95"><a href="#cb5-95" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Cache<span class="op">;</span></span>
<span id="cb5-96"><a href="#cb5-96" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-97"><a href="#cb5-97" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> ReturnType<span class="op">,</span> <span class="kw">typename</span><span class="op">...</span> Args<span class="op">,</span> <span class="kw">typename</span> Lambda<span class="op">&gt;</span></span>
<span id="cb5-98"><a href="#cb5-98" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Cache<span class="op">&lt;</span>ReturnType<span class="op">(</span>Args<span class="op">...),</span> Lambda<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb5-99"><a href="#cb5-99" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span><span class="op">...</span> DummyArgs<span class="op">&gt;</span></span>
<span id="cb5-100"><a href="#cb5-100" aria-hidden="true" tabindex="-1"></a>    ReturnType <span class="kw">operator</span><span class="op">()(</span>DummyArgs<span class="op">&amp;&amp;...</span> args<span class="op">)</span> <span class="op">{</span></span>
<span id="cb5-101"><a href="#cb5-101" aria-hidden="true" tabindex="-1"></a>        <span class="kw">auto</span> tied_args <span class="op">=</span> <span class="bu">std::</span>tie<span class="op">(</span>args<span class="op">...);</span></span>
<span id="cb5-102"><a href="#cb5-102" aria-hidden="true" tabindex="-1"></a>        <span class="kw">auto</span> it <span class="op">=</span> memo<span class="op">.</span>find<span class="op">(</span>tied_args<span class="op">);</span></span>
<span id="cb5-103"><a href="#cb5-103" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(</span>it <span class="op">==</span> memo<span class="op">.</span>end<span class="op">())</span> <span class="op">{</span></span>
<span id="cb5-104"><a href="#cb5-104" aria-hidden="true" tabindex="-1"></a>            <span class="kw">auto</span><span class="op">&amp;&amp;</span> ans <span class="op">=</span> f<span class="op">(*</span><span class="kw">this</span><span class="op">,</span> <span class="bu">std::</span>forward<span class="op">&lt;</span>DummyArgs<span class="op">&gt;(</span>args<span class="op">)...);</span></span>
<span id="cb5-105"><a href="#cb5-105" aria-hidden="true" tabindex="-1"></a>            memo<span class="op">[</span>tied_args<span class="op">]</span> <span class="op">=</span> ans<span class="op">;</span></span>
<span id="cb5-106"><a href="#cb5-106" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> ans<span class="op">;</span></span>
<span id="cb5-107"><a href="#cb5-107" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb5-108"><a href="#cb5-108" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> it<span class="op">-&gt;</span>second<span class="op">;</span></span>
<span id="cb5-109"><a href="#cb5-109" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb5-110"><a href="#cb5-110" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb5-111"><a href="#cb5-111" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-112"><a href="#cb5-112" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> _Lambda<span class="op">&gt;</span></span>
<span id="cb5-113"><a href="#cb5-113" aria-hidden="true" tabindex="-1"></a>    Cache<span class="op">(</span><span class="bu">std::</span>tuple<span class="op">&lt;&gt;,</span> _Lambda<span class="op">&amp;&amp;</span> _f<span class="op">)</span> <span class="op">:</span> f<span class="op">(</span><span class="bu">std::</span>forward<span class="op">&lt;</span>_Lambda<span class="op">&gt;(</span>_f<span class="op">))</span> <span class="op">{}</span></span>
<span id="cb5-114"><a href="#cb5-114" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-115"><a href="#cb5-115" aria-hidden="true" tabindex="-1"></a>    Lambda f<span class="op">;</span></span>
<span id="cb5-116"><a href="#cb5-116" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> TiedArgs <span class="op">=</span> <span class="bu">std::</span>tuple<span class="op">&lt;</span><span class="bu">std::</span>decay_t<span class="op">&lt;</span>Args<span class="op">&gt;...&gt;;</span></span>
<span id="cb5-117"><a href="#cb5-117" aria-hidden="true" tabindex="-1"></a>    pbds<span class="op">::</span>unordered_map<span class="op">&lt;</span>TiedArgs<span class="op">,</span> ReturnType<span class="op">,</span> hashing<span class="op">::</span>custom_hash<span class="op">&lt;</span>TiedArgs<span class="op">&gt;&gt;</span> memo<span class="op">;</span></span>
<span id="cb5-118"><a href="#cb5-118" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb5-119"><a href="#cb5-119" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-120"><a href="#cb5-120" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> Signature<span class="op">,</span> <span class="kw">class</span> Lambda<span class="op">&gt;</span></span>
<span id="cb5-121"><a href="#cb5-121" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> use_cache<span class="op">(</span>Lambda<span class="op">&amp;&amp;</span> f<span class="op">)</span> <span class="op">{</span></span>
<span id="cb5-122"><a href="#cb5-122" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> Cache<span class="op">&lt;</span>Signature<span class="op">,</span> Lambda<span class="op">&gt;(</span><span class="bu">std::</span>tuple<span class="op">{},</span> <span class="bu">std::</span>forward<span class="op">&lt;</span>Lambda<span class="op">&gt;(</span>f<span class="op">));</span></span>
<span id="cb5-123"><a href="#cb5-123" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
</details>
<p>Let's first try to replicate the python example from above:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> factorial <span class="op">=</span> use_cache<span class="op">&lt;</span><span class="dt">int</span><span class="op">(</span><span class="dt">int</span><span class="op">)&gt;([](</span><span class="kw">auto</span><span class="op">&amp;&amp;</span> self<span class="op">,</span> <span class="dt">int</span> n<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">int</span> <span class="op">{</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="op">(</span>n<span class="op">)</span> <span class="cf">return</span> n <span class="op">*</span> self<span class="op">(</span>n <span class="op">-</span> <span class="dv">1</span><span class="op">);</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">else</span> <span class="cf">return</span> <span class="dv">1</span><span class="op">;</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a><span class="op">});</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a><span class="bu">std::</span>cout <span class="op">&lt;&lt;</span> factorial<span class="op">(</span><span class="dv">10</span><span class="op">)</span> <span class="op">&lt;&lt;</span> <span class="ch">&#39;</span><span class="sc">\n</span><span class="ch">&#39;</span><span class="op">;</span></span></code></pre></div>
<p>You can do more complicated things with this template too. Let's say you want to have a recursive function that takes a <code>char</code> and <code>pair&lt;int, string&gt;</code> as a DP state, and stores a bool. It also requires values of some array you have taken as input, so you need to capture it as well.</p>
<p>You write it like this:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>vector<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> v<span class="op">;</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="co">// read v</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> solve <span class="op">=</span> use_cache<span class="op">&lt;</span><span class="dt">bool</span><span class="op">(</span><span class="dt">char</span><span class="op">,</span> pair<span class="op">&lt;</span><span class="dt">int</span><span class="op">,</span> string<span class="op">&gt;)&gt;([&amp;](</span><span class="kw">auto</span><span class="op">&amp;&amp;</span> self<span class="op">,</span> <span class="dt">char</span> c<span class="op">,</span> pair<span class="op">&lt;</span><span class="dt">int</span><span class="op">,</span> string<span class="op">&gt;</span> p<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">bool</span> <span class="op">{</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>    <span class="co">// note that v was captured by &amp;</span></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>    <span class="co">// use c, p, v as needed</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>    <span class="co">// let&#39;s say you have c1 and p1 as arguments for a recursive call</span></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> x <span class="op">=</span> self<span class="op">(</span>c1<span class="op">,</span> p1<span class="op">);</span> <span class="co">// recursive call - do as many of them as needed</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a>    <span class="co">// use c, p, v as needed</span></span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> y<span class="op">;</span> <span class="co">// return something</span></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a><span class="op">});</span></span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a><span class="bu">std::</span>cout <span class="op">&lt;&lt;</span> solve<span class="op">(</span><span class="ch">&#39;a&#39;</span><span class="op">,</span> pair<span class="op">{</span><span class="dv">1</span><span class="op">,</span> <span class="st">&quot;hello&quot;</span><span class="bu">s</span><span class="op">})</span> <span class="op">&lt;&lt;</span> <span class="ch">&#39;</span><span class="sc">\n</span><span class="ch">&#39;</span><span class="op">;</span></span></code></pre></div>
<h2 id="caveats">Caveats</h2>
<p>The most important caveat is that since it uses a hash-table under the hood, you will often miss the performance that you get from just using multidimensional arrays. You can adapt the template to do things like that, but I didn't, for the sake of clarity and ease of implementation.</p>
<p>Since it doesn't make a lot of sense to store function calls with arguments that can change over time, the template doesn't support lambdas that take things by reference either. This is done in order to avoid any possible bugs that might come with references being modified on the fly somewhere in your code.</p>
<p>However, if for some reason (maybe for performance you want const refs of large structs/vectors instead of copies) you really want to use references, you can remedy that by doing the following:</p>
<ul>
<li>Wrap your arguments within <code>std::reference_wrapper_t</code> (for example, rather than <code>int&amp;</code>, use <code>std::reference_wrapper_t&lt;int&gt;</code>) --- this makes a reference behave like a value (and is copyable for example).</li>
<li>Provide a hashing implementation for <code>std::reference_wrapper_t&lt;T&gt;</code>.</li>
<li>Avoid reference invalidation, i.e., the hash table should store values and not references, because references to temporary variables get invalidated during the run of the algorithm.</li>
<li>Handle any other issues that might crop up, on your own.</li>
</ul>
<p>Do let me know if you know of a better way of doing these things, and if there are any errors that might have crept into this post!</p>
<details>
<summary>Cite this post</summary>
<div class="sourceCode" id="cb8"><pre class="sourceCode bibtex"><code class="sourceCode bibtex"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="va">@online</span>{<span class="ot">easy</span>-<span class="ot">recursive</span>-<span class="ot">dp</span>-<span class="ot">template</span>-<span class="ot">2024</span>,</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">author</span>    = {nor},</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">title</span>     = {Write recursive DP without thinking about memoization},</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">year</span>      = {2024},</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>  <span class="dt">month</span>     = {01},</span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">day</span>       = {14},</span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>  <span class="dt">url</span>       = {https://nor-blog.pages.dev/posts/2024-01-14-easy-recursive-dp-template},</span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
</details>]]></content:encoded>
</item><item>
<title>On lambdas, C++ and otherwise: the what, the why, and the how</title>
<link>https://nor-blog.pages.dev/posts/2023-12-02-lambdas-cpp-and-otherwise/</link>
<guid>https://nor-blog.pages.dev/posts/2023-12-02-lambdas-cpp-and-otherwise/</guid>
<pubDate>Sat, 02 Dec 2023 00:00:00 +0000</pubDate>
<description>A tutorial on lambdas, from lambda-calculus context and C++ closure mechanics to recursion, stateful patterns, STL use, and competitive-programming examples.</description>
<content:encoded><![CDATA[<p>The contents are as follows:</p>
<ul>
<li>Introduction</li>
<li>Why you should use lambdas</li>
<li>Some context</li>
<li>Hand-rolling our own lambdas</li>
<li>C++ lambda syntax explained</li>
<li>Using lambdas</li>
<li>Using lambdas with the STL</li>
<li>Some useful non-trivial patterns</li>
<li>Some other interesting patterns</li>
<li>Examples of competitive programming code using C++ lambdas</li>
</ul>
<p><strong>Prerequisites</strong>: knowing a bit about structs/classes in C++, member functions, knowing that the STL exists.</p>
<p>If you feel something is not very clear, I recommend waiting for a bit, because I tried to ensure that all important ideas are explained at some point or another, and if you don't understand and it doesn't pop up later, it is probably not that important (and should not harm the experience of reading this post). Nevertheless, if I missed out on explaining something that looks important, please ask me in the comments --- I'd be happy to answer your questions!</p>
<p>I would like to thank (in alphabetical order) <a href="https://codeforces.com/profile/AlperenT">AlperenT</a>, <a href="https://codeforces.com/profile/bestial-42-centroids">bestial-42-centroids</a> and <a href="https://codeforces.com/profile/kostia244">kostia244</a> for discussions that helped improve the presentation and teachability of this post.</p>
<hr />
<h2 id="introduction">Introduction</h2>
<p>A few years back, I co-authored a <a href="https://codeforces.com/blog/entry/96344">blog</a> on pragmas because there were very few people who understood what pragmas do. I noticed that the same is true, albeit to a lower extent, for lambdas (C++ and otherwise) --- some using them as a minor convenience but nothing more; others having an irrational (and ignorant) disdain for them, mainly arising either out of some experiences that come from not using them properly or a love of all things "minimalistic".</p>
<p>Hence, part of the motivation behind this post is to show and convince people that lambdas can be very useful, both for your code AND your thought process, and that they will make your life easier if you do any amount of programming in a language that has decent support for lambdas (yes, not only C++). Thus, a significant part of the post would also talk about some topics related to models of computation and some history. And, of course, I will make a few philosophical arguments along the way, which you can feel free to skip, but they are helpful as a first step to realizing why such a change in perspective is quite important for any learning.</p>
<p>The other reason I am writing this post is to explain C++ lambdas on a much deeper level than people usually go into, without being as terse and unreadable for a beginner as the <a href="https://en.cppreference.com/w/cpp/language/lambda">cppreference page</a> --- this will involve rolling our own lambdas! This activity will also help us understand why certain behaviors are intuitive for C++ lambdas. And in the end, as everyone expects a tutorial on CF to be, we will also show some tricks that are especially useful in the competitive programming context.</p>
<p>Examples of usage of lambdas in code doesn't come until much later in this post, because we develop an understanding of what role lambdas actually play in a language, instead of just introducing them as nifty tricks that can help you shorten your code. <strong>If you want to only look at applications, please skip to the last few sections.</strong></p>
<p>Hopefully, this post will also get people interested in programming language theory --- especially functional programming and parts that deal with language design.</p>
<p>Finally, no matter how experienced you are with lambdas/C++/programming languages, there is a high chance that you will find some piece of code/idea in this post that will look very new. I recommend checking out the two sections on patterns (in one of them we implement OOP using lambdas, for example), and the discussion on untyped v/s typed lambda calculus and implementing recursion.</p>
<hr />
<h2 id="why-you-should-use-lambdas">Why you should use lambdas</h2>
<p>I recommend reading this section <em>again</em> after reading the rest of the blog since it'll make more sense after you understand what lambdas are. But since the reader is probably growing restless about why they should be investing their time in lambdas, here's a list of reasons why you should learn about lambdas:</p>
<ul>
<li>Philosophical reasons: Imperfect as it may be, the <a href="https://wiki.c2.com/?BlubParadox=">Blub paradox</a> implies that a programmer's way of problem-solving using code is upper-bounded by the language they use itself to the point that they can correctly realize how limited more primitive languages are, but fail to realize why any feature a higher level language gives them should help them as a programmer, and dismiss higher level languages as just their preferred language + some weird feature that they don't care about. Meanwhile, as people who know math, we probably already realize that thinking on a lower level than necessary is harmful to our development because we don't see the bigger picture. Think of it like having induction as a tool in our toolbox versus having to repeat an argument 1000 times to show that <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>P</mi><mo stretchy="false" form="prefix">(</mo><mn>1000</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">P(1000)</annotation></semantics></math> is true for some predicate <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>P</mi><annotation encoding="application/x-tex">P</annotation></semantics></math> --- this is what it feels like to code in a language that does not have for-loops, which a person who exclusively copypastes code to manually implement what a loop could have done would be very proud of. The moral of the story? Think on a higher level, code in whichever language you want to.</li>
<li>More practical reasons --- You can define a lambda anywhere instead of functions that must be defined at namespace (global or otherwise) scope. So lambdas require you to scroll much less, prevent bugs, keep things local, and avoid polluting the namespace --- all of which are supposed to be good practices. They also reduce context switching that makes code bug-prone.</li>
<li>You can store functions in data and pass functions more uniformly. This can be achieved by function pointers, too, but the other features make lambdas much more convenient for this purpose. It bypasses the need to make "tagged" versions of functions and implement your own vtable kind of things.</li>
<li>You can store data inside functions! Instead of passing a value/reference as a parameter each time a function is called (for example, using the same dfs function for a local graph requires you to pass the local graph by reference to the dfs, which is inconvenient), you can just store (in C++ lambda language, "capture") the reference/value of a variable inside the lambda and be done with it.</li>
<li>The standard library has a ton of support for lambdas, such as in sorting, binary searching, filtering, aggregating, etc. The usage is as simple as passing a single line lambda into a function provided by the STL.</li>
</ul>
<hr />
<h2 id="some-context">Some context</h2>
<p>The unusual name lambda comes from <strong>lambda calculus</strong>, which is a mathematical system for expressing computation, much like what a computer program is supposed to be written in. In this computation system, we have only three types of expressions, which are supposed to be the representation of each computation:</p>
<ul>
<li>terms of the form <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>x</mi><annotation encoding="application/x-tex">x</annotation></semantics></math>: these correspond to variables.</li>
<li>terms of the form <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>λ</mi><mi>x</mi><mi>.</mi><mi>E</mi></mrow><annotation encoding="application/x-tex">\lambda x. E</annotation></semantics></math>: this corresponds to a function that takes input <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>x</mi><annotation encoding="application/x-tex">x</annotation></semantics></math> and returns the result of evaluating <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>E</mi><annotation encoding="application/x-tex">E</annotation></semantics></math>, which is an expression that may or may not involve <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>x</mi><annotation encoding="application/x-tex">x</annotation></semantics></math>. In C++, this would roughly correspond to a function with parameter <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>x</mi><annotation encoding="application/x-tex">x</annotation></semantics></math> and function body <code>return</code> <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>E</mi><annotation encoding="application/x-tex">E</annotation></semantics></math>.</li>
<li>terms of the form <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false" form="prefix">(</mo><msub><mi>E</mi><mn>1</mn></msub><mspace width="0.167em"></mspace><msub><mi>E</mi><mn>2</mn></msub><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">(E_1 \, E_2)</annotation></semantics></math> where <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><msub><mi>E</mi><mn>1</mn></msub><annotation encoding="application/x-tex">E_1</annotation></semantics></math> and <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><msub><mi>E</mi><mn>2</mn></msub><annotation encoding="application/x-tex">E_2</annotation></semantics></math> are two expressions: this corresponds to applying the function represented by the expression <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><msub><mi>E</mi><mn>1</mn></msub><annotation encoding="application/x-tex">E_1</annotation></semantics></math> to the argument <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><msub><mi>E</mi><mn>2</mn></msub><annotation encoding="application/x-tex">E_2</annotation></semantics></math>. In C++, this would roughly correspond to a function <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><msub><mi>E</mi><mn>1</mn></msub><annotation encoding="application/x-tex">E_1</annotation></semantics></math> being called with <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><msub><mi>E</mi><mn>2</mn></msub><annotation encoding="application/x-tex">E_2</annotation></semantics></math> as a parameter, i.e., <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>E</mi><mn>1</mn></msub><mo stretchy="false" form="prefix">(</mo><msub><mi>E</mi><mn>2</mn></msub><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">E_1(E_2)</annotation></semantics></math>.</li>
</ul>
<p>And that's it. Note that there are no numbers and no restriction on what <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><msub><mi>E</mi><mn>2</mn></msub><annotation encoding="application/x-tex">E_2</annotation></semantics></math> evaluates to. In particular, <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><msub><mi>E</mi><mn>2</mn></msub><annotation encoding="application/x-tex">E_2</annotation></semantics></math> can be a function too! The same holds for <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>E</mi><annotation encoding="application/x-tex">E</annotation></semantics></math> and <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><msub><mi>E</mi><mn>1</mn></msub><annotation encoding="application/x-tex">E_1</annotation></semantics></math> as well, so there are many kinds of expressions that you can write that will make sense in this "language". Evaluation of these expressions is done using certain rules called reductions (which resemble simplification of mathematical expressions), though at this stage, it is not really necessary to understand what they do (it is sufficient to take some amount of intuition from any language of your choice to develop an intuition for it, though care should be taken to avoid taking the intuition too far, because there are certain core concepts in languages that are simply not present in this lambda calculus --- for instance, types).</p>
<p>It turns out that this system of computation is <a href="https://en.wikipedia.org/wiki/Turing_completeness">Turing complete</a>, i.e., any program that can be run on a Turing machine can be simulated using this method of computation. But why is this relevant to the discussion?</p>
<p>The second type of term here is called a lambda term. This is where the lambda terminology comes from --- because lambdas play the role of functions in this system. Except in lambda calculus, you're allowed to do a large variety of things by virtue of the lack of constraints in the definition. For example, you can pass around functions to other functions (remember that <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><msub><mi>E</mi><mn>2</mn></msub><annotation encoding="application/x-tex">E_2</annotation></semantics></math> is not constrained to be of a particular "type").</p>
<details>
<summary>Nitpick</summary>
<p>There is no concept of a type in this system of computation. Even the reduction mechanism for a standard lambda calculus is something that doesn't care about types. It turns out that if we assign types to any of these terms, then it forces all valid reductions to terminate, and some expressions end up being untypable even though there can be a possibly infinite sequence of reductions that can be applied to them.</p>
</details>
<p>But note that we are not allowed to manipulate functions in C++ as freely as the above definition dictates. For example, we are not allowed to return functions that depend on the input because function pointers in C/C++ are supposed to be pointers to things known at compile time.</p>
<p>To illustrate this, let's temporarily add numbers and the <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>+</mi><annotation encoding="application/x-tex">+</annotation></semantics></math> operator to the lambda calculus (by the way, they can be semantically simulated using just lambda expressions using what are called Church numerals, but that is a completely different story for another day). The following is a valid lambda expression:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>λ</mi><mi>x</mi><mi>.</mi><mi>λ</mi><mi>y</mi><mi>.</mi><mo stretchy="false" form="prefix">(</mo><mi>x</mi><mo>+</mo><mi>y</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex"> \lambda x. \lambda y.(x + y) </annotation></semantics></math></p>
<p>This function takes a value <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>x</mi><annotation encoding="application/x-tex">x</annotation></semantics></math> and returns a lambda that takes an input <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>y</mi><annotation encoding="application/x-tex">y</annotation></semantics></math> and returns <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi><mo>+</mo><mi>y</mi></mrow><annotation encoding="application/x-tex">x + y</annotation></semantics></math>. Note that the output of the inner lambda depends on the value of <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>x</mi><annotation encoding="application/x-tex">x</annotation></semantics></math>. For example, <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false" form="prefix">(</mo><mi>λ</mi><mi>x</mi><mi>.</mi><mi>λ</mi><mi>y</mi><mi>.</mi><mo stretchy="false" form="prefix">(</mo><mi>x</mi><mo>+</mo><mi>y</mi><mo stretchy="false" form="postfix">)</mo><mo stretchy="false" form="postfix">)</mo><mo stretchy="false" form="prefix">(</mo><mn>42</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">(\lambda x. \lambda y.(x + y)) (42)</annotation></semantics></math> is just <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>λ</mi><mi>y</mi><mi>.</mi><mo stretchy="false" form="prefix">(</mo><mn>42</mn><mo>+</mo><mi>y</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\lambda y.(42 + y)</annotation></semantics></math>. So we have something analogous to a function that returns a function, such that the returned function is <em>dependent</em> on the input to the outer function. (By the way, this is what I meant by lambdas reducing the dependence on "tagged" functions, because you have a great tagging mechanism for lambdas --- just store the data inside it).</p>
<p>The corresponding in C++ style syntax should be something like (but this isn't legal C++ code, so I took the liberty of using non-standard syntax here):</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span><span class="op">(</span><span class="dt">int</span><span class="op">)</span> lambda1<span class="op">(</span><span class="dt">int</span> x<span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> lambda2<span class="op">(</span><span class="dt">int</span> y<span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> x <span class="op">+</span> y<span class="op">;</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> lambda2<span class="op">;</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>So, there is a clear difference between C++ functions and lambda terms from the lambda calculus despite all the other semantic similarities. This discussion already hints to us what a lambda function (as we will call it from now on) should look like in C++.</p>
<p>Let's digress for the rest of this section into the discussion of functional programming languages.</p>
<p>Note that the imperative programming model (let's think about C for the sake of concreteness) is largely based on the Turing machine model of computation --- you have tapes (memory), pointers, and states. The main focus is on evolving the state of the program and the memory in order to get to an end goal.</p>
<p>The functional programming model, on the other hand, is largely based on lambda calculus. You rarely have any state in a functional programming language like Haskell or OCaml (especially in a purely functional language like Haskell). Instead, you express your code in the form of function applications and some basic inbuilt types (like integral types) and functions (like numerical operators).</p>
<p>Both of them are equally powerful. However, functional programming languages are often at a much higher level than imperative languages because of the power of abstraction and resemblance to mathematics, which rarely talks about state in any of its fundamental parts.</p>
<p>Also, a fun fact --- the sharp eyed reader would have noticed that the lambda function we wrote is semantically equivalent to a function that takes two numbers <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>x</mi><annotation encoding="application/x-tex">x</annotation></semantics></math> and <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>y</mi><annotation encoding="application/x-tex">y</annotation></semantics></math> and returns their sum, except that we have partial application for free, by "binding" <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>x</mi><annotation encoding="application/x-tex">x</annotation></semantics></math> to the lambda after the first application and returning a function that adds <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>x</mi><annotation encoding="application/x-tex">x</annotation></semantics></math> to anything. This style of writing lambda terms is called <a href="https://en.wikipedia.org/wiki/Currying">currying</a> and can be used to implement multi-argument functions in a language where functions only have one argument.</p>
<p>This is just scraping the surface of what is otherwise a crazy set of things that can be done with lambda calculus. For example, one interesting thing you can do with it is to show how weird computation systems like the <a href="https://en.wikipedia.org/wiki/SKI_combinator_calculus">SKI combinator calculus</a> are in fact Turing complete. Also, since the lambda calculus is Turing complete, there is a way (a quite elegant one at that) to represent recursion called a <a href="https://en.wikipedia.org/wiki/Fixed-point_combinator">fixed point combinator</a>, which can be implemented in multiple ways, one of which is the Y-combinator.</p>
<hr />
<h2 id="hand-rolling-our-own-lambdas">Hand-rolling our own lambdas</h2>
<p>Since C++ is Turing complete, should we expect there to be a way to implement (a typed variant of) lambda calculus in C++? Definitely, though we <em>probably</em> shouldn't expect it to be very elegant. Or can we? Read on to find out.</p>
<p>Let's think about what a lambda function (shortened to lambda for convenience) should behave like in C++.</p>
<p>It should be what is called a <a href="https://en.wikipedia.org/wiki/First-class_citizen">"first-class citizen"</a> of the language in programming language design --- i.e., all operations that are supported for other entities should also be supported for lambdas. In other words, it should have the following properties at the very least:</p>
<ul>
<li>Should be able to be passed as a function argument</li>
<li>Should be able to be returned from a function</li>
<li>Should be able to be assigned to a variable</li>
</ul>
<p>The most general kind of thing that C++ supports that adheres to these rules is an object. Let's try to implement a lambda as an object in that case.</p>
<p>So for now, a lambda looks like this for us:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Lambda <span class="op">{</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ???</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>Lambda lambda<span class="op">{};</span></span></code></pre></div>
<p>Note that since structs can be defined in a local scope, we will be able to do whatever follows inside a local scope as well as a namespace scope.</p>
<p>Now according to its definition, we should be able to call a lambda as well. The most obvious way of associating a function with a struct is to implement a member function, let's say <code>call</code>. However, one cool functionality that C++ provides is the ability to overload <code>operator()</code> for a struct --- this is the function call operator, and it will help us reduce the syntactic boundaries between a function and an object. So rather than using the name <code>call</code>, we will overload <code>operator()</code>, which does the same thing but with a better syntax.</p>
<p>So, something like the following prints <code>2</code> in a new line:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Lambda <span class="op">{</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> <span class="kw">operator</span><span class="op">()(</span><span class="dt">int</span> x<span class="op">)</span> <span class="at">const</span> <span class="op">{</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> x <span class="op">+</span> <span class="dv">1</span><span class="op">;</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>Lambda lambda<span class="op">;</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a><span class="bu">std::</span>cout <span class="op">&lt;&lt;</span> lambda<span class="op">(</span><span class="dv">1</span><span class="op">)</span> <span class="op">&lt;&lt;</span> <span class="ch">&#39;</span><span class="sc">\n</span><span class="ch">&#39;</span><span class="op">;</span></span></code></pre></div>
<p>At this point, we should note that such a struct which overloads <code>operator()</code> is called a function object in the C++ standard (and is frequently informally referred to as the horribly named "functor" which has a very different meaning in category theory, so it will irk a lot of people if you call a function object a functor in front of them).</p>
<p>Now that we can wrap functions into objects, we can do whatever an object can --- for example, we can now return something that behaves like a function, so it might seem that the story ends here. However, note that we didn't implement anything that allows us to "bind" data to functions, as we wanted to do in our addition example. It is necessary to implement this, in order to make <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>E</mi><annotation encoding="application/x-tex">E</annotation></semantics></math> aware of the value of <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>x</mi><annotation encoding="application/x-tex">x</annotation></semantics></math> somehow, when applying <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>λ</mi><mi>x</mi><mi>.</mi><mi>E</mi></mrow><annotation encoding="application/x-tex">\lambda x. E</annotation></semantics></math> to some <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>x</mi><annotation encoding="application/x-tex">x</annotation></semantics></math>.</p>
<p>Since we want to emulate a mathematical language, for now we don't really care about C++ semantics, and we will choose value semantics for <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>x</mi><annotation encoding="application/x-tex">x</annotation></semantics></math> (which will make a lot of copies, but will make reasoning easier). This basically means that whenever we store <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>x</mi><annotation encoding="application/x-tex">x</annotation></semantics></math>, it will be, just like in mathematics, completely independent of wherever its value was taken from.</p>
<p>Let's try our hand again at the <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>λ</mi><mi>x</mi><mi>.</mi><mi>λ</mi><mi>y</mi><mi>.</mi><mo stretchy="false" form="prefix">(</mo><mi>x</mi><mo>+</mo><mi>y</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\lambda x. \lambda y.(x + y)</annotation></semantics></math> example. Let's write it in a more computer-program-style syntax with parentheses at all the right places (which some people might recognize as being one infix-to-prefix transformation away from being Lisp code):</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode lisp"><code class="sourceCode commonlisp"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>(<span class="kw">lambda</span> x.</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>    (<span class="kw">lambda</span> y.</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>        (x <span class="op">+</span> y)))</span></code></pre></div>
<p>Since there are two <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>λ</mi><annotation encoding="application/x-tex">\lambda</annotation></semantics></math>-s, we would need two structs this time --- one for the outer lambda and one for the inner lambda. The inner lambda needs to "capture" <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>x</mi><annotation encoding="application/x-tex">x</annotation></semantics></math>, so we store a copy of <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>x</mi><annotation encoding="application/x-tex">x</annotation></semantics></math> in it whenever it is constructed.</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> LambdaInner <span class="op">{</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> <span class="va">x_</span><span class="op">;</span> <span class="co">// our binding</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>    LambdaInner<span class="op">(</span><span class="dt">int</span> x<span class="op">)</span> <span class="op">:</span> <span class="va">x_</span><span class="op">{</span>x<span class="op">}</span> <span class="op">{}</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> <span class="kw">operator</span><span class="op">()(</span><span class="dt">int</span> y<span class="op">)</span> <span class="at">const</span> <span class="op">{</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="va">x_</span> <span class="op">+</span> y<span class="op">;</span></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> LambdaOuter <span class="op">{</span></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a>    LambdaInner <span class="kw">operator</span><span class="op">()(</span><span class="dt">int</span> x<span class="op">)</span> <span class="at">const</span> <span class="op">{</span></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> LambdaInner<span class="op">(</span>x<span class="op">);</span></span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span> lambda_outer<span class="op">;</span></span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a>LambdaInner lambda_inner <span class="op">=</span> lambda_outer<span class="op">(</span><span class="dv">1</span><span class="op">);</span></span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a><span class="bu">std::</span>cout <span class="op">&lt;&lt;</span> lambda_inner<span class="op">(</span><span class="dv">2</span><span class="op">)</span> <span class="op">&lt;&lt;</span> <span class="ch">&#39;</span><span class="sc">\n</span><span class="ch">&#39;</span><span class="op">;</span> <span class="co">// or lambda_outer(1)(2)</span></span></code></pre></div>
<p>But this starts looking less and less like actual lambda functions now. The trick is to use the fact that we are able to declare structs in local scope.</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> LambdaOuter <span class="op">{</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> <span class="kw">operator</span><span class="op">()(</span><span class="dt">int</span> x<span class="op">)</span> <span class="at">const</span> <span class="op">{</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>        <span class="kw">struct</span> LambdaInner <span class="op">{</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>            <span class="dt">int</span> <span class="va">x_</span><span class="op">;</span> <span class="co">// our binding</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>            LambdaInner<span class="op">(</span><span class="dt">int</span> x<span class="op">)</span> <span class="op">:</span> <span class="va">x_</span><span class="op">{</span>x<span class="op">}</span> <span class="op">{}</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>            <span class="dt">int</span> <span class="kw">operator</span><span class="op">()(</span><span class="dt">int</span> y<span class="op">)</span> <span class="at">const</span> <span class="op">{</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>                <span class="cf">return</span> <span class="va">x_</span> <span class="op">+</span> y<span class="op">;</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>            <span class="op">}</span></span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>        <span class="op">};</span></span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> LambdaInner<span class="op">(</span>x<span class="op">);</span></span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span> lambda_outer<span class="op">;</span></span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true" tabindex="-1"></a><span class="bu">std::</span>cout <span class="op">&lt;&lt;</span> lambda_outer<span class="op">(</span><span class="dv">1</span><span class="op">)(</span><span class="dv">2</span><span class="op">)</span> <span class="op">&lt;&lt;</span> <span class="ch">&#39;</span><span class="sc">\n</span><span class="ch">&#39;</span><span class="op">;</span></span></code></pre></div>
<p>Okay, this now resembles lambda expressions a bit more than before. But there is still a large amount of noise in the code --- for example, having to declare <code>x_</code> and naming the structs for the lambdas. Turns out that we have exactly the tools for the job with C++ lambdas, which provide syntactic sugar for this kind of a thing:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> lambda_outer <span class="op">=</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>    <span class="op">[](</span><span class="dt">int</span> x<span class="op">)</span> <span class="op">{</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="op">[</span>x<span class="op">](</span><span class="dt">int</span> y<span class="op">)</span> <span class="op">{</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> x <span class="op">+</span> y<span class="op">;</span></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>        <span class="op">};</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">};</span></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a><span class="bu">std::</span>cout <span class="op">&lt;&lt;</span> lambda_outer<span class="op">(</span><span class="dv">1</span><span class="op">)(</span><span class="dv">2</span><span class="op">)</span> <span class="op">&lt;&lt;</span> <span class="ch">&#39;</span><span class="sc">\n</span><span class="ch">&#39;</span><span class="op">;</span></span></code></pre></div>
<p>Here, the lambda being returned has "captured" or "bound" the variable <code>x</code> by storing a copy of it inside itself.</p>
<p>Don't worry if you're a bit baffled with the syntax going from that monstrosity of object oriented code to this simple of a code, for now is the time to look at the syntax of a C++ lambda.</p>
<hr />
<h2 id="c-lambda-syntax-explained">C++ lambda syntax explained</h2>
<p>A C++ lambda expression (or lambda function), in its simplest form, has the syntax</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="op">[</span>capture_list<span class="op">](</span>parameter_list<span class="op">)</span> specifiers <span class="op">-&gt;</span> <span class="dt">trailing_return_type</span> <span class="op">{</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>    <span class="co">// function body</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span></code></pre></div>
<p>where the trailing return type and specifiers are both optional (we will get to them in a moment, they're not super critical for now).</p>
<p>Given that lambda functions aim to replicate a lot of C++ function functionality, there is a lot of noise you could introduce here too, with syntax that I have not mentioned in the above --- you can make it something as complex as the following as of C++20 (even ignoring the possible <code>*this</code> and variadic captures):</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> x <span class="op">=</span> <span class="dv">1</span><span class="op">;</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> y <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> lambda <span class="op">=</span> <span class="op">[&amp;,</span> x <span class="op">=</span> <span class="bu">std::</span>move<span class="op">(</span>x<span class="op">)]</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>                <span class="op">&lt;</span><span class="bu">std::</span>integral T<span class="op">&gt;</span></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>                <span class="kw">requires</span><span class="op">(</span><span class="kw">sizeof</span><span class="op">(</span>T<span class="op">)</span> <span class="op">&lt;=</span> <span class="dv">8</span><span class="op">)</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>                <span class="op">(</span>T a<span class="op">,</span> <span class="kw">auto</span> b<span class="op">,</span> <span class="dt">int</span> c<span class="op">)</span></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>                <span class="at">mutable</span> <span class="kw">constexpr</span> <span class="kw">noexcept</span> <span class="op">[[</span><span class="at">deprecated</span><span class="op">]]</span></span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a>                <span class="op">-&gt;</span> <span class="bu">std::</span>uint64_t <span class="op">{</span></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a>    y <span class="op">=</span> x<span class="op">;</span></span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="kw">static_cast</span><span class="op">&lt;</span><span class="bu">std::</span>uint64_t<span class="op">&gt;(</span>c<span class="op">)</span> <span class="op">+</span> a <span class="op">+</span> <span class="kw">sizeof</span><span class="op">(</span>b<span class="op">)</span> <span class="op">+</span> x <span class="op">+</span> y<span class="op">;</span></span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span></code></pre></div>
<p>However, we won't be really concerned with a lot of this, and will only deal with a few special cases (besides, if you understand the rough correspondence between function objects and lambdas, it becomes more intuitive to guess how this syntax works).</p>
<p>In the syntax mentioned earlier, the lambda roughly corresponds to this struct (don't worry if you don't understand this yet, we will explain the terms used here in detail):</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> UnnamedLambda <span class="op">{</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>    <span class="co">// 1. variables corresponding to the capture list go here</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// 2. constructor for storing captured variables</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>    <span class="co">// 3. call operator - with some specifiers if specified:</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> <span class="kw">operator</span><span class="op">()(</span>parameter_list<span class="op">)</span> <span class="op">-&gt;</span> <span class="co">/* trailing_return_type, if any, goes here */</span> <span class="at">const</span> <span class="op">{</span></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a>        <span class="co">// lambda function body</span></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span></code></pre></div>
<p>Note that the member function is marked const regardless of what we specify for the lambda --- this means that it is not allowed to do anything that mutates/is-allowed-to-mutate-but-doesn't the member variables. We can get past this restriction as we will see later.</p>
<p><strong>Warning</strong>: this is only a representative correspondence and works well for almost all purposes (for example, the copy-assignment constructor of lambdas is deleted, but we didn't show it for the sake of simplicity). It is possible for the C++ lambda behaviour to diverge in some edge cases from the behaviour of this struct, but I haven't seen any such divergences.</p>
<p>For example, a lambda like the following:</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> y <span class="op">=</span> <span class="dv">1</span><span class="op">,</span> x <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> lambda <span class="op">=</span> <span class="op">[</span>y<span class="op">,</span> <span class="op">&amp;</span>x<span class="op">](</span><span class="kw">auto</span> a<span class="op">,</span> <span class="dt">int</span> b<span class="op">)</span> <span class="kw">constexpr</span> <span class="at">mutable</span> <span class="op">-&gt;</span> <span class="dt">int</span> <span class="op">{</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="kw">sizeof</span><span class="op">(</span>a<span class="op">)</span> <span class="op">*</span> y <span class="op">+</span> b <span class="op">*</span> x<span class="op">;</span></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span></code></pre></div>
<p>corresponds to</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> UnnamedLambda <span class="op">{</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>    <span class="co">// captured variables</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> <span class="va">y_</span><span class="op">;</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span><span class="op">&amp;</span> <span class="va">x_</span><span class="op">;</span></span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>    <span class="co">// constructor - constexpr by default if possible</span></span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> UnnamedLambda<span class="op">(</span><span class="dt">int</span> y<span class="op">,</span> <span class="dt">int</span><span class="op">&amp;</span> x<span class="op">)</span> <span class="op">:</span> <span class="va">y_</span><span class="op">{</span>y<span class="op">},</span> <span class="va">x_</span><span class="op">{</span>x<span class="op">}</span> <span class="op">{}</span></span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a>    <span class="co">// call operator - the constexpr specifier marks this function as constexpr (a bit useless since it is constexpr whenever possible anyway), and the mutable specifier removes the const</span></span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> <span class="kw">auto</span> <span class="kw">operator</span><span class="op">()(</span><span class="kw">auto</span> a<span class="op">,</span> <span class="dt">int</span> b<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">int</span> <span class="op">{</span></span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="kw">sizeof</span><span class="op">(</span>a<span class="op">)</span> <span class="op">*</span> y <span class="op">+</span> b <span class="op">*</span> x<span class="op">;</span></span>
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb12-11"><a href="#cb12-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>It is possible to template a lambda starting from C++20, but it is not something that is very useful for competitive programming, so I will omit it for the sake of simplicity, since the syntax has quite a lot of parts already.</p>
<p>Now let's look at every part in a bit of detail.</p>
<h4 id="the-capture-list">The capture list</h4>
<p>Firstly, global/static variables and global constants don't need to be captured (and can't be) --- they are accessible without any captures and will always be usable inside a lambda like a normal variable. It is similar to being captured by reference by default for those variables.</p>
<p>Let's say we want to capture a variable <code>y</code> by value and <code>x</code> by reference (so in the struct, we store a copy of <code>y</code> and a reference to <code>x</code>). In that case, the capture list becomes <code>y, &amp;x</code> or <code>&amp;x, y</code>. We can do this for any number of variables in any order --- <code>&amp;x, y, z</code>, <code>x, &amp;y, &amp;z, w</code> etc.</p>
<p>Now let's say you don't want to manually capture all variables that you're going to be using.</p>
<p>Let's say you want to capture all variables by value. The capture list becomes <code>=</code>.</p>
<p>And if you want to capture all variables by reference, the capture list becomes <code>&amp;</code>.</p>
<p>But you'd say, I don't want to be stuck using the same semantics for all my captured variables. C++ has a way of allowing you to specify variables for which the default semantics are not followed.</p>
<p>If you want to capture all variables by value, but <code>g</code> by reference since it is a large graph, your capture list becomes <code>=, &amp;g</code> (the default should be at the beginning of the capture list).</p>
<p>If you want to do the opposite and capture all variables by reference, but capture <code>g</code> by value, your capture list becomes <code>&amp;, g</code>.</p>
<p>Now let's say that rather than capturing a variable directly, you want to store a value computed by a function, and all other variables should be captured by reference. Then your capture list becomes <code>&amp;, var = func_call(/* as usual */)</code>. This can be done for multiple variables. The semantics are the same as if you had done <code>auto var = func_call()</code>.</p>
<p>Similarly, if <code>func_call</code> returns a reference, you can also use <code>&amp;var = func_call()</code>. The semantics are the same as if you had done <code>auto&amp; var = func_call()</code>.</p>
<p><strong>Note</strong>: when capturing a variable by reference and using lambdas after the variable has been destroyed, you will end up with dangling references where accessing that variable in the lambda is undefined behaviour, just like with any other usage of dangling references --- this is one of the reasons why I chose to capture by value instead of by reference when showing the 2 lambda example. Keep this in mind while using lambdas.</p>
<h4 id="the-parameter-list">The parameter list</h4>
<p>This is pretty much what you would use for any other function. In particular, there is also support for default parameters.</p>
<p>Also, it is noteworthy that the support for <code>auto</code> parameters was added to lambdas back in C++14, but was added for usual functions only in C++20. This shows how much simpler lambdas are for the language itself, when compared to functions. In the corresponding struct, this corresponds to a templated <code>operator()</code>, one for each instantiation that is needed.</p>
<p>So your lambdas can look like this (while compiling in C++14 as well):</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a><span class="dt">bool</span> f<span class="op">(</span><span class="dt">int</span> a<span class="op">,</span> <span class="dt">int</span> b<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> a <span class="op">&lt;</span> b<span class="op">;</span> <span class="op">}</span></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> main<span class="op">()</span> <span class="op">{</span></span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> x <span class="op">=</span> <span class="dv">1</span><span class="op">;</span></span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> z <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> lambda <span class="op">=</span> <span class="op">[&amp;</span>x<span class="op">,</span> y <span class="op">=</span> f<span class="op">(</span><span class="dv">1</span><span class="op">,</span> z<span class="op">)](</span><span class="dt">int</span> a<span class="op">,</span> <span class="kw">auto</span> b<span class="op">,</span> <span class="dt">int</span> c <span class="op">=</span> <span class="dv">1</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(</span>y<span class="op">)</span> <span class="op">{</span></span>
<span id="cb13-9"><a href="#cb13-9" aria-hidden="true" tabindex="-1"></a>            x <span class="op">=</span> c<span class="op">;</span></span>
<span id="cb13-10"><a href="#cb13-10" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> a <span class="op">+</span> b<span class="op">;</span></span>
<span id="cb13-11"><a href="#cb13-11" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb13-12"><a href="#cb13-12" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> x <span class="op">-</span> b <span class="op">+</span> c<span class="op">;</span></span>
<span id="cb13-13"><a href="#cb13-13" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb13-14"><a href="#cb13-14" aria-hidden="true" tabindex="-1"></a>    <span class="op">};</span></span>
<span id="cb13-15"><a href="#cb13-15" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h4 id="the-specifiers">The specifiers</h4>
<p>For this section, it would be helpful to keep in mind our model of structs corresponding to lambdas, in order to understand how the specifier <code>mutable</code> helps, which we will explain below.</p>
<p>You might have noticed that we have not changed the captured value of any variable that we captured by value (the ones we capture by reference can mutate the variables they refer to, so <code>a = b</code> is possible for <code>a</code> being a reference captured variable). The reason is that with the correspondence, the call operator is <code>const</code> by default.</p>
<p>So, how would we mutate these variables? The answer is the usage of the <code>mutable</code> specifier --- the same keyword that helps you mutate a variable in a class when you are calling a function that is marked const.</p>
<p>We're now able to do something like this:</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> alternate_even_odd <span class="op">=</span> <span class="op">[</span>i <span class="op">=</span> <span class="dv">0</span><span class="op">]()</span> <span class="at">mutable</span> <span class="op">{</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>    i <span class="op">^=</span> <span class="dv">1</span><span class="op">;</span></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> i<span class="op">;</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span></code></pre></div>
<p>When <code>mutable</code> is specified in a lambda, the const appended to the <code>operator()</code> is removed. This in turn allows us to mutate all captured variables (in this context it means calling functions/operators/member functions on them which require a non-const reference to them).</p>
<p>There are other specifiers --- <code>constexpr</code> (since C++17), <code>consteval</code> (since C++20) and <code>static</code> (since C++23), but they would not be very useful in a competitive programming context, so we omit them.</p>
<h4 id="the-trailing-return-type">The trailing return type</h4>
<p>Notice that the default syntax for a lambda doesn't have a return type, but the syntax for C++ functions has a return type.</p>
<p>In fact, you can have <code>auto</code> return type for C++ functions starting from C++14, and the type is deduced using some type deduction rules. By default, these rules apply for lambdas as well.</p>
<p>However, it is possible to have certain ambiguities/underspecification, like the following:</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> f <span class="op">=</span> <span class="op">[](</span><span class="dt">int64_t</span> x<span class="op">)</span> <span class="op">{</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="op">(</span>x <span class="op">&lt;</span> <span class="dv">0</span><span class="op">)</span> <span class="cf">return</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> x<span class="op">;</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span></code></pre></div>
<p>or</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> f <span class="op">=</span> <span class="op">[](</span><span class="kw">auto</span> g<span class="op">,</span> <span class="dt">int</span> x<span class="op">)</span> <span class="op">{</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> g<span class="op">(</span>g<span class="op">,</span> x<span class="op">);</span></span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span></code></pre></div>
<p>In the first, the compiler is unable to deduce whether the lambda's return type is supposed to be <code>int</code> or <code>int64_t</code>.</p>
<p>In the latter, since the type of <code>g</code> is unknown, it is also unknown what <code>g</code> returns.</p>
<p>In such cases, we must either cast the return values to a certain type, or specify the return type on our own, like the following:</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> f <span class="op">=</span> <span class="op">[](</span><span class="dt">int64_t</span> x<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">int64_t</span> <span class="op">{</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="op">(</span>x <span class="op">&lt;</span> <span class="dv">0</span><span class="op">)</span> <span class="cf">return</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> x<span class="op">;</span></span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span></code></pre></div>
<div class="sourceCode" id="cb18"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> f <span class="op">=</span> <span class="op">[](</span><span class="kw">auto</span> g<span class="op">,</span> <span class="dt">int</span> x<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">int</span> <span class="op">{</span></span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> g<span class="op">(</span>g<span class="op">,</span> x<span class="op">);</span></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span></code></pre></div>
<hr />
<h2 id="using-lambdas">Using lambdas</h2>
<p>Okay, now that we have finally shown what the lambda syntax can do in C++, we are yet to use them in any application.</p>
<p>In order to use them, we need to know how to do the following, since the type of the corresponding structs of two different lambdas can be different (and the types of two separately defined lambdas are indeed different in C++):</p>
<ul>
<li>Defining lambdas</li>
<li>Passing lambdas</li>
<li>Storing lambdas</li>
</ul>
<h4 id="defining-lambdas">Defining lambdas</h4>
<p>This is very easy, as we have already seen before:</p>
<div class="sourceCode" id="cb19"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> f <span class="op">=</span> <span class="op">[](){};</span></span></code></pre></div>
<p>And a cool trick that I didn't mention earlier is that if your parameter list is empty, you can simply drop the <code>()</code>.</p>
<p>So the shortest lambda definition looks like this:</p>
<div class="sourceCode" id="cb20"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> f <span class="op">=</span> <span class="op">[]{};</span></span></code></pre></div>
<h4 id="passing-lambdas">Passing lambdas</h4>
<p>In C++20, you can do this:</p>
<div class="sourceCode" id="cb21"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> print_result<span class="op">(</span><span class="dt">int</span> x<span class="op">,</span> <span class="kw">auto</span> f<span class="op">)</span> <span class="op">{</span></span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>    <span class="bu">std::</span>cout <span class="op">&lt;&lt;</span> f<span class="op">(</span>x<span class="op">)</span> <span class="op">&lt;&lt;</span> <span class="ch">&#39;</span><span class="sc">\n</span><span class="ch">&#39;</span><span class="op">;</span></span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> print_result_1<span class="op">(</span><span class="dt">int</span> x<span class="op">,</span> <span class="kw">auto</span><span class="op">&amp;</span> f<span class="op">)</span> <span class="op">{</span></span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a>    <span class="bu">std::</span>cout <span class="op">&lt;&lt;</span> f<span class="op">(</span>x<span class="op">)</span> <span class="op">&lt;&lt;</span> <span class="ch">&#39;</span><span class="sc">\n</span><span class="ch">&#39;</span><span class="op">;</span></span>
<span id="cb21-6"><a href="#cb21-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb21-7"><a href="#cb21-7" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> print_result_2<span class="op">(</span><span class="dt">int</span> x<span class="op">,</span> <span class="kw">auto</span><span class="op">&amp;&amp;</span> f<span class="op">)</span> <span class="op">{</span></span>
<span id="cb21-8"><a href="#cb21-8" aria-hidden="true" tabindex="-1"></a>    <span class="bu">std::</span>cout <span class="op">&lt;&lt;</span> f<span class="op">(</span>x<span class="op">)</span> <span class="op">&lt;&lt;</span> <span class="ch">&#39;</span><span class="sc">\n</span><span class="ch">&#39;</span><span class="op">;</span></span>
<span id="cb21-9"><a href="#cb21-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>A small nitpick: the last one is better if you want to pass a lambda by reference if it is an lvalue (informally, something that has an address), but by value if it is not. For example <code>print_result_2(2, [](int x) { return 2 * x; });</code> and <code>print_result_2(2, some_lambda);</code> both work, but the first of these doesn't work with the <code>print_result_1</code>.</p>
<p>When passing a lambda to a lambda, the above syntax works even for something as old as C++14.</p>
<p>In older standards of C++, like C++11/14/17, you can do this (the <code>&amp;</code> and <code>&amp;&amp;</code> variants still work, but I omitted them for the sake of not having too much code):</p>
<div class="sourceCode" id="cb22"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Func<span class="op">&gt;</span></span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> print_result<span class="op">(</span><span class="dt">int</span> x<span class="op">,</span> Func f<span class="op">)</span> <span class="op">{</span></span>
<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a>    <span class="bu">std::</span>cout <span class="op">&lt;&lt;</span> f<span class="op">(</span>x<span class="op">)</span> <span class="op">&lt;&lt;</span> <span class="ch">&#39;</span><span class="sc">\n</span><span class="ch">&#39;</span><span class="op">;</span></span>
<span id="cb22-4"><a href="#cb22-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h4 id="storing-lambdas">Storing lambdas</h4>
<p>This is something that competitive programmers rarely do, but when they do, a lot of them add unnecessary overheads mostly due to lack of understanding of lambdas/templates.</p>
<p>Firstly I will show how people end up storing lambdas:</p>
<div class="sourceCode" id="cb23"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Storage <span class="op">{</span></span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> Func<span class="op">&gt;</span></span>
<span id="cb23-3"><a href="#cb23-3" aria-hidden="true" tabindex="-1"></a>    Storage<span class="op">(</span>Func <span class="va">f_</span><span class="op">)</span> <span class="op">:</span> f<span class="op">{</span><span class="va">f_</span><span class="op">}</span> <span class="op">{}</span></span>
<span id="cb23-4"><a href="#cb23-4" aria-hidden="true" tabindex="-1"></a>    <span class="co">// or Storage(auto f_) : f{f_} {}</span></span>
<span id="cb23-5"><a href="#cb23-5" aria-hidden="true" tabindex="-1"></a>    <span class="co">// or Storage(std::function&lt;int(int)&gt; f_) : f{f_} {}</span></span>
<span id="cb23-6"><a href="#cb23-6" aria-hidden="true" tabindex="-1"></a>    <span class="bu">std::</span>function<span class="op">&lt;</span><span class="dt">int</span><span class="op">(</span><span class="dt">int</span><span class="op">)&gt;</span> f<span class="op">;</span></span>
<span id="cb23-7"><a href="#cb23-7" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb23-8"><a href="#cb23-8" aria-hidden="true" tabindex="-1"></a>Storage storage<span class="op">([](</span><span class="dt">int</span> x<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> x <span class="op">*</span> <span class="dv">2</span><span class="op">;</span> <span class="op">});</span></span></code></pre></div>
<p>Other people use this very limited version (we'll get to why it is limited):</p>
<div class="sourceCode" id="cb24"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Storage <span class="op">{</span></span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> F <span class="op">=</span> <span class="dt">int</span><span class="op">(*)(</span><span class="dt">int</span><span class="op">);</span></span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a>    Storage<span class="op">(</span>F <span class="va">f_</span><span class="op">)</span> <span class="op">:</span> f<span class="op">{</span><span class="va">f_</span><span class="op">}</span> <span class="op">{}</span></span>
<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a>    F f<span class="op">;</span></span>
<span id="cb24-5"><a href="#cb24-5" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb24-6"><a href="#cb24-6" aria-hidden="true" tabindex="-1"></a>Storage storage<span class="op">([](</span><span class="dt">int</span> x<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> <span class="dv">2</span> <span class="op">*</span> x<span class="op">;</span> <span class="op">});</span></span>
<span id="cb24-7"><a href="#cb24-7" aria-hidden="true" tabindex="-1"></a><span class="co">// Storage storage(+[](int x) { return 2 * x; }); also works, relies on decaying from a lambda to function pointer</span></span></code></pre></div>
<p>The most natural way, however, is to do either this:</p>
<div class="sourceCode" id="cb25"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> F<span class="op">&gt;</span></span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Storage <span class="op">{</span></span>
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a>    Storage<span class="op">(</span>F <span class="va">f_</span><span class="op">)</span> <span class="op">:</span> f<span class="op">{</span><span class="va">f_</span><span class="op">}</span> <span class="op">{}</span></span>
<span id="cb25-4"><a href="#cb25-4" aria-hidden="true" tabindex="-1"></a>    F f<span class="op">;</span></span>
<span id="cb25-5"><a href="#cb25-5" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb25-6"><a href="#cb25-6" aria-hidden="true" tabindex="-1"></a>Storage f<span class="op">([](</span><span class="dt">int</span> x<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> <span class="dv">2</span> <span class="op">*</span> x<span class="op">;</span> <span class="op">})</span></span></code></pre></div>
<p>or</p>
<div class="sourceCode" id="cb26"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> make_struct <span class="op">=</span> <span class="op">[](</span><span class="kw">auto</span> <span class="va">f_</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">struct</span> Storage <span class="op">{</span></span>
<span id="cb26-3"><a href="#cb26-3" aria-hidden="true" tabindex="-1"></a>        <span class="bu">std::</span>remove_reference_t<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(</span><span class="va">f_</span><span class="op">)&gt;</span> f<span class="op">;</span></span>
<span id="cb26-4"><a href="#cb26-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">};</span></span>
<span id="cb26-5"><a href="#cb26-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> Storage<span class="op">{</span><span class="va">f_</span><span class="op">};</span></span>
<span id="cb26-6"><a href="#cb26-6" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb26-7"><a href="#cb26-7" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> s <span class="op">=</span> make_struct<span class="op">([](</span><span class="dt">int</span> x<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> <span class="dv">2</span> <span class="op">*</span> x<span class="op">;</span> <span class="op">});</span></span></code></pre></div>
<p>For the sake of convenience, let's name these v1, v2, v3 and v4.</p>
<p>v1 seems to be the most generic way, but has unnecessary overhead if you don't need to do something like making a vector of lambdas. The reason it works is that <code>std::function</code> "erases" the type of the lambda (with a technique called type erasure), but to do that it needs heap allocation and other overheads, and often is unable to optimize the code in the lambda that interacts with the outside (for instance, recursion). Meanwhile, lambdas are able to be optimized as much as, if not faster than, usual functions, since structs are zero-cost abstractions. I have seen spectacular slowdowns with v1 (50x sometimes) due to lack of optimizations, and I'm of the opinion that unless necessary, type erasure should never be used in a context where performance matters. Of course, no kidding, type erasure is an engineering marvel that deserves its own post, and <code>std::function</code>, as an extension does so too.</p>
<p>v2 falls back to the concept of a function pointer, which exists since the old days when C was all the rage. It works decently fine in practice, but has a couple of issues:</p>
<ul>
<li>It is impossible to cast a lambda that has a capture to a usual function. This should be clear when we think about how a lambda can be represented as a struct. The very fact that a lambda can be converted to a function pointer is a surprise if you know how lambdas are implemented.</li>
<li>Function pointers suffer from having to use one more indirection than necessary, due to the function call not being known "by the struct". Still better than <code>std::function</code> in terms of speed, though.</li>
</ul>
<p>v3 solves all the above problems, in the case you don't need to be able to store the container in a vector. The only drawback is that since it is a templated struct, it can not be defined in local scope, as much as we want to. The reason is that in many implementations, symbols in a template must have external linkage, and this is simply impossible for something in a local scope. There is another minor drawback, which is an inconvenience at best --- since partial template specialization is not allowed in C++, you must rely on CTAD (class template argument deduction) to make your code shorter. Otherwise you would have to do something like</p>
<div class="sourceCode" id="cb27"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> f <span class="op">=</span> <span class="op">[](</span><span class="dt">int</span> x<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> <span class="dv">2</span> <span class="op">*</span> x<span class="op">;</span> <span class="op">};</span></span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a>Storage<span class="op">&lt;</span><span class="kw">decltype</span><span class="op">(</span>f<span class="op">)&gt;</span> s<span class="op">(</span>f<span class="op">);</span> <span class="co">// or std::remove_reference_t&lt;decltype(f)&gt; to remove the reference that comes attached with decltype on an lvalue</span></span></code></pre></div>
<p>Coming to v4 --- it does all the things that the other solutions do, and since it is a lambda, it doesn't suffer from the issues that templates do.</p>
<p>As it turns out, v4 is also the most "functional" implementation out of all of them, because you are literally just using functions and nothing object oriented is required.</p>
<p>Is the fact that v4 is the most convenient out of the above 4 just coincidental? I think not.</p>
<p>Anyway, partly since all my library code had been written many years ago, I use v3 for my competitive programming library code --- for instance, my implementation that modifies and generalizes the AtCoder library code for lazy segment tree can be found <a href="https://judge.yosupo.jp/submission/71256">here</a>, starting at line 393. As an aside, it is one of the fastest implementations for that problem, and it used to be the fastest for a very long time until a couple of months ago, and is off from the fastest solution by a few ms. The current fastest solution also uses the v3 pattern for making things generic.</p>
<p>But for anything new, I like using v4 --- it is functional and flexible.</p>
<p>The verdict:</p>
<ul>
<li>Use v1 whenever you need type erasure but can't do without captures</li>
<li>Use v2 whenever you need type erasure but can do without captures</li>
<li>Use v3 whenever you don't need type erasure, but want a classical struct definition somewhere, and want all the performance</li>
<li>Use v4 whenever you don't want type erasure and want your code to be flexible and not depend on CTAD.</li>
</ul>
<hr />
<h2 id="using-lambdas-with-the-stl">Using lambdas with the STL</h2>
<p>As promised, here are some applications of lambdas with some of the STL algorithms/data structures.</p>
<p>Since STL algorithms are implemented mainly as functions or function-like objects, the main use of lambdas is as callbacks to the functions. We are able to pass lambdas as one of the parameters of the STL functions in question, and the lambda is called inside the body, which is why it is a callback.</p>
<p>It is also possible to use them in STL containers during construction.</p>
<p>For the precise functionality of the functions I mention below, I would recommend reading about them on <a href="https://en.cppreference.com">cppreference</a>.</p>
<p>Lambdas are used in multiple forms:</p>
<h4 id="comparators">Comparators</h4>
<p>A comparator is something that returns the result of comparison of its inputs. It is used in the following:</p>
<ul>
<li>sorting: <code>std::sort(l, r, comparator);</code> where the comparator tells whether <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mo>&lt;</mo><mi>b</mi></mrow><annotation encoding="application/x-tex">a &lt; b</annotation></semantics></math> or not for inputs <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>a</mi><annotation encoding="application/x-tex">a</annotation></semantics></math> and <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>b</mi><annotation encoding="application/x-tex">b</annotation></semantics></math>.</li>
<li>binary_search/lower_bound/upper_bound/heap operations/set intersection etc.: similar to sorting.</li>
<li>next_permutation: finds the next permutation according to an order provided by a predicate.</li>
<li>containers (map/set, unordered_map/unordered_set): for the constructor for ordered versions, we can pass a lambda that tells when <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mo>&lt;</mo><mi>b</mi></mrow><annotation encoding="application/x-tex">a &lt; b</annotation></semantics></math> for inputs <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>a</mi><annotation encoding="application/x-tex">a</annotation></semantics></math> and <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>b</mi><annotation encoding="application/x-tex">b</annotation></semantics></math>, and for the unordered versions, we can pass a lambda that tells when <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mo>=</mo><mi>b</mi></mrow><annotation encoding="application/x-tex">a = b</annotation></semantics></math> for inputs <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>a</mi><annotation encoding="application/x-tex">a</annotation></semantics></math> and <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>b</mi><annotation encoding="application/x-tex">b</annotation></semantics></math>.</li>
</ul>
<h4 id="predicates">Predicates</h4>
<p>A predicate is something that decides whether some condition is true or not, based on its inputs. It is used in the following:</p>
<ul>
<li>partition_point --- returns the point <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>p</mi><annotation encoding="application/x-tex">p</annotation></semantics></math> in a range <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false" form="prefix">[</mo><mi>l</mi><mo>,</mo><mi>r</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">[l, r)</annotation></semantics></math> such that <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>f</mi><annotation encoding="application/x-tex">f</annotation></semantics></math> is true on <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false" form="prefix">[</mo><mi>l</mi><mo>,</mo><mi>p</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">[l, p)</annotation></semantics></math> and false on <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false" form="prefix">[</mo><mi>p</mi><mo>,</mo><mi>r</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">[p, r)</annotation></semantics></math>.</li>
<li>filtering and filtering-based algorithms:
<ul>
<li>find_if/find_if_not --- returns the first position where the predicate is true/false (also see find_last_if/find_last_if_not)</li>
<li>default_searcher, boyer_moore_searcher, boyer_moore_horspool_searcher --- used in std::search to search for a pattern based on the predicate</li>
<li>copy_if/copy_if_not --- copies all things on which the predicate evaluates to true/false</li>
<li>remove_if/remove_if_not --- similar to copy_if/copy_if_not but removes elements instead</li>
<li>and others, which are too numerous to list in a blog post</li>
</ul></li>
</ul>
<h4 id="generatorstransformers">Generators/transformers</h4>
<ul>
<li>std::generate expects a function object --- usually a lambda --- and assigns the result of successive calls to every element in the input range. To implement this, a solution using stateful lambdas is the following:</li>
</ul>
<!--listend-->
<div class="sourceCode" id="cb28"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a><span class="bu">std::</span>generate<span class="op">(</span>l<span class="op">,</span> r<span class="op">,</span> <span class="op">[</span>i <span class="op">=</span> <span class="dv">0</span><span class="op">]()</span> <span class="at">mutable</span> <span class="op">{</span> <span class="cf">return</span> i<span class="op">++;</span> <span class="op">});</span></span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a><span class="co">// the same as std::iota(l, r, 0);</span></span></code></pre></div>
<p>There is a more idiomatic solution using coroutines, but coroutines in C++ allocate on the heap.</p>
<ul>
<li>std::transform expects a function object and for each <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>x</mi><annotation encoding="application/x-tex">x</annotation></semantics></math> in a range, updates the corresponding position in another range with <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false" form="prefix">(</mo><mi>x</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">f(x)</annotation></semantics></math>.</li>
</ul>
<h4 id="hash-functions">Hash functions</h4>
<ul>
<li>unordered maps/sets, boyer_moore_searcher, boyer_moore_horspool_searcher all expect a hashing function to be implemented (if not, they fall back to std::hash), and this should be passed during construction.</li>
</ul>
<h4 id="n-ary-operators">n-ary operators</h4>
<ul>
<li>std::accumulate and std::reduce expect you to have a binary operator (by default, std::plus) to be able to aggregate over a range</li>
<li>std::partial_sum does the same, but stores values for every prefix sum</li>
<li>the multitude of inclusive/exclusive_scans and their transform variants also do something similar.</li>
<li>std::inner_product allows you to pass two different binary operators (one being an analog for +, the other for *).</li>
<li>std::adjacent_difference does the opposite of std::partial_sum, but in a different order, and expects a function object to be called as the difference operator.</li>
</ul>
<hr />
<h2 id="some-useful-non-trivial-patterns">Some useful non-trivial patterns</h2>
<h4 id="immediately-invoked-lambdas">Immediately invoked lambdas</h4>
<p>Consider this situation: you have to initialize some data (let's say some result of precomputation), but you want to</p>
<ul>
<li>keep it local, because global scope usually leads to potentially buggy code</li>
<li>avoid polluting your scope with unnecessary variables, in order to prevent bugs with the same variable</li>
</ul>
<p>The concept of an immediately invoked lambda comes in here.</p>
<p>In a nutshell, the idea is that we would like to make a new nested scope for it, but scopes are not expression while lambdas are.</p>
<p>So your solution would earlier look like this:</p>
<div class="sourceCode" id="cb29"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a><span class="bu">std::</span>vector<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> a<span class="op">;</span></span>
<span id="cb29-2"><a href="#cb29-2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb29-3"><a href="#cb29-3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// process and modify a</span></span>
<span id="cb29-4"><a href="#cb29-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>and it becomes this:</p>
<div class="sourceCode" id="cb30"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> a <span class="op">=</span> <span class="op">[&amp;]</span> <span class="op">{</span></span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a>    <span class="bu">std::</span>vector<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> a<span class="op">;</span></span>
<span id="cb30-3"><a href="#cb30-3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// process and modify a</span></span>
<span id="cb30-4"><a href="#cb30-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> a<span class="op">;</span></span>
<span id="cb30-5"><a href="#cb30-5" aria-hidden="true" tabindex="-1"></a><span class="op">}();</span> <span class="co">// notice these parentheses</span></span></code></pre></div>
<p>There are a couple more benefits to this, arising out of the fact that we have now managed to convert a scope into an expression.</p>
<p>So we can do the following easily:</p>
<ul>
<li>Complicated initialization can easily be done in the constructor like this (more useful for real life code than competitive programming):</li>
</ul>
<!--listend-->
<div class="sourceCode" id="cb31"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb31-1"><a href="#cb31-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> A <span class="op">{</span></span>
<span id="cb31-2"><a href="#cb31-2" aria-hidden="true" tabindex="-1"></a>    A<span class="op">(</span><span class="dt">size_t</span> n<span class="op">,</span> <span class="dt">int</span> val<span class="op">)</span> <span class="op">:</span></span>
<span id="cb31-3"><a href="#cb31-3" aria-hidden="true" tabindex="-1"></a>        a<span class="op">{[&amp;]</span> <span class="op">{</span></span>
<span id="cb31-4"><a href="#cb31-4" aria-hidden="true" tabindex="-1"></a>            <span class="bu">std::</span>vector<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> v<span class="op">(</span>n<span class="op">);</span></span>
<span id="cb31-5"><a href="#cb31-5" aria-hidden="true" tabindex="-1"></a>            <span class="bu">std::</span>fill<span class="op">(</span>v<span class="op">.</span>begin<span class="op">(),</span> v<span class="op">.</span>end<span class="op">(),</span> val<span class="op">);</span></span>
<span id="cb31-6"><a href="#cb31-6" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> v<span class="op">;</span></span>
<span id="cb31-7"><a href="#cb31-7" aria-hidden="true" tabindex="-1"></a>        <span class="op">}()}</span> <span class="op">{}</span></span>
<span id="cb31-8"><a href="#cb31-8" aria-hidden="true" tabindex="-1"></a>    <span class="bu">std::</span>vector<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> a<span class="op">;</span></span>
<span id="cb31-9"><a href="#cb31-9" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span></code></pre></div>
<ul>
<li><p>Make variables with potentially complicated initialization const if mutation is not needed --- this is somewhat of an extension of the previous point, and it often leads to optimized code, even if we ignore the number of errors we would save at compile time.</p></li>
<li><p>Precompute and assign at compile time --- if we have an array to precompute, we can do it at compile time globally like this:</p></li>
</ul>
<!--listend-->
<div class="sourceCode" id="cb32"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> precomputed_array <span class="op">=</span> <span class="op">[]</span> <span class="op">{</span></span>
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true" tabindex="-1"></a>    <span class="bu">std::</span>array<span class="op">&lt;</span><span class="dt">int</span><span class="op">,</span> <span class="dv">10000</span><span class="op">&gt;</span> a<span class="op">{};</span></span>
<span id="cb32-3"><a href="#cb32-3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// preprocess</span></span>
<span id="cb32-4"><a href="#cb32-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> a<span class="op">;</span></span>
<span id="cb32-5"><a href="#cb32-5" aria-hidden="true" tabindex="-1"></a><span class="op">}();</span></span></code></pre></div>
<p>Since lambdas are constexpr by default, if everything inside the lambda is constexpr-friendly, the compiler will try to perform this lambda call at compile time, which will in general be faster than computing stuff at runtime, and the compiler can also reason about the data that it has generated at compile time, so it even makes the rest of the program faster.</p>
<p>One small drawback (for Codeforces) is that if there are too many operations in the lambda, you will risk getting a compile time error (telling you to increase your compiler's constexpr operations limit --- for which I have not yet been able to find a way from within the source code).</p>
<p>The compiler is doing the best it can (and the assembly for constexpr-ed code will be much faster than the assembly for non-constexpr-ed code, simply because what is left to run is the bare minimum possible), and for the compiler, there is no limit on computational resources other than the ones due to the machine. Unfortunately, this doesn't work out for practical purposes like contests, where compile-time and system limitations (which include compiler limits that are built into it, but can be changed).</p>
<p>One hacky workaround is:</p>
<div class="sourceCode" id="cb33"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb33-1"><a href="#cb33-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> something <span class="op">=</span> <span class="op">[]</span> <span class="op">{</span></span>
<span id="cb33-2"><a href="#cb33-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> a<span class="op">;</span> <span class="co">// note that it is not initialized, only declared, so it is not constexpr friendly. so the compiler will not constexpr it. it is definitely a code smell, but what can we do?</span></span>
<span id="cb33-3"><a href="#cb33-3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// rest of the function</span></span>
<span id="cb33-4"><a href="#cb33-4" aria-hidden="true" tabindex="-1"></a><span class="op">}();</span></span></code></pre></div>
<p>This is a workaround that I have been using for a long time now, as a way to prevent things from getting constexpr-ed at compile time. Don't do this in real-life code though.</p>
<h4 id="recursive-lambdas">Recursive lambdas</h4>
<p>We can implement recursion in a Turing machine, but can we do so with lambdas? Recall that we noted that the Y-combinator is a way to do precisely this thing in an untyped lambda calculus.</p>
<p>We can write a somewhat similar analog for it in C++ lambdas too, using the C++14 feature that allows us to have auto arguments.</p>
<div class="sourceCode" id="cb34"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb34-1"><a href="#cb34-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> fib <span class="op">=</span> <span class="op">[](</span><span class="kw">auto</span> self<span class="op">,</span> <span class="dt">int</span> n<span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">int</span> <span class="op">{</span></span>
<span id="cb34-2"><a href="#cb34-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="op">(</span>n <span class="op">&lt;=</span> <span class="dv">1</span><span class="op">)</span> <span class="cf">return</span> n<span class="op">;</span></span>
<span id="cb34-3"><a href="#cb34-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> self<span class="op">(</span>self<span class="op">,</span> n <span class="op">-</span> <span class="dv">1</span><span class="op">)</span> <span class="op">+</span> self<span class="op">(</span>self<span class="op">,</span> n <span class="op">-</span> <span class="dv">2</span><span class="op">);</span></span>
<span id="cb34-4"><a href="#cb34-4" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb34-5"><a href="#cb34-5" aria-hidden="true" tabindex="-1"></a><span class="bu">std::</span>cout <span class="op">&lt;&lt;</span> fib<span class="op">(</span>fib<span class="op">,</span> <span class="dv">10</span><span class="op">)</span> <span class="op">&lt;&lt;</span> <span class="ch">&#39;</span><span class="sc">\n</span><span class="ch">&#39;</span><span class="op">;</span></span></code></pre></div>
<p>(If you want to be more efficient in the general case, consider using auto&amp;&amp; instead of auto).</p>
<p>Let's look at how we came up with this implementation.</p>
<p>We don't have a way to refer to the unnamed lambda inside itself with C++ syntax (and the lambda calculus syntax).</p>
<p>So what is the next best thing we can do? Yes, just make a dummy parameter that will (whenever it should be used) be itself, and remember to call the defined lambda with itself whenever it needs to be used. This is precisely what the above code does.</p>
<p>As a fun exercise, let's try writing a function that takes a lambda, which has 2 arguments --- one referring to itself, and the other being what it should call (and will eventually become itself). Our target would be to do something like the following:</p>
<div class="sourceCode" id="cb35"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb35-1"><a href="#cb35-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> lambda <span class="op">=</span> <span class="op">[](</span><span class="kw">auto</span> self<span class="op">,</span> <span class="dt">int</span> n<span class="op">)</span> <span class="op">{</span></span>
<span id="cb35-2"><a href="#cb35-2" aria-hidden="true" tabindex="-1"></a>    <span class="co">// something</span></span>
<span id="cb35-3"><a href="#cb35-3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// the recursive call is of the form self(n - 1)</span></span>
<span id="cb35-4"><a href="#cb35-4" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb35-5"><a href="#cb35-5" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> rec_lambda <span class="op">=</span> add_recursion<span class="op">(</span>lambda<span class="op">);</span></span>
<span id="cb35-6"><a href="#cb35-6" aria-hidden="true" tabindex="-1"></a><span class="bu">std::</span>cout <span class="op">&lt;&lt;</span> rec_lambda<span class="op">(</span><span class="dv">10</span><span class="op">)</span> <span class="op">&lt;&lt;</span> <span class="ch">&#39;</span><span class="sc">\n</span><span class="ch">&#39;</span><span class="op">;</span></span></code></pre></div>
<p>We will ignore all considerations of performance for now, and make copies of everything, for ease of presentation.</p>
<p>Let's make a function object that provides an overload for <code>operator()</code>, and abstracts out the <code>self(self, ...)</code> calls into just <code>self2(...)</code> calls --- then we can use <code>self2</code> as the <code>self</code> parameter in the original lambda's definition, and the double recursion (which should ideally be optimized away) will allow us to do what we want.</p>
<div class="sourceCode" id="cb36"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb36-1"><a href="#cb36-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> F<span class="op">&gt;</span></span>
<span id="cb36-2"><a href="#cb36-2" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> <span class="dt">add_recursion_t</span> <span class="op">{</span></span>
<span id="cb36-3"><a href="#cb36-3" aria-hidden="true" tabindex="-1"></a>    F f<span class="op">;</span></span>
<span id="cb36-4"><a href="#cb36-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> X<span class="op">&gt;</span></span>
<span id="cb36-5"><a href="#cb36-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">auto</span> <span class="kw">operator</span><span class="op">()(</span>X x<span class="op">)</span> <span class="op">{</span></span>
<span id="cb36-6"><a href="#cb36-6" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> f<span class="op">(*</span><span class="kw">this</span><span class="op">,</span> x<span class="op">);</span></span>
<span id="cb36-7"><a href="#cb36-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb36-8"><a href="#cb36-8" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb36-9"><a href="#cb36-9" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> F<span class="op">&gt;</span></span>
<span id="cb36-10"><a href="#cb36-10" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> add_recursion<span class="op">(</span>F f<span class="op">)</span> <span class="op">{</span> <span class="co">// could have as well been implemented as a lambda</span></span>
<span id="cb36-11"><a href="#cb36-11" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="dt">add_recursion_t</span><span class="op">{</span>f<span class="op">};</span></span>
<span id="cb36-12"><a href="#cb36-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>This is also what the <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0200r0.html">std::y_combinator proposal</a> does, but with better optimizations that sadly renders the code less than readable. This paper is redundant with the C++23 feature called "Deducing <code>this</code>" (which also solves a lot of other problems, not limited to lambdas).</p>
<p>To avoid writing <code>self</code> so many times, it allows us to refer to the lambda itself in its body, and write</p>
<div class="sourceCode" id="cb37"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb37-1"><a href="#cb37-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> fib <span class="op">=</span> <span class="op">[](</span><span class="kw">this</span> <span class="kw">auto</span><span class="op">&amp;&amp;</span> self<span class="op">,</span> <span class="dt">int</span> n<span class="op">)</span> <span class="op">{</span> <span class="co">// notice that the -&gt; int is gone</span></span>
<span id="cb37-2"><a href="#cb37-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="op">(</span>n <span class="op">&lt;=</span> <span class="dv">1</span><span class="op">)</span> <span class="cf">return</span> n<span class="op">;</span></span>
<span id="cb37-3"><a href="#cb37-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> self<span class="op">(</span>n <span class="op">-</span> <span class="dv">1</span><span class="op">)</span> <span class="op">+</span> self<span class="op">(</span>n <span class="op">-</span> <span class="dv">2</span><span class="op">);</span></span>
<span id="cb37-4"><a href="#cb37-4" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb37-5"><a href="#cb37-5" aria-hidden="true" tabindex="-1"></a><span class="bu">std::</span>cout <span class="op">&lt;&lt;</span> fib<span class="op">(</span><span class="dv">10</span><span class="op">)</span> <span class="op">&lt;&lt;</span> <span class="ch">&#39;</span><span class="sc">\n</span><span class="ch">&#39;</span><span class="op">;</span></span></code></pre></div>
<p>You can test this code out on the latest Clang release.</p>
<p>But can we do this in just lambdas? The answer is</p>
<details>
<summary>Yes and no</summary>
<p>As we pointed out, the Y-combinator allows us to do this in a lambda calculus (which is untyped by default).</p>
<p>But, there is no way to use C++ lambdas in the exact same manner to implement a Y-combinator, or in fact any fixpoint combinator, because "pure" lambda expressions in C++ follow a simply typed lambda calculus, and simply typed lambda calculus does not admit a fixpoint combinator.</p>
<p>The existence of strong typing is something that prevents recursion to be implemented in C++ lambdas itself (at least without relying on other features in the function body), which is why even though untyped lambda calculus is Turing complete, simply typed lambda calculus is not.</p>
<p>In fact, it can be shown via induction that there are no programs that don't terminate in a simply typed lambda calculus. However, if a fixpoint combinator existed, applying it to itself would lead to infinite recursion, a contradiction. More generally, if there was a general recursion mechanism that could emulate a Turing machine, the existence of an infinite loop would lead to a contradiction to the guaranteed termination of an expression in a simply typed lambda calculus. The keyword here is "strongly normalizing".</p>
<p>If it was allowed to capture <code>this</code> in a lambda, then this would have been possible, and indeed this is how C++23 handles this problem. People use <code>std::function</code> to implement recursive lambdas just because they can capture the <code>std::function</code> that they assign the lambda to. The fact that it is a concrete type but allows us to typecast from a structure that is of an arbitrary type is quite a feat, which is why anyone serious about programming language design should learn about how type erasure is implemented.</p>
<p><a href="https://okmij.org/ftp/Computation/fixed-point-combinators.html">This</a> is a great resource on how to implement recursion in OCaml and Haskell.</p>
</details>
<h4 id="stateful-lambdas">Stateful lambdas</h4>
<p>Have you ever wanted a Python generator in your code? Turns out that with mutable state, you can implement stateful lambdas that work in a similar manner.</p>
<p>It should be abundantly clear with the std::generate example we used a while back that stateful lambdas are nothing but objects with a single member function accessible via the call operator, and some mutable state represented by the data captured by them. It is helpful to remember the struct-to-lambda correspondence here.</p>
<p>For instance, let's say you want to print something that looks like a tuple, and <code>std::apply</code> works on it.</p>
<p>How would you print its space separated members?</p>
<div class="sourceCode" id="cb38"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb38-1"><a href="#cb38-1" aria-hidden="true" tabindex="-1"></a><span class="bu">std::</span>apply<span class="op">([</span>i <span class="op">=</span> <span class="dv">0</span><span class="bu">ULL</span><span class="op">]</span> <span class="op">(</span><span class="at">const</span> <span class="kw">auto</span><span class="op">&amp;...</span> x<span class="op">)</span> <span class="at">mutable</span> <span class="op">-&gt;</span> <span class="dt">void</span> <span class="op">{</span></span>
<span id="cb38-2"><a href="#cb38-2" aria-hidden="true" tabindex="-1"></a>    <span class="op">(((</span>i<span class="op">++</span> <span class="op">?</span> <span class="op">(</span><span class="bu">std::</span>cout <span class="op">&lt;&lt;</span> <span class="ch">&#39; &#39;</span><span class="op">)</span> <span class="op">:</span> <span class="dt">void</span><span class="op">()),</span> <span class="bu">std::</span>cout <span class="op">&lt;&lt;</span> x<span class="op">),</span> <span class="op">...);</span></span>
<span id="cb38-3"><a href="#cb38-3" aria-hidden="true" tabindex="-1"></a><span class="op">},</span> tuple_object<span class="op">);</span></span></code></pre></div>
<p>Here we have made abundant use of fold expressions, but the main point is that after expansion, this mutates the state of <code>i</code> inside the body each time there is an <code>i++</code>, and a space is printed before every element except the first element.</p>
<p>Similarly, you can write a random number generator as follows (taking the example from <a href="https://codeforces.com/blog/entry/62393">here</a>):</p>
<div class="sourceCode" id="cb39"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb39-1"><a href="#cb39-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> next_random <span class="op">=</span> <span class="op">[</span></span>
<span id="cb39-2"><a href="#cb39-2" aria-hidden="true" tabindex="-1"></a>    splitmix64 <span class="op">=</span> <span class="op">[](</span><span class="dt">uint64_t</span> x<span class="op">)</span> <span class="op">{</span></span>
<span id="cb39-3"><a href="#cb39-3" aria-hidden="true" tabindex="-1"></a>        x <span class="op">+=</span> <span class="bn">0x9e3779b97f4a7c15</span><span class="op">;</span></span>
<span id="cb39-4"><a href="#cb39-4" aria-hidden="true" tabindex="-1"></a>        x <span class="op">=</span> <span class="op">(</span>x <span class="op">^</span> <span class="op">(</span>x <span class="op">&gt;&gt;</span> <span class="dv">30</span><span class="op">))</span> <span class="op">*</span> <span class="bn">0xbf58476d1ce4e5b9</span><span class="op">;</span></span>
<span id="cb39-5"><a href="#cb39-5" aria-hidden="true" tabindex="-1"></a>        x <span class="op">=</span> <span class="op">(</span>x <span class="op">^</span> <span class="op">(</span>x <span class="op">&gt;&gt;</span> <span class="dv">27</span><span class="op">))</span> <span class="op">*</span> <span class="bn">0x94d049bb133111eb</span><span class="op">;</span></span>
<span id="cb39-6"><a href="#cb39-6" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> x <span class="op">^</span> <span class="op">(</span>x <span class="op">&gt;&gt;</span> <span class="dv">31</span><span class="op">);</span></span>
<span id="cb39-7"><a href="#cb39-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">},</span></span>
<span id="cb39-8"><a href="#cb39-8" aria-hidden="true" tabindex="-1"></a>    FIXED_RANDOM <span class="op">=</span> chrono<span class="op">::</span>steady_clock<span class="op">::</span>now<span class="op">().</span>time_since_epoch<span class="op">().</span>count<span class="op">(),</span></span>
<span id="cb39-9"><a href="#cb39-9" aria-hidden="true" tabindex="-1"></a>    random <span class="op">=</span> <span class="dv">0</span></span>
<span id="cb39-10"><a href="#cb39-10" aria-hidden="true" tabindex="-1"></a><span class="op">]</span> <span class="op">()</span> <span class="at">mutable</span> <span class="op">{</span></span>
<span id="cb39-11"><a href="#cb39-11" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> random <span class="op">=</span> splitmix64<span class="op">(</span>random <span class="op">+</span> FIXED_RANDOM<span class="op">);</span></span>
<span id="cb39-12"><a href="#cb39-12" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb39-13"><a href="#cb39-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb39-14"><a href="#cb39-14" aria-hidden="true" tabindex="-1"></a><span class="cf">while</span> <span class="op">(</span>n<span class="op">--)</span> <span class="bu">std::</span>cout <span class="op">&lt;&lt;</span> next_random<span class="op">()</span> <span class="op">&lt;&lt;</span> <span class="ch">&#39;</span><span class="sc">\n</span><span class="ch">&#39;</span><span class="op">;</span></span></code></pre></div>
<p>If you want to, it is also possible to write all of your code in a single immediately-invoked lambda, but that is something I discourage you from writing, unless you want to obfuscate code or just want to challenge your brain.</p>
<p>For example, <a href="https://codeforces.com/contest/1903/submission/235380488">this code</a> for the latest Div2A works, but I definitely do NOT recommend that you write code this way. However, it is quite instructive to understand why this code works and why certain variations do not, so I definitely DO recommend reading and understanding this --- it'll help cement your understanding of how captures work, what is called when, and so on.</p>
<div class="sourceCode" id="cb40"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb40-1"><a href="#cb40-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&quot;bits/stdc++.h&quot;</span></span>
<span id="cb40-2"><a href="#cb40-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb40-3"><a href="#cb40-3" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> main<span class="op">()</span> <span class="op">{</span></span>
<span id="cb40-4"><a href="#cb40-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">[</span>rd <span class="op">=</span> <span class="op">[]</span> <span class="op">{</span></span>
<span id="cb40-5"><a href="#cb40-5" aria-hidden="true" tabindex="-1"></a>         <span class="dt">int</span> x<span class="op">;</span> <span class="bu">std::</span>cin <span class="op">&gt;&gt;</span> x<span class="op">;</span></span>
<span id="cb40-6"><a href="#cb40-6" aria-hidden="true" tabindex="-1"></a>         <span class="cf">return</span> x<span class="op">;</span></span>
<span id="cb40-7"><a href="#cb40-7" aria-hidden="true" tabindex="-1"></a>     <span class="op">},</span></span>
<span id="cb40-8"><a href="#cb40-8" aria-hidden="true" tabindex="-1"></a>     wt <span class="op">=</span> <span class="op">[](</span><span class="kw">auto</span> x<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> <span class="op">(</span><span class="bu">std::</span>cout <span class="op">&lt;&lt;</span> x<span class="op">,</span> <span class="dv">0</span><span class="op">);</span> <span class="op">},</span></span>
<span id="cb40-9"><a href="#cb40-9" aria-hidden="true" tabindex="-1"></a>     sorted <span class="op">=</span> <span class="op">[](</span><span class="kw">auto</span> x<span class="op">)</span> <span class="op">{</span></span>
<span id="cb40-10"><a href="#cb40-10" aria-hidden="true" tabindex="-1"></a>         <span class="bu">std::</span>sort<span class="op">(</span>x<span class="op">.</span>begin<span class="op">(),</span> x<span class="op">.</span>end<span class="op">());</span></span>
<span id="cb40-11"><a href="#cb40-11" aria-hidden="true" tabindex="-1"></a>         <span class="cf">return</span> x<span class="op">;</span></span>
<span id="cb40-12"><a href="#cb40-12" aria-hidden="true" tabindex="-1"></a>     <span class="op">},</span></span>
<span id="cb40-13"><a href="#cb40-13" aria-hidden="true" tabindex="-1"></a>     forn <span class="op">=</span> <span class="op">[](</span><span class="kw">auto</span> f<span class="op">,</span> <span class="dt">int</span> n<span class="op">)</span> <span class="op">{</span></span>
<span id="cb40-14"><a href="#cb40-14" aria-hidden="true" tabindex="-1"></a>         <span class="cf">while</span> <span class="op">(</span>n<span class="op">--)</span> f<span class="op">();</span></span>
<span id="cb40-15"><a href="#cb40-15" aria-hidden="true" tabindex="-1"></a>         <span class="cf">return</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb40-16"><a href="#cb40-16" aria-hidden="true" tabindex="-1"></a>     <span class="op">}]</span> <span class="op">{</span></span>
<span id="cb40-17"><a href="#cb40-17" aria-hidden="true" tabindex="-1"></a>        <span class="op">[&amp;,</span> _ <span class="op">=</span> forn<span class="op">(</span></span>
<span id="cb40-18"><a href="#cb40-18" aria-hidden="true" tabindex="-1"></a>                <span class="op">[&amp;]()</span> <span class="op">{</span></span>
<span id="cb40-19"><a href="#cb40-19" aria-hidden="true" tabindex="-1"></a>                    <span class="kw">auto</span> n <span class="op">=</span> rd<span class="op">();</span></span>
<span id="cb40-20"><a href="#cb40-20" aria-hidden="true" tabindex="-1"></a>                    <span class="kw">auto</span> k <span class="op">=</span> rd<span class="op">();</span></span>
<span id="cb40-21"><a href="#cb40-21" aria-hidden="true" tabindex="-1"></a>                    <span class="op">[&amp;,</span> a <span class="op">=</span> <span class="bu">std::</span>vector<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;(</span>n<span class="op">)]()</span> <span class="at">mutable</span> <span class="op">{</span></span>
<span id="cb40-22"><a href="#cb40-22" aria-hidden="true" tabindex="-1"></a>                        <span class="op">[&amp;,</span> _ <span class="op">=</span> <span class="bu">std::</span>generate_n<span class="op">(</span>a<span class="op">.</span>begin<span class="op">(),</span> a<span class="op">.</span>size<span class="op">(),</span> rd<span class="op">)]()</span> <span class="op">{</span></span>
<span id="cb40-23"><a href="#cb40-23" aria-hidden="true" tabindex="-1"></a>                            <span class="op">[&amp;,</span> ans <span class="op">=</span> <span class="op">(</span>k <span class="op">==</span> <span class="dv">1</span> <span class="op">&amp;&amp;</span> a <span class="op">!=</span> sorted<span class="op">(</span>a<span class="op">)</span> <span class="op">?</span> <span class="st">&quot;NO</span><span class="sc">\n</span><span class="st">&quot;</span> <span class="op">:</span> <span class="st">&quot;YES</span><span class="sc">\n</span><span class="st">&quot;</span><span class="op">)]()</span> <span class="op">{</span></span>
<span id="cb40-24"><a href="#cb40-24" aria-hidden="true" tabindex="-1"></a>                                <span class="op">[</span>_ <span class="op">=</span> wt<span class="op">(</span>ans<span class="op">)]()</span> <span class="op">{</span></span>
<span id="cb40-25"><a href="#cb40-25" aria-hidden="true" tabindex="-1"></a>                                <span class="op">};</span></span>
<span id="cb40-26"><a href="#cb40-26" aria-hidden="true" tabindex="-1"></a>                            <span class="op">}();</span></span>
<span id="cb40-27"><a href="#cb40-27" aria-hidden="true" tabindex="-1"></a>                        <span class="op">}();</span></span>
<span id="cb40-28"><a href="#cb40-28" aria-hidden="true" tabindex="-1"></a>                    <span class="op">}();</span></span>
<span id="cb40-29"><a href="#cb40-29" aria-hidden="true" tabindex="-1"></a>                <span class="op">},</span></span>
<span id="cb40-30"><a href="#cb40-30" aria-hidden="true" tabindex="-1"></a>                rd<span class="op">())]()</span> <span class="op">{</span></span>
<span id="cb40-31"><a href="#cb40-31" aria-hidden="true" tabindex="-1"></a>        <span class="op">}();</span></span>
<span id="cb40-32"><a href="#cb40-32" aria-hidden="true" tabindex="-1"></a>    <span class="op">}();</span></span>
<span id="cb40-33"><a href="#cb40-33" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<hr />
<h2 id="some-other-interesting-patterns">Some other interesting patterns</h2>
<h4 id="using-lambdas-for-implementing-classes">Using lambdas for implementing classes</h4>
<p>Note that we claimed that lambda calculus is Turing complete. But can it implement classes? The answer is of course yes.</p>
<p>Can C++ lambdas implement classes? Also yes.</p>
<p>Let's let go of the implementation of lambdas in C++ for now, and think of implementing objects in terms of functions.</p>
<p>For implementing classes, we need data and member functions. For data, we can just store the data as a capture in a lambda. But what does the lambda do? We should be able to call something using the captured data, so the lambda should take as a parameter whatever the implementation of the member function should be.</p>
<p>So, once we have an object, we can call the data with the function, instead of calling the function on the data.</p>
<div class="sourceCode" id="cb41"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb41-1"><a href="#cb41-1" aria-hidden="true" tabindex="-1"></a><span class="co">// constructor</span></span>
<span id="cb41-2"><a href="#cb41-2" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> range <span class="op">=</span> <span class="op">[](</span><span class="dt">size_t</span> l<span class="op">,</span> <span class="dt">size_t</span> r<span class="op">)</span> <span class="op">{</span></span>
<span id="cb41-3"><a href="#cb41-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="op">[</span>l<span class="op">,</span> r<span class="op">](</span><span class="kw">auto</span> f<span class="op">)</span> <span class="op">{</span></span>
<span id="cb41-4"><a href="#cb41-4" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> f<span class="op">(</span>l<span class="op">,</span> r<span class="op">);</span></span>
<span id="cb41-5"><a href="#cb41-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">};</span></span>
<span id="cb41-6"><a href="#cb41-6" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb41-7"><a href="#cb41-7" aria-hidden="true" tabindex="-1"></a><span class="co">// (free) member functions</span></span>
<span id="cb41-8"><a href="#cb41-8" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> len   <span class="op">=</span> <span class="op">[](</span><span class="dt">size_t</span> x<span class="op">,</span> <span class="dt">size_t</span> y<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> y <span class="op">-</span> x<span class="op">;</span> <span class="op">};</span></span>
<span id="cb41-9"><a href="#cb41-9" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> right <span class="op">=</span> <span class="op">[](</span><span class="dt">size_t</span> x<span class="op">,</span> <span class="dt">size_t</span> y<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> y<span class="op">;</span> <span class="op">};</span></span>
<span id="cb41-10"><a href="#cb41-10" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> left  <span class="op">=</span> <span class="op">[](</span><span class="dt">size_t</span> x<span class="op">,</span> <span class="dt">size_t</span> y<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> x<span class="op">;</span> <span class="op">};</span></span>
<span id="cb41-11"><a href="#cb41-11" aria-hidden="true" tabindex="-1"></a><span class="co">// usage</span></span>
<span id="cb41-12"><a href="#cb41-12" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> a <span class="op">=</span> range<span class="op">(</span><span class="dv">1</span><span class="op">,</span> <span class="dv">5</span><span class="op">);</span> <span class="co">// this is an object</span></span>
<span id="cb41-13"><a href="#cb41-13" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> len_a <span class="op">=</span> a<span class="op">(</span>len<span class="op">);</span>  <span class="co">// compare with a.len() in usual C++ syntax</span></span></code></pre></div>
<p>And if we want to support recursive functions, we can change the definitions a tiny bit.</p>
<div class="sourceCode" id="cb42"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb42-1"><a href="#cb42-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> range <span class="op">=</span> <span class="op">[](</span><span class="dt">size_t</span> l<span class="op">,</span> <span class="dt">size_t</span> r<span class="op">)</span> <span class="op">{</span></span>
<span id="cb42-2"><a href="#cb42-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="op">[</span>l<span class="op">,</span> r<span class="op">](</span><span class="kw">auto</span> f<span class="op">)</span> <span class="op">{</span></span>
<span id="cb42-3"><a href="#cb42-3" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> f<span class="op">(</span>f<span class="op">,</span> l<span class="op">,</span> r<span class="op">);</span></span>
<span id="cb42-4"><a href="#cb42-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">};</span></span>
<span id="cb42-5"><a href="#cb42-5" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb42-6"><a href="#cb42-6" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> len   <span class="op">=</span> <span class="op">[](</span><span class="kw">auto</span> self<span class="op">,</span> <span class="dt">size_t</span> x<span class="op">,</span> <span class="dt">size_t</span> y<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> y <span class="op">-</span> x<span class="op">;</span> <span class="op">};</span></span>
<span id="cb42-7"><a href="#cb42-7" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> right <span class="op">=</span> <span class="op">[](</span><span class="kw">auto</span> self<span class="op">,</span> <span class="dt">size_t</span> x<span class="op">,</span> <span class="dt">size_t</span> y<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> y<span class="op">;</span> <span class="op">};</span></span>
<span id="cb42-8"><a href="#cb42-8" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> left  <span class="op">=</span> <span class="op">[](</span><span class="kw">auto</span> self<span class="op">,</span> <span class="dt">size_t</span> x<span class="op">,</span> <span class="dt">size_t</span> y<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> x<span class="op">;</span> <span class="op">};</span></span>
<span id="cb42-9"><a href="#cb42-9" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> depth <span class="op">=</span> <span class="op">[](</span><span class="kw">auto</span> self<span class="op">,</span> <span class="dt">size_t</span> x<span class="op">,</span> <span class="dt">size_t</span> y<span class="op">)</span> <span class="op">{</span></span>
<span id="cb42-10"><a href="#cb42-10" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="op">(</span>y <span class="op">-</span> x <span class="op">&lt;=</span> <span class="dv">1</span><span class="op">)</span> <span class="cf">return</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb42-11"><a href="#cb42-11" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="dv">1</span> <span class="op">+</span> self<span class="op">(</span>self<span class="op">,</span> x<span class="op">,</span> x <span class="op">+</span> <span class="op">(</span>y <span class="op">-</span> x<span class="op">)</span> <span class="op">/</span> <span class="dv">2</span><span class="op">);</span></span>
<span id="cb42-12"><a href="#cb42-12" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb42-13"><a href="#cb42-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb42-14"><a href="#cb42-14" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> a <span class="op">=</span> range<span class="op">(</span><span class="dv">1</span><span class="op">,</span> <span class="dv">5</span><span class="op">);</span></span>
<span id="cb42-15"><a href="#cb42-15" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> len_a <span class="op">=</span> a<span class="op">(</span>len<span class="op">);</span></span></code></pre></div>
<p>Mutual recursion can also be implemented similarly, but would require much more effort. Do let me know if you find some way to implement mutual recursion in a clean manner!</p>
<h4 id="inheriting-from-lambdas">Inheriting from lambdas</h4>
<div class="sourceCode" id="cb43"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb43-1"><a href="#cb43-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span><span class="op">...</span> T<span class="op">&gt;</span></span>
<span id="cb43-2"><a href="#cb43-2" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> S <span class="op">:</span> T<span class="op">...</span> <span class="op">{</span></span>
<span id="cb43-3"><a href="#cb43-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span><span class="op">...</span> L<span class="op">&gt;</span></span>
<span id="cb43-4"><a href="#cb43-4" aria-hidden="true" tabindex="-1"></a>    S<span class="op">(</span>L<span class="op">&amp;&amp;...</span> l<span class="op">)</span> <span class="op">:</span> T<span class="op">(</span><span class="bu">std::</span>forward<span class="op">&lt;</span>L<span class="op">&gt;(</span>l<span class="op">)...)</span> <span class="op">{}</span></span>
<span id="cb43-5"><a href="#cb43-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> T<span class="op">::</span><span class="kw">operator</span><span class="op">()...;</span></span>
<span id="cb43-6"><a href="#cb43-6" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span></code></pre></div>
<p>This can be used to implement a somewhat generic lambda by providing different implementations like this:</p>
<div class="sourceCode" id="cb44"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb44-1"><a href="#cb44-1" aria-hidden="true" tabindex="-1"></a>S generic_lambda <span class="op">=</span> <span class="op">{</span></span>
<span id="cb44-2"><a href="#cb44-2" aria-hidden="true" tabindex="-1"></a>    <span class="op">[](</span><span class="dt">int</span> x<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> <span class="dv">1</span><span class="op">;</span> <span class="op">},</span></span>
<span id="cb44-3"><a href="#cb44-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">[](</span><span class="dt">double</span> d<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> <span class="fl">0.0</span><span class="op">;</span> <span class="op">}</span></span>
<span id="cb44-4"><a href="#cb44-4" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb44-5"><a href="#cb44-5" aria-hidden="true" tabindex="-1"></a><span class="bu">std::</span>cout <span class="op">&lt;&lt;</span> generic_lambda<span class="op">(</span><span class="dv">0</span><span class="op">)</span> <span class="op">&lt;&lt;</span> <span class="ch">&#39;</span><span class="sc">\n</span><span class="ch">&#39;</span><span class="op">;</span></span>
<span id="cb44-6"><a href="#cb44-6" aria-hidden="true" tabindex="-1"></a><span class="bu">std::</span>cout <span class="op">&lt;&lt;</span> generic_lambda<span class="op">(</span><span class="fl">1.0</span><span class="op">)</span> <span class="op">&lt;&lt;</span> <span class="ch">&#39;</span><span class="sc">\n</span><span class="ch">&#39;</span><span class="op">;</span></span></code></pre></div>
<p>But we already have generic lambdas in C++20, and they're pretty interesting in themselves.</p>
<hr />
<h2 id="examples-of-competitive-programming-code-using-c-lambdas">Examples of competitive programming code using C++ lambdas</h2>
<p>Finally, let's come to some useful code patterns involving lambdas that I use (and used to use) while solving problems.</p>
<h4 id="as-a-local-function">As a local function</h4>
<p>This seems to be the most popular usecase for lambdas, and for good reason --- you can avoid code duplication by literally making a code block executable (the <code>&amp;</code> capture does wonders for this usecase). It ends up being particularly useful in the following scenarios:</p>
<ul>
<li>When you have to implement a function for a certain query, but it will be used multiple times, perhaps with slightly different behaviours.</li>
<li>When you are implementing a data structure inline --- i.e., when you don't have library code at hand, and want to avoid having to declare a struct for, say, a segment tree or a Fenwick tree or a DSU.</li>
<li>When you want to avoid rewriting annoying bits of code like when you are writing code for an interactive problem, where the input/output format is complex (even for a very basic format, you need to print, flush, read and return, which deserves a function of its own).</li>
</ul>
<p>For example, although the intent is not very clear in <a href="https://codeforces.com/contest/1896/submission/234282511">this example</a> (unless we try solving the problem itself), it is clear that there would have been a lot of code duplication without the use of a lambda --- just count the number of calls to the lambda.</p>
<h4 id="dfs-and-other-applications-of-recursive-lambdas">DFS and other applications of recursive lambdas</h4>
<p>Most people implement DFS as a function, and to do that, they make their graphs global too.</p>
<p>What happens when we want to do a multi-test problem? Clear graphs each time? Of course that has the potential to be buggy.</p>
<p>So what some other people do is to make graphs local, but pass them as a parameter. Similarly, if they want to update any arrays/vectors/integer, like visited/color/component/n_components, they also pass them as a parameter.</p>
<p>Why is this bad? If you swap out two arrays/variables in the references, it would not be a very obvious bug. And it just increases your context switch, because now you have to care about every function call. So if you are implementing a particularly involved DFS, you will end up being more prone to bugs than you could bargain for.</p>
<p>Some smart people realized this and started using local lambdas for DFS, but they used the following trick (which is still not the best trick, I'll explain why in a moment):</p>
<div class="sourceCode" id="cb45"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb45-1"><a href="#cb45-1" aria-hidden="true" tabindex="-1"></a><span class="bu">std::</span>function<span class="op">&lt;</span><span class="dt">int</span><span class="op">(</span><span class="dt">int</span><span class="op">,</span> <span class="dt">int</span><span class="op">)&gt;</span> dfs <span class="op">=</span> <span class="op">[&amp;](</span><span class="dt">int</span> u<span class="op">,</span> <span class="dt">int</span> p<span class="op">)</span> <span class="op">{</span></span>
<span id="cb45-2"><a href="#cb45-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> sum <span class="op">=</span> <span class="dv">1</span><span class="op">;</span></span>
<span id="cb45-3"><a href="#cb45-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span> v <span class="op">:</span> g<span class="op">[</span>u<span class="op">])</span></span>
<span id="cb45-4"><a href="#cb45-4" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(</span>v <span class="op">!=</span> p<span class="op">)</span> sum <span class="op">+=</span> dfs<span class="op">(</span>v<span class="op">,</span> u<span class="op">);</span></span>
<span id="cb45-5"><a href="#cb45-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> sum<span class="op">;</span></span>
<span id="cb45-6"><a href="#cb45-6" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb45-7"><a href="#cb45-7" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> sz <span class="op">=</span> dfs<span class="op">(</span><span class="dv">0</span><span class="op">,</span> <span class="op">-</span><span class="dv">1</span><span class="op">);</span></span></code></pre></div>
<p>Why it is not the best approach:</p>
<ul>
<li>Typing the types twice is too much work</li>
<li>Type erasure (yet again) makes recursive functions quite slow. It might not be visible for DFS, but once you start using it for something like divide and conquer or recursive DP that needs of the order of <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mn>10</mn><mn>7</mn></msup><mo>−</mo><msup><mn>10</mn><mn>8</mn></msup></mrow><annotation encoding="application/x-tex">10^7-10^8</annotation></semantics></math> recursive calls, the performance hit would almost invariably make your solution too slow to get AC.</li>
<li>No support for default parameters --- some might see this as a good thing, but the point is that it is abstracting away too much detail from the lambda.</li>
</ul>
<p>Here's what I use:</p>
<div class="sourceCode" id="cb46"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb46-1"><a href="#cb46-1" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> dfs <span class="op">=</span> <span class="op">[&amp;](</span><span class="kw">auto</span> self<span class="op">,</span> <span class="dt">int</span> u<span class="op">,</span> <span class="dt">int</span> p <span class="op">=</span> <span class="op">-</span><span class="dv">1</span><span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">int</span> <span class="op">{</span> <span class="co">// can also be auto&amp;&amp; if you want to be careful</span></span>
<span id="cb46-2"><a href="#cb46-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> sum <span class="op">=</span> <span class="dv">1</span><span class="op">;</span></span>
<span id="cb46-3"><a href="#cb46-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span> v <span class="op">:</span> g<span class="op">[</span>u<span class="op">])</span></span>
<span id="cb46-4"><a href="#cb46-4" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(</span>v <span class="op">!=</span> p<span class="op">)</span> sum <span class="op">+=</span> self<span class="op">(</span>self<span class="op">,</span> v<span class="op">,</span> u<span class="op">);</span></span>
<span id="cb46-5"><a href="#cb46-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> sum<span class="op">;</span></span>
<span id="cb46-6"><a href="#cb46-6" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb46-7"><a href="#cb46-7" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> sz <span class="op">=</span> dfs<span class="op">(</span>dfs<span class="op">,</span> <span class="dv">0</span><span class="op">);</span></span></code></pre></div>
<p>Some very high rated programmers use this pattern too, for example, <a href="https://codeforces.com/contest/1876/submission/227270487">this submission</a>, and for good reason --- it pretty much always compiles down to the most optimal code (according to the compiler). The only case I know of this being slower than a usual implementation was because the compiler was vectorizing the DFS(!) and was leading to instruction cache misses. That was a very peculiar case, and I don't expect it to encounter it again in the wild, especially not in a problem with a tight TL.</p>
<p>Others use the idea outlined in the now-redundant <code>std::y_combinator</code> proposal, and do something like this:</p>
<div class="sourceCode" id="cb47"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb47-1"><a href="#cb47-1" aria-hidden="true" tabindex="-1"></a><span class="co">// template code</span></span>
<span id="cb47-2"><a href="#cb47-2" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">class</span> Fun<span class="op">&gt;</span></span>
<span id="cb47-3"><a href="#cb47-3" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> y_combinator_result <span class="op">{</span></span>
<span id="cb47-4"><a href="#cb47-4" aria-hidden="true" tabindex="-1"></a>    Fun <span class="va">fun_</span><span class="op">;</span></span>
<span id="cb47-5"><a href="#cb47-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">public</span><span class="op">:</span></span>
<span id="cb47-6"><a href="#cb47-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> T<span class="op">&gt;</span></span>
<span id="cb47-7"><a href="#cb47-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">explicit</span> y_combinator_result<span class="op">(</span>T <span class="op">&amp;&amp;</span>fun<span class="op">):</span> <span class="va">fun_</span><span class="op">(</span><span class="bu">std::</span>forward<span class="op">&lt;</span>T<span class="op">&gt;(</span>fun<span class="op">))</span> <span class="op">{}</span></span>
<span id="cb47-8"><a href="#cb47-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> <span class="op">...</span>Args<span class="op">&gt;</span></span>
<span id="cb47-9"><a href="#cb47-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">decltype</span><span class="op">(</span><span class="kw">auto</span><span class="op">)</span> <span class="kw">operator</span><span class="op">()(</span>Args <span class="op">&amp;&amp;...</span>args<span class="op">)</span> <span class="op">{</span></span>
<span id="cb47-10"><a href="#cb47-10" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="va">fun_</span><span class="op">(</span><span class="bu">std::</span>ref<span class="op">(*</span><span class="kw">this</span><span class="op">),</span> <span class="bu">std::</span>forward<span class="op">&lt;</span>Args<span class="op">&gt;(</span>args<span class="op">)...);</span></span>
<span id="cb47-11"><a href="#cb47-11" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb47-12"><a href="#cb47-12" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb47-13"><a href="#cb47-13" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span><span class="op">&lt;</span><span class="kw">class</span> Fun<span class="op">&gt;</span></span>
<span id="cb47-14"><a href="#cb47-14" aria-hidden="true" tabindex="-1"></a><span class="kw">decltype</span><span class="op">(</span><span class="kw">auto</span><span class="op">)</span> y_combinator<span class="op">(</span>Fun <span class="op">&amp;&amp;</span>fun<span class="op">)</span> <span class="op">{</span></span>
<span id="cb47-15"><a href="#cb47-15" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> y_combinator_result<span class="op">&lt;</span><span class="bu">std::</span>decay_t<span class="op">&lt;</span>Fun<span class="op">&gt;&gt;(</span><span class="bu">std::</span>forward<span class="op">&lt;</span>Fun<span class="op">&gt;(</span>fun<span class="op">));</span></span>
<span id="cb47-16"><a href="#cb47-16" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb47-17"><a href="#cb47-17" aria-hidden="true" tabindex="-1"></a><span class="co">// actual code</span></span>
<span id="cb47-18"><a href="#cb47-18" aria-hidden="true" tabindex="-1"></a><span class="kw">auto</span> dfs <span class="op">=</span> y_combinator<span class="op">([&amp;](</span><span class="kw">auto</span> self<span class="op">,</span> <span class="dt">int</span> u<span class="op">,</span> <span class="dt">int</span> p <span class="op">=</span> <span class="op">-</span><span class="dv">1</span><span class="op">)</span> <span class="op">-&gt;</span> <span class="dt">int</span> <span class="op">{</span></span>
<span id="cb47-19"><a href="#cb47-19" aria-hidden="true" tabindex="-1"></a>    <span class="dt">int</span> sum <span class="op">=</span> <span class="dv">1</span><span class="op">;</span></span>
<span id="cb47-20"><a href="#cb47-20" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span> v <span class="op">:</span> g<span class="op">[</span>u<span class="op">])</span></span>
<span id="cb47-21"><a href="#cb47-21" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="op">(</span>v <span class="op">!=</span> p<span class="op">)</span> sum <span class="op">+=</span> self<span class="op">(</span>v<span class="op">,</span> u<span class="op">);</span></span>
<span id="cb47-22"><a href="#cb47-22" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> sum<span class="op">;</span></span>
<span id="cb47-23"><a href="#cb47-23" aria-hidden="true" tabindex="-1"></a><span class="op">});</span></span>
<span id="cb47-24"><a href="#cb47-24" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> sz <span class="op">=</span> dfs<span class="op">(</span><span class="dv">0</span><span class="op">);</span></span></code></pre></div>
<p>For instance, <a href="https://codeforces.com/contest/1896/submission/234316807">this submission</a>.</p>
<p>In fact, this is such a popular pattern that some high-rated people put it on top of their bare minimum templates as well, for instance, <a href="https://codeforces.com/contest/1893/submission/231773474">here</a>.</p>
<p>The one drawback for this template is that sometimes the compiler is not able to reason through all the abstraction, and the code generated might be slightly slower. This is fortunately not the case for most cases, but there is a visible overhead difference in a few cases I have seen.</p>
<h4 id="interfacing-library-code">Interfacing library code</h4>
<p>Library code should ideally be hidden away in a header file, but since most online judges don't have header file support, we are forced to write library code before any of the actual code begins.</p>
<p>It is also important to ensure that after copypasting library code into your submission, there is absolutely no change that you need to do in the library code unless it is a fundamental difference from the logic of the data structure/algorithm, and you just happen to have all the code at hand. Otherwise, you would be editing a large piece of code that you might have forgotten the details/quirks of, and it is easy to end up with bugs.</p>
<p>To do this, it is quite important to implement your library in a way that is as generic as possible. And there are few things more generic than allowing your data structure to execute arbitrary code.</p>
<p>Hence, it makes for a really good choice to use a lambda as a customization point. In fact, the C++ standard calls certain types of function objects "customization points" which goes on to show that interfacing into library code with functions/function objects is a well-understood/well-adopted design practice that is also very convenient for library usage.</p>
<p>As an example of such a thing, my implementation that modifies and generalizes the AtCoder library code for lazy segment tree can be found <a href="https://judge.yosupo.jp/submission/71256">here</a>, and it uses lambdas as possible customization points. It not only implements lazy segment trees (with some opt-in optimizations), but it also has functionality for normal segment tree, with barely any overhead compared to a usual segment tree implementation.</p>
<h4 id="algorithms-with-custom-predicateaggregation-function">Algorithms with custom predicate/aggregation function</h4>
<p>This is in fact one of the most common applications. There are countless lines of code among codeforces submissions that essentially sorts an array according to a given predicate: for instance, <a href="https://codeforces.com/contest/1896/submission/234249255">this code</a>.</p>
<p>There are also a very large number of binary search submissions that follow the template "define a predicate, do binary search on it" --- for instance, <a href="https://codeforces.com/contest/1903/submission/235102757">this code</a>. Note that the manually written binary search could have been avoided by using <code>std::partition_point</code> as well, but it is not very popular for some reason.</p>
<p>Prefix and suffix sums (usual addition or multiplication or xor) can be implemented using <code>std::partial_sum</code> using lambdas as well.</p>
<hr />
<p>Please let me know if there is anything I missed out, and constructive comments on the content in general are welcome!</p>
<details>
<summary>Cite this post</summary>
<div class="sourceCode" id="cb48"><pre class="sourceCode bibtex"><code class="sourceCode bibtex"><span id="cb48-1"><a href="#cb48-1" aria-hidden="true" tabindex="-1"></a><span class="va">@online</span>{<span class="ot">lambdas</span>-<span class="ot">cpp</span>-<span class="ot">and</span>-<span class="ot">otherwise</span>-<span class="ot">2023</span>,</span>
<span id="cb48-2"><a href="#cb48-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">author</span>    = {nor},</span>
<span id="cb48-3"><a href="#cb48-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">title</span>     = {On lambdas, C++ and otherwise: the what, the why, and the how},</span>
<span id="cb48-4"><a href="#cb48-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">year</span>      = {2023},</span>
<span id="cb48-5"><a href="#cb48-5" aria-hidden="true" tabindex="-1"></a>  <span class="dt">month</span>     = {12},</span>
<span id="cb48-6"><a href="#cb48-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">day</span>       = {02},</span>
<span id="cb48-7"><a href="#cb48-7" aria-hidden="true" tabindex="-1"></a>  <span class="dt">url</span>       = {https://nor-blog.pages.dev/posts/2023-12-02-lambdas-cpp-and-otherwise},</span>
<span id="cb48-8"><a href="#cb48-8" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
</details>]]></content:encoded>
</item><item>
<title>Avoiding temporaries - generalizing i++ using std::exchange</title>
<link>https://nor-blog.pages.dev/posts/2023-11-27-std-exchange-cpp/</link>
<guid>https://nor-blog.pages.dev/posts/2023-11-27-std-exchange-cpp/</guid>
<pubDate>Mon, 27 Nov 2023 00:00:00 +0000</pubDate>
<description>A discussion and generalization of post-increment through std::exchange, with examples in recurrences, GCD code, lazy updates, moves, locks, and iterators.</description>
<content:encoded><![CDATA[<p><strong>Note</strong>: for those who don't like using the post-increment operator (<code>i++</code>), hopefully this post convinces you that it is not just a convention that C programmers coaxed the world into following out of tradition. Also, all of the following discusses the increment operators in C++, and not C, where the semantics are slightly different.</p>
<p><strong>Disclaimer</strong>: I use <code>++i</code> much more often in code. But <code>i++</code> has its own place, and I use it --- and the generalization I mention --- quite frequently wherever it is a sane choice.</p>
<h2 id="is-i-better-than-i">Is <code>++i</code> better than <code>i++</code>?</h2>
<p>A lot of people are taught that since <code>i++</code> also returns the old value of <code>i</code> before the increment, it needs a temporary, and hence it must be slower. Good news: almost all compilers today optimize this part away whenever this behaviour is not needed, and the difference between <code>i++</code> and <code>++i</code> doesn't matter.</p>
<p>So what's the difference? In C++, turns out that apart from this old/new value difference, there is another difference.</p>
<p>Any expression in C++ that looks like <code>a op</code> b= where <code>op</code> is a binary operator in fact "returns" a reference to the variable <code>a</code> after completing the operation. As a result of this, you can do things like this:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="co">// replaces x by a * x % p</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> mod_mul<span class="op">(</span><span class="dt">int64_t</span><span class="op">&amp;</span> x<span class="op">,</span> <span class="dt">int</span> a<span class="op">,</span> <span class="dt">int</span> p<span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">(</span>x <span class="op">*=</span> a<span class="op">)</span> <span class="op">%=</span> p<span class="op">;</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Turns out that since you only need the value after the increment for the pre-increment operator, it is possible to have similar behaviour there too, and that is precisely what C++ chose to do:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="co">// replaces x by (x + 1) % p</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> mod_inc<span class="op">(</span><span class="dt">int64_t</span><span class="op">&amp;</span> x<span class="op">,</span> <span class="dt">int</span> p<span class="op">)</span> <span class="op">{</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">++</span>x <span class="op">%=</span> p<span class="op">;</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>However, the post-increment doesn't enjoy any of these properties. Perhaps this is why the <a href="https://google.github.io/styleguide/cppguide.html">Google C++ Style Guide</a> (which I don't really like all that much, but will just quote here) recommends</p>
<blockquote>
<p>Use the prefix form (++i) of the increment and decrement operators unless you need postfix semantics.</p>
</blockquote>
<p>Another part of the language where you can see this distinction in practice is when you overload pre-increment and post-increment operators for a class:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Int <span class="op">{</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> value<span class="op">{};</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>  Int<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">++()</span> <span class="op">{</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>    <span class="bu">std::</span>cout <span class="op">&lt;&lt;</span> <span class="st">&quot;pre-incrementing</span><span class="sc">\n</span><span class="st">&quot;</span><span class="op">;</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span>value<span class="op">;</span> <span class="cf">return</span> <span class="op">*</span><span class="kw">this</span><span class="op">;</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>  Int <span class="kw">operator</span><span class="op">++(</span><span class="dt">int</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>    <span class="bu">std::</span>cout <span class="op">&lt;&lt;</span> <span class="st">&quot;post-incrementing</span><span class="sc">\n</span><span class="st">&quot;</span><span class="op">;</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>    Int temp <span class="op">=</span> <span class="op">*</span><span class="kw">this</span><span class="op">;</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span>value<span class="op">;</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> temp<span class="op">;</span></span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span></code></pre></div>
<p>If you notice closely, the return type of the pre-increment overload is a <em>reference</em>, which is not the case with the post-increment overload. Using a post-increment also makes a copy, so if you're using a post-increment on a struct/class object that defines both, it is likely that there is a potential performance improvement lying right there.</p>
<h2 id="so-is-there-any-legitimate-use-case-for-post-increment">So, is there any legitimate use-case for post-increment?</h2>
<p>Indeed, there is. Notice how in the post-increment code in the previous example, we had to store a temporary. This gives us a hint as to where exactly post-increment is useful: when you need to avoid temporary variables! And one of the places where temporary variables are not needed is when an operation (in this case, increment) must be done after any use of a value.</p>
<p>An example to illustrate this point comes when you want to implement copying of a C-style, null-terminated string (without copying the null terminator so that you're able to, let's say, concatenate strings into a buffer). Let's say we didn't have post-increment in the language at all. The algorithm looks like this:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> copy_c_string<span class="op">(</span><span class="at">const</span> <span class="dt">char</span><span class="op">*</span> input<span class="op">,</span> <span class="dt">char</span><span class="op">*</span> output<span class="op">)</span> <span class="op">{</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">while</span> <span class="op">(*</span>input<span class="op">)</span> <span class="op">{</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">*</span>output <span class="op">=</span> <span class="op">*</span>input<span class="op">;</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span>input<span class="op">;</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">++</span>output<span class="op">;</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>The first thing one would say is that there are too many lines of code --- you need to check <code>input</code>, need to separately handle <code>input</code> and <code>output</code> pointers, and if someone is refactoring this code and accidentally deletes one of the increments, they will introduce a bug that is hard to find in a large codebase.</p>
<p>Contrast that with the following:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> copy_c_string<span class="op">(</span><span class="at">const</span> <span class="dt">char</span><span class="op">*</span> input<span class="op">,</span> <span class="dt">char</span><span class="op">*</span> output<span class="op">)</span> <span class="op">{</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">while</span> <span class="op">(*</span>input<span class="op">)</span> <span class="op">{</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">*</span>output<span class="op">++</span> <span class="op">=</span> <span class="op">*</span>input<span class="op">++;</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>The intent of moving the pointer forward immediately after every use (and using it exactly once, too) is perfectly conveyed, we don't have too many lines of code, and all is well. Of course, it takes some time getting used to writing/reading this kind of code, but thinking of it in terms of "immediate operation after use" shows that it works analogously to what RAII is to a manual destructor call.</p>
<p>In fact, the usage of post-increment and pre-decrement (not pre-increment) was (and is) so popular (partly due to widespread use of half-open ranges), that certain architectures in the past had special functionality for them (for example, <a href="https://en.wikipedia.org/wiki/Motorola_68000#Instruction_set_details">this</a>). Thus, in some rare cases, it is imperative to use post-increment instead of pre-increment for performance.</p>
<h2 id="do-we-have-an-op-style-compound-assignment-generalization-for-post-increment">Do we have an <code>op=</code> style (compound assignment) generalization for post-increment?</h2>
<p>Yes, we do. It is called <a href="https://en.cppreference.com/w/cpp/utility/exchange"><code>std::exchange</code></a>.</p>
<details>
<summary>For the C++ experts</summary>
<p>And sometimes it functions as an analogue, in a philosophical sense, for <code>std::swap</code> when it comes to idioms like copy-and-swap. <code>std::exchange</code> is ideal for use in implementing move constructors and move assignment operators, if you are of the opinion that <code>std::move</code> should perform cleanup as much as possible.</p>
</details>
<p>What it does is this --- <code>std::exchange(a, b)</code> returns the old value of <code>a</code> after setting it to <code>b</code>. So <code>i++</code> is the same as <code>std::exchange(i, i + 1)</code> in terms of semantics.</p>
<p>Similarly, <code>a = std::exchange(b, a)</code> swaps the values of a and b, which shows that it is more general than <code>std::swap</code>, though maybe at a small performance hit for types more complicated than a simple integer. Adding a bunch of =std::move=s should fix that to some extent, though.</p>
<h4 id="why-the-strange-name-how-do-i-remember-it">Why the strange name? How do I remember it?</h4>
<p>I consider this to be a naming disaster, and believe that if there was a better succinct name that does NOT imply bidirectional flow of data, the C++ committee would probably have tried to do it.</p>
<p>The way I remember it is <code>a = std::exchange(b, f(a, b))</code> is (morally) equivalent to <code>std::tie(a, b) = std::make_pair(b, f(a, b))</code> --- that is, the assignments are done at the same time. So somewhat like storing temporaries for everything that is to be assigned, and then performing the assignments at the same time.</p>
<p>A more general example is <code>a = g(a, std::exchange(b, f(a, b)))</code> which does <code>std::tie(a, b) = std::make_pair(g(a, b), f(a, b))</code> --- in a mathematical sense, it allows you to do two parallel assignments in a linear chain-like syntax. I believe this is what brings about the <code>exchange</code> naming (if not the CMPXCHG instruction).</p>
<p>A more intuitive way to read <code>A = std::exchange(B, C)</code> is that A becomes B and B becomes C at the same time.</p>
<h2 id="some-competitive-programming-relevant-examples">Some competitive programming relevant examples</h2>
<h4 id="fibonaccilinear-recurrences">Fibonacci/linear recurrences</h4>
<p>Writing <code>a = std::exchange(b, a + b)</code> is much easier and less error-prone than <code>auto tmp = a; a = b; b = tmp + b;</code> (in fact, someone pointed out that the initial version of this code was wrong). The same goes for any other linear recurrence in 2 variables.</p>
<h4 id="iterative-gcd-and-extended-gcd">Iterative GCD and extended GCD</h4>
<p>Since the Euclidean GCD algorithm is also an affine transformation (especially one where you swap after update), the implementation goes from the less readable/intuitive</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="bu">std::</span>array<span class="op">&lt;</span>T<span class="op">,</span> <span class="dv">3</span><span class="op">&gt;</span> extgcd<span class="op">(</span>T a<span class="op">,</span> T b<span class="op">)</span> <span class="op">{</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>    <span class="bu">std::</span>array x<span class="op">{</span>T<span class="op">{</span><span class="dv">1</span><span class="op">},</span> T<span class="op">{</span><span class="dv">0</span><span class="op">}};</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">while</span> <span class="op">(</span>b<span class="op">)</span> <span class="op">{</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>        <span class="bu">std::</span>swap<span class="op">(</span>x<span class="op">[</span><span class="dv">0</span><span class="op">]</span> <span class="op">-=</span> a <span class="op">/</span> b <span class="op">*</span> x<span class="op">[</span><span class="dv">1</span><span class="op">],</span> x<span class="op">[</span><span class="dv">1</span><span class="op">]);</span>   <span class="co">// x[0] = x[1], x[1] = x[0] - a/b * x[1]</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>        <span class="bu">std::</span>swap<span class="op">(</span>a <span class="op">%=</span> b<span class="op">,</span> b<span class="op">);</span>                    <span class="co">// a = b, b = a % b</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="op">{</span>x<span class="op">[</span><span class="dv">0</span><span class="op">],</span> x<span class="op">[</span><span class="dv">1</span><span class="op">],</span> a<span class="op">};</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>to</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="bu">std::</span>array<span class="op">&lt;</span>T<span class="op">,</span> <span class="dv">3</span><span class="op">&gt;</span> extgcd<span class="op">(</span>T a<span class="op">,</span> T b<span class="op">)</span> <span class="op">{</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>    <span class="bu">std::</span>array x<span class="op">{</span>T<span class="op">{</span><span class="dv">1</span><span class="op">},</span> T<span class="op">{</span><span class="dv">0</span><span class="op">}};</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">while</span> <span class="op">(</span>b<span class="op">)</span> <span class="op">{</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>        x<span class="op">[</span><span class="dv">0</span><span class="op">]</span> <span class="op">=</span> <span class="bu">std::</span>exchange<span class="op">(</span>x<span class="op">[</span><span class="dv">1</span><span class="op">],</span> x<span class="op">[</span><span class="dv">0</span><span class="op">]</span> <span class="op">-</span> a <span class="op">/</span> b <span class="op">*</span> x<span class="op">[</span><span class="dv">1</span><span class="op">]);</span></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>        a <span class="op">=</span> <span class="bu">std::</span>exchange<span class="op">(</span>b<span class="op">,</span> a <span class="op">%</span> b<span class="op">);</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="op">{</span>x<span class="op">[</span><span class="dv">0</span><span class="op">],</span> x<span class="op">[</span><span class="dv">1</span><span class="op">],</span> a<span class="op">};</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h4 id="lazy-updates-in-buffers-use-and-clear">Lazy updates in buffers (use-and-clear)</h4>
<p>It is usually error-prone to clear a buffer of, let's say, updates that you want to process, in the very end of the processing function, as follows:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> flush<span class="op">()</span> <span class="op">{</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span> x <span class="op">:</span> updates<span class="op">)</span> <span class="op">{</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// do something</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>  updates<span class="op">.</span>clear<span class="op">();</span> <span class="co">// easy to forget</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Sometimes this might lead to a MLE as well, if this <code>flush</code> function is in fact a DFS that is called in a loop after processing the updates, where the graph is built during the function itself, and the memory limit is low or the structure you store inside the buffer has quite a lot of information.</p>
<p>To be able to deal with the first of these issues, people used something of the following sort:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> flush<span class="op">()</span> <span class="op">{</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>  <span class="bu">std::</span>vector<span class="op">&lt;</span>Update<span class="op">&gt;</span> updates_tmp<span class="op">;</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">using</span> <span class="bu">std::</span>swap<span class="op">;</span> swap<span class="op">(</span>updates_tmp<span class="op">,</span> updates<span class="op">);</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>  <span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span> x <span class="op">:</span> updates_tmp<span class="op">)</span> <span class="op">{</span></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>    <span class="co">// do something</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>This faces multiple issues</p>
<ul>
<li>You need to create and assign a temporary, and also need to remember the type of the <code>updates</code> variable (can you see where we are going with this?)</li>
<li>The temporary exists till the end of the function, so this doesn't fix the second issue.</li>
<li>Initializing/declaring and then modifying is a very non-functional (anti-)pattern, and making it a habit in code will almost invariably lead to state-mutation-related bugs.</li>
</ul>
<p>Consider the following solution using <code>std::exchange</code>:</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="dt">void</span> flush<span class="op">()</span> <span class="op">{</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span> x <span class="op">:</span> <span class="bu">std::</span>exchange<span class="op">(</span>updates<span class="op">,</span> <span class="op">{}))</span> <span class="op">{</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>    <span class="co">// do something</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Which of these two implementations mirrors the intent of the original function? And which one would you choose to write yourself?</p>
<h2 id="some-software-engineering-relevant-examples">Some software engineering relevant examples</h2>
<h4 id="implementing-move-constructors-and-assignment-operators">Implementing move constructors and assignment operators</h4>
<p>While defining move semantics for your class, it is usually a good idea to keep the moved-from object in defined state. Sometimes this might even be necessary, for instance, when you want to implement something with semantics like <code>std::unique_ptr</code>.</p>
<h4 id="avoiding-redundancy.">Avoiding redundancy.</h4>
<p>It is possible to avoid having to implement post-increment when pre-increment is already available by just doing <code>return std::exchange(*this, ++Type{*this})</code></p>
<h4 id="acrobatics-with-locks">Acrobatics with locks</h4>
<p>The "immediately do after use" idea also carries over to when you're using locks --- it is clearly optimal to use locks for as short a time as possible, when comparing across the same kinds of software architecture. One way that <code>std::exchange</code> can be used to this effect is to use a scoped lock inside a lambda, that returns <code>std::exchange(resource, resetted_resource)</code>.</p>
<p>In fact, there is a common primitive in lock-free programming that uses the exchange idiom (compare-and-swap, test-and-set, std::atomic_exchange).</p>
<h4 id="generic-programming-with-iterators">Generic programming with iterators</h4>
<p>Sometimes the only way to increment an iterator is <code>std::next</code>. Using <code>std::exchange</code>, we can implement our own version of post-increment to be able to write generic code using iterators. Since iterators are very general, you might find yourself using this trick in very unexpected places too.</p>
<hr />
<p>Please let me know what you think about this C++ feature and if there are any mistakes in the above post. Comments are welcome!</p>
<details>
<summary>Cite this post</summary>
<div class="sourceCode" id="cb11"><pre class="sourceCode bibtex"><code class="sourceCode bibtex"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="va">@online</span>{<span class="ot">std</span>-<span class="ot">exchange</span>-<span class="ot">cpp</span>-<span class="ot">2023</span>,</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">author</span>    = {nor},</span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">title</span>     = {Avoiding temporaries - generalizing i++ using std::exchange},</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">year</span>      = {2023},</span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a>  <span class="dt">month</span>     = {11},</span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">day</span>       = {27},</span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a>  <span class="dt">url</span>       = {https://nor-blog.pages.dev/posts/2023-11-27-std-exchange-cpp},</span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
</details>]]></content:encoded>
</item><item>
<title>The Boost C++ library in competitive programming</title>
<link>https://nor-blog.pages.dev/posts/2023-10-28-boost-in-competitive-programming/</link>
<guid>https://nor-blog.pages.dev/posts/2023-10-28-boost-in-competitive-programming/</guid>
<pubDate>Sat, 28 Oct 2023 00:00:00 +0000</pubDate>
<description>The Boost C++ library and examples of what it would give competitive programmers beyond the standard library.</description>
<content:encoded><![CDATA[<p>I believe that adding the Boost library on Codeforces would be a great addition for C++ competitive programmers. AtCoder already supports it (alongside GMP and Eigen, but Boost has replacements/wrappers for those: Boost.Multiprecision and Boost.uBLAS). CodeChef supports it too (or at least used to support it at some point, not sure now). I've seen at least 3 posts by people trying to use Boost on Codeforces and failing, and on thinking about it, I couldn't really come up with a good reason (in my opinion) that Boost should not be supported on Codeforces.</p>
<p>Some might argue against adding a library on Codeforces, but for them, I recommend viewing this post as an educational resource on some of the library's features that I find cool.</p>
<p>There are a lot of things in the STL in the newer C++ standards, whose implementations were originally inspired from Boost, so you could be able to use some features that might not be available until the next few C++ standards.</p>
<p>As of now, the latest version of Boost is 1.83.0, and its documentation can be found <a href="https://www.boost.org/doc/libs/1_83_0/">here</a>.</p>
<p>Here are a few features from Boost that are pretty useful for competitive programming:</p>
<ol type="1">
<li><p><strong>Algorithms from <a href="https://www.boost.org/doc/libs/1_83_0/libs/algorithm/doc/html/index.html">Boost.Algorithms</a></strong> --- this includes algorithms like KMP and binary exponentiation (<code>power</code> for arbitrary associative operations) as well. It also makes for much cleaner code and with significantly less effort. It also includes some "mini" algorithms that are annoying to write, that one might use in some technical contexts (for example, <code>gather</code> is an algorithm like this, and gets used a lot in divide and conquer problems). There are some algorithms that ended up in the STL, like <code>partition_point</code> for doing binary search.</p></li>
<li><p><strong>Containers from <a href="https://www.boost.org/doc/libs/1_83_0/doc/html/container.html">Boost.Container</a></strong> --- this includes a multitude of containers that are not in the C++ standard yet. My personal favourites among these containers are the <code>flat_map</code> and <code>flat_set</code> containers, which are much better implementations for the corresponding associative data structures than the STL ones, and <code>small_vector</code>, which does similar optimizations as the <code>basic_string</code> STL container, but has less stringent conditions on the type of things it can contain.</p></li>
<li><p><strong>Better bitsets using the <code>dynamic_bitset</code> <a href="https://www.boost.org/doc/libs/1_83_0/libs/dynamic_bitset/dynamic_bitset.html">library</a></strong> --- there was a <a href="https://codeforces.com/blog/entry/121783">recent post</a> about dynamic bitsets in Python, but I mentioned a way of getting there using a hack with C++ STL bitsets. However, dynamic bitsets are supported in Boost. In fact, the Boost implementation also exposes functions like <code>find_first</code>, <code>find_next</code>, range <code>set</code>, range <code>flip</code> and so on.</p></li>
<li><p><strong>Graph algorithms from the <a href="https://www.boost.org/doc/libs/1_83_0/libs/graph/doc/table_of_contents.html">Boost Graph Library</a></strong> --- it contains practically every useful graph algorithm that we encounter in competitive programming.</p></li>
<li><p><strong>Different kinds of heaps with <a href="https://www.boost.org/doc/libs/1_83_0/doc/html/heap.html">Boost.Heap</a></strong> --- this contains multiple types of heaps with a lot of useful specialized functions. Ever wanted to try out a Fibonacci heap? Or just any heap with decrease-min or deletion operations? This library will cater to all your needs.</p></li>
<li><p><strong>Interval handling using <a href="https://www.boost.org/doc/libs/1_83_0/libs/icl/doc/html/index.html">Boost.Icl</a></strong> --- often we want to handle ranges of integers in competitive programming problems. This library gives us ready-made data structures to solve such problems, without having to think about corner cases that arise with interval sets. <a href="https://codeforces.com/blog/entry/57934#comment-416182">This solution</a> is a prime example that would be much easier to implement with this library.</p></li>
<li><p><strong>Intrusive containers using <a href="https://www.boost.org/doc/libs/1_83_0/doc/html/intrusive.html">Boost.Intrusive</a></strong> --- there are times when we want to implement a list manually, with some additional information inside the node. For example, there is an implementation of adjacency lists that is quite popular in China, which makes an array of nodes, and inside those nodes, it stores pointers/index of next/previous edges. Doing that using an <code>std::list</code> would be quite painful, and there is a reasonable compromise using intrusive lists. In general, intrusive containers tend to be faster, so if you like constant optimization, this library is pretty nice to know about.</p></li>
<li><p><strong><a href="https://www.boost.org/doc/libs/1_83_0/libs/math/doc/html/index.html">Boost.Math</a></strong> --- this contains a ton of useful math features. Unfortunately, the polynomial library they provide doesn't have fast operations (polynomial multiplication is quadratic for example), but the rest of the functionality is pretty good. It has things like continued fractions, root finding and quaternions, all of which I have seen in competitive programming contests.</p></li>
<li><p><strong>BigInt using <a href="https://www.boost.org/doc/libs/1_83_0/libs/multiprecision/doc/html/index.html">Boost.Multiprecision</a></strong> --- self-explanatory.</p></li>
<li><p><strong>Linear algebra using <a href="https://www.boost.org/doc/libs/1_83_0/libs/numeric/ublas/doc/index.html">Boost uBLAS</a></strong> --- this is a linear algebra library that has pretty much all the functionality one would ever need on a competitive programming problem. However, this library is quite old, and it is usually recommended to use other libraries just for that reason (though I don't find this to be off-putting). The one thing you need to squeeze out performance is to define the macro <code>BOOST_UBLAS_NDEBUG</code>.</p></li>
</ol>
<details>
<summary>Some other libraries that are not directly applicable, but I really like</summary>
<ol type="1">
<li><a href="https://www.boost.org/doc/libs/1_83_0/doc/html/accumulators/user_s_guide.html">Boost.Accumulator</a> --- supports quite generic online algorithm stuff.</li>
<li><a href="https://www.boost.org/doc/libs/1_83_0/libs/fusion/doc/html/">Boost.Fusion</a></li>
<li><a href="https://www.boost.org/doc/libs/1_83_0/libs/msm/doc/HTML/index.html">Boost MSM</a></li>
<li><a href="https://www.boost.org/doc/libs/1_83_0/libs/mp11/doc/html/mp11.html">Boost.Mp11</a></li>
</ol>
</details>
<p>Hopefully this was enough to convince some people that Boost is quite a handy library, that might be worth putting effort into learning, and that it convinces <a href="https://codeforces.com/profile/MikeMirzayanov">MikeMirzayanov</a> to add it on Codeforces.</p>
<details>
<summary>Cite this post</summary>
<div class="sourceCode" id="cb1"><pre class="sourceCode bibtex"><code class="sourceCode bibtex"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="va">@online</span>{<span class="ot">boost</span>-<span class="ot">in</span>-<span class="ot">competitive</span>-<span class="ot">programming</span>-<span class="ot">2023</span>,</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">author</span>    = {nor},</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">title</span>     = {The Boost C++ library in competitive programming},</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">year</span>      = {2023},</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>  <span class="dt">month</span>     = {10},</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">day</span>       = {28},</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>  <span class="dt">url</span>       = {https://nor-blog.pages.dev/posts/2023-10-28-boost-in-competitive-programming},</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
</details>]]></content:encoded>
</item><item>
<title>Writing C++ like Python: tricks Python doesn&#x27;t want you to know</title>
<link>https://nor-blog.pages.dev/posts/2023-01-11-cpp-like-python/</link>
<guid>https://nor-blog.pages.dev/posts/2023-01-11-cpp-like-python/</guid>
<pubDate>Wed, 11 Jan 2023 00:00:00 +0000</pubDate>
<description>A collection of modern C++ tricks that make code succinct and clean, from negative indexing and ranges to lambdas and compact utilities.</description>
<content:encoded><![CDATA[<p>People often say C++ is much more cumbersome to write than any sane language should be, but I think that is mainly due to lack of knowledge about how to write modern C++ code. Here's how you can write code more smartly and succinctly in C++(20):</p>
<h2 id="negative-indexing-with-end">Negative indexing with <code>end</code></h2>
<p>Have you ever found yourself using a vector like a stack just because you have to also access the last few positions, or writing a sliding window code using a deque (where the size might be variable, but you want to access an element at some offset from the end)?</p>
<p>Chances are that you have written code like this:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="cf">while</span> <span class="op">(</span>stk<span class="op">.</span>size<span class="op">()</span> <span class="op">&gt;=</span> <span class="dv">3</span> <span class="op">&amp;&amp;</span> stk<span class="op">[</span>stk<span class="op">.</span>size<span class="op">()</span> <span class="op">-</span> <span class="dv">2</span><span class="op">]</span> <span class="op">+</span> stk<span class="op">[</span>stk<span class="op">.</span>size<span class="op">()</span> <span class="op">-</span> <span class="dv">1</span><span class="op">]</span> <span class="op">&gt;</span> stk<span class="op">[</span>stk<span class="op">.</span>size<span class="op">()</span> <span class="op">-</span> <span class="dv">3</span><span class="op">])</span> <span class="op">{</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>  stk<span class="op">.</span>pop_back<span class="op">();</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>A cleaner way of writing the same thing is this:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="cf">while</span> <span class="op">(</span>stk<span class="op">.</span>size<span class="op">()</span> <span class="op">&gt;=</span> <span class="dv">3</span> <span class="op">&amp;&amp;</span> end<span class="op">(</span>stk<span class="op">)[-</span><span class="dv">2</span><span class="op">]</span> <span class="op">+</span> end<span class="op">(</span>stk<span class="op">)[-</span><span class="dv">1</span><span class="op">]</span> <span class="op">&gt;</span> end<span class="op">(</span>stk<span class="op">)[-</span><span class="dv">3</span><span class="op">])</span> <span class="op">{</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>  stk<span class="op">.</span>pop_back<span class="op">();</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>This trick works not just for <code>end</code>, but for any iterator, provided that (roughly) there is no undefined behaviour like out of bounds accesses.</p>
<p>This can be done only with iterators which provide random access. For example, iterators for vectors but not for sets.</p>
<h2 id="free-functions-like-len-and-str">Free functions like <code>len</code> and <code>str</code></h2>
<p>Python's <code>len</code> and <code>str</code> come in handy a lot of times, and they're convenient to use because they're free functions (that is, not member functions).</p>
<p>Fortunately, C++ has its own set of free functions that are quite helpful:</p>
<ol type="1">
<li><code>size(v)</code>: It returns the unsigned size of <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>v</mi><annotation encoding="application/x-tex">v</annotation></semantics></math>, and does the same thing as <code>v.size()</code> That is, its numerical value is the size of <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>v</mi><annotation encoding="application/x-tex">v</annotation></semantics></math>, and type is some unspecified unsigned type (aliased to <code>size_t</code>). This also works for arrays (but not raw pointers).</li>
<li><code>ssize(v)</code>: It returns the signed size of <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>v</mi><annotation encoding="application/x-tex">v</annotation></semantics></math>. This is quite useful, because it prevents bugs like <code>a.size() - 1</code> on empty <code>a</code>. It doesn't have a member function analogue, though. This also works for arrays (but not raw pointers). If you use <code>sz</code> macros, you can safely remove them from your code!</li>
<li><code>begin(v)</code>, <code>end(v)</code>, <code>rbegin(v)</code>, <code>rend(v)</code>: They do the same thing as what their corresponding member functions do. These also work for arrays (but not raw pointers).</li>
<li><code>empty(v)</code>: This checks if <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>v</mi><annotation encoding="application/x-tex">v</annotation></semantics></math> is empty or not. Analogous to <code>v.empty()</code></li>
<li><code>data(v)</code>: This returns a pointer to the block of data where it works.</li>
<li><code>to_string(x)</code>: This returns the string representation of a datatype. They're only defined for things like <code>int</code> and <code>double</code> though.</li>
</ol>
<h2 id="variable-declaration-in-loopsconditions">Variable declaration in loops/conditions</h2>
<p>If you have used range-based for loops, you might have noticed that there is no support for indexing by default. So people usually either just switch to index based loop, or do the following:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> i <span class="op">=</span> <span class="op">-</span><span class="dv">1</span><span class="op">;</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span> x <span class="op">:</span> a<span class="op">)</span> <span class="op">{</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>  i<span class="op">++;</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>  <span class="co">// do something</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a><span class="co">// or</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> i <span class="op">=</span> <span class="op">-</span><span class="dv">1</span><span class="op">;</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>  <span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span> x <span class="op">:</span> a<span class="op">)</span> <span class="op">{</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>    i<span class="op">++;</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a>    <span class="co">// do something</span></span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>However, it either pollutes the parent scope with the variable <code>i</code> and makes things buggy, or just looks ugly. C++20 has the following feature that makes it cleaner:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> <span class="op">(</span><span class="dt">int</span> i <span class="op">=</span> <span class="op">-</span><span class="dv">1</span><span class="op">;</span> <span class="kw">auto</span> x <span class="op">:</span> a<span class="op">)</span> <span class="op">{</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>  i<span class="op">++;</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>  <span class="co">// do something</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Similarly, if there is an object such that you only have to inspect its properties just once and it becomes useless later on, you can construct it in the init part of the if condition, like this:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="op">(</span><span class="kw">auto</span> x <span class="op">=</span> construct_object<span class="op">();</span> x<span class="op">.</span>good<span class="op">()</span> <span class="op">&amp;&amp;</span> <span class="op">!</span>x<span class="op">.</span>bad<span class="op">())</span> <span class="op">{</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>  <span class="co">// do something</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h2 id="unpacking-structs">Unpacking structs</h2>
<p>A lot of people write code that looks like this:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="bu">std::</span>vector<span class="op">&lt;</span><span class="bu">std::</span>tuple<span class="op">&lt;</span><span class="dt">int</span><span class="op">,</span> <span class="dt">char</span><span class="op">,</span> <span class="bu">std::</span>string<span class="op">&gt;&gt;</span> a<span class="op">;</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a><span class="co">// populate a</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> <span class="op">(</span><span class="dt">int</span> i <span class="op">=</span> <span class="dv">0</span><span class="op">;</span> i <span class="op">&lt;</span> <span class="op">(</span><span class="dt">int</span><span class="op">)</span>a<span class="op">.</span>size<span class="op">();</span> <span class="op">++</span>i<span class="op">)</span> <span class="op">{</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> x <span class="op">=</span> <span class="bu">std::</span>get<span class="op">&lt;</span><span class="dv">0</span><span class="op">&gt;(</span>a<span class="op">[</span>i<span class="op">]);</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>  <span class="dt">char</span> y <span class="op">=</span> <span class="bu">std::</span>get<span class="op">&lt;</span><span class="dv">1</span><span class="op">&gt;(</span>a<span class="op">[</span>i<span class="op">]);</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>  <span class="bu">std::</span>string z <span class="op">=</span> <span class="bu">std::</span>get<span class="op">&lt;</span><span class="dv">2</span><span class="op">&gt;(</span>a<span class="op">[</span>i<span class="op">]);</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a><span class="co">// or</span></span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span><span class="op">&amp;</span> A <span class="op">:</span> a<span class="op">)</span> <span class="op">{</span></span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> x <span class="op">=</span> <span class="bu">std::</span>get<span class="op">&lt;</span><span class="dv">0</span><span class="op">&gt;(</span>A<span class="op">);</span></span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a>  <span class="dt">char</span> y <span class="op">=</span> <span class="bu">std::</span>get<span class="op">&lt;</span><span class="dv">1</span><span class="op">&gt;(</span>A<span class="op">);</span></span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true" tabindex="-1"></a>  <span class="bu">std::</span>string z <span class="op">=</span> <span class="bu">std::</span>get<span class="op">&lt;</span><span class="dv">2</span><span class="op">&gt;(</span>A<span class="op">);</span></span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true" tabindex="-1"></a><span class="co">// or</span></span>
<span id="cb6-15"><a href="#cb6-15" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span><span class="op">&amp;</span> A <span class="op">:</span> a<span class="op">)</span> <span class="op">{</span></span>
<span id="cb6-16"><a href="#cb6-16" aria-hidden="true" tabindex="-1"></a>  <span class="dt">int</span> x<span class="op">;</span> <span class="dt">char</span> y<span class="op">;</span> <span class="bu">std::</span>string z<span class="op">;</span></span>
<span id="cb6-17"><a href="#cb6-17" aria-hidden="true" tabindex="-1"></a>  <span class="bu">std::</span>tie<span class="op">(</span>x<span class="op">,</span> y<span class="op">,</span> z<span class="op">)</span> <span class="op">=</span> A<span class="op">;</span></span>
<span id="cb6-18"><a href="#cb6-18" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>A cleaner and more consistent way of writing this can be:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span> <span class="op">[</span>x<span class="op">,</span> y<span class="op">,</span> z<span class="op">]</span> <span class="op">:</span> a<span class="op">)</span> <span class="op">{</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a><span class="co">// or</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span><span class="op">&amp;</span> A <span class="op">:</span> a<span class="op">)</span> <span class="op">{</span></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span> <span class="op">[</span>x<span class="op">,</span> y<span class="op">,</span> z<span class="op">]</span> <span class="op">=</span> A<span class="op">;</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>If you want references instead of copies stored in <code>x, y, z</code>, then you can do this:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span><span class="op">&amp;</span> <span class="op">[</span>x<span class="op">,</span> y<span class="op">,</span> z<span class="op">]</span> <span class="op">:</span> a<span class="op">)</span> <span class="op">{</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a><span class="co">// or</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span><span class="op">&amp;</span> A <span class="op">:</span> a<span class="op">)</span> <span class="op">{</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">auto</span><span class="op">&amp;</span> <span class="op">[</span>x<span class="op">,</span> y<span class="op">,</span> z<span class="op">]</span> <span class="op">=</span> A<span class="op">;</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Note that this is not limited to for loops, or even to just tuples, and you can use this sort of unpacking (structured binding) for most structs (in particular, custom structs you make, or <code>std::pair</code>). In fact, if you have <code>std::array&lt;int, 3&gt;</code>, then this unpacking will give you its contents in three different variables.</p>
<h2 id="some-more-utilities">Some more utilities</h2>
<p>There are some lesser known functionalities that C++20 introduced, like <code>starts_with</code> and <code>ends_with</code> on strings. Some of the more useful ones can be found <a href="https://codeforces.com/blog/entry/96040?#comment-851241">here</a>.</p>
<p>Notably, there is also support for binary searching like we do in competitive programming, and the relevant information can be found in <a href="https://codeforces.com/blog/entry/96699">the language specific section of this post</a>.</p>
<p>You can also print a number in binary, analogously to what you can do in Python. This can be done by constructing a bitset out of the integer and converting it to a string, or just by printing <code>std::format("{:b}", a)</code> (which is unfortunately not on CF yet).</p>
<h2 id="emplace_back-emplace_front-and-emplace"><code>emplace_back</code>, <code>emplace_front</code> and <code>emplace</code></h2>
<p>Seriously, stop using <code>a.push_back(make_pair(1, 2))</code> and <code>a.push_back(make_tuple(1, 2, 3))</code> and even <code>a.push_back({1, 2, 3})</code>, and start using <code>a.emplace_back(1, 2)</code> instead.</p>
<p>The only reasonably common place this doesn't work is when you have a container that stores <code>std::array</code>, so <code>emplace_back</code> doesn't work; in that case <code>a.push_back({1, 2, 3})</code> is fine.</p>
<p>The other variants: <code>emplace_front</code> and <code>emplace</code> do the same thing for their other counterparts (for example, in a deque, queue or priority_queue).</p>
<h2 id="lambdas">Lambdas</h2>
<p>Lambdas in C++ are in fact cleaner and more intuitive (with more features) than in Python. Compared to <em>both</em> Python lambdas (being able to have more than 1 line of code) and local functions (having mutable states more intuitively and capturing parameters from an ancestor scope), in fact. This is because you can capture stuff more explicitly, have mutable state, can pass them as function objects, and even implement recursion using generic lambdas, though C++23 will have a feature called <code>deducing this</code> which will make a lot of things much simpler.</p>
<p>They can be passed around to almost all algorithms in the STL algorithms library, which is part of the reason why the STL is so powerful and generic.</p>
<p>They can also be used to make certain functions local, and avoid polluting the global namespace with function definitions. One more thing about them is that they are constexpr by default, which is not true for traditional functions.</p>
<h2 id="vector-like-data-structure-without-iterator-invalidation">Vector-like data structure without iterator invalidation</h2>
<p>You probably know what we're coming to at this point: <code>std::deque</code>. It is essentially <code>std::vector</code> (without <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>O</mi><mo stretchy="false" form="prefix">(</mo><mn>1</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">O(1)</annotation></semantics></math> move guarantees but whatever), but with no iterator invalidation on resizing/adding elements.</p>
<p>That is why it is ideal in a very important setting:</p>
<ul>
<li>Making buffers of elements (so that we can use pointers to elements without worrying about what happens when the buffer is resized).</li>
</ul>
<p>No more Python laughing in our face about having to worry about iterator invalidation!</p>
<h2 id="python-style-ranges-and-even-more-flexible-range-manipulation">Python style ranges and even more flexible range manipulation</h2>
<h4 id="using-temporary-container-in-for-loop"><strong>Using temporary container in for loop</strong></h4>
<p>Suppose you want to do something for multiple arguments, but they aren't indices. Most people would either duplicate code, or do something like this:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a>vector<span class="op">&lt;</span><span class="dt">char</span><span class="op">&gt;</span> a<span class="op">{</span><span class="ch">&#39;L&#39;</span><span class="op">,</span> <span class="ch">&#39;R&#39;</span><span class="op">,</span> <span class="ch">&#39;D&#39;</span><span class="op">,</span> <span class="ch">&#39;U&#39;</span><span class="op">};</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span> x <span class="op">:</span> a<span class="op">)</span> <span class="op">{</span> <span class="co">/* do something */</span> <span class="op">}</span></span></code></pre></div>
<p>But this has a disadvantage: it needs more characters and also makes it more error-prone to use vectors. Instead of this, you can do this:</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span> x <span class="op">:</span> <span class="op">{</span><span class="ch">&#39;L&#39;</span><span class="op">,</span> <span class="ch">&#39;R&#39;</span><span class="op">,</span> <span class="ch">&#39;D&#39;</span><span class="op">,</span> <span class="ch">&#39;U&#39;</span><span class="op">})</span> <span class="op">{</span> <span class="co">/* do something */</span> <span class="op">}</span></span></code></pre></div>
<p>or even</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span> x <span class="op">:</span> <span class="st">&quot;LRDU&quot;</span><span class="bu">s</span><span class="op">)</span> <span class="op">{</span> <span class="co">/* do something */</span> <span class="op">}</span></span></code></pre></div>
<p>Note that the <code>s</code> at the end makes it a string literal which is why it works, and <code>const char*</code> doesn't work because there is a <code>\0</code> at the end of the literal. This can still allocate on the heap (not in this case, only for big strings due to SSO).</p>
<p>In case you explicitly want an allocation with a vector for some reason, you can use</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span> x <span class="op">:</span> <span class="bu">std::</span>vector<span class="op">{</span><span class="ch">&#39;L&#39;</span><span class="op">,</span> <span class="ch">&#39;R&#39;</span><span class="op">,</span> <span class="ch">&#39;D&#39;</span><span class="op">,</span> <span class="ch">&#39;U&#39;</span><span class="op">})</span></span></code></pre></div>
<p>or</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span> x <span class="op">:</span> <span class="bu">std::</span>vector<span class="op">&lt;</span><span class="dt">char</span><span class="op">&gt;{</span><span class="ch">&#39;L&#39;</span><span class="op">,</span> <span class="ch">&#39;R&#39;</span><span class="op">,</span> <span class="ch">&#39;D&#39;</span><span class="op">,</span> <span class="ch">&#39;U&#39;</span><span class="op">})</span></span></code></pre></div>
<h4 id="ranges"><strong>Ranges</strong></h4>
<p>C++20 has a feature called ranges, that allows you to do manipulations on, well, ranges.</p>
<p>Let's think about how to implement this: For integers between 1 to 5, multiply them by 2, and print the last 3 elements in reversed order.</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;bits/stdc++.h&gt;</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> main<span class="op">()</span> <span class="op">{</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>  <span class="bu">std::</span>vector<span class="op">&lt;</span><span class="dt">int</span><span class="op">&gt;</span> a<span class="op">{</span><span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">5</span><span class="op">};</span></span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>  <span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span><span class="op">&amp;</span> x <span class="op">:</span> a<span class="op">)</span> x <span class="op">*=</span> <span class="dv">2</span><span class="op">;</span></span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a>  <span class="cf">for</span> <span class="op">(</span><span class="dt">int</span> i <span class="op">=</span> <span class="dv">0</span><span class="op">;</span> i <span class="op">&lt;</span> <span class="dv">3</span><span class="op">;</span> <span class="op">++</span>i<span class="op">)</span> <span class="bu">std::</span>cout <span class="op">&lt;&lt;</span> a<span class="op">[(</span><span class="dt">int</span><span class="op">)</span>a<span class="op">.</span>size<span class="op">()</span> <span class="op">-</span> i <span class="op">-</span> <span class="dv">1</span><span class="op">]</span> <span class="op">&lt;&lt;</span> <span class="ch">&#39;</span><span class="sc">\n</span><span class="ch">&#39;</span><span class="op">;</span></span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>However, this is prone to having bugs (what about out of bounds errors in some other scenario?), and doesn't look intuitive at all.</p>
<p>Now consider this:</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;bits/stdc++.h&gt;</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a><span class="kw">namespace</span> R <span class="op">=</span> <span class="bu">std::</span>ranges<span class="op">;</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a><span class="kw">namespace</span> V <span class="op">=</span> <span class="bu">std::</span>ranges::views<span class="op">;</span></span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> main<span class="op">()</span> <span class="op">{</span></span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> <span class="op">(</span><span class="kw">auto</span> x <span class="op">:</span> V<span class="op">::</span>iota<span class="op">(</span><span class="dv">1</span><span class="op">,</span> <span class="dv">6</span><span class="op">)</span> <span class="op">|</span> V<span class="op">::</span>transform<span class="op">([](</span><span class="dt">int</span> x<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> x <span class="op">*</span> <span class="dv">2</span><span class="op">;</span> <span class="op">})</span> <span class="op">|</span> V<span class="op">::</span>reverse <span class="op">|</span> V<span class="op">::</span>take<span class="op">(</span><span class="dv">3</span><span class="op">))</span></span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a>        <span class="bu">std::</span>cout <span class="op">&lt;&lt;</span> x <span class="op">&lt;&lt;</span> <span class="ch">&#39;</span><span class="sc">\n</span><span class="ch">&#39;</span><span class="op">;</span></span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Here the intent is pretty clear. You take integers in <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false" form="prefix">[</mo><mn>1</mn><mo>,</mo><mn>6</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">[1, 6)</annotation></semantics></math>, multiply them by 2, reverse them, and take the first 3. Now in this resulting range of numbers, you print each of them.</p>
<p>So let's see what happens here. The <code>|</code> operator is defined for ranges and an operation on ranges that returns a range. For example, <code>V::transform(range, lambda)</code> gives a range where every element is transformed, and doing <code>range | V::transform(lambda)</code> does the same thing. In fact, for a lot of cases, this isn't stored in memory at all (and operations are done while iterating on the fly), unless you have things like reversing a range.</p>
<p>One thing that you can finally do is split a string with delimiters in a nice way (which used to be a major point of ridicule directed towards C++ from a lot of Python users). This is as simple as using a <code>split</code> view in the ranges library. For more information, see <a href="https://en.cppreference.com/w/cpp/ranges/split_view">this</a>. Here's an example taken verbatim from the cppreference page:</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;iomanip&gt;</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;iostream&gt;</span></span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;ranges&gt;</span></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;string_view&gt;</span></span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> main<span class="op">()</span> <span class="op">{</span></span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> <span class="bu">std::</span>string_view words<span class="op">{</span><span class="st">&quot;Hello^_^C++^_^20^_^!&quot;</span><span class="op">};</span></span>
<span id="cb16-8"><a href="#cb16-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constexpr</span> <span class="bu">std::</span>string_view delim<span class="op">{</span><span class="st">&quot;^_^&quot;</span><span class="op">};</span></span>
<span id="cb16-9"><a href="#cb16-9" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> <span class="op">(</span><span class="at">const</span> <span class="kw">auto</span> word <span class="op">:</span> <span class="bu">std::</span>views::split<span class="op">(</span>words<span class="op">,</span> delim<span class="op">))</span></span>
<span id="cb16-10"><a href="#cb16-10" aria-hidden="true" tabindex="-1"></a>        <span class="bu">std::</span>cout <span class="op">&lt;&lt;</span> <span class="bu">std::</span>quoted<span class="op">(</span><span class="bu">std::</span>string_view<span class="op">{</span>word<span class="op">.</span>begin<span class="op">(),</span> word<span class="op">.</span>end<span class="op">()})</span> <span class="op">&lt;&lt;</span> <span class="ch">&#39; &#39;</span><span class="op">;</span></span>
<span id="cb16-11"><a href="#cb16-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>A more common example can be like this:</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#include </span><span class="im">&lt;bits/stdc++.h&gt;</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a><span class="kw">namespace</span> R <span class="op">=</span> <span class="bu">std::</span>ranges<span class="op">;</span></span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a><span class="kw">namespace</span> V <span class="op">=</span> <span class="bu">std::</span>ranges::views<span class="op">;</span></span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-6"><a href="#cb17-6" aria-hidden="true" tabindex="-1"></a><span class="dt">int</span> main<span class="op">()</span> <span class="op">{</span></span>
<span id="cb17-7"><a href="#cb17-7" aria-hidden="true" tabindex="-1"></a>    <span class="bu">std::</span>cin<span class="op">.</span>tie<span class="op">(</span><span class="kw">nullptr</span><span class="op">)-&gt;</span>sync_with_stdio<span class="op">(</span><span class="kw">false</span><span class="op">);</span></span>
<span id="cb17-8"><a href="#cb17-8" aria-hidden="true" tabindex="-1"></a>    <span class="bu">std::</span>string s<span class="op">(</span><span class="dv">1000000</span><span class="op">,</span> <span class="ch">&#39;0&#39;</span><span class="op">);</span></span>
<span id="cb17-9"><a href="#cb17-9" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> <span class="op">(</span><span class="dt">int</span> i <span class="op">=</span> <span class="dv">0</span><span class="op">;</span> i <span class="op">&lt;</span> <span class="dv">1000000</span> <span class="op">/</span> <span class="dv">2</span><span class="op">;</span> <span class="op">++</span>i<span class="op">)</span> s<span class="op">[</span>i <span class="op">*</span> <span class="dv">2</span><span class="op">]</span> <span class="op">=</span> <span class="ch">&#39;1&#39;</span><span class="op">;</span></span>
<span id="cb17-10"><a href="#cb17-10" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> <span class="op">(</span><span class="at">const</span> <span class="kw">auto</span> word <span class="op">:</span> V<span class="op">::</span>split<span class="op">(</span>s<span class="op">,</span> <span class="ch">&#39;1&#39;</span><span class="op">))</span></span>
<span id="cb17-11"><a href="#cb17-11" aria-hidden="true" tabindex="-1"></a>        <span class="bu">std::</span>cout <span class="op">&lt;&lt;</span> <span class="bu">std::</span>string_view<span class="op">{</span>begin<span class="op">(</span>word<span class="op">),</span> end<span class="op">(</span>word<span class="op">)}</span> <span class="op">&lt;&lt;</span> <span class="ch">&#39; &#39;</span><span class="op">;</span></span>
<span id="cb17-12"><a href="#cb17-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Some ranges functionality is as follows:</p>
<ul>
<li>converting to and from a range: conversion to a range is implicit for most STL containers. If <code>r</code> is a range, then for most STL containers, like <code>std::vector</code>, you can do something like <code>std::vector&lt;int&gt; a(r.begin(), r.end())</code>. C++23 has a feature <code>R::to&lt;ContainerType&gt;(range)</code> that will construct a container out of a range, and you could even do <code>range | R::to&lt;ContainerType&gt;()</code>.</li>
<li>iota: This works similarly to Python's <code>range()</code> but without the stride.</li>
<li>reverse: This works similarly to Python's <code>reversed()</code></li>
<li>take: This takes the first <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>n</mi><annotation encoding="application/x-tex">n</annotation></semantics></math> elements of a range (unless you run out of elements by then)</li>
<li>drop: This takes everything but the first <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>n</mi><annotation encoding="application/x-tex">n</annotation></semantics></math> elements of a range (unless you run out of elements by then)</li>
<li>counted: This takes <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>n</mi><annotation encoding="application/x-tex">n</annotation></semantics></math> elements of a range starting from an iterator.</li>
<li>keys, values: <code>keys</code> takes a range whose elements are pair-like and returns a range of their first elements (so if we have (key, value) pairs, it will return keys), similar to <code>.keys()</code> in Python. Similarly, <code>values</code> returns a range of the values.</li>
<li>elements: if we have a range of tuple-like elements, this takes the <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>n</mi><annotation encoding="application/x-tex">n</annotation></semantics></math>-th members of each of these tuples (where <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>N</mi><annotation encoding="application/x-tex">N</annotation></semantics></math> is a compile-time constant).</li>
<li>all: though type conversions from containers to ranges are usually implicit, it takes a container and takes everything in that container.</li>
<li>Some upcoming C++23 features that will make it even more convenient to use ranges: to, zip, slide, stride, repeat, adjacent, pairwise, cartesian_product.</li>
</ul>
<p>Note that this is not the only thing you can do with ranges. In fact, with almost all possible algorithms that you can find in the algorithms library that use a begin and an end iterator (like <code>std::sort</code> or <code>std::partial_sum</code> or <code>std::all_of</code>), you can find a ranges version <a href="https://en.cppreference.com/w/cpp/algorithm/ranges">here</a>, where you can just pass the range/container name instead of the begin and end iterators you usually pass.</p>
<p>By the way, if you don't want to wait for C++23, you can use some of the functionality from this code, which I used to use a couple of years ago when C++20 was not a thing.</p>
<details>
<summary>Spoiler</summary>
<div class="sourceCode" id="cb18"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> iterable<span class="op">;</span></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> iterable<span class="op">&lt;</span>T<span class="op">&amp;&gt;</span> <span class="op">{</span></span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> type <span class="op">=</span> T<span class="op">&amp;;</span></span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb18-8"><a href="#cb18-8" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> iterable<span class="op">&lt;</span>T<span class="op">&amp;&amp;&gt;</span> <span class="op">{</span></span>
<span id="cb18-9"><a href="#cb18-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> type <span class="op">=</span> T<span class="op">;</span></span>
<span id="cb18-10"><a href="#cb18-10" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb18-11"><a href="#cb18-11" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">,</span> <span class="bu">std::</span>size_t N<span class="op">&gt;</span></span>
<span id="cb18-12"><a href="#cb18-12" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> iterable<span class="op">&lt;</span>T <span class="op">(&amp;&amp;)[</span>N<span class="op">]&gt;</span> <span class="op">{</span></span>
<span id="cb18-13"><a href="#cb18-13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> type <span class="op">=</span> <span class="kw">typename</span> T<span class="op">::</span>unsupported<span class="op">;</span></span>
<span id="cb18-14"><a href="#cb18-14" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb18-15"><a href="#cb18-15" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb18-16"><a href="#cb18-16" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> iterator_from_iterable <span class="op">{</span></span>
<span id="cb18-17"><a href="#cb18-17" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> iterable <span class="op">=</span> <span class="kw">typename</span> <span class="bu">std::</span>remove_reference<span class="op">&lt;</span>T<span class="op">&gt;::</span>type<span class="op">&amp;;</span></span>
<span id="cb18-18"><a href="#cb18-18" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> type <span class="op">=</span> <span class="kw">decltype</span><span class="op">(</span><span class="bu">std::</span>begin<span class="op">(</span><span class="bu">std::</span>declval<span class="op">&lt;</span>iterable<span class="op">&gt;()));</span></span>
<span id="cb18-19"><a href="#cb18-19" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb18-20"><a href="#cb18-20" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb18-21"><a href="#cb18-21" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> iterable_traits <span class="op">{</span></span>
<span id="cb18-22"><a href="#cb18-22" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> raw_iterable <span class="op">=</span> T<span class="op">;</span></span>
<span id="cb18-23"><a href="#cb18-23" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> raw_iterator <span class="op">=</span> <span class="kw">typename</span> iterator_from_iterable<span class="op">&lt;</span>raw_iterable<span class="op">&gt;::</span>type<span class="op">;</span></span>
<span id="cb18-24"><a href="#cb18-24" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> wrapped_iterable <span class="op">=</span> <span class="kw">typename</span> iterable<span class="op">&lt;</span>T<span class="op">&gt;::</span>type<span class="op">;</span></span>
<span id="cb18-25"><a href="#cb18-25" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> <span class="dt">deref_value_type</span> <span class="op">=</span> <span class="kw">decltype</span><span class="op">(*</span><span class="bu">std::</span>declval<span class="op">&lt;</span>raw_iterator<span class="op">&gt;());</span></span>
<span id="cb18-26"><a href="#cb18-26" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb18-27"><a href="#cb18-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-28"><a href="#cb18-28" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb18-29"><a href="#cb18-29" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> Range <span class="op">{</span></span>
<span id="cb18-30"><a href="#cb18-30" aria-hidden="true" tabindex="-1"></a>   <span class="kw">private</span><span class="op">:</span></span>
<span id="cb18-31"><a href="#cb18-31" aria-hidden="true" tabindex="-1"></a>    <span class="at">const</span> T l<span class="op">,</span> r<span class="op">,</span> skip<span class="op">;</span></span>
<span id="cb18-32"><a href="#cb18-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-33"><a href="#cb18-33" aria-hidden="true" tabindex="-1"></a>   <span class="kw">public</span><span class="op">:</span></span>
<span id="cb18-34"><a href="#cb18-34" aria-hidden="true" tabindex="-1"></a>    <span class="kw">struct</span> It <span class="op">:</span> <span class="kw">public</span> <span class="bu">std::</span>iterator<span class="op">&lt;</span><span class="bu">std::</span>forward_iterator_tag<span class="op">,</span> T<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb18-35"><a href="#cb18-35" aria-hidden="true" tabindex="-1"></a>        T i<span class="op">;</span></span>
<span id="cb18-36"><a href="#cb18-36" aria-hidden="true" tabindex="-1"></a>        <span class="at">const</span> T skip<span class="op">;</span></span>
<span id="cb18-37"><a href="#cb18-37" aria-hidden="true" tabindex="-1"></a>        <span class="kw">explicit</span> It<span class="op">(</span>T _i<span class="op">,</span> T _skip<span class="op">)</span> <span class="op">:</span> i<span class="op">(</span>_i<span class="op">),</span> skip<span class="op">(</span>_skip<span class="op">)</span> <span class="op">{}</span></span>
<span id="cb18-38"><a href="#cb18-38" aria-hidden="true" tabindex="-1"></a>        It<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">++()</span> <span class="op">{</span> <span class="cf">return</span> i <span class="op">+=</span> skip<span class="op">,</span> <span class="op">*</span><span class="kw">this</span><span class="op">;</span> <span class="op">}</span></span>
<span id="cb18-39"><a href="#cb18-39" aria-hidden="true" tabindex="-1"></a>        <span class="at">const</span> It<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">++(</span><span class="dt">int</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb18-40"><a href="#cb18-40" aria-hidden="true" tabindex="-1"></a>            <span class="kw">auto</span> temp <span class="op">=</span> <span class="op">*</span><span class="kw">this</span><span class="op">;</span></span>
<span id="cb18-41"><a href="#cb18-41" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> <span class="kw">operator</span><span class="op">++(),</span> temp<span class="op">;</span></span>
<span id="cb18-42"><a href="#cb18-42" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb18-43"><a href="#cb18-43" aria-hidden="true" tabindex="-1"></a>        T <span class="kw">operator</span><span class="op">*()</span> <span class="at">const</span> <span class="op">{</span> <span class="cf">return</span> i<span class="op">;</span> <span class="op">}</span></span>
<span id="cb18-44"><a href="#cb18-44" aria-hidden="true" tabindex="-1"></a>        <span class="dt">bool</span> <span class="kw">operator</span><span class="op">!=(</span><span class="at">const</span> It<span class="op">&amp;</span> it<span class="op">)</span> <span class="at">const</span> <span class="op">{</span> <span class="cf">return</span> <span class="op">(</span>skip <span class="op">&gt;=</span> <span class="dv">0</span><span class="op">)</span> <span class="op">?</span> <span class="op">(</span>i <span class="op">&lt;</span> <span class="op">*</span>it<span class="op">)</span> <span class="op">:</span> <span class="op">(</span>i <span class="op">&gt;</span> <span class="op">*</span>it<span class="op">);</span> <span class="op">}</span></span>
<span id="cb18-45"><a href="#cb18-45" aria-hidden="true" tabindex="-1"></a>        <span class="dt">bool</span> <span class="kw">operator</span><span class="op">==(</span><span class="at">const</span> It<span class="op">&amp;</span> it<span class="op">)</span> <span class="at">const</span> <span class="op">{</span> <span class="cf">return</span> <span class="op">(</span>skip <span class="op">&gt;=</span> <span class="dv">0</span><span class="op">)</span> <span class="op">?</span> <span class="op">(</span>i <span class="op">&gt;=</span> <span class="op">*</span>it<span class="op">)</span> <span class="op">:</span> <span class="op">(</span>i <span class="op">&lt;=</span> <span class="op">*</span>it<span class="op">);</span> <span class="op">}</span></span>
<span id="cb18-46"><a href="#cb18-46" aria-hidden="true" tabindex="-1"></a>    <span class="op">};</span></span>
<span id="cb18-47"><a href="#cb18-47" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> iterator <span class="op">=</span> It<span class="op">;</span></span>
<span id="cb18-48"><a href="#cb18-48" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> <span class="dt">value_type</span> <span class="op">=</span> T<span class="op">;</span></span>
<span id="cb18-49"><a href="#cb18-49" aria-hidden="true" tabindex="-1"></a>    Range<span class="op">(</span>T _l<span class="op">,</span> T _r<span class="op">,</span> T _skip <span class="op">=</span> <span class="dv">1</span><span class="op">)</span> <span class="op">:</span> l<span class="op">(</span>_l<span class="op">),</span> r<span class="op">(</span>_r<span class="op">),</span> skip<span class="op">(</span>_skip<span class="op">)</span> <span class="op">{</span></span>
<span id="cb18-50"><a href="#cb18-50" aria-hidden="true" tabindex="-1"></a><span class="pp">#ifdef DEBUG</span></span>
<span id="cb18-51"><a href="#cb18-51" aria-hidden="true" tabindex="-1"></a>        <span class="ot">assert</span><span class="op">(</span>skip <span class="op">!=</span> <span class="dv">0</span><span class="op">);</span></span>
<span id="cb18-52"><a href="#cb18-52" aria-hidden="true" tabindex="-1"></a><span class="pp">#endif</span></span>
<span id="cb18-53"><a href="#cb18-53" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb18-54"><a href="#cb18-54" aria-hidden="true" tabindex="-1"></a>    Range<span class="op">(</span>T n<span class="op">)</span> <span class="op">:</span> Range<span class="op">(</span>T<span class="op">(</span><span class="dv">0</span><span class="op">),</span> n<span class="op">,</span> T<span class="op">(</span><span class="dv">1</span><span class="op">))</span> <span class="op">{}</span></span>
<span id="cb18-55"><a href="#cb18-55" aria-hidden="true" tabindex="-1"></a>    It begin<span class="op">()</span> <span class="at">const</span> <span class="op">{</span></span>
<span id="cb18-56"><a href="#cb18-56" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> It<span class="op">(</span>l<span class="op">,</span> skip<span class="op">);</span></span>
<span id="cb18-57"><a href="#cb18-57" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb18-58"><a href="#cb18-58" aria-hidden="true" tabindex="-1"></a>    It end<span class="op">()</span> <span class="at">const</span> <span class="op">{</span></span>
<span id="cb18-59"><a href="#cb18-59" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> It<span class="op">(</span>r<span class="op">,</span> skip<span class="op">);</span></span>
<span id="cb18-60"><a href="#cb18-60" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb18-61"><a href="#cb18-61" aria-hidden="true" tabindex="-1"></a>    It begin<span class="op">()</span> <span class="op">{</span></span>
<span id="cb18-62"><a href="#cb18-62" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> It<span class="op">(</span>l<span class="op">,</span> skip<span class="op">);</span></span>
<span id="cb18-63"><a href="#cb18-63" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb18-64"><a href="#cb18-64" aria-hidden="true" tabindex="-1"></a>    It end<span class="op">()</span> <span class="op">{</span></span>
<span id="cb18-65"><a href="#cb18-65" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> It<span class="op">(</span>r<span class="op">,</span> skip<span class="op">);</span></span>
<span id="cb18-66"><a href="#cb18-66" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb18-67"><a href="#cb18-67" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb18-68"><a href="#cb18-68" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-69"><a href="#cb18-69" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span><span class="op">...</span> T<span class="op">&gt;</span></span>
<span id="cb18-70"><a href="#cb18-70" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> zip <span class="op">{</span></span>
<span id="cb18-71"><a href="#cb18-71" aria-hidden="true" tabindex="-1"></a>   <span class="kw">public</span><span class="op">:</span></span>
<span id="cb18-72"><a href="#cb18-72" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> <span class="dt">value_type</span> <span class="op">=</span> <span class="bu">std::</span>tuple<span class="op">&lt;</span><span class="kw">typename</span> iterable_traits<span class="op">&lt;</span>T<span class="op">&gt;::</span><span class="dt">deref_value_type</span><span class="op">...&gt;;</span></span>
<span id="cb18-73"><a href="#cb18-73" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> wrapped_iterables <span class="op">=</span> <span class="bu">std::</span>tuple<span class="op">&lt;</span><span class="kw">typename</span> iterable_traits<span class="op">&lt;</span>T<span class="op">&gt;::</span>wrapped_iterable<span class="op">...&gt;;</span></span>
<span id="cb18-74"><a href="#cb18-74" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> raw_iterators <span class="op">=</span> <span class="bu">std::</span>tuple<span class="op">&lt;</span><span class="kw">typename</span> iterable_traits<span class="op">&lt;</span>T<span class="op">&gt;::</span>raw_iterator<span class="op">...&gt;;</span></span>
<span id="cb18-75"><a href="#cb18-75" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> sequence <span class="op">=</span> <span class="bu">std::</span>index_sequence_for<span class="op">&lt;</span>T<span class="op">...&gt;;</span></span>
<span id="cb18-76"><a href="#cb18-76" aria-hidden="true" tabindex="-1"></a>    <span class="kw">struct</span> It <span class="op">:</span> <span class="kw">public</span> <span class="bu">std::</span>iterator<span class="op">&lt;</span><span class="bu">std::</span>forward_iterator_tag<span class="op">,</span> <span class="dt">value_type</span><span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb18-77"><a href="#cb18-77" aria-hidden="true" tabindex="-1"></a>       <span class="kw">public</span><span class="op">:</span></span>
<span id="cb18-78"><a href="#cb18-78" aria-hidden="true" tabindex="-1"></a>        <span class="kw">explicit</span> It<span class="op">(</span>raw_iterators iterators<span class="op">)</span> <span class="op">:</span> <span class="va">iterators_</span><span class="op">(</span><span class="bu">std::</span>move<span class="op">(</span>iterators<span class="op">))</span> <span class="op">{}</span></span>
<span id="cb18-79"><a href="#cb18-79" aria-hidden="true" tabindex="-1"></a>        <span class="dt">bool</span> <span class="kw">operator</span><span class="op">==(</span><span class="at">const</span> It<span class="op">&amp;</span> it<span class="op">)</span> <span class="at">const</span> <span class="op">{</span> <span class="cf">return</span> any_eq<span class="op">(</span>it<span class="op">,</span> sequence<span class="op">());</span> <span class="op">}</span></span>
<span id="cb18-80"><a href="#cb18-80" aria-hidden="true" tabindex="-1"></a>        <span class="dt">bool</span> <span class="kw">operator</span><span class="op">!=(</span><span class="at">const</span> It<span class="op">&amp;</span> it<span class="op">)</span> <span class="at">const</span> <span class="op">{</span> <span class="cf">return</span> <span class="op">!</span>any_eq<span class="op">(</span>it<span class="op">,</span> sequence<span class="op">());</span> <span class="op">}</span></span>
<span id="cb18-81"><a href="#cb18-81" aria-hidden="true" tabindex="-1"></a>        <span class="dt">value_type</span> <span class="kw">operator</span><span class="op">*()</span> <span class="at">const</span> <span class="op">{</span> <span class="cf">return</span> deref<span class="op">(</span>sequence<span class="op">());</span> <span class="op">}</span></span>
<span id="cb18-82"><a href="#cb18-82" aria-hidden="true" tabindex="-1"></a>        It<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">++()</span> <span class="op">{</span> <span class="cf">return</span> inc<span class="op">(</span>sequence<span class="op">()),</span> <span class="op">*</span><span class="kw">this</span><span class="op">;</span> <span class="op">}</span></span>
<span id="cb18-83"><a href="#cb18-83" aria-hidden="true" tabindex="-1"></a>        <span class="at">const</span> It<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">++(</span><span class="dt">int</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb18-84"><a href="#cb18-84" aria-hidden="true" tabindex="-1"></a>            <span class="kw">auto</span> temp <span class="op">=</span> <span class="op">*</span><span class="kw">this</span><span class="op">;</span></span>
<span id="cb18-85"><a href="#cb18-85" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> <span class="kw">operator</span><span class="op">++(),</span> temp<span class="op">;</span></span>
<span id="cb18-86"><a href="#cb18-86" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb18-87"><a href="#cb18-87" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-88"><a href="#cb18-88" aria-hidden="true" tabindex="-1"></a>       <span class="kw">private</span><span class="op">:</span></span>
<span id="cb18-89"><a href="#cb18-89" aria-hidden="true" tabindex="-1"></a>        raw_iterators <span class="va">iterators_</span><span class="op">;</span></span>
<span id="cb18-90"><a href="#cb18-90" aria-hidden="true" tabindex="-1"></a>        <span class="kw">template</span> <span class="op">&lt;</span><span class="bu">std::</span>size_t<span class="op">...</span> I<span class="op">&gt;</span></span>
<span id="cb18-91"><a href="#cb18-91" aria-hidden="true" tabindex="-1"></a>        <span class="dt">bool</span> any_eq<span class="op">(</span><span class="at">const</span> It<span class="op">&amp;</span> it<span class="op">,</span> <span class="bu">std::</span>index_sequence<span class="op">&lt;</span>I<span class="op">...&gt;)</span> <span class="at">const</span> <span class="op">{</span></span>
<span id="cb18-92"><a href="#cb18-92" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> <span class="op">(...</span> <span class="op">||</span> <span class="op">(</span><span class="bu">std::</span>get<span class="op">&lt;</span>I<span class="op">&gt;(</span><span class="va">iterators_</span><span class="op">)</span> <span class="op">==</span> <span class="bu">std::</span>get<span class="op">&lt;</span>I<span class="op">&gt;(</span>it<span class="op">.</span><span class="va">iterators_</span><span class="op">)));</span></span>
<span id="cb18-93"><a href="#cb18-93" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb18-94"><a href="#cb18-94" aria-hidden="true" tabindex="-1"></a>        <span class="kw">template</span> <span class="op">&lt;</span><span class="bu">std::</span>size_t<span class="op">...</span> I<span class="op">&gt;</span></span>
<span id="cb18-95"><a href="#cb18-95" aria-hidden="true" tabindex="-1"></a>        <span class="dt">value_type</span> deref<span class="op">(</span><span class="bu">std::</span>index_sequence<span class="op">&lt;</span>I<span class="op">...&gt;)</span> <span class="at">const</span> <span class="op">{</span></span>
<span id="cb18-96"><a href="#cb18-96" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> <span class="op">{(*</span><span class="bu">std::</span>get<span class="op">&lt;</span>I<span class="op">&gt;(</span><span class="va">iterators_</span><span class="op">))...};</span></span>
<span id="cb18-97"><a href="#cb18-97" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb18-98"><a href="#cb18-98" aria-hidden="true" tabindex="-1"></a>        <span class="kw">template</span> <span class="op">&lt;</span><span class="bu">std::</span>size_t<span class="op">...</span> I<span class="op">&gt;</span></span>
<span id="cb18-99"><a href="#cb18-99" aria-hidden="true" tabindex="-1"></a>        <span class="dt">void</span> inc<span class="op">(</span><span class="bu">std::</span>index_sequence<span class="op">&lt;</span>I<span class="op">...&gt;)</span> <span class="op">{</span></span>
<span id="cb18-100"><a href="#cb18-100" aria-hidden="true" tabindex="-1"></a>            <span class="op">(++</span><span class="bu">std::</span>get<span class="op">&lt;</span>I<span class="op">&gt;(</span><span class="va">iterators_</span><span class="op">),</span> <span class="op">...);</span></span>
<span id="cb18-101"><a href="#cb18-101" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb18-102"><a href="#cb18-102" aria-hidden="true" tabindex="-1"></a>    <span class="op">};</span></span>
<span id="cb18-103"><a href="#cb18-103" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> iterator <span class="op">=</span> It<span class="op">;</span></span>
<span id="cb18-104"><a href="#cb18-104" aria-hidden="true" tabindex="-1"></a>    <span class="kw">explicit</span> zip<span class="op">(</span>T<span class="op">&amp;&amp;...</span> iterables<span class="op">)</span> <span class="op">:</span> <span class="va">iterables_</span><span class="op">(</span><span class="bu">std::</span>forward<span class="op">&lt;</span>T<span class="op">&gt;(</span>iterables<span class="op">)...)</span> <span class="op">{}</span></span>
<span id="cb18-105"><a href="#cb18-105" aria-hidden="true" tabindex="-1"></a>    It begin<span class="op">()</span> <span class="op">{</span> <span class="cf">return</span> <span class="va">begin_</span><span class="op">(</span>sequence<span class="op">());</span> <span class="op">}</span></span>
<span id="cb18-106"><a href="#cb18-106" aria-hidden="true" tabindex="-1"></a>    It end<span class="op">()</span> <span class="op">{</span> <span class="cf">return</span> <span class="va">end_</span><span class="op">(</span>sequence<span class="op">());</span> <span class="op">}</span></span>
<span id="cb18-107"><a href="#cb18-107" aria-hidden="true" tabindex="-1"></a>    It begin<span class="op">()</span> <span class="at">const</span> <span class="op">{</span> <span class="cf">return</span> <span class="va">begin_</span><span class="op">(</span>sequence<span class="op">());</span> <span class="op">}</span></span>
<span id="cb18-108"><a href="#cb18-108" aria-hidden="true" tabindex="-1"></a>    It end<span class="op">()</span> <span class="at">const</span> <span class="op">{</span> <span class="cf">return</span> <span class="va">end_</span><span class="op">(</span>sequence<span class="op">());</span> <span class="op">}</span></span>
<span id="cb18-109"><a href="#cb18-109" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-110"><a href="#cb18-110" aria-hidden="true" tabindex="-1"></a>   <span class="kw">private</span><span class="op">:</span></span>
<span id="cb18-111"><a href="#cb18-111" aria-hidden="true" tabindex="-1"></a>    wrapped_iterables <span class="va">iterables_</span><span class="op">;</span></span>
<span id="cb18-112"><a href="#cb18-112" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="bu">std::</span>size_t<span class="op">...</span> Int<span class="op">&gt;</span></span>
<span id="cb18-113"><a href="#cb18-113" aria-hidden="true" tabindex="-1"></a>    iterator <span class="va">begin_</span><span class="op">(</span><span class="bu">std::</span>index_sequence<span class="op">&lt;</span>Int<span class="op">...&gt;)</span> <span class="op">{</span></span>
<span id="cb18-114"><a href="#cb18-114" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> iterator<span class="op">(</span><span class="bu">std::</span>tuple<span class="op">(</span><span class="bu">std::</span>begin<span class="op">(</span><span class="bu">std::</span>get<span class="op">&lt;</span>Int<span class="op">&gt;(</span><span class="va">iterables_</span><span class="op">))...));</span></span>
<span id="cb18-115"><a href="#cb18-115" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb18-116"><a href="#cb18-116" aria-hidden="true" tabindex="-1"></a>    <span class="kw">template</span> <span class="op">&lt;</span><span class="bu">std::</span>size_t<span class="op">...</span> Int<span class="op">&gt;</span></span>
<span id="cb18-117"><a href="#cb18-117" aria-hidden="true" tabindex="-1"></a>    iterator <span class="va">end_</span><span class="op">(</span><span class="bu">std::</span>index_sequence<span class="op">&lt;</span>Int<span class="op">...&gt;)</span> <span class="op">{</span></span>
<span id="cb18-118"><a href="#cb18-118" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> iterator<span class="op">(</span><span class="bu">std::</span>tuple<span class="op">(</span><span class="bu">std::</span>end<span class="op">(</span><span class="bu">std::</span>get<span class="op">&lt;</span>Int<span class="op">&gt;(</span><span class="va">iterables_</span><span class="op">))...));</span></span>
<span id="cb18-119"><a href="#cb18-119" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb18-120"><a href="#cb18-120" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb18-121"><a href="#cb18-121" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-122"><a href="#cb18-122" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span><span class="op">...</span> T<span class="op">&gt;</span></span>
<span id="cb18-123"><a href="#cb18-123" aria-hidden="true" tabindex="-1"></a>zip<span class="op">(</span>T<span class="op">&amp;&amp;...)</span> <span class="op">-&gt;</span> zip<span class="op">&lt;</span>T<span class="op">&amp;&amp;...&gt;;</span></span>
<span id="cb18-124"><a href="#cb18-124" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-125"><a href="#cb18-125" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb18-126"><a href="#cb18-126" aria-hidden="true" tabindex="-1"></a><span class="kw">struct</span> enumerate <span class="op">{</span></span>
<span id="cb18-127"><a href="#cb18-127" aria-hidden="true" tabindex="-1"></a>   <span class="kw">public</span><span class="op">:</span></span>
<span id="cb18-128"><a href="#cb18-128" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> <span class="dt">size_type</span> <span class="op">=</span> <span class="kw">typename</span> <span class="bu">std::</span>make_signed<span class="op">&lt;</span><span class="bu">std::</span>size_t<span class="op">&gt;::</span>type<span class="op">;</span></span>
<span id="cb18-129"><a href="#cb18-129" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> wrapped_iterable <span class="op">=</span> <span class="kw">typename</span> iterable_traits<span class="op">&lt;</span>T<span class="op">&gt;::</span>wrapped_iterable<span class="op">;</span></span>
<span id="cb18-130"><a href="#cb18-130" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> raw_iterator <span class="op">=</span> <span class="kw">typename</span> iterable_traits<span class="op">&lt;</span>T<span class="op">&gt;::</span>raw_iterator<span class="op">;</span></span>
<span id="cb18-131"><a href="#cb18-131" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> <span class="dt">value_type</span> <span class="op">=</span> <span class="bu">std::</span>pair<span class="op">&lt;</span><span class="dt">size_type</span><span class="op">,</span> <span class="kw">typename</span> iterable_traits<span class="op">&lt;</span>T<span class="op">&gt;::</span><span class="dt">deref_value_type</span><span class="op">&gt;;</span></span>
<span id="cb18-132"><a href="#cb18-132" aria-hidden="true" tabindex="-1"></a>    <span class="kw">struct</span> It <span class="op">:</span> <span class="kw">public</span> <span class="bu">std::</span>iterator<span class="op">&lt;</span><span class="bu">std::</span>forward_iterator_tag<span class="op">,</span> <span class="dt">value_type</span><span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb18-133"><a href="#cb18-133" aria-hidden="true" tabindex="-1"></a>        raw_iterator <span class="va">iter_</span><span class="op">;</span></span>
<span id="cb18-134"><a href="#cb18-134" aria-hidden="true" tabindex="-1"></a>        <span class="dt">size_type</span> <span class="va">start_</span><span class="op">;</span></span>
<span id="cb18-135"><a href="#cb18-135" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-136"><a href="#cb18-136" aria-hidden="true" tabindex="-1"></a>       <span class="kw">public</span><span class="op">:</span></span>
<span id="cb18-137"><a href="#cb18-137" aria-hidden="true" tabindex="-1"></a>        It<span class="op">(</span>raw_iterator it<span class="op">,</span> <span class="dt">size_type</span> start<span class="op">)</span> <span class="op">:</span> <span class="va">iter_</span><span class="op">(</span>it<span class="op">),</span> <span class="va">start_</span><span class="op">(</span>start<span class="op">)</span> <span class="op">{}</span></span>
<span id="cb18-138"><a href="#cb18-138" aria-hidden="true" tabindex="-1"></a>        <span class="dt">bool</span> <span class="kw">operator</span><span class="op">==(</span><span class="at">const</span> It<span class="op">&amp;</span> it<span class="op">)</span> <span class="at">const</span> <span class="op">{</span> <span class="cf">return</span> <span class="va">iter_</span> <span class="op">==</span> it<span class="op">.</span><span class="va">iter_</span><span class="op">;</span> <span class="op">}</span></span>
<span id="cb18-139"><a href="#cb18-139" aria-hidden="true" tabindex="-1"></a>        <span class="dt">bool</span> <span class="kw">operator</span><span class="op">!=(</span><span class="at">const</span> It<span class="op">&amp;</span> it<span class="op">)</span> <span class="at">const</span> <span class="op">{</span> <span class="cf">return</span> <span class="va">iter_</span> <span class="op">!=</span> it<span class="op">.</span><span class="va">iter_</span><span class="op">;</span> <span class="op">}</span></span>
<span id="cb18-140"><a href="#cb18-140" aria-hidden="true" tabindex="-1"></a>        It<span class="op">&amp;</span> <span class="kw">operator</span><span class="op">++()</span> <span class="op">{</span> <span class="cf">return</span> <span class="op">++</span><span class="va">iter_</span><span class="op">,</span> <span class="op">++</span><span class="va">start_</span><span class="op">,</span> <span class="op">*</span><span class="kw">this</span><span class="op">;</span> <span class="op">}</span></span>
<span id="cb18-141"><a href="#cb18-141" aria-hidden="true" tabindex="-1"></a>        <span class="at">const</span> It <span class="kw">operator</span><span class="op">++(</span><span class="dt">int</span><span class="op">)</span> <span class="op">{</span></span>
<span id="cb18-142"><a href="#cb18-142" aria-hidden="true" tabindex="-1"></a>            <span class="kw">auto</span> temp <span class="op">=</span> <span class="op">*</span><span class="kw">this</span><span class="op">;</span></span>
<span id="cb18-143"><a href="#cb18-143" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> <span class="kw">operator</span><span class="op">++(),</span> temp<span class="op">;</span></span>
<span id="cb18-144"><a href="#cb18-144" aria-hidden="true" tabindex="-1"></a>        <span class="op">}</span></span>
<span id="cb18-145"><a href="#cb18-145" aria-hidden="true" tabindex="-1"></a>        <span class="dt">value_type</span> <span class="kw">operator</span><span class="op">*()</span> <span class="at">const</span> <span class="op">{</span> <span class="cf">return</span> <span class="op">{</span><span class="va">start_</span><span class="op">,</span> <span class="op">*</span><span class="va">iter_</span><span class="op">};</span> <span class="op">}</span></span>
<span id="cb18-146"><a href="#cb18-146" aria-hidden="true" tabindex="-1"></a>    <span class="op">};</span></span>
<span id="cb18-147"><a href="#cb18-147" aria-hidden="true" tabindex="-1"></a>    <span class="kw">using</span> iterator <span class="op">=</span> It<span class="op">;</span></span>
<span id="cb18-148"><a href="#cb18-148" aria-hidden="true" tabindex="-1"></a>    <span class="kw">explicit</span> enumerate<span class="op">(</span>T<span class="op">&amp;&amp;</span> iterable<span class="op">,</span> <span class="dt">size_type</span> start <span class="op">=</span> <span class="dv">0</span><span class="op">)</span> <span class="op">:</span> <span class="va">iterable_</span><span class="op">(</span><span class="bu">std::</span>forward<span class="op">&lt;</span>T<span class="op">&gt;(</span>iterable<span class="op">)),</span> <span class="va">start_</span><span class="op">(</span>start<span class="op">)</span> <span class="op">{}</span></span>
<span id="cb18-149"><a href="#cb18-149" aria-hidden="true" tabindex="-1"></a>    It begin<span class="op">()</span> <span class="op">{</span> <span class="cf">return</span> It<span class="op">(</span><span class="bu">std::</span>begin<span class="op">(</span><span class="va">iterable_</span><span class="op">),</span> <span class="va">start_</span><span class="op">);</span> <span class="op">}</span></span>
<span id="cb18-150"><a href="#cb18-150" aria-hidden="true" tabindex="-1"></a>    It end<span class="op">()</span> <span class="op">{</span> <span class="cf">return</span> It<span class="op">(</span><span class="bu">std::</span>end<span class="op">(</span><span class="va">iterable_</span><span class="op">),</span> <span class="dv">0</span><span class="op">);</span> <span class="op">}</span></span>
<span id="cb18-151"><a href="#cb18-151" aria-hidden="true" tabindex="-1"></a>    It begin<span class="op">()</span> <span class="at">const</span> <span class="op">{</span> <span class="cf">return</span> It<span class="op">(</span><span class="bu">std::</span>begin<span class="op">(</span><span class="va">iterable_</span><span class="op">),</span> <span class="va">start_</span><span class="op">);</span> <span class="op">}</span></span>
<span id="cb18-152"><a href="#cb18-152" aria-hidden="true" tabindex="-1"></a>    It end<span class="op">()</span> <span class="at">const</span> <span class="op">{</span> <span class="cf">return</span> It<span class="op">(</span><span class="bu">std::</span>end<span class="op">(</span><span class="va">iterable_</span><span class="op">),</span> <span class="dv">0</span><span class="op">);</span> <span class="op">}</span></span>
<span id="cb18-153"><a href="#cb18-153" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-154"><a href="#cb18-154" aria-hidden="true" tabindex="-1"></a>   <span class="kw">private</span><span class="op">:</span></span>
<span id="cb18-155"><a href="#cb18-155" aria-hidden="true" tabindex="-1"></a>    wrapped_iterable <span class="va">iterable_</span><span class="op">;</span></span>
<span id="cb18-156"><a href="#cb18-156" aria-hidden="true" tabindex="-1"></a>    <span class="dt">size_type</span> <span class="va">start_</span><span class="op">;</span></span>
<span id="cb18-157"><a href="#cb18-157" aria-hidden="true" tabindex="-1"></a><span class="op">};</span></span>
<span id="cb18-158"><a href="#cb18-158" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-159"><a href="#cb18-159" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">&gt;</span></span>
<span id="cb18-160"><a href="#cb18-160" aria-hidden="true" tabindex="-1"></a>enumerate<span class="op">(</span>T<span class="op">&amp;&amp;)</span> <span class="op">-&gt;</span> enumerate<span class="op">&lt;</span>T<span class="op">&amp;&amp;&gt;;</span></span>
<span id="cb18-161"><a href="#cb18-161" aria-hidden="true" tabindex="-1"></a><span class="kw">template</span> <span class="op">&lt;</span><span class="kw">typename</span> T<span class="op">,</span> <span class="kw">typename</span> Index<span class="op">&gt;</span></span>
<span id="cb18-162"><a href="#cb18-162" aria-hidden="true" tabindex="-1"></a>enumerate<span class="op">(</span>T<span class="op">&amp;&amp;,</span> Index<span class="op">)</span> <span class="op">-&gt;</span> enumerate<span class="op">&lt;</span>T<span class="op">&amp;&amp;&gt;;</span></span></code></pre></div>
</details>
<p>Finally, I'd like to thank <a href="https://codeforces.com/profile/ToxicPie9">ToxicPie9</a>, <a href="https://codeforces.com/profile/meooow">meooow</a> and <a href="https://codeforces.com/profile/magnus.hegdahl">magnus.hegdahl</a> for discussing certain contents of this post, and other members of the AC server for giving their inputs too.</p>
<details>
<summary>Cite this post</summary>
<div class="sourceCode" id="cb19"><pre class="sourceCode bibtex"><code class="sourceCode bibtex"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="va">@online</span>{<span class="ot">cpp</span>-<span class="ot">like</span>-<span class="ot">python</span>-<span class="ot">2023</span>,</span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">author</span>    = {nor},</span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">title</span>     = {Writing C++ like Python: tricks Python doesn&#39;t want you to know},</span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">year</span>      = {2023},</span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a>  <span class="dt">month</span>     = {01},</span>
<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">day</span>       = {11},</span>
<span id="cb19-7"><a href="#cb19-7" aria-hidden="true" tabindex="-1"></a>  <span class="dt">url</span>       = {https://nor-blog.pages.dev/posts/2023-01-11-cpp-like-python},</span>
<span id="cb19-8"><a href="#cb19-8" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
</details>]]></content:encoded>
</item>
</channel>
</rss>
