<?xml version="1.0" encoding="UTF-8"?>
<rss  xmlns:atom="http://www.w3.org/2005/Atom" 
      xmlns:media="http://search.yahoo.com/mrss/" 
      xmlns:content="http://purl.org/rss/1.0/modules/content/" 
      xmlns:dc="http://purl.org/dc/elements/1.1/" 
      version="2.0">
<channel>
<title>quantdev.blog</title>
<link>http://quantdev.blog/</link>
<atom:link href="http://quantdev.blog/index.xml" rel="self" type="application/rss+xml"/>
<description></description>
<generator>quarto-1.9.38</generator>
<lastBuildDate>Fri, 29 May 2026 23:00:00 GMT</lastBuildDate>
<item>
  <title>Linkers, Loaders and Shared Libraries</title>
  <dc:creator>`dev::author` </dc:creator>
  <link>http://quantdev.blog/posts/linkers-loaders-and-shared-libraries/</link>
  <description><![CDATA[ 





<section id="terminology" class="level1">
<h1>Terminology</h1>
<p>Let’s start by fixing some terminology.</p>
<ul>
<li><p>Shared Library. We use the cross-platform term <em>shared library</em> to refer to, what is otherwise known as shared objects, dynamic object, Dynamic Shared Object(DSO) or on Windows Dynamic Load Library(DLL).</p></li>
<li><p>Binary. An executable or a <em>shared library</em>.</p></li>
<li><p>Symbol. Function / global variables.</p></li>
<li><p>Linux. I will loosely use the term <em>linux</em> for all UNIX descendants.</p></li>
</ul>
</section>
<section id="nano-introduction-to-linking" class="level1">
<h1>Nano-introduction to Linking</h1>
<p>We start with source files. In the first phase, the compiler translates them into object files. An object file is nothing but a container for sections. Two canonical examples for sections are as <code>.text</code> which contains machine code and <code>.data</code> which contains program data.</p>
<p>In the second phase, the linker - the first thing it does is, it pulls together the identically named sections and concatenates them into one larger section. The second thing it does, is it reorders the sections. So, sections with similar required run-time permissions are adjacent on disk.</p>
<p>In the final stage, the loader takes these adjacent chunks called segments and maps them to memory on page-aligned boundaries. After this mapping, the loader adjusts the page permissions accordingly.</p>
<p>Now, code typically does lots of function calls. The simplest case is that of from the binary into itself. But, that is not the general case. In general, the process can map shared libraries into its address space and perform calls into functions which are implemented in the shared library. The shared library itself can perform calls into functions implemented in yet other shared libraries. Arguably, the most important job of both the linker and loader is to properly wire these calls. How would might a wiring look like?</p>
<p>Say, we have a <code>.code</code> section that calls the function <code>foo()</code>, which is implemented in another binary. The <code>.code</code> section itself does not contain the string <code>foo</code>, it contains a <code>call 0x0000</code> instruction into an address yet unknown at link time. So, the <code>.code</code> section contains a placeholder - a string of <code>0</code>s. In addition, the linker generates another section called <code>.reloc</code> for relocation. On Windows, these are sometimes called fixups. A <code>.reloc</code> section is essentially a small TODO item for the loader. The linker says, “<em>Dear loader, please find the function <code>foo</code>, when you do overwrite this placeholder with the address you found.</em>”. This relocation does happen in practice, but it is generally frowned upon, for two reasons. First, modifying the <code>.code</code> section makes the <code>.code</code> section unshareable between processes and second this form of relocation needs to be done once per call site, not once per function, which can amount to a large difference if you have tens of thousands of calls into the same function e.g.&nbsp;a game engine with calls to the math function <code>sqrt()</code>.</p>
<p>The more typical scheme is to route all calls to the same function through an indirect call into a single placeholder. In this scheme, when the loader reads the <code>.reloc</code> section, it knows it needs to overwrite just a single slot with the function <code>foo()</code>’s address and not all the call sites. This design trades a little bit of run-time performance for a lot of load-time savings. There is an entire section of such placeholders. On win64, it is called the IAT (Import Address Table). In Linux, this is a rough approximation for a section known as the GOT(Global Offset Table). Note already, that this design means that cross-binary calls are indirect. They carry the same overhead as virtual functions do. And this is not the full truth, it is just the first step in our journey towards it.</p>
<section id="windows-binary" class="level2">
<h2 class="anchored" data-anchor-id="windows-binary">Windows Binary</h2>
<p>Let us take a closer look at Windows first. A windows binary contains descriptions of all the imports it consumes in a section called <code>.idata</code> (the <code>i</code> stands for import). The most important data-structure in the <code>.idata</code> section is the directory table. The directory table is a table of entries - one per shared library. Such an entry contains the DLL name, an <strong>import lookup table</strong> (an offset) which contains imported symbol names for the loader’s usage, an offset into the import lookup table, which contains information about which symbols to locate within this library and an offset into an import address table (IAT), which tells the loader where to write the addresses of these located symbols once they are found.</p>
<p>Schematically, what Windows binary tells the world, tells the loader is, “<em>Dear loader, please load the library <code>lib1</code>, and from it, please locate the symbols <code>f1</code>, <code>f2</code> and <code>f3</code>. Then, load the library <code>lib2</code> and from it, please locate the symbols <code>g1</code>, <code>g2</code> and <code>g3</code>.</em>”.</p>
<pre><code>Windows Binary (.exe / .dll)
+------------------------------------------------------------------------------+
|  .idata section                                                              |
|  +--------------------------+                                                |
|  |     Directory table      |                                                |
|  |                          |                                                |
|  |  +--------------------+  |   ILT (symbol names)    IAT (addresses)        |
|  |  |  Entry: lib1.dll   |--+--&gt; +--------------+    +--------------+        |
|  |  |  name / ILT / IAT  |  |    |  f1          |    |  &lt;- addr(f1) |        |
|  |  +--------------------+  | +-&gt;|  f2          |    |  &lt;- addr(f2) |        |
|  |           |              | |  |  f3          |    |  &lt;- addr(f3) |        |
|  |           +--------------+-+  +--------------+    +--------------+        |
|  |                          |              ^                   ^             |
|  |  +--------------------+  |   ILT        |        IAT        |             |
|  |  |  Entry: lib2.dll   |--+--&gt; +--------------+    +--------------+        |
|  |  |  name / ILT / IAT  |  |    |  g1          |    |  &lt;- addr(g1) |        |
|  |  +--------------------+  | +-&gt;|  g2          |    |  &lt;- addr(g2) |        |
|  |           |              | |  |  g3          |    |  &lt;- addr(g3) |        |
|  |           +--------------+-+  +--------------+    +--------------+        |
|  +--------------------------+              |                   |             |
|                                            +---------+---------+             |
+------------------------------------------------------------------------------+</code></pre>
</section>
<section id="linux-import-sections" class="level2">
<h2 class="anchored" data-anchor-id="linux-import-sections">Linux import sections</h2>
<p>As we shall see, this is not what happens in Linux. A linux binary contains not one but two sections, encoding almost identical information to that of <code>idata</code> in Windows. A <code>.dynamic</code> section contains a raw list of library names and the <code>.dynsym</code> section contains the more famous symbol table. It contains not just the symbols to be imported, but all the symbols that this binary contains. The ones to be imported are marked in the binary as undefined <code>UND</code>.</p>
<section id="dynamic-section" class="level4">
<h4 class="anchored" data-anchor-id="dynamic-section"><code>.dynamic</code> section</h4>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb2-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">readelf</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-d</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$(</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">which</span> ls<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">grep</span> NEEDED</span>
<span id="cb2-2"> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">0x0000000000000001</span> <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">NEEDED</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span>             <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Shared</span> library: <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">[</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">libcap.so.2</span><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb2-3"> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">0x0000000000000001</span> <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">NEEDED</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span>             <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Shared</span> library: <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">[</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">libc.so.6</span><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">]</span></span></code></pre></div></div>
</section>
<section id="dynsym-section" class="level4">
<h4 class="anchored" data-anchor-id="dynsym-section"><code>.dynsym</code> section</h4>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb3-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">readelf</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-W</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--syms</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$(</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">which</span> ls<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-2"></span>
<span id="cb3-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Symbol</span> table .dynsym contains 132 entries:</span>
<span id="cb3-4">   <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Num:</span>    Value          Size Type    Bind   Vis      Ndx Name</span>
<span id="cb3-5">     <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">0:</span> 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND </span>
<span id="cb3-6">     <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">1:</span> 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __ctype_toupper_loc@GLIBC_2.3 <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">2</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span></span>
<span id="cb3-7">     <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">2:</span> 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND getenv@GLIBC_2.2.5 <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span></span>
<span id="cb3-8">     <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">3:</span> 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND cap_to_text</span>
<span id="cb3-9">     <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">4:</span> 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND sigprocmask@GLIBC_2.2.5 <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span></span>
<span id="cb3-10">     <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">5:</span> 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __snprintf_chk@GLIBC_2.3.4 <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">4</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span></span>
<span id="cb3-11">     <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">6:</span> 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND raise@GLIBC_2.2.5 <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span></span>
<span id="cb3-12">     <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">7:</span> 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND free@GLIBC_2.2.5 <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span></span>
<span id="cb3-13">     <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">8:</span> 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __vfprintf_chk@GLIBC_2.3.4 <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">4</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span></span>
<span id="cb3-14">     <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">9:</span> 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.34 <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">5</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span></span>
<span id="cb3-15">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">10:</span> 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __mempcpy_chk@GLIBC_2.3.4 <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">4</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span></span>
<span id="cb3-16">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">11:</span> 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND abort@GLIBC_2.2.5 <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span></span>
<span id="cb3-17">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">12:</span> 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __errno_location@GLIBC_2.2.5 <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span></span>
<span id="cb3-18">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">13:</span> 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND strncmp@GLIBC_2.2.5 <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span></span>
<span id="cb3-19">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">14:</span> 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterTMCloneTable</span>
<span id="cb3-20">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">15:</span> 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND localtime_r@GLIBC_2.2.5 <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span></span>
<span id="cb3-21">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">16:</span> 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _exit@GLIBC_2.2.5 <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span></span>
<span id="cb3-22">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">17:</span> 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __fpending@GLIBC_2.2.5 <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span></span>
<span id="cb3-23">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">18:</span> 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND flistxattr@GLIBC_2.3 <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">2</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span></span>
<span id="cb3-24">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">19:</span> 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND isatty@GLIBC_2.2.5 <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span></span>
<span id="cb3-25">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">20:</span> 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND sigaction@GLIBC_2.2.5 <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span></span>
<span id="cb3-26">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">21:</span> 0000000000000000     0 FUNC    GLOBAL DEFAU</span></code></pre></div></div>
<p>To summarize, <code>.dynamic</code> and <code>.dynsym</code> are separate buckets of lib names and symbol names.</p>
<p>Schematically, a linux binary speaks to the loader in very different terms. It tells the loader - here are the libraries, I want you to map into the process. And here’s the bucket of symbols, I ask you locate anywhere within these libraries.</p>
<pre><code>Linux Binary (ELF)
 +------------------------------------------------------------------------------+
|                                                                              |
|  .code section                                                               |
|  +------------------------------------------------------------------------+  |
|  |  .text   (executable instructions)                                     |  |
|  |  .rodata (read-only data, string literals, ...)                        |  |
|  |  PLT     (per-symbol call stubs -&gt; resolved via GOT at runtime)        |  |
|  +------------------------------------------------------------------------+  |
|                                                                              |
|  .data section                                                               |
|  +------------------------------------------------------------------------+  |
|  |  .data   (initialised global/static variables)                         |  |
|  |  .bss    (uninitialised global/static variables)                       |  |
|  |  GOT     (per-symbol address slots, patched by loader at runtime)      |  |
|  +------------------------------------------------------------------------+  |
|                                                                              |
|  .dynamic section                                                            |
|  +------------------------------------------------------------------------+  |
|  |  NEEDED  libcap.so.2                                                   |  |
|  |  NEEDED  libc.so.6                                                     |  |
|  |  (library names only -- no symbol information)                         |  |
|  +------------------------------------------------------------------------+  |
|                                                                              |
|  .dynsym section                                                             |
|  +------------------------------------------------------------------------+  |
|  |  Ndx  Name                         Bind    Source                      |  |
|  |  ---  ---------------------------  ------  --------------------------  |  |
|  |  UND  __ctype_toupper_loc          GLOBAL  GLIBC_2.3                   |  |
|  |  UND  getenv                       GLOBAL  GLIBC_2.2.5                 |  |
|  |  UND  cap_to_text                  GLOBAL  libcap.so.2                 |  |
|  |  UND  sigprocmask                  GLOBAL  GLIBC_2.2.5                 |  |
|  |  UND  free                         GLOBAL  GLIBC_2.2.5                 |  |
|  |  UND  abort                        GLOBAL  GLIBC_2.2.5                 |  |
|  |   :   ...                                                              |  |
|  |   9   main                         GLOBAL  (defined in this binary)    |  |
|  |  10   some_exported_fn             GLOBAL  (defined in this binary)    |  |
|  |   :   ...                                                              |  |
|  +------------------------------------------------------------------------+  |
|                                                                              |
+------------------------------------------------------------------------------+</code></pre>
<p>These seemingly benign differences in the architecture have far-reaching consequences. A symbol in Linux can be resolved from any of these libraries. The one that you intended it to be, or another. On the plus side, this might be an intentional behavior. It might have imported some third-party library and you want to override some implementation of the function with your own. This design enables it. This is an iceberg tip of much deeper design decisions.</p>
</section>
</section>
</section>
<section id="interposition" class="level1">
<h1>Interposition</h1>
<p>Interposition is the ability of overriding a symbol in one binary from another. This is a cornerstone of the design of linux execution model. It is a fundamental ABI design pillar.</p>
<p>You might come across alleged motivation for this. There are some claims online that say, the ELF pioneers designed it this way, so dynamic shared libraries would mimic the behavior of earlier static libs. Supposedly, in static libraries, if several libraries implement the same symbol, then the first definition encountered is used and it shadows the later ones. However, that is not entirely true. It might be the case, but you might also get a linker error complaining about ODR violations. The exact behavior depends upon which members are extracted from the static archives.</p>
<p>A different conjectured motivation is that the canonical model in the minds of the ELF architects was the library <code>libc</code>. <code>libc</code> is beyond ubiquitous, it is universal. It is loaded by practically all applications and it is huge. Therefore, it is reasonable to anticipate that users might want to override some of its implementations. Therefore, this capability was baked into the architecture. But this is guesswork. We have internal knowledge about the motivation.</p>
<p>So, we have discussed one facility that enables interposition - that is the separation of library names from list of symbols to consume. Let’s discuss another - library search order.</p>
</section>
<section id="library-search-order" class="level1">
<h1>Library Search Order</h1>
<p>The library search order in Linux is breadth-first search. What this means is, suppose we have an executable which loads the dynamic libraries <code>lib1</code> and <code>lib2</code> and these internally load the libraries <code>lib3</code>, <code>lib4</code> and <code>lib5</code>. Furthermore say that, <code>lib5</code> wants to use the symbol <code>foo</code>. The order in which the binaries would be searched by the loader for the symbol <code>foo</code> is the first the <code>exe</code> (the executable), then <code>lib1</code>, <code>lib2</code>, then <code>lib3</code> and <code>lib4</code> and only finally <code>lib5</code>, even if <code>lib5</code> implements <code>foo</code>. All the other binaries get an opportunity to interpose <code>foo</code> before it is sought in <code>lib5</code> itself.</p>
<pre><code>                    ┌───────────────┐
                    │      exe      │
                    └───────┬───────┘
            ┌───────────────┴───────────────┐
            │                               │
    ┌───────┴───────┐               ┌───────┴───────┐
    │     lib1      │               │     lib2      │
    └───────┬───────┘               └───────┬───────┘
    ┌───────┴───────┐                       │
    │               │                       │
┌───┴───────┐ ┌─────┴─────┐         ┌───────┴───────┐
│   lib3    │ │   lib4    │         │     lib5      │
└───────────┘ └───────────┘         │  defines foo  │
                                    └───────────────┘</code></pre>
<p>In particular, the executable is consulte before the current library. This is the default behavior, it can be adjusted. The most direct way is linking <code>lib5</code> with the linker switch <code>-Bsymbolic</code>. <code>-Bsymbolic</code> tells the linker, that when resolving symbols in <code>lib5</code>, searchn in <code>lib5</code> before the usual breadth first order.</p>
<section id="ld_preload" class="level2">
<h2 class="anchored" data-anchor-id="ld_preload"><code>LD_PRELOAD</code></h2>
<p><code>LD_PRELOAD</code> is an environment variable that, if it exists, and contains library names, they are loaded after the executable, but before any dependent libraries.</p>
<pre><code>                    ┌───────────────┐
                    │      exe      │ 
                    └───────┬───────┘
                    ┌───────┴───────┐
                    │   LD_PRELOAD  │  
                    └───────┬───────┘
            ┌───────────────┴───────────────┐
            │                               │
    ┌───────┴───────┐               ┌───────┴───────┐
    │     lib1      │               │     lib2      │
    └───────┬───────┘               └───────┬───────┘
    ┌───────┴───────┐                       │
    │               │                       │
┌───┴───────┐ ┌─────┴─────┐         ┌───────┴───────┐
│   lib3    │ │   lib4    │         │     lib5      │
└───────────┘ └───────────┘         │  defines foo  │
                                    └───────────────┘</code></pre>
</section>
<section id="can-a-shared-library-symbol-be-overriden-from-an-executable" class="level2">
<h2 class="anchored" data-anchor-id="can-a-shared-library-symbol-be-overriden-from-an-executable">Can a shared-library symbol be overriden from an executable?</h2>
<p>Can a shared-library symbol be overriden from an executable? In Windows, the answer is no. In Linux, the answer is yes, thanks to Interposition. This is exactly what Interposition does. In Mac, the answer is yes, but not by default.</p>
</section>
<section id="c-new-operator" class="level2">
<h2 class="anchored" data-anchor-id="c-new-operator">C++ <code>new</code> operator</h2>
<p>Here is a quote from the C++ standard.</p>
<blockquote class="blockquote">
<ul>
<li><code>operator new(std::size_t)</code></li>
<li><code>operator new(std::size_t, std::align_val_t)</code></li>
<li>…</li>
</ul>
<p>The program’s definitions are used instead of the default versions supplied by the C++ standard library.</p>
</blockquote>
<p>That is what happens on Linux, thanks to interposition. That is not what happens on Windows.</p>
<pre><code>                    ┌─────────────────────┐
                    │          exe        │
                    | operator new(size_t)|
                    └───────────┬─────────┘
            ┌───────────────────┴────────────────────┐
            │                                        │
    ┌───────┴───────┐                   ┌────────────┴─────────┐
    │     glibc     │                   │       libc++         │
    |               |                   | operator new(size_t) |
    +---------------+                   +----------------------+</code></pre>
<p>In fact, Windows can’t do that. Strictly speaking, Windows does not conform to this clause of the standard.</p>
</section>
</section>
<section id="symbol-resolution-time" class="level1">
<h1>Symbol Resolution Time</h1>
<p>Let’s discuss another mechanism that supports interposition. The default behavior is governed by the default switch <code>--allow-shlib-undefined</code>. If we have the below tree of dependencies and suppose <code>lib5</code> wishes to import the symbol <code>foo</code> and the <code>exe</code> wishes to import the symbol <code>bar</code>. The resolution for the <code>exe</code> symbols is checked at link-time. The linker would refuse to link the executable, if it cannot resolve the symbol <code>bar</code>.</p>
<p>That is not true of the libraries. The linker would very happily agree to link <code>lib5</code>, even if it cannot see <code>foo</code>. As far as the linker is concerned, the implementation of <code>foo</code> might lie in the executable, where it has no chance of discovering it.</p>
<pre><code>                    ┌───────────────┐
                    │      exe      │---(bar    Resolution checked 
                    └───────┬───────┘           at link time
                    ┌───────┴───────┐
                    │   LD_PRELOAD  │  
                    └───────┬───────┘
            ┌───────────────┴───────────────┐
            │                               │
    ┌───────┴───────┐               ┌───────┴───────┐
    │     lib1      │               │     lib2      │
    └───────┬───────┘               └───────┬───────┘
    ┌───────┴───────┐                       │
    │               │                       │
┌───┴───────┐ ┌─────┴─────┐         ┌───────┴───────┐
│   lib3    │ │   lib4    │         │     lib5      │---(foo  Resolution NOT
└───────────┘ └───────────┘         └───────────────┘        checked at link time</code></pre>
<p>This behavior can be controlled with some switches. The easiest would be linking the executable with a <code>--no-allow-shlib-undefined</code> on the exe.</p>
</section>
<section id="c-impliciation-how-to-form-a-process-wide-singleton" class="level1">
<h1>C++ Impliciation : How to form a process-wide singleton?</h1>
<p>Let’s discuss a developer facing implication of this. Can we have a process-wide singleton? By singleton, I mean the Meyers singleton design pattern - a single object which has a unique instance which is usable by all the code in the process, from all binaries.</p>
<p>In Windows, the usual singleton design pattern would create a per-binary singleton.</p>


</section>

 ]]></description>
  <category>C++</category>
  <guid>http://quantdev.blog/posts/linkers-loaders-and-shared-libraries/</guid>
  <pubDate>Fri, 29 May 2026 23:00:00 GMT</pubDate>
  <media:content url="http://quantdev.blog/posts/linkers-loaders-and-shared-libraries/cpp.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>Setting up a modern C++ dev environment</title>
  <dc:creator>`dev::author` </dc:creator>
  <link>http://quantdev.blog/posts/setting-up-a-modern-cpp-dev-env/</link>
  <description><![CDATA[ 





<section id="introduction" class="level1">
<h1>Introduction</h1>
<p>This blog post is a guide on setting up a modern C++ development environment. This can be especially helpful, if you are getting started with C++.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="http://quantdev.blog/posts/setting-up-a-modern-cpp-dev-env/image_01.png" class="img-fluid figure-img"></p>
<figcaption>VS Code</figcaption>
</figure>
</div>
<p>Here is a very brief primer on building C++ code.</p>
<section id="c-compiler" class="level2">
<h2 class="anchored" data-anchor-id="c-compiler">C++ Compiler</h2>
<p>A compiler translates C++ source code into low-level machine code (targeted to a specific architecture, for example x86_64, ARM etc). More specifically, each source file is translated into an object file, that contains machine code. Object files are little pieces of machine code, that can be linked together.</p>
<p><code>gcc/g++</code>, <code>clang/clang++</code>, <code>msvc</code> are examples of major compilers.</p>
</section>
<section id="build-system" class="level2">
<h2 class="anchored" data-anchor-id="build-system">Build system</h2>
<p>While a hobby project starts out simple enough that you can build it just using a compiler, as your system grows more complex, it can quickly become unwieldy. Sure enough, you can write a script, but you begin spending almost as much time working on build scripts as on real code. To make sure you aren’t accidentally relying on stale libraries, you have your build script build every dependency in order every time you run it. Very quickly, you run into a classic problem of scale.</p>
<p>Here is crash-course on build systems. A <strong>build system</strong> automates the compilation and linking of the source code in a code base into a library or executable. At a high-level build systems are tools or libraries that provide a way to <strong>define</strong> and <strong>execute</strong> a series of transformations from input data to output data that are memoized by caching them in an object store.</p>
<p>Transformations are called <strong>steps</strong> or <strong>rules</strong> and define how to execute a task that generates zero or more outputs from one or more inputs. A rule is usually a <strong>unit</strong> of caching; i.e.&nbsp;<strong>cache points</strong> are the outputs of a rule, and <strong>cache invalidations</strong> must happen on the inputs of a rule. Rules are the like the edges of a graph, they can have dependencies on previous outputs, forming a <strong>dependency graph</strong>. The dependency graph must be a DAG.</p>
<p>Each invocation of the build tool is called a <strong>build</strong>. A <strong>full build</strong> or a <strong>clean build</strong> occurs when the cache is empty and all transformations are executed as a batch job. An <strong>incremental build</strong> occurs when the cache is partially full but some outputs are outdated and need to be rebuild. Deleting the cache is called <strong>cleaning</strong>.</p>
<p>A build is <strong>correct</strong> or <strong>sound</strong> if all possible incremental builds have the same result as a full build.</p>
<p>A build system without caching is called a <strong>task runner</strong> or <strong>batch compiler</strong>. Some examples of build systems are: <code>ninja</code>, GNU <code>make</code>, <code>docker build</code>, <code>rustc</code>. Some examples of task runners are: <code>just</code>, shell scripts.</p>
<p>In the context of builds, <strong>build files</strong> contain rule definitions, input and output declarations.</p>
</section>
<section id="toolchain" class="level2">
<h2 class="anchored" data-anchor-id="toolchain">Toolchain</h2>
<p>All of the above programming tools combined together form a toolchain (a suite of tools used in a serial manner). Examples would be the GNU toolchain, the LLVM project.</p>
</section>
<section id="meta-build-system" class="level2">
<h2 class="anchored" data-anchor-id="meta-build-system">Meta-build system</h2>
<p>Usually, a meta-build system runs a <strong>configuration step</strong> and requires another tool such as <code>ninja</code> for the actual <strong>build step</strong>. The meta-build system discovers the rules that need to be executed (often through a programmatic way to describe dependencies or through file globbing), and then <strong>serializes</strong> (persists) these rules into an action graph, which can be stored either in memory or on disk. On-disk serialized action graphs are themselves build files, in the sense, you can write them by hand but you wouldn’t want to.</p>
<p>If you’ve ever used CMake, you know that there are two steps involved : a <strong>configure</strong> step (<code>cmake -b build-dir</code>) and a build step <code>cmake --build -S source-dir</code>, An action graph is a serialization of all the build steps, with the ability to regenerate the graph by rerunning the configure step.</p>
<p>Some examples of meta-build systems are CMake, meson and autotools.</p>
<p>Not all meta-build systems serialize their action graph. <code>bazel</code> and <code>buck2</code> run persistent servers that store it in memory and allow querying it, but never serialize it to the disk. For large graphs, this requires a lot of memory.</p>
</section>
<section id="language-servers" class="level2">
<h2 class="anchored" data-anchor-id="language-servers">Language Servers</h2>
<p>Most modern IDEs provide programnmers with sophisticated features like code completion, hover tooltips, finding symbols, jump-to-definitions, syntax highlighting etc. Language services used to be tightly embedded within the editor or IDE. Assume that there are <img src="https://latex.codecogs.com/png.latex?m"> code editors and <img src="https://latex.codecogs.com/png.latex?n"> language servers, we would need to write <img src="https://latex.codecogs.com/png.latex?m%20%5Ctimes%20n"> (<img src="https://latex.codecogs.com/png.latex?m">-times-<img src="https://latex.codecogs.com/png.latex?n">) plugins to provide Visual Studio like sophisticated features for all programming languages on all code-editors.</p>
<p>The Language Server Protocol(LSP) reduces an <img src="https://latex.codecogs.com/png.latex?m%20%5Ctimes%20n"> problem to an <img src="https://latex.codecogs.com/png.latex?m%20+%20n"> problem. LSP allows language communities to concentrate their efforts on building a single, high performing language server that can provide code completion, hover tooltips, jump-to-definition, find-references, while editor and client communities can concentrate on a building a single, intuitive, high-performing extension that can communicate with any language server.</p>
<p>The LSP is a protocol for sending messages in a JSON-RPC format that allows the development tool to communicate with any language server. And a single language server can be reused in multiple development tools.</p>
</section>
<section id="debugger" class="level2">
<h2 class="anchored" data-anchor-id="debugger">Debugger</h2>
<p>Debuggers are the most valuable tool in any developer’s kit. Debuggers allow you to step through the source code, inspect the values of variables, set breakpoints and much more.</p>
</section>
<section id="debug-adapter-protocoldap" class="level2">
<h2 class="anchored" data-anchor-id="debug-adapter-protocoldap">Debug Adapter Protocol(DAP)</h2>
<p>The Debug Adapter Protocol(DAP) is an abstract protcol that allows any development tool to communicate with any debug-adapter.</p>
</section>
</section>
<section id="setup" class="level1">
<h1>Setup</h1>
<p>This is my development environment setup on Arch.</p>
<ul>
<li>Compiler: clang++</li>
<li>Debugger: lldb</li>
<li>Language Server: <a href="https://clangd.llvm.org/"><code>clangd</code></a></li>
<li>Meta-build system: CMake</li>
<li>Build system: <code>ninja</code></li>
<li>Integrated Development Environment: Visual Studio Code</li>
<li>C++ code linter: clang-tidy</li>
<li>Source code formatter: clang-format</li>
<li>Source code documentation generator: doxygen</li>
<li>Software package distribution management: CPack</li>
<li>VCS(Version Control System): Git</li>
</ul>
<section id="packages" class="level2">
<h2 class="anchored" data-anchor-id="packages">Packages</h2>
<p>Debian/Ubuntu</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb1-1"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">LLVM_VER</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"19"</span></span>
<span id="cb1-2"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">GCC_VER</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"16"</span> </span>
<span id="cb1-3"></span>
<span id="cb1-4"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">PACKAGES</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb1-5">    ninja-build valgrind htop gcc-<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$GCC_VER</span> g++-<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$GCC_VER</span></span>
<span id="cb1-6">    clang-<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$LLVM_VER</span> clangd-<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$LLVM_VER</span> llvm-<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$LLVM_VER</span>-dev</span>
<span id="cb1-7">    clang-format-<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$LLVM_VER</span> clang-tidy-<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$LLVM_VER</span></span>
<span id="cb1-8">    libc++-<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$LLVM_VER</span>-dev libc++abi-<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$LLVM_VER</span></span>
<span id="cb1-9">    libpolly-<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$LLVM_VER</span>-dev lld-<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$LLVM_VER</span> lldb-<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$LLVM_VER</span></span>
<span id="cb1-10">    cmake curl jq htop build-essential ripgrep snapd</span>
<span id="cb1-11">    texlive-latex-base latexmk</span>
<span id="cb1-12"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-13"></span>
<span id="cb1-14"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sudo</span> apt install <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">${PACMAN_PACKAGES</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[@]</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span></span></code></pre></div></div>
<p>Arch</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb2-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#!/usr/bin/env bash</span></span>
<span id="cb2-2"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">set</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-euo</span> pipefail</span>
<span id="cb2-3"></span>
<span id="cb2-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># --- Official repo packages (pacman) ---</span></span>
<span id="cb2-5"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">PACMAN_PACKAGES</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb2-6">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># LLVM / Clang toolchain (versioned slot from official repos)</span></span>
<span id="cb2-7">  llvm</span>
<span id="cb2-8">  clang          <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># clang++, clangd, clang-format, clang-tidy all bundled here</span></span>
<span id="cb2-9">  libc++</span>
<span id="cb2-10"></span>
<span id="cb2-11">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># GCC toolchain</span></span>
<span id="cb2-12">  gcc            <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># includes g++</span></span>
<span id="cb2-13"></span>
<span id="cb2-14">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Build tools</span></span>
<span id="cb2-15">  cmake ninja</span>
<span id="cb2-16">  make           <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># equivalent of build-essential's make</span></span>
<span id="cb2-17">  binutils       <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># equivalent of build-essential's binutils</span></span>
<span id="cb2-18">  autoconf</span>
<span id="cb2-19">  automake</span>
<span id="cb2-20"></span>
<span id="cb2-21">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Debugger / profiler</span></span>
<span id="cb2-22">  lld lldb valgrind</span>
<span id="cb2-23"></span>
<span id="cb2-24">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Utilities</span></span>
<span id="cb2-25">  curl jq htop ripgrep git</span>
<span id="cb2-26"></span>
<span id="cb2-27">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># LaTeX</span></span>
<span id="cb2-28">  texlive-basic       <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># equivalent of texlive-latex-base</span></span>
<span id="cb2-29">  texlive-binextra    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># includes latexmk</span></span>
<span id="cb2-30"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb2-31"></span>
<span id="cb2-32"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sudo</span> pacman <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-Syu</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--needed</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--noconfirm</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">${PACMAN_PACKAGES</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[@]</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span></span></code></pre></div></div>
</section>
<section id="visual-studio-extensions" class="level2">
<h2 class="anchored" data-anchor-id="visual-studio-extensions">Visual Studio Extensions</h2>
<p>I recommend the below VS Code extensions. You could create and optionally customize the below <code>.vscode/extensions.json</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode json code-with-copy"><code class="sourceCode json"><span id="cb3-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-2">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"recommendations"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span></span>
<span id="cb3-3">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"llvm-vs-code-extensions.vscode-clangd"</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb3-4">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ms-vscode.cpptools-extension-pack"</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb3-5">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ms-vscode-remote.vscode-remote-extensionpack"</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb3-6">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"cs128.cs128-clang-tidy"</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb3-7">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"donjayamanne.githistory"</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb3-8">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"josetr.cmake-language-support-vscode"</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb3-9">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"mhutchie.git-graph"</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb3-10">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ms-vscode.cmake-tools"</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb3-11">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"vadimcn.vscode-lldb"</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb3-12">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"waderyan.gitblame"</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb3-13">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"xaver.clang-format"</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb3-14">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"github.vscode-pull-request-github"</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb3-15">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ms-vsliveshare.vsliveshare"</span></span>
<span id="cb3-16">    <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb3-17"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>


</section>
</section>

 ]]></description>
  <category>C++</category>
  <guid>http://quantdev.blog/posts/setting-up-a-modern-cpp-dev-env/</guid>
  <pubDate>Fri, 08 May 2026 23:00:00 GMT</pubDate>
  <media:content url="http://quantdev.blog/posts/setting-up-a-modern-cpp-dev-env/cpp.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>Implementing std::visit</title>
  <dc:creator>`dev::author` </dc:creator>
  <link>http://quantdev.blog/posts/implementing_visit/</link>
  <description><![CDATA[ 





<section id="introduction" class="level1">
<h1>Introduction</h1>
<p>A <code>variant</code> models a <strong>choice between types</strong>. It is a smart union. Variants are <strong>sum types</strong>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb1-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> on <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">temperature_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb1-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> off <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb1-3"></span>
<span id="cb1-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> oven_state <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>on<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> off<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;;</span></span></code></pre></div></div>
<p>Recursive node-based structures, error handling, state machines etc. are examples of concepts that can be elegantly modeled by variants:</p>
<ul>
<li>JSON</li>
<li>ASTs(Abstract Syntax Trees)</li>
<li>State Machines</li>
<li>Error Handling</li>
</ul>
</section>
<section id="variant-visitation" class="level1">
<h1>Variant visitation</h1>
<section id="what-is-visitation" class="level2">
<h2 class="anchored" data-anchor-id="what-is-visitation">What is visitation?</h2>
<p>Visitation can be defined as an <strong>abstraction</strong> that allows you to access the currently active variant <em>alternative</em> in an <strong>exhaustive</strong> and <strong>expressive</strong> manner. You are forced to provide some behavior for all the types that the variant supports. Its expressive, because it doesn’t work through a chain of if-else; its a very elegant way of saying, for these types perform these actions.</p>
</section>
<section id="traditional-visitation" class="level2">
<h2 class="anchored" data-anchor-id="traditional-visitation">Traditional visitation</h2>
<p>Traditional visitation requires a <code>Callable</code> object which can be invoked with every possible variant alternative. The traditional way of creating such an object is defining a <code>struct</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb2-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Traditional visitation example - one variant</span></span>
<span id="cb2-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> printer<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-3">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"int"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-4">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"float"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-5">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"double"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-6"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb2-7"></span>
<span id="cb2-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> my_variant <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;;</span></span>
<span id="cb2-9">my_variant v0<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">20.0</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">f</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb2-10"></span>
<span id="cb2-11"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>printer<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{},</span> v0<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span></code></pre></div></div>
<p>If you call <code>std::visit</code> with an instance of your <code>printer</code> struct and the <code>variant</code>, it will automatically figure out, what type is in the variant and call the corresponding overload.</p>
<p>You can extend this logic to multiple variants.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb3-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> circle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">radius_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb3-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> box<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> </span>
<span id="cb3-3">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">width_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> </span>
<span id="cb3-4">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">height_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-5">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span> depth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-6"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb3-7"></span>
<span id="cb3-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> collision_resolver<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-9">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()(</span>circle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> circle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/*...*/</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-10">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()(</span>circle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> box<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/*...*/</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-11">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()(</span>box<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> circle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/*...*/</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-12">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()(</span>box<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> box<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/*...*/</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-13"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb3-14"></span>
<span id="cb3-15"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> my_variant <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>circle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> box<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;;</span></span>
<span id="cb3-16">my_variant v0<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>circle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}};</span></span>
<span id="cb3-17">my_variant v1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>box<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}};</span></span>
<span id="cb3-18"></span>
<span id="cb3-19"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>collision_resolver<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{},</span> v0<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> v1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span></code></pre></div></div>
<p>What you get is a form of multiple dispatch, that has to handle all possible combinations. This is also really powerful way of implementing multiple dispatch.</p>
</section>
</section>
<section id="building-helper-functions-needed-for-stdvisit" class="level1">
<h1>Building helper functions needed for <code>std::visit</code></h1>
<p>Under the hood <code>std::visit</code> must invoke the right candidate for the currently active alternatives from the function overload set. We start with the simplest case of <img src="https://latex.codecogs.com/png.latex?2"> variants. The central idea is to maintain a single array of function pointers. Each entry in the function pointer table has the shape <code>[](Visitor visitor, Variant0 v0, Variant1 v1)</code>. For concreteness, assume that both variants <code>v0</code> and <code>v1</code> offer a choice between <img src="https://latex.codecogs.com/png.latex?2"> types:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb4-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> Variant0 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;;</span></span>
<span id="cb4-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> Variant1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;;</span></span></code></pre></div></div>
<p>It is possible to have <img src="https://latex.codecogs.com/png.latex?4"> distinguishable behaviors(overloads), when a visitor visits these variants. So, we build an array of size <img src="https://latex.codecogs.com/png.latex?4">.</p>
<p>The <code>std::visit</code> implementation should automatically invoke the correct function overload based on the currently active types in <code>v0</code> and <code>v1</code>. Before we proceed, let us fix some terminology first. Suppose a variant <code>v</code> allows a choice amongst <img src="https://latex.codecogs.com/png.latex?n"> types:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb5-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Pseudo-code</span></span>
<span id="cb5-2"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T0<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> T1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...,</span> Tn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
<p>In the case of 2 variants <code>v0</code> and <code>v1</code> offering a choice amongst <img src="https://latex.codecogs.com/png.latex?n_1"> and <img src="https://latex.codecogs.com/png.latex?n_2"> alternative types respectively, we have a total of <img src="https://latex.codecogs.com/png.latex?n_1%20%5Ctimes%20n_2"> distinguishgable choices. For example, consider the case of <code>v0</code> offer a choice of <img src="https://latex.codecogs.com/png.latex?3"> types and <code>v1</code> offering a choice of <img src="https://latex.codecogs.com/png.latex?4"> types. Each choice is a distinct entry in the 2d-table, and we have a total of <img src="https://latex.codecogs.com/png.latex?3%20%5Ctimes%204%20=%2012"> distinct choices. We will have <img src="https://latex.codecogs.com/png.latex?12"> candidates in our function overload set. We can assign a multi-index <code>&lt;i,j&gt;</code> to the function overload <code>[](Ti, Tj){ /*...*/ }</code>.</p>
<table class="caption-top table">
<thead>
<tr class="header">
<th></th>
<th>j=0</th>
<th>j=1</th>
<th>j=2</th>
<th>j=3</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><strong>i=0</strong></td>
<td>&lt;0, 0&gt;</td>
<td>&lt;0, 1&gt;</td>
<td>&lt;0, 2&gt;</td>
<td>&lt;0, 3&gt;</td>
</tr>
<tr class="even">
<td><strong>i=1</strong></td>
<td>&lt;1, 0&gt;</td>
<td>&lt;1, 1&gt;</td>
<td>&lt;1, 2&gt;</td>
<td>&lt;1, 3&gt;</td>
</tr>
<tr class="odd">
<td><strong>i=2</strong></td>
<td>&lt;2, 0&gt;</td>
<td>&lt;2, 1&gt;</td>
<td>&lt;2, 2&gt;</td>
<td>&lt;2, 3&gt;</td>
</tr>
</tbody>
</table>
<p>We can convert this 2d-table to a 1d-table.</p>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Multi-index</th>
<th>1D-index</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>&lt;0, 0&gt;</td>
<td>0</td>
</tr>
<tr class="even">
<td>&lt;0, 1&gt;</td>
<td>1</td>
</tr>
<tr class="odd">
<td>&lt;0, 2&gt;</td>
<td>2</td>
</tr>
<tr class="even">
<td>&lt;0, 3&gt;</td>
<td>3</td>
</tr>
<tr class="odd">
<td>&lt;1, 0&gt;</td>
<td>4</td>
</tr>
<tr class="even">
<td>&lt;1, 1&gt;</td>
<td>5</td>
</tr>
<tr class="odd">
<td>&lt;1, 2&gt;</td>
<td>6</td>
</tr>
<tr class="even">
<td>&lt;1, 3&gt;</td>
<td>7</td>
</tr>
<tr class="odd">
<td>&lt;2, 0&gt;</td>
<td>8</td>
</tr>
<tr class="even">
<td>&lt;2, 1&gt;</td>
<td>9</td>
</tr>
<tr class="odd">
<td>&lt;2, 2&gt;</td>
<td>10</td>
</tr>
<tr class="even">
<td>&lt;2, 3&gt;</td>
<td>11</td>
</tr>
</tbody>
</table>
<p>Thus, the pointer to the function <code>[](Ti, Tj){ /*...*/}</code> with multi-index <code>&lt;i,j&gt;</code> is mapped to <code>4i + j</code> 1d-index in a 1d-table.</p>
<p>In the case of 3 variants <code>v0</code>, <code>v1</code> and <code>v2</code> offering a choice amongst <img src="https://latex.codecogs.com/png.latex?n_1%20=%203">, <img src="https://latex.codecogs.com/png.latex?n_2%20=%204"> and <img src="https://latex.codecogs.com/png.latex?n_3%20=%205"> alternative types respectively, we have a total of <img src="https://latex.codecogs.com/png.latex?3%20%5Ctimes%204%20%5Ctimes%205%20=%2060"> distinguishable choices. We will have <img src="https://latex.codecogs.com/png.latex?60"> candidates in our function overload set. We can assign a multi-index <code>&lt;i,j,k&gt;</code> to the function overload <code>[](Ti, Tj, Tk){ /*...*/ }</code>.</p>
<table class="caption-top table">
<thead>
<tr class="header">
<th></th>
<th>j=0</th>
<th>j=1</th>
<th>j=2</th>
<th>j=3</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><strong>i=0</strong></td>
<td>&lt;0,0,k&gt;</td>
<td>&lt;0,1,k&gt;</td>
<td>&lt;0,2,k&gt;</td>
<td>&lt;0,3,k&gt;</td>
</tr>
<tr class="even">
<td><strong>i=1</strong></td>
<td>&lt;1,0,k&gt;</td>
<td>&lt;1,1,k&gt;</td>
<td>&lt;1,2,k&gt;</td>
<td>&lt;1,3,k&gt;</td>
</tr>
<tr class="odd">
<td><strong>i=2</strong></td>
<td>&lt;2,0,k&gt;</td>
<td>&lt;2,1,k&gt;</td>
<td>&lt;2,2,k&gt;</td>
<td>&lt;2,3,k&gt;</td>
</tr>
</tbody>
</table>
<p>where each entry <code>&lt;i,j,k&gt;</code> expands over <img src="https://latex.codecogs.com/png.latex?k%20=%200,%201,%202,%203,%204">. The full set of multi-indices and their 1D mappings is:</p>
<table class="caption-top table">
<colgroup>
<col style="width: 18%">
<col style="width: 14%">
<col style="width: 18%">
<col style="width: 14%">
<col style="width: 18%">
<col style="width: 14%">
</colgroup>
<thead>
<tr class="header">
<th>Multi-index</th>
<th>1D-index</th>
<th>Multi-index</th>
<th>1D-index</th>
<th>Multi-index</th>
<th>1D-index</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>&lt;0, 0, 0&gt;</td>
<td>0</td>
<td>&lt;1, 0, 0&gt;</td>
<td>20</td>
<td>&lt;2, 0, 0&gt;</td>
<td>40</td>
</tr>
<tr class="even">
<td>&lt;0, 0, 1&gt;</td>
<td>1</td>
<td>&lt;1, 0, 1&gt;</td>
<td>21</td>
<td>&lt;2, 0, 1&gt;</td>
<td>41</td>
</tr>
<tr class="odd">
<td>&lt;0, 0, 2&gt;</td>
<td>2</td>
<td>&lt;1, 0, 2&gt;</td>
<td>22</td>
<td>&lt;2, 0, 2&gt;</td>
<td>42</td>
</tr>
<tr class="even">
<td>&lt;0, 0, 3&gt;</td>
<td>3</td>
<td>&lt;1, 0, 3&gt;</td>
<td>23</td>
<td>&lt;2, 0, 3&gt;</td>
<td>43</td>
</tr>
<tr class="odd">
<td>&lt;0, 0, 4&gt;</td>
<td>4</td>
<td>&lt;1, 0, 4&gt;</td>
<td>24</td>
<td>&lt;2, 0, 4&gt;</td>
<td>44</td>
</tr>
<tr class="even">
<td>&lt;0, 1, 0&gt;</td>
<td>5</td>
<td>&lt;1, 1, 0&gt;</td>
<td>25</td>
<td>&lt;2, 1, 0&gt;</td>
<td>45</td>
</tr>
<tr class="odd">
<td>&lt;0, 1, 1&gt;</td>
<td>6</td>
<td>&lt;1, 1, 1&gt;</td>
<td>26</td>
<td>&lt;2, 1, 1&gt;</td>
<td>46</td>
</tr>
<tr class="even">
<td>&lt;0, 1, 2&gt;</td>
<td>7</td>
<td>&lt;1, 1, 2&gt;</td>
<td>27</td>
<td>&lt;2, 1, 2&gt;</td>
<td>47</td>
</tr>
<tr class="odd">
<td>&lt;0, 1, 3&gt;</td>
<td>8</td>
<td>&lt;1, 1, 3&gt;</td>
<td>28</td>
<td>&lt;2, 1, 3&gt;</td>
<td>48</td>
</tr>
<tr class="even">
<td>&lt;0, 1, 4&gt;</td>
<td>9</td>
<td>&lt;1, 1, 4&gt;</td>
<td>29</td>
<td>&lt;2, 1, 4&gt;</td>
<td>49</td>
</tr>
<tr class="odd">
<td>&lt;0, 2, 0&gt;</td>
<td>10</td>
<td>&lt;1, 2, 0&gt;</td>
<td>30</td>
<td>&lt;2, 2, 0&gt;</td>
<td>50</td>
</tr>
<tr class="even">
<td>&lt;0, 2, 1&gt;</td>
<td>11</td>
<td>&lt;1, 2, 1&gt;</td>
<td>31</td>
<td>&lt;2, 2, 1&gt;</td>
<td>51</td>
</tr>
<tr class="odd">
<td>&lt;0, 2, 2&gt;</td>
<td>12</td>
<td>&lt;1, 2, 2&gt;</td>
<td>32</td>
<td>&lt;2, 2, 2&gt;</td>
<td>52</td>
</tr>
<tr class="even">
<td>&lt;0, 2, 3&gt;</td>
<td>13</td>
<td>&lt;1, 2, 3&gt;</td>
<td>33</td>
<td>&lt;2, 2, 3&gt;</td>
<td>53</td>
</tr>
<tr class="odd">
<td>&lt;0, 2, 4&gt;</td>
<td>14</td>
<td>&lt;1, 2, 4&gt;</td>
<td>34</td>
<td>&lt;2, 2, 4&gt;</td>
<td>54</td>
</tr>
<tr class="even">
<td>&lt;0, 3, 0&gt;</td>
<td>15</td>
<td>&lt;1, 3, 0&gt;</td>
<td>35</td>
<td>&lt;2, 3, 0&gt;</td>
<td>55</td>
</tr>
<tr class="odd">
<td>&lt;0, 3, 1&gt;</td>
<td>16</td>
<td>&lt;1, 3, 1&gt;</td>
<td>36</td>
<td>&lt;2, 3, 1&gt;</td>
<td>56</td>
</tr>
<tr class="even">
<td>&lt;0, 3, 2&gt;</td>
<td>17</td>
<td>&lt;1, 3, 2&gt;</td>
<td>37</td>
<td>&lt;2, 3, 2&gt;</td>
<td>57</td>
</tr>
<tr class="odd">
<td>&lt;0, 3, 3&gt;</td>
<td>18</td>
<td>&lt;1, 3, 3&gt;</td>
<td>38</td>
<td>&lt;2, 3, 3&gt;</td>
<td>58</td>
</tr>
<tr class="even">
<td>&lt;0, 3, 4&gt;</td>
<td>19</td>
<td>&lt;1, 3, 4&gt;</td>
<td>39</td>
<td>&lt;2, 3, 4&gt;</td>
<td>59</td>
</tr>
</tbody>
</table>
<p>Thus, the pointer to the function <code>[](Ti, Tj, Tk){ /*...*/}</code> with multi-index <code>&lt;i,j,k&gt;</code> is mapped to the 1D-index <img src="https://latex.codecogs.com/png.latex?20i%20+%205j%20+%20k">.</p>
<p>We shall code up two helper functions <code>to_1d_index&lt;3,4,5&gt;(size_t, size_t, size_t)</code> and <code>from_1d_index&lt;3,4,5&gt;(size_t)</code> to convert a multi-index to a 1d-index and back.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb6-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Dimensions<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb6-3">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> build_coeffs_array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb6-4">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">sizeof</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...(</span>Dimensions<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)&gt;</span> dimensions <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> Dimensions<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb6-5">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t coeffs_size <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">sizeof</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...(</span>Dimensions<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb6-6">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> coeffs_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> coeffs <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{};</span></span>
<span id="cb6-7">        </span>
<span id="cb6-8">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> coeffs_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-9">            coeffs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb6-10"></span>
<span id="cb6-11">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> coeffs_size <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb6-12">            <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// In step i, we need to populate all coeffs[j], j &lt;= i</span></span>
<span id="cb6-13">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t j<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span> j <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;=</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span>j<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb6-14">                coeffs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>j<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*=</span> dimensions<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">];</span></span>
<span id="cb6-15">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-16">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-17">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> coeffs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb6-18">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-19">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/*</span></span>
<span id="cb6-20"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    coeff[0] = v1size * ... * v[n-1] size</span></span>
<span id="cb6-21"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    coeff[1] = v2size * .... *v[n-1] size</span></span>
<span id="cb6-22"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    ...</span></span>
<span id="cb6-23"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    coeff[n-2] = v[n-1] size</span></span>
<span id="cb6-24"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    coeff[n-1] = 1</span></span>
<span id="cb6-25"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    */</span></span>
<span id="cb6-26">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Dimensions<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb6-27">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> to_1d_index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> indices<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb6-28">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">sizeof</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...(</span>Dimensions<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)&gt;</span> dimensions <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> Dimensions<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb6-29">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t coeffs_size <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">sizeof</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...(</span>Dimensions<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb6-30">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> coeffs <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> build_coeffs_array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Dimensions<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;();</span></span>
<span id="cb6-31">                                                                                                       </span>
<span id="cb6-32">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">sizeof</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...(</span>indices<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)&gt;</span> indices_arr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> indices<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb6-33">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//std::println("{}", indices_arr); </span></span>
<span id="cb6-34">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>inner_product<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>coeffs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> coeffs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> indices_arr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> </span>
<span id="cb6-35">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-36"></span>
<span id="cb6-37">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/*</span></span>
<span id="cb6-38"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    Suppose we have the dimensions &lt;3, 5, 2&gt; and the coordinates (1, 3, 1).</span></span>
<span id="cb6-39"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    (1, 3, 1) maps to the linear index 17. </span></span>
<span id="cb6-40"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    */</span></span>
<span id="cb6-41"></span>
<span id="cb6-42">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> N<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb6-43">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> build_coords_array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>N<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> coeffs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> initState<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span> </span>
<span id="cb6-44">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> state <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> initState<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb6-45">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> N<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> coords<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{};</span></span>
<span id="cb6-46">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> N<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb6-47">            coords<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_cast</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>state <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> coeffs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]);</span></span>
<span id="cb6-48">            state <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-=</span> coords<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> coeffs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">];</span></span>
<span id="cb6-49">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-50">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> coords<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb6-51">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-52"></span>
<span id="cb6-53">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Dimensions<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb6-54">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">decltype</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> from_1d_index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t n<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb6-55">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t coords_arr_size <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">sizeof</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...(</span>Dimensions<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb6-56">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> coeffs <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> build_coeffs_array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Dimensions<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;();</span></span>
<span id="cb6-57">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> coords_arr_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> coords <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> build_coords_array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>coeffs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> n<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb6-58">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> coords<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb6-59">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-60"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
</section>
<section id="simpler-case-of-1-and-2-variants" class="level1">
<h1>Simpler case of <img src="https://latex.codecogs.com/png.latex?1"> and <img src="https://latex.codecogs.com/png.latex?2"> variants</h1>
<p>I strongly recommend creating a simpler version first, maybe hardcoded with two or three variants. So you can get an idea of the actual shape before making it variadic. Otherwise you’d be facing both problems at once.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb7-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Simple case of 2 variants</span></span>
<span id="cb7-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-3"></span>
<span id="cb7-4">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> example<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-5"></span>
<span id="cb7-6">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Dummy<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{};</span></span>
<span id="cb7-7">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb7-8">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> Wrapper <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>conditional_t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>is_void_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;,</span>Dummy<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;;</span></span>
<span id="cb7-9"></span>
<span id="cb7-10"></span>
<span id="cb7-11">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Visitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Variant0<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Variant1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb7-12">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">decltype</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Visitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> visitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Variant0 v0<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Variant1 v1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb7-13">            <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> dimensions <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant_size_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Variant0<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant_size_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Variant1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb7-14">            <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t vtable_size <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant_size_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Variant0<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant_size_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Variant1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;);</span></span>
<span id="cb7-15">            <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">cases_t</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*)(</span>Visitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Variant0<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Variant1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb7-16">            <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">static</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> vtable <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-17">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Indices<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>index_sequence<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Indices<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;){</span></span>
<span id="cb7-18">                    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">cases_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;{</span></span>
<span id="cb7-19">                        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span>Visitor vis<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Variant0 v0<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Variant1 v1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span> </span>
<span id="cb7-20">                            <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> multi_idx <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>from_1d_index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>Indices<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb7-21">                            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> vis<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>multi_idx<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]&gt;(</span>v0<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>multi_idx<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]&gt;(</span>v1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb7-22">                    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}...</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb7-23">                    </span>
<span id="cb7-24">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>make_index_sequence<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>vtable_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;())</span></span>
<span id="cb7-25">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb7-26"></span>
<span id="cb7-27">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> vtable<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>to_1d_index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>v0<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> v1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">())](</span>visitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> v0<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> v1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb7-28">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb7-29">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb7-30"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb7-31"></span>
<span id="cb7-32"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Callables<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb7-33"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Visitor <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> Callables<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...{</span></span>
<span id="cb7-34">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> Callables<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()...;</span></span>
<span id="cb7-35"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb7-36"></span>
<span id="cb7-37"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> test_single_dispatch<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb7-38">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb7-39"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb7-40"></span>
<span id="cb7-41"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> test_double_dispatch<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb7-42">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> v1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb7-43">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> v2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.14</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">f</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb7-44"></span>
<span id="cb7-45">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> result <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>example<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb7-46">        Visitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-47">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(int, int)"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb7-48">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(int, float)"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb7-49">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(float, int)"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb7-50">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(float, float)"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb7-51">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb7-52">        v1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> v2</span>
<span id="cb7-53">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb7-54"></span>
<span id="cb7-55">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"result = "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> result <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-56"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
</section>
<section id="generalizing-to-a-pack-of-variants." class="level1">
<h1>Generalizing to a pack of variants.</h1>
<p>The shape of a function inside the vtable_func array should be something like this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb8-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span>Visitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> vis<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Variants<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;...</span> var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/* ... */</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>Internally you would invoke <code>vis</code> with <code>std::get&lt;Is&gt;(var)...</code>, where <code>Is...</code> would be an index sequence or constexpr array of the desired indices.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb9-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb9-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Visitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Variants<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb9-3">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">decltype</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Visitor <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span>visitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Variants <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;...</span>vs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb9-4">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t vtable_size <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant_size_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>remove_cvref_t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Variants<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...);</span></span>
<span id="cb9-5"></span>
<span id="cb9-6">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Each entry in the vtable should have the shape [](Visitor visitor, Variants... vs){}</span></span>
<span id="cb9-7">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">result_t</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">decltype</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>visitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>vs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)...));</span></span>
<span id="cb9-8">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">cases_t</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">result_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*)(</span>Visitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Variants<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...);</span></span>
<span id="cb9-9"></span>
<span id="cb9-10">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">static</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> vtable<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb9-11">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Indices<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>index_sequence<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Indices<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;){</span></span>
<span id="cb9-12">                <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">sizeof</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...(</span>Variants<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)&gt;</span> dimensions <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant_size_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>remove_cvref_t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Variants<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;...</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb9-13">                <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t vtable_size <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant_size_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>remove_cvref_t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Variants<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...);</span></span>
<span id="cb9-14">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">cases_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> vtable_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;{</span></span>
<span id="cb9-15">                    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span>Visitor vis<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Variants<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> vs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">result_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb9-16">                        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> multi_idx <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>from_1d_index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant_size_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>remove_cvref_t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Variants<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;...&gt;(</span>Indices<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb9-17">                        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[&amp;]&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Is<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>index_sequence<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Is<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;){</span></span>
<span id="cb9-18">                            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> vis<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">((</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_cast</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant_alternative_t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Is<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>remove_cvref_t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Variants<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>multi_idx<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>Is<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]&gt;(</span>vs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)))...);</span></span>
<span id="cb9-19">                        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>make_index_sequence<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">sizeof</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...(</span>Variants<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)&gt;());</span></span>
<span id="cb9-20">                    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}...</span></span>
<span id="cb9-21">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb9-22">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>make_index_sequence<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>vtable_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;())</span></span>
<span id="cb9-23">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb9-24"></span>
<span id="cb9-25">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>to_1d_index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant_size_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>remove_cvref_t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Variants<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;...&gt;(</span>vs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()...);</span></span>
<span id="cb9-26">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> vtable<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">](</span>visitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> vs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb9-27">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb9-28"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb9-29"></span>
<span id="cb9-30"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> test_multiple_dispatch<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb9-31">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> v1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb9-32">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> v2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.14</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">f</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb9-33">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//std::variant&lt;char, int, long, float, double&gt; v3{'H'};</span></span>
<span id="cb9-34"></span>
<span id="cb9-35">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> result <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb9-36">        Visitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb9-37">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(int, int)"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb9-38">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(int, float)"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb9-39">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(int, double)"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb9-40">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(float, int)"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb9-41">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb9-42">        v1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> v2</span>
<span id="cb9-43">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb9-44"></span>
<span id="cb9-45">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"result = "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> result <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb9-46"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://godbolt.org/z/z5q6s7nrr">Compiler Explorer</a></p>
<section id="references" class="level2">
<h2 class="anchored" data-anchor-id="references">References</h2>
<ul>
<li><a href="https://www.youtube.com/watch?v=3KyW5Ve3LtI">Implementing <code>variant</code> visitation using lambdas</a>, CppCon 2017 talk by Vittorio Romeo.</li>
</ul>


</section>
</section>

 ]]></description>
  <category>C++</category>
  <guid>http://quantdev.blog/posts/implementing_visit/</guid>
  <pubDate>Fri, 24 Apr 2026 23:00:00 GMT</pubDate>
  <media:content url="http://quantdev.blog/posts/implementing_visit/cpp.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>The Visitor pattern and multiple dispatch</title>
  <dc:creator>`dev::author` </dc:creator>
  <link>http://quantdev.blog/posts/visitor_pattern/</link>
  <description><![CDATA[ 





<section id="what-is-the-visitor-pattern" class="level1">
<h1>What is the Visitor pattern?</h1>
<p>The Visitor pattern is a pattern that separates the algorithm from the object structure, which is the data for this algorithm. Using the Visitor pattern, we can add a new operation to the class hierarchy without modifying the classes themselves. The use of the Visitor pattern follows the <strong>open/closed principle</strong> of software design - a class (or another unit of code, such as a module) should be closed for modifications; once the class presents an interface to clients, the clients come to depend on this interface and the functionality it provides. This interface should remain stable; it should not be necessary to modify the classes in order to maintain the software and continue its development. At the same time, a class should be open for extensions - new functionality can be added to satisfy new requirements.</p>
<p>When viewed this way, the Visitor pattern allows us to add functionality to a class or an entire class hierarchy without having to modify the class. This feature can be particularly useful when dealing with public APIs - the users of the API can extend it with additional operations wihtout having the modify the source code.</p>
<p>A very different, more technical way to describe the Visitor pattern is to say that it implements <strong>double dispatch</strong>. This requires some explanation. Let’s start with the regular virtual function calls.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb1-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;print&gt;</span></span>
<span id="cb1-2"></span>
<span id="cb1-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> Base<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-4">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb1-5">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">virtual</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-6"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb1-7"></span>
<span id="cb1-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> Derived1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> Base<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-9">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb1-10">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Derived1::f()"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-11"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb1-12"></span>
<span id="cb1-13"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> Derived2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> Base<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-14">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb1-15">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Derived2::f()"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-16"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb1-17"></span>
<span id="cb1-18"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb1-19">    Base<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> b<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb1-20">    b <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> Derived1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb1-21">    b<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb1-22">    b <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> Derived2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb1-23">    b<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb1-24"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/d8Tqa7W3E">Compiler Explorer</a></p>
<p>If we invoke the <code>b-&gt;f()</code> virtual function through a pointer to the <code>b</code> base class, the call is dispatched to <code>Derived1::f()</code> or <code>Derived2::f()</code>, depending on the real type of the object. This is called <strong>single dispatch</strong> - the function that is actually called is determined by a single factor, the type of the object.</p>
<p>Now, let’s assume that the function <code>f()</code> also takes an argument that is a pointer to the base class:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb2-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;print&gt;</span></span>
<span id="cb2-2"></span>
<span id="cb2-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> Base<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-4">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb2-5">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">virtual</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Base<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-6">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">virtual</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> g<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-7"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb2-8"></span>
<span id="cb2-9"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> Derived1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> Base<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-10">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb2-11">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Base<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Derived1::f()"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>g<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-12">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> g<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Derived1::g()"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-13"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb2-14"></span>
<span id="cb2-15"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> Derived2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> Base<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-16">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb2-17">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Base<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Derived2::f()"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>g<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-18">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> g<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Derived2::g()"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-19"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb2-20"></span>
<span id="cb2-21"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb2-22">    Base<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> b<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb2-23">    Base<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb2-24"></span>
<span id="cb2-25">    b <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> Derived1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb2-26">    p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> Derived1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb2-27">    b<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb2-28">    p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> Derived2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb2-29">    b<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb2-30"></span>
<span id="cb2-31">    b <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> Derived2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb2-32">    p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> Derived1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb2-33">    b<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb2-34">    p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> Derived2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb2-35">    b<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb2-36"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/fYEaTojrx">Compiler Explorer</a></p>
<p>The actual type of the <code>p*</code> object is also one of the derived classes. Now, the <code>b-&gt;f(p)</code> call can have four different versions: both the <code>*b</code> and <code>*p</code> objects can be of either of the two derived types. It is reasonable to want the implementation to do something different in each of these cases. This would be double dispatch - the code that ultimately runs is determined by two separate factors. Virtual functions do not provide a way to implement double dispatch directly, but the Visitor pattern does exactly that.</p>
<p>When presented in this way, it is not obvious that the <strong>double-dispatch</strong> visitor pattern has anything to do with the <strong>operation-adding</strong> visitor pattern. However, they are exactly the same pattern, and the two requirements are really one and the same. Here is a way to look at it that might help - if we want to add an operation to all classes in a hierarchy, that is equivalent to adding a virtual function, so we have one factor controlling the final disposition of each call, the object type. But, if we can effectively add virtual functions, we can add more than one - one for each operation we need to support. The type of operation is the second factor controlling the dispatch, similar to the argument to the function in our previous example. Thus, the operation-adding visitor is able to provide double dispatch. Alternatively, if we had a way to implement double dispatch, we could do what the Visitor pattern does - effectively add a virtual function for each operation we want to support.</p>
<p>Now, that we know what the Visitor pattern does, it is reasonable to ask, <em>why</em> would we want to do it? What is the use of double dispatch? And why would we want another way to add a virtual function substitute to a class when we can just add a <em>genuine</em> virtual function? Setting aside the case of the public API with unavailable source code, why would we want to add an operation <em>externally</em> instead of implementing it in every class?</p>
<p>Consider the example of the serialization/deserialization problem. Serialization is an operation that converts an object into a format that can be stored or transmitted (for example, written into a flat file). Deserialization is the inverse operation - it constructs a new object from its serialized and stored image. To support serialization and deserialization in a straight-forward object-oriented way, each class in the hierarchy would need two methods, one for each operation. But, what if there is more than one way to store an object? For example, we may need to write an object into a memory buffer, to be transmitted across the network and deserialized on another machine. Alternatively, we may need to save the object to disk, or else we may need to convert all objects in a container to a markup format such as JSON. The straightforward approach would have us add a serialization and a deserialization method to every object for every serialization mechanism. If a new and different serialization approach is needed, we have to go over the entire class hierarchy and add support for it.</p>
<p>An alternative is to implement the entire serialization/deserialization operation in a separate function that can handle all classes. The resulting code is a loop that iterates over all objects, with large decision tree inside of it. The code must interrogate every object and determine its type, for example, using dynamic casts. When a new class is added to the hierarchy, all serialization and deserialization implementations must be updated to handle the new objects.</p>
<p>Both implementations are difficult to maintain for large hierarchies. The Visitor pattern offers a solution - it allows us to implement a new operation - in our case, the serialization outside of the classes and without modifying them, but also without the downside of a huge decision tree in a loop. Note that the Visitor pattern is not the only solution to the serialization probleml C++ offers other possible approaches as well, but we focus on the Visitor pattern.</p>
</section>
<section id="basic-visitor-in-c" class="level1">
<h1>Basic Visitor in C++</h1>
<p>The only way to really understand how the Visitor pattern operates is to work through an example. Let’s start with a very simple one. First we need a class hierarchy:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb3-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;string&gt;</span></span>
<span id="cb3-2"></span>
<span id="cb3-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-4">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">virtual</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span>Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){}</span></span>
<span id="cb3-5">    Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string_view color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_color</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> color <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb3-6">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_color</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-7"></span>
<span id="cb3-8">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">private</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb3-9">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_color</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-10"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb3-11"></span>
<span id="cb3-12"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Cat <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-13">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb3-14">    Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string_view color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> color <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb3-15"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb3-16"></span>
<span id="cb3-17"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Dog <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-18">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb3-19">    Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string_view color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> color <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb3-20"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb3-21"></span>
<span id="cb3-22"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/9hchPdEGz">Compiler Explorer</a></p>
<p>In this hierarchy, we have the <code>Pet</code> base class and several derived classes for different pet animals. Now, we want to add some operations to our classes, suhc as <em>feed the pet</em> or <em>play with the pet</em>. The implementation depends on the type of the pet, so these would have to be virtual functions if added directly to each class. This is not a problem for such a simple class hierarchy, but we are anticipating the future need for maintaining a much larger system in which modifying every class in the clas hierarchy is going to be expensive and time-consuming. We need a better way and we begin by creating a new class <code>PetVisitor</code>, which will be applied to every <code>Pet</code> object(visit it) and perform the operations we need. First, we need to declare the class.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb4-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-3"></span>
<span id="cb4-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb4-5">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">virtual</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-6">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">virtual</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-7"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>
<p>We had to forward declare the <code>Pet</code> hierarchy classes because <code>PetVistor</code> has to be declared before the concrete <code>Pet</code> classes. Now, we need to make the <code>Pet</code> hierarchy visitable, which means we do need to modify it, but only once, regardless of how many operations we want to add later. We need to add a virtual function to accept the Visitor pattern to every class that can be visited:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb5-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb5-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">virtual</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-3">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_color</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb5-4"></span>
<span id="cb5-5">    Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string_view color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_color</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> color <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}{}</span></span>
<span id="cb5-6">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">private</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb5-7">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_color</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-8"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb5-9"></span>
<span id="cb5-10"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Cat <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb5-11">    Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string_view color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> color <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}{}</span></span>
<span id="cb5-12">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb5-13"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb5-14"></span>
<span id="cb5-15"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Dog <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb5-16">    Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string_view color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> color <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}{}</span></span>
<span id="cb5-17">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb5-18"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>
<p>Now, our <code>Pet</code> hierarchy is visitable and we have an abstract <code>PetVisitor</code> class. Everything is ready to implement the new operations for our clases(note that nothing that we have done so far depends on what operations we are going to add; we have created the visiting infrastructure that has to be implemented once). The operations are added by implementing concrete Visitor classes derived from <code>PetVisitor</code>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb6-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;print&gt;</span></span>
<span id="cb6-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> FeedingVisitor <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-3">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-4">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Feed tuna to the </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> cat"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb6-5">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-6"></span>
<span id="cb6-7">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-8">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Feed steak to the </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> dog"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb6-9">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-10"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb6-11"></span>
<span id="cb6-12"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> PlayingVisitor <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-13">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-14">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Play with a feather with the </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> cat"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb6-15">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-16"></span>
<span id="cb6-17">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-18">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Play fetch with the </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> dog"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb6-19">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-20"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>
<p>Assuming the visitation infrastructure is already build into our class-hierarchy, we can implement a new operation by implementing a derived <code>Visitor</code> class, and all its virtual functions overrides for <code>visit()</code>. To invoke one of the new operations on an object from our class hierarchy, we need to create a visitor and visit the object:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb7-1">Cat c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"organge tabby"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb7-2">FeedingVisitor fv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-3">c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>fv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Feeding tuna to the organge tabby cat</span></span></code></pre></div></div>
<p>This example of a call is too simple in one important way - at the point of calling the visitor, we know the exact type of the object we are visiting. To make the example more realistic, we have to visit an object polymorphically.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb8-1"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unique_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"orange tabby"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb8-2">FeedingVisitor fv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb8-3">p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>fv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span></code></pre></div></div>
<p>Here, we do not know at compile-time the actual type of the object pointed to by <code>p</code>; at the point where the visitor is accepted, <code>p</code> could come from different sources. Whule less common, the visitor can also be used polymorphically:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb9-1"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unique_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"orange tabby"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb9-2"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unique_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> FeedingVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb9-3">p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span>v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/YhxsY9sG5">Compiler Explorer</a></p>
<p>When written this way, the code highlights the double dispatch aspect of the visitor pattern - the call to <code>accept()</code> ends up dispatched to a particular <code>visit()</code> function based on two factors - the type of the visitable <code>*p</code> object and the type of the visitor <code>*v</code> object.</p>
<p>We now have the most bare-bones example of the class object-oriented visitor in C++. Despite its simplicity, it has all the necessary components: an implementation for a large real-life class hierarchgy and multiple visitor operations has a lot more code, but no new kinds of code, just more of things we have already done. This example shows both aspects of the Visitor pattern: on the one hand, if we focus on the functionality of the software, with the visitation infrastructure now in place, we can add new operations without any changes to the classes themselves. On the other hand, if we look just at the way the operation is invoked, the <code>accept()</code> call, we have implemented double dispatch.</p>
<p>We can immediately see the appeal of the Visitor pattern, we can add any number of new operations without having to modify every class in the hierarchy. If a new class is added to the <code>Pet</code> hierarchy, it is impossible to forget to handle it - if we do nothing at all to the visitor, the <code>accept()</code> call on the new class will not compile since there is no corresponding <code>visit()</code> function to call. Once we add the new <code>visit()</code> overload to the <code>PetVisitor</code> base class, we have to add it to all derived classes as well; otherwise the compiler will let us know that we have a pure virtual function without an override. The latter is also one of the main disadvantages of the Visitor pattern - if a new class is added to the hierarchy. all visitors must be updated, whether the new classes actually need to support these operations or not. For this reason, it is sometimes recommended to use the visitor only on <em>relatively stable</em> hierarchies that do not have new classes added often. There is also an alternative visitor implementation that somewhat mitigates this problem.</p>
</section>
<section id="visitor-generalizations-and-limitations" class="level1">
<h1>Visitor generalizations and limitations</h1>
<p>Our very first visitor in the previous section allowed us to effectively add a virtual function to every class in the hierarchy. That virtual function had no parameters and no return value. The former is easy to extend, there is no reason at all why our <code>visit()</code> functions cannot have parameters. Let’s expand our class hierarchy by allowing our pets to be kittens and puppies. This extension cannot be done using only the Visitor pattern - we need to add not only new operations but also new data memebers. The Visitor pattern can be used for the former, but the latter requires code changes.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb10-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb10-2">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> add_child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_children</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>push_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb10-3">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">virtual</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb10-4">    Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string_view color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_color</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> color <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}{}</span></span>
<span id="cb10-5">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_color</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb10-6"></span>
<span id="cb10-7">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">private</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb10-8">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*&gt;</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_children</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb10-9">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string       <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_color</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb10-10"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>
<p>Each parent <code>Pet</code> object tracks its child objects (note that the container is a vector of pointers, not a vector of unique pointers, so the object doesn’t own its children, but merely has access to them). We have also added the new <code>add_child()</code> member function to to add objects to the vector. We could have done this with a visitor, but this function is non-virtual, so we have to add it only once to the base class, not to every derived class - the visitor is unnecessary here. The <code>accept()</code> function has been modified to have an additional parameter that would have to be added to all derived classes as well, where it is simply forwarded to the <code>visit()</code> function:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb11-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb11-2">    </span>
<span id="cb11-3">    Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string_view color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb11-4"></span>
<span id="cb11-5">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb11-6">        v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb11-7">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb11-8"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb11-9"></span>
<span id="cb11-10"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Dog <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb11-11">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb11-12">    Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string_view color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb11-13">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb11-14">        v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb11-15">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb11-16"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>The <code>visit()</code> function also has to be modified to accept the additional argument, even for the visitors that do not need it. Changing the parameters of the <code>accept()</code> function is, therefore, an expensive global operation that should not be done often, if at all. Note that, all overrides for the same virtual function in the hierarchy already have to have the same parameters. The Visitor pattern extends this restriction to all operations added using the same base Visitor object. A common workaround for this is to pass parameters using aggregates (classes or structures that combine multiple parameters together). The <code>visit()</code> function is declared to accept a pointer to the base aggregate class, while each visitor receives a pointer to a derived class that may have additional fields, and uses them as needed.</p>
<p>Now, our additional argument is forwarded through the chain of virtual function calls to the visitor, where we can make use of it. Let’s create a visitor that records the pet births and adds new pet objects, as children to their parent objects:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb12-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;vector&gt;</span></span>
<span id="cb12-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;print&gt;</span></span>
<span id="cb12-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;memory&gt;</span></span>
<span id="cb12-4"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;cassert&gt;</span></span>
<span id="cb12-5"></span>
<span id="cb12-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb12-7"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb12-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb12-9"></span>
<span id="cb12-10"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb12-11">   <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">virtual</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb12-12">   <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">virtual</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb12-13"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb12-14"></span>
<span id="cb12-15"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb12-16">   <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> add_child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_children</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>push_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb12-17">   <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">virtual</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb12-18">   Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string_view color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_color</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> color <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}{}</span></span>
<span id="cb12-19">   <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_color</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb12-20"></span>
<span id="cb12-21">   <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">private</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb12-22">   <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*&gt;</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_children</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb12-23">   <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string       <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_color</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb12-24"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb12-25"></span>
<span id="cb12-26"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Cat <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb12-27">   Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string_view color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> color <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}{}</span></span>
<span id="cb12-28">   <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb12-29"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb12-30"></span>
<span id="cb12-31"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Dog <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb12-32">   Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string_view color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> color <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}{}</span></span>
<span id="cb12-33">   <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb12-34"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb12-35"></span>
<span id="cb12-36"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> FeedingVisitor <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb12-37">   <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb12-38">       <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Feed tuna to the </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> cat"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb12-39">   <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb12-40"></span>
<span id="cb12-41">   <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb12-42">       <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Feed steak to the </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> dog"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb12-43">   <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb12-44"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb12-45"></span>
<span id="cb12-46"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> PlayingVisitor <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb12-47">   <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb12-48">       <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Play with a feather with the </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> cat"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb12-49">   <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb12-50"></span>
<span id="cb12-51">   <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb12-52">       <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Play fetch with the </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> dog"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb12-53">   <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb12-54"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb12-55"></span>
<span id="cb12-56"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> BirthVisitor <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb12-57">   <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb12-58">       <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">dynamic_cast</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*&gt;(</span>child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb12-59">       c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>add_child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb12-60">       <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> gave birth to child </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb12-61">   <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb12-62"></span>
<span id="cb12-63">   <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb12-64">       <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">dynamic_cast</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*&gt;(</span>child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb12-65">       d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>add_child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb12-66">       <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> gave birth to child </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb12-67">   <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb12-68"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb12-69"></span>
<span id="cb12-70"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb12-71">   <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unique_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> parent<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"orange tabby"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb12-72">   Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"calico"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb12-73"></span>
<span id="cb12-74">   <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unique_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> pv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> PlayingVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb12-75">   <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unique_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> fv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> FeedingVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb12-76">   BirthVisitor bv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb12-77"></span>
<span id="cb12-78">   parent<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span>pv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Play with a feather with orange tabby cat</span></span>
<span id="cb12-79">   parent<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span>fv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Feeding tuna to the organge tabby cat</span></span>
<span id="cb12-80">   parent<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>bv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb12-81"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/nTbW1azoT">Compiler Explorer</a></p>
<p>Once we have established the parenthood relationships, we want to examine our pet families. That is another operation we want to add, which calls for another visitor.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb13-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;print&gt;</span></span>
<span id="cb13-2"></span>
<span id="cb13-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> FamilyTreeVisitor <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb13-4">   <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb13-5">       <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Kittens : "</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb13-6">       <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> k <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_children</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb13-7">           <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> k<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb13-8">       <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb13-9">   <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb13-10"></span>
<span id="cb13-11">   <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb13-12">       <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Puppies : "</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb13-13">       <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_children</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb13-14">           <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb13-15">       <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb13-16">   <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb13-17"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>
<p>We have hit a slight problem, though, because as written, the code will not compile. The reason is that the <code>FamilyTreeVisitor</code> is trying to access the <code>Pet::m_children</code> data member, which is private. THis is another weakness of the Visitor pattern - from our point of view, the visitors add new operations to the classes, just like virtual functions, but from the compiler’s point of view, they are completely separate classes, not at all like member functions of the <code>Pet</code> classes and have no special access. Application of the visitor pattern usually requires that the encapsulation is relaxed in one of two ways - we can either allow public access to the data(directly or through <code>get</code> member functions) or declare the Visitor classes to be friends. In our example, we will follow the second route:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb14-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;vector&gt;</span></span>
<span id="cb14-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;print&gt;</span></span>
<span id="cb14-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;memory&gt;</span></span>
<span id="cb14-4"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;cassert&gt;</span></span>
<span id="cb14-5"></span>
<span id="cb14-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb14-7"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb14-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb14-9"></span>
<span id="cb14-10"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb14-11">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">virtual</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb14-12">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">virtual</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb14-13"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb14-14"></span>
<span id="cb14-15"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb14-16">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">friend</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> FamilyTreeVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb14-17"></span>
<span id="cb14-18">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> add_child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_children</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>push_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb14-19">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">virtual</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb14-20">    Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string_view color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_color</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> color <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}{}</span></span>
<span id="cb14-21">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_color</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb14-22"></span>
<span id="cb14-23">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">private</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb14-24">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*&gt;</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_children</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb14-25">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string       <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_color</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb14-26"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb14-27"></span>
<span id="cb14-28"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Cat <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb14-29">    Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string_view color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> color <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}{}</span></span>
<span id="cb14-30">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb14-31"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb14-32"></span>
<span id="cb14-33"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Dog <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb14-34">    Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string_view color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> color <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}{}</span></span>
<span id="cb14-35">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb14-36"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb14-37"></span>
<span id="cb14-38"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> FeedingVisitor <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb14-39">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb14-40">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Feed tuna to the </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> cat"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb14-41">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb14-42"></span>
<span id="cb14-43">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb14-44">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Feed steak to the </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> dog"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb14-45">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb14-46"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb14-47"></span>
<span id="cb14-48"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> PlayingVisitor <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb14-49">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb14-50">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Play with a feather with the </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> cat"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb14-51">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb14-52"></span>
<span id="cb14-53">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb14-54">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Play fetch with the </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> dog"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb14-55">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb14-56"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb14-57"></span>
<span id="cb14-58"> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> BirthVisitor <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb14-59">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb14-60">        <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">dynamic_cast</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*&gt;(</span>child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb14-61">        c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>add_child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb14-62">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> gave birth to child </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb14-63">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb14-64"></span>
<span id="cb14-65">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb14-66">        <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">dynamic_cast</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*&gt;(</span>child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb14-67">        d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>add_child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb14-68">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> gave birth to child </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb14-69">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb14-70"> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb14-71"></span>
<span id="cb14-72"></span>
<span id="cb14-73"> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> FamilyTreeVisitor <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb14-74">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb14-75">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Kittens"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb14-76">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> k <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_children</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb14-77">            <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\t{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> k<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb14-78">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb14-79">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb14-80"></span>
<span id="cb14-81">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb14-82">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Puppies"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb14-83">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_children</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb14-84">            <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\t{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb14-85">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb14-86">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb14-87"> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb14-88"></span>
<span id="cb14-89"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb14-90">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unique_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> parent<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"orange tabby"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb14-91">    Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> child1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"calico"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb14-92">    Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> child2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"garfield"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb14-93"></span>
<span id="cb14-94">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unique_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> pv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> PlayingVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb14-95">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unique_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> fv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> FeedingVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb14-96">    BirthVisitor bv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb14-97"></span>
<span id="cb14-98">    parent<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span>pv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Play with a feather with orange tabby cat</span></span>
<span id="cb14-99">    parent<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span>fv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Feeding tuna to the organge tabby cat</span></span>
<span id="cb14-100">    parent<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>bv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> child1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb14-101">    parent<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>bv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> child2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb14-102"></span>
<span id="cb14-103">    FamilyTreeVisitor tv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb14-104">    parent<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>tv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb14-105"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/WGv6P548a">Compiler Explorer</a></p>
<p>Unlike <code>BirthVisitor</code>, <code>FamilyTreeVisitor</code> does not need the additional argument.</p>
<p>Now, we have visitors that implement operations with parameters. What about return values? Technically, there is no requirement for <code>visit()</code> and <code>accept()</code> functions to return <code>void</code>. They can return anything else. However, the limitation that they have to all return the same type usuallyt makes this capability useless. Virtual functions can have covariant return types, where the base class virtual function returns an object of some class and the derived class overrides return objects derived from that class, but even that is usually too limiting. There is another, much simpler solution - the <code>visit()</code> functions of every visitor object has full access to the data members of the object. THere is no reason why we cannot store the the return value in the Visitor class itself and access it later. This fits well with the most common use where each visitor adds a different operation and is likely to have a unique return type, but the operation itself usually has the same return type for all the classes in the hierarchy. For example, we can make our <code>FamilyTreeVisitor</code> count the total number of children and return the value through the visitor object.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb15-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;vector&gt;</span></span>
<span id="cb15-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;print&gt;</span></span>
<span id="cb15-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;memory&gt;</span></span>
<span id="cb15-4"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;cassert&gt;</span></span>
<span id="cb15-5"></span>
<span id="cb15-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb15-7"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb15-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb15-9"></span>
<span id="cb15-10"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb15-11">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">virtual</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb15-12">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">virtual</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb15-13"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb15-14"></span>
<span id="cb15-15"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb15-16">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">friend</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> FamilyTreeVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb15-17"></span>
<span id="cb15-18">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> add_child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_children</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>push_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb15-19">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">virtual</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb15-20">    Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string_view color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_color</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> color <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}{}</span></span>
<span id="cb15-21">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_color</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb15-22"></span>
<span id="cb15-23">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">private</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb15-24">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*&gt;</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_children</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb15-25">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string       <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_color</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb15-26"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb15-27"></span>
<span id="cb15-28"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Cat <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb15-29">    Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string_view color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> color <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}{}</span></span>
<span id="cb15-30">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb15-31"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb15-32"></span>
<span id="cb15-33"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Dog <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb15-34">    Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string_view color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> color <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}{}</span></span>
<span id="cb15-35">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb15-36"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb15-37"></span>
<span id="cb15-38"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> FeedingVisitor <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb15-39">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb15-40">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Feed tuna to the </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> cat"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb15-41">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb15-42"></span>
<span id="cb15-43">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb15-44">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Feed steak to the </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> dog"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb15-45">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb15-46"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb15-47"></span>
<span id="cb15-48"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> PlayingVisitor <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb15-49">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb15-50">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Play with a feather with the </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> cat"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb15-51">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb15-52"></span>
<span id="cb15-53">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb15-54">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Play fetch with the </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> dog"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb15-55">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb15-56"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb15-57"></span>
<span id="cb15-58"> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> BirthVisitor <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb15-59">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb15-60">        <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">dynamic_cast</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*&gt;(</span>child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb15-61">        c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>add_child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb15-62">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> gave birth to child </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb15-63">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb15-64"></span>
<span id="cb15-65">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb15-66">        <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">dynamic_cast</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*&gt;(</span>child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb15-67">        d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>add_child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb15-68">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> gave birth to child </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> child<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb15-69">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb15-70"> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb15-71"></span>
<span id="cb15-72"></span>
<span id="cb15-73"> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> FamilyTreeVisitor <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb15-74">    FamilyTreeVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_child_count</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">uz</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb15-75">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> reset<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_child_count</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb15-76">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> get_child_count<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_child_count</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb15-77"></span>
<span id="cb15-78">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb15-79">        visit_impl<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Kittens"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb15-80">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb15-81"></span>
<span id="cb15-82">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Dog<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb15-83">        visit_impl<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Puppies"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb15-84">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb15-85"></span>
<span id="cb15-86">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">private</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb15-87">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_child_count</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb15-88"></span>
<span id="cb15-89">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb15-90">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit_impl<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb15-91">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb15-92">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_children</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb15-93">            <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\t{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb15-94">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_child_count</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb15-95">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb15-96">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb15-97"> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb15-98"></span>
<span id="cb15-99"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb15-100">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unique_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> parent<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"orange tabby"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb15-101">    Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> child1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"calico"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb15-102">    Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> child2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> Cat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"garfield"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb15-103"></span>
<span id="cb15-104">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unique_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> pv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> PlayingVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb15-105">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unique_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> fv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> FeedingVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb15-106">    BirthVisitor bv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb15-107"></span>
<span id="cb15-108">    parent<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span>pv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Play with a feather with orange tabby cat</span></span>
<span id="cb15-109">    parent<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span>fv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Feeding tuna to the organge tabby cat</span></span>
<span id="cb15-110">    parent<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>bv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> child1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb15-111">    parent<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>bv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> child2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb15-112"></span>
<span id="cb15-113">    FamilyTreeVisitor tv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb15-114">    parent<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>tv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb15-115"></span>
<span id="cb15-116">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> kittens total"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> tv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>get_child_count<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb15-117"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/cTndEvYPb">Compiler Explorer</a></p>
<p>This approach imposes some limitations in multithreaded programs - the visitor is now not thread safe since multiple threads cannot use the same Visitor object to visit different pet objects. The most common solution is to use one visitor object per thread.</p>
<p>Let’s return for a moment and examine the <code>FamilyTreeVisitor</code> implementation again. Note that it iterates over the child objects of the parent object and calls the same operation on each one, in turn. It does not, however, process the children of the child object - our family tree is only one-generation deep. The problem of visiting objects that contain other objects is very general and occurs rather often. Our motivational example - the problem of serialization demonstrates this need perfectly - every complex object is serialized by serializing its components one by one and they in turn are serialized the same way, until we get all the way down to the built-in types such as <code>int</code> and <code>double</code> which we know to read and write.</p>
</section>
<section id="visiting-complex-objects" class="level1">
<h1>Visiting complex objects</h1>
<p>In the last section, we saw, how the Visitor pattern allows us to add new operations to the existing hierarchy. In one of the examples, we visited a complex object that contained pointers to other objects. The visitor iterated over these pointers, in a limited way. We are now going to consider the general problem of visiting objects that are composed of other objects, or objects that contain other objects and build up to the demonstration of a working serialization./deserialization solution at the end.</p>
<section id="visiting-composite-objects" class="level2">
<h2 class="anchored" data-anchor-id="visiting-composite-objects">Visiting composite objects</h2>
<p>The general idea of visiting complex objects is quite straightforward - when visiting the object itself, we generally do not know all the details of how to handle each component or contained object. But there is something else that does - the visitor for that object type is written specifically to handle that class and nothing else. This observation suggests that the correct way to handle the component objects is to simply visit each one, and thus delegate the problem to someone else.</p>
<p>Let’s first demonstrate this idea on the example of a simple container class, such as the <code>Shelter</code> class, which can contain any number of pet objects representing the pets waiting for adoption:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb16-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Shelter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb16-2">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> add<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb16-3">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_pets</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>emplace_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb16-4">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb16-5"></span>
<span id="cb16-6">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb16-7">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_pets</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb16-8">            p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb16-9">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb16-10">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb16-11"></span>
<span id="cb16-12">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">private</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb16-13">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unique_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Pet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_pets</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb16-14"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>
<p>This class is essentially an adapter to make a vector of pet objects visitable(more on the adapter pattern in another blog post). Note that the objects of this class do own the pet objects they contain - when the <code>Shelter</code> object is destroyed, so are all the <code>Pet</code> objects in the vector. Any container of unique pointers is a container that owns its contained objects; this is how polymorphic objects should be stored in a container such as <code>std::vector</code>.</p>
<p>The code relevant to our current problem is, of course, <code>Shelter::accept()</code>, which determines how a <code>Shelter</code> object is visited. As you can see, we do not invoke the visitor on the shelter object itself. Instead, we delegate the visitation to each of the containing objects. Since our Visitors are already written to handle <code>Pet</code> objects, nothing more needs to be done. When <code>Shelter</code> is visited by, say, <code>FeedingVisitor</code>, every pet in the shelter gets fed, and we didn’t have to write any special code to make it happen.</p>
<p>Visitation of composite objects is done in a similar manner - if an object is composed of several smaller objects, we have to visit each of these objects. Let’s consider an object representing a family with two family pets, a dog and a cat(the humans who serve the pets are not included in the following code, but we assume they are there too):</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb17-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Family<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb17-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb17-3">    Family<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> car<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> cat_color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> dog_color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb17-4">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_cat</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> cat_color <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb17-5">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_dog</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> dog_color <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb17-6">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb17-7"></span>
<span id="cb17-8">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>PetVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb17-9">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_cat</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb17-10">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_dog</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb17-11">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb17-12"></span>
<span id="cb17-13">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">private</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb17-14">    Cat <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_cat</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb17-15">    Dog <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_dog</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb17-16"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>
<p>Again, visiting the family with a visitor from the <code>PetVisitor</code> hierarchy is delegated so that each <code>Pet</code> object is visited, and the visitors already have everything they need to handle these objects. Now, at last, we have all the pieces we need to tackle the problem of serialization and deserialization of arbitrary objects.</p>
</section>
</section>
<section id="serialization-and-deserialization-with-visitor" class="level1">
<h1>Serialization and Deserialization with visitor</h1>
<p>The problem itself was described in detail in the previous section - for serialization, each object needs to be converted to a sequence of bits, and these bits need to be stored, copied or sent. The first part of the action depends on the object(each object is converted differently), but the second part depends on the specific application of the serialization(saving to the disk is different from sending across the network). The implementation depends on two factors, hence the need for double dispatch, which is exactly what the Visitor pattern provides. Furthermore, if we have a way to serialize some object and then deserialize it (reconstruct the object from the sequence of bits), we should use the same method when this object is included in another object.</p>
<p>To demonstrate serialization/deserialization of a class hierarchy using the Visitor pattern. we meed a more complex hierarchy than the toy examples we have used so far. Let’s consider this hierarchy of two-dimensional geometric objects:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb18-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Geometry<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb18-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">virtual</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span>Geometry<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){}</span></span>
<span id="cb18-3"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb18-4"></span>
<span id="cb18-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Point <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> Geometry<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb18-6">    Point<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">default</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb18-7">    Point<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span> y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">x_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">y_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb18-8">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb18-9"></span>
<span id="cb18-10">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">private</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb18-11">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">x_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb18-12">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">y_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb18-13"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb18-14"></span>
<span id="cb18-15"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Circle <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> Geometry<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb18-16">    Circle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">default</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb18-17">    Circle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Point center<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span> radius<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> </span>
<span id="cb18-18">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">center_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> center <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb18-19">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">radius_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> radius <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb18-20">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb18-21"></span>
<span id="cb18-22">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">private</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb18-23">    Point <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">center_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb18-24">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">radius_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb18-25"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb18-26"></span>
<span id="cb18-27"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Line <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> Geometry<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb18-28">    Line<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">default</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb18-29">    Line<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Point p1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Point p2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> </span>
<span id="cb18-30">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">p1_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> p1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb18-31">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">p2_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> p2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb18-32">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb18-33"></span>
<span id="cb18-34">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">private</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb18-35">    Point <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">p1_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb18-36">    Point <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">p2_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb18-37"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>All objects derived from the abstract <code>Geometry</code> base class, but the more complex object contains one or more of the simpler objects; for example, <code>Line</code> is defined by two <code>Point</code> objects. Note that, at the end of the day, all our objects are made of <code>double</code> numbers, and therefore, will serialize into a sequence of numbers. The key is knowing, which <code>double</code> represents which field of which object: we ned this to restore the original objects correctly.</p>
<p>To serialize these objects using the Visitor pattern, we follow the same process we used in the last section. First, we need to declare the base Visitor class:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb19" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb19-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Visitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb19-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">virtual</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb19-3">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">virtual</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Point<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb19-4">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">virtual</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Circle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb19-5">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">virtual</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Line<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb19-6"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>
<p>There is one additional detail here - we can also visit double values; each visitor would need to handle them appropriately(write them, read them and so on). Visiting any geometry object will result, eventually, in visiting the numbers it is composed of.</p>
<p>Our base <code>Geometry</code> class and all classes derived from it need to accept this visitor:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb20-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Geometry<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb20-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">virtual</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span>Geometry<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){}</span></span>
<span id="cb20-3">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">virtual</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Visitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb20-4"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>
<p>There is of course, no way to add an <code>accept()</code> member function to <code>double</code>, but we won’t have to. The <code>accept()</code> member functions of the derived classes, each of which is composed of one or more members and other classes, visit every data member in order:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb21" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb21-1"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> Point<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>accpet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Visitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb21-2">    v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">x_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb21-3">    v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">y_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb21-4"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb21-5"></span>
<span id="cb21-6"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> Circle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Visitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb21-7">    v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">center_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb21-8">    v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">radius_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb21-9"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb21-10"></span>
<span id="cb21-11"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> Line<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Visitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb21-12">    v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">p1_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb21-13">    v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">p2_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb21-14"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>The concrete Visitor classes, all derived from the base <code>Visitor</code> class, are responsible for the specific mechanisms of serialization and deserialization. The order in which the objects are broken down into their parts, all the way down to the numbers, is controlled by each object, but the visitors determine what is done with these numbers. For example, we can serialize all objects into a string using formatted I/O(similar to what we get if we print the numbers into <code>cout</code>).</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb22" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb22-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> StringSerializeVisitor <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> Visitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb22-2">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb22-3">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">sstream_</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">" "</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb22-4">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb22-5">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Point<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb22-6">        p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb22-7">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb22-8"></span>
<span id="cb22-9">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Line<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb22-10">        l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>accept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb22-11">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb22-12"></span>
<span id="cb22-13">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string str<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb22-14">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">sstream_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>str<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb22-15">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb22-16"></span>
<span id="cb22-17">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">private</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb22-18">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>stringstream <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">sstream_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb22-19"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>
<p>The string is accumulated in <code>stringstream</code> until all the ncessary objects are serialized.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb23" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb23-1">Point p1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb23-2">Point p2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb23-3">Line l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>p1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> p2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb23-4">Circle c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>p1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">5.0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb23-5"></span>
<span id="cb23-6">StringSerializeVisitor serializer<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb23-7">serializer<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb23-8">serializer<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb23-9"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>serializer<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>str<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()};</span></span></code></pre></div></div>
<p>Now, that we have the objects printed into the <code>s</code> string, we can also restore them from this string perhaps on a different machine(if we arranged for the string to be sent there). First, we need the deserializing visitor:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb24" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb24-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> StringDeserializeVisitor <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> Visitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb24-2">    StringDeserializeVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb24-3">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">sstream_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>str<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb24-4">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb24-5"></span>
<span id="cb24-6">    </span>
<span id="cb24-7"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>


</section>

 ]]></description>
  <category>C++</category>
  <guid>http://quantdev.blog/posts/visitor_pattern/</guid>
  <pubDate>Fri, 10 Apr 2026 23:00:00 GMT</pubDate>
  <media:content url="http://quantdev.blog/posts/visitor_pattern/cpp.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>Implementing std::variant</title>
  <dc:creator>`dev::author` </dc:creator>
  <link>http://quantdev.blog/posts/implementing_variant/</link>
  <description><![CDATA[ 





<section id="introduction" class="level1">
<h1>Introduction</h1>
<p>C unions are simple and crude. You don’t have a way to know what’s the currently active type. The destructor is implicitly deleted, and if the user supplies a destructor, we don’t know which underlying type should be destroyed.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb1-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;iostream&gt;</span></span>
<span id="cb1-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;vector&gt;</span></span>
<span id="cb1-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;string&gt;</span></span>
<span id="cb1-4"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;print&gt;</span></span>
<span id="cb1-5"></span>
<span id="cb1-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">union</span> S<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-7">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string str<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-8">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-9">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span>S<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){}</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// what to delete?</span></span>
<span id="cb1-10"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb1-11"></span>
<span id="cb1-12"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb1-13">    S s <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Hello World"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb1-14">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"s.str = </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>str<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-15"></span>
<span id="cb1-16">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// you have to call the destructor of the contained objects</span></span>
<span id="cb1-17">    s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>str<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.~</span>basic_string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;();</span></span>
<span id="cb1-18"></span>
<span id="cb1-19">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// and a constructor</span></span>
<span id="cb1-20">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(&amp;</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;{};</span></span>
<span id="cb1-21"></span>
<span id="cb1-22">    s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>push_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-23">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"s.vec.size() = </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb1-24"></span>
<span id="cb1-25">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// another destructor</span></span>
<span id="cb1-26">    s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.~</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;();</span></span>
<span id="cb1-27"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/WeMMfjh9n">Compiler Explorer</a></p>
<p>As you see, the <code>S</code> union needs a lot of maintenance from our side. We have to know, which type is active and call appropriate constructors/destructors before switching to a new type.</p>
</section>
<section id="stdvariant-usage" class="level1">
<h1><code>std::variant</code> usage</h1>
<p>The <code>std::variant</code> template is essentially a <strong>smart union</strong>. <code>std::variant&lt;T1, T2, T3&gt;</code> is similar to <code>union{T1 v1; T2 v2; T3 v3}</code> in that both can store a value of one of the specified types and only one value can be stored at a time. The key difference is that a variant objects knows which type it contains, while with a union the programmer is wholly responsible for reading the same type as what was written earlier. It is undefined behavior to access a union as a type that differs from the one used to initialize it:</p>
<p>In contrast <code>std::variant</code> offers a safe way to store values of different types in the same memory. It is easy to check at runtime which alternative type is currently stored in the vartiant, and accessing a variant as the wrong type throws an exception.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb2-1"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-2">v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-3"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb2-4"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb2-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// std::get&lt;1&gt;(v);  //throws std::bad_variant_access</span></span></code></pre></div></div>
<p>In many ways, <code>std::variant</code> offers capabilities similar to inheritance-based run-timne polymorphism: both let us write code where the same variable name can refer to objects of different types at run-time. The two major differences are: first, a <code>std::variant</code> does not require that all its types come from the same hierarchy(they need not be classes at all) and second, a variant object can only store one of the types listed in its declaration, while a base class pointer can point to any derived class.</p>
<p>Visitors are objects that are used to implement the Visitor design pattern. Typically, they are used to add an operation to all classes in a class hierarchy, that is the equivalent of adding a virtual function, but without modifying the classes themselves. When a visitor object visits a variant, they invoke the best matching function call operator for the actual value of the variant.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb3-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;variant&gt;</span></span>
<span id="cb3-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;string&gt;</span></span>
<span id="cb3-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;iostream&gt;</span></span>
<span id="cb3-4"></span>
<span id="cb3-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> MyVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-6">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-7">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"int: "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-8">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-9"></span>
<span id="cb3-10">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-11">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"string: "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> s <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> </span>
<span id="cb3-12">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-13"></span>
<span id="cb3-14">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-15">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"double: "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> d <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-16">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-17"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb3-18"></span>
<span id="cb3-19"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb3-20">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-21">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>MyVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// calls operator()(int)</span></span>
<span id="cb3-22"></span>
<span id="cb3-23">    var <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"hello"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-24">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>MyVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// calls operator()(std::string)</span></span>
<span id="cb3-25"></span>
<span id="cb3-26">    var <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.14</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-27">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>MyVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// calls operator()(double)</span></span>
<span id="cb3-28">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-29"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/Tzn53YT76">Compiler Explorer</a></p>
</section>
<section id="using-generic-lambdas-as-visitors" class="level1">
<h1>Using generic lambdas as visitors</h1>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb4-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;variant&gt;</span></span>
<span id="cb4-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;string&gt;</span></span>
<span id="cb4-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;iostream&gt;</span></span>
<span id="cb4-4"></span>
<span id="cb4-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> printVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb4-6">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-7"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb4-8"></span>
<span id="cb4-9"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb4-10">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb4-11">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>printVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb4-12">    var <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"hello"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-13">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>printVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb4-14">    var <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">42.7</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-15">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>printVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb4-16">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-17"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
</section>
<section id="the-cracked-mans-match" class="level1">
<h1>The cracked-man’s match</h1>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb5-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb5-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> overload <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb5-3">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()...;</span></span>
<span id="cb5-4"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb5-5"></span>
<span id="cb5-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// base types are deduced from the passed arguments</span></span>
<span id="cb5-7"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb5-8">overload<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> overload<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;;</span></span>
<span id="cb5-9"></span>
<span id="cb5-10"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb5-11">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb5-12">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>overload<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb5-13">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"int : "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb5-14">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"string : "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb5-15">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"double : "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb5-16">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span> var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb5-17"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>Since the struct <code>overload</code> inherits from the closure types (<code>__my_lambda_with_int_param_struct</code> and <code>__my_lambda_with_string_param_struct</code>), we need to bring their function call operators in scope.</p>
<section id="multiple-dispatch" class="level2">
<h2 class="anchored" data-anchor-id="multiple-dispatch">Multiple Dispatch</h2>
<p>As mentioned before, the killer feature of <code>std::variant</code> is multiple dispatch. Here is a common interview problem. Imagine you have an excel spreadsheet, and a spreadsheet has cells. By definition, in a cell, you can have either an <code>int</code> or a <code>string</code>. And then, there’s an operation defined like plus <code>operator+()</code>. For example, you can add two numbers. Adding two strings results in concatentation. <code>string</code> + <code>int</code> : you convert into <code>int</code> to <code>string</code> and concatenate. And <code>int</code> + <code>string</code> : you throw an error. This interview problem is much easier to solve, if you have a <code>variant</code>.</p>
<p>Here, you have to select an overload not based on just one type (like in virtual functions), but on two types or in general <img src="https://latex.codecogs.com/png.latex?N"> types.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb6-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;string&gt;</span></span>
<span id="cb6-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;variant&gt;</span></span>
<span id="cb6-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;stdexcept&gt;</span></span>
<span id="cb6-4"></span>
<span id="cb6-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb6-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> overloaded <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...{</span></span>
<span id="cb6-7">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()...;</span></span>
<span id="cb6-8"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb6-9"></span>
<span id="cb6-10"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// base types are deduced from passed arguments</span></span>
<span id="cb6-11"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb6-12">overloaded<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> overloaded<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;;</span></span>
<span id="cb6-13"></span>
<span id="cb6-14"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Cell<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-15">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb6-16"></span>
<span id="cb6-17">    Cell<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+=(</span>Cell<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb6-18">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>overloaded<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-19">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> a<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> b<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span> a <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+=</span> b<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb6-20">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string a<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> b<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span> a <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>to_string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>b<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb6-21">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> a<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string b<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">throw</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>runtime_error<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Invalid inputs!"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb6-22">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string a<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string b<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span> a <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+=</span> b<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-23">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span> data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb6-24"></span>
<span id="cb6-25">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb6-26">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-27"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb6-28"></span>
<span id="cb6-29"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/qqKTK99dE">Compiler Explorer</a></p>
<p><code>std::visit()</code> is a way to dispatch on a variant. It does multiple dispatch - based on my own <code>self</code> Cell type and the <code>other</code> Cell type.</p>
</section>
</section>
<section id="what-is-a-stdvariant-under-the-hood" class="level1">
<h1>What is a <code>std::variant</code> under the hood?</h1>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb7-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Pseudo-code</span></span>
<span id="cb7-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-3">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb7-4">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-5">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">union</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-6">            Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> elements<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-7">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb7-8"></span>
<span id="cb7-9">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ....</span></span>
<span id="cb7-10">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">index_type</span> index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-11">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb7-12"></span>
<span id="cb7-13">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> visitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;...</span> args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb7-14">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">switch</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(...)</span></span>
<span id="cb7-15">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">case</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb7-16">                visitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)...);</span></span>
<span id="cb7-17">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">case</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb7-18">                visitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)...);</span></span>
<span id="cb7-19">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb7-20"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>Under the hood, a <code>std::variant</code> is a union of all of the possible alternatives. It has an active index. And then, in <code>visit</code> there is some sort of <code>switch</code> statement, between all of the possible types. And we’re going to implement all of these components.</p>
</section>
<section id="tmp-utilities" class="level1">
<h1>TMP Utilities</h1>
<p>We are going to start with just a bunch of template metaprogramming utilities.</p>
<section id="find_index_of_v" class="level2">
<h2 class="anchored" data-anchor-id="find_index_of_v"><code>find_index_of_v</code></h2>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb8-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;print&gt;</span></span>
<span id="cb8-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;concepts&gt;</span></span>
<span id="cb8-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;initializer_list&gt;</span></span>
<span id="cb8-4"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;string&gt;</span></span>
<span id="cb8-5"></span>
<span id="cb8-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb8-7"></span>
<span id="cb8-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb8-9">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> type_lists<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb8-10">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb8-11">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> find_index_of_impl<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb8-12">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">uz</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb8-13">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">bool</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">is_same_type</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>is_same_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;...</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}){</span></span>
<span id="cb8-14">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">is_same_type</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb8-15">                    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">break</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb8-16"></span>
<span id="cb8-17">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb8-18">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb8-19"></span>
<span id="cb8-20">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb8-21">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb8-22"></span>
<span id="cb8-23">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// define a concept that checks if the index is not</span></span>
<span id="cb8-24">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// out of bounds</span></span>
<span id="cb8-25">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb8-26">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">concept</span> out_of_bounds_check <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb8-27">            find_index_of_impl<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">sizeof</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...(</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb8-28">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb8-29">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// namespace type_lists</span></span>
<span id="cb8-30"></span>
<span id="cb8-31">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb8-32">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">requires</span> type_lists<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>out_of_bounds_check<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;</span></span>
<span id="cb8-33">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> find_index_of_v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> type_lists<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>find_index_of_impl<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;();</span></span>
<span id="cb8-34"></span>
<span id="cb8-35">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb8-36">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">concept</span> exists <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">requires</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb8-37">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> find_index_of_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb8-38">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb8-39"></span>
<span id="cb8-40"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// namespace tools</span></span>
<span id="cb8-41"></span>
<span id="cb8-42"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb8-43"></span>
<span id="cb8-44"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// -------------- tests ------------</span></span>
<span id="cb8-45"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>find_index_of_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb8-46"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>find_index_of_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb8-47"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>exists<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;);</span></span>
<span id="cb8-48"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(!</span>dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>exists<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;);</span></span>
<span id="cb8-49"></span>
<span id="cb8-50"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/5rbM5cd48">Compiler Explorer</a></p>
</section>
<section id="uint_atleast_t" class="level2">
<h2 class="anchored" data-anchor-id="uint_atleast_t"><code>uint_atleast_t</code></h2>
<p>The next utility we are going to write is <code>uint_atleast_t</code>. I want to represent a number and I want to use the smallest <code>unsigned int</code> possible to store this number. For a <code>100</code>, <code>uint8_t</code> will be enough. For <code>256</code>, I already need <code>uint16_t</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb9-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;cstdint&gt;</span></span>
<span id="cb9-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// -------------- tests ------------</span></span>
<span id="cb9-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>same_as<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint8_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>uint_atleast<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;);</span></span>
<span id="cb9-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>same_as<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint8_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>uint_atleast<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">255</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;);</span></span>
<span id="cb9-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>same_as<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint16_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>uint_atleast<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">256</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;);</span></span>
<span id="cb9-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>same_as<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint32_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>uint_atleast<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>numeric_limits<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint32_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;);</span></span>
<span id="cb9-7"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>same_as<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint64_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>uint_atleast<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5'000'000'000</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;);</span></span></code></pre></div></div>
<p>We define <code>uint_atleast_t</code> as the type returned by the function <code>uint_atleast_impl()</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb10-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb10-2"></span>
<span id="cb10-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb10-4">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> max<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb10-5">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint_atleast_t</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">decltype</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>int_utils<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>uint_atleast_impl<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>max<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;());</span></span>
<span id="cb10-6"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb10-7"></span>
<span id="cb10-8"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>The implementation is very easy - we just define a <code>constexpr</code> table. If you see, I am just checking conditions one after the other, in a fallthrough.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb11-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;cstdint&gt;</span></span>
<span id="cb11-2"></span>
<span id="cb11-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb11-4"></span>
<span id="cb11-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb11-6">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> int_utils<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb11-7">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> max<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb11-8">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> uint_atleast_impl<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb11-9">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>max <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>numeric_limits<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>uint8_t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;::</span>max<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">())</span></span>
<span id="cb11-10">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint8_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{};</span></span>
<span id="cb11-11">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>max <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>numeric_limits<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>uint16_t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;::</span>max<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">())</span></span>
<span id="cb11-12">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint16_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{};</span></span>
<span id="cb11-13">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>max <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>numeric_limits<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>uint32_t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;::</span>max<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">())</span></span>
<span id="cb11-14">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint32_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{};</span></span>
<span id="cb11-15">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>max <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>numeric_limits<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>uint64_t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;::</span>max<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">())</span></span>
<span id="cb11-16">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint64_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{};</span>                </span>
<span id="cb11-17">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb11-18">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb11-19">    </span>
<span id="cb11-20">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> max<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb11-21">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint_atleast_t</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">decltype</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>int_utils<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>uint_atleast_impl<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>max<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;());</span></span>
<span id="cb11-22">    </span>
<span id="cb11-23"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb11-24"></span>
<span id="cb11-25"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// -------------- tests ------------</span></span>
<span id="cb11-26"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>is_same_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint8_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint_atleast_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;);</span></span>
<span id="cb11-27"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>is_same_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint8_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint_atleast_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">255</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;);</span></span>
<span id="cb11-28"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>is_same_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint16_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint_atleast_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">256</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;);</span></span>
<span id="cb11-29"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>is_same_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint32_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint_atleast_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>numeric_limits<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint32_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;);</span></span>
<span id="cb11-30"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>is_same_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint64_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint_atleast_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5'000'000'000</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;);</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/rxfdaqrdE">Compiler Explorer</a></p>
</section>
<section id="get_nth_type" class="level2">
<h2 class="anchored" data-anchor-id="get_nth_type"><code>get_nth_type</code></h2>
<p>Writing a good <code>get_nth_type</code> implementation is a surprisingly difficult problem. There is an excellent CppCon talk by <a href="https://www.youtube.com/watch?v=MLmDm1XFhEM">Kris Jusiak</a> on this, called the <code>nth_element</code> case study, where he talks specifically about this problem - how to get the <code>n</code>th type from a pack. This problem is not trivial to solve in optimal compile-time.</p>
<p>What we do is, to create a <code>constexpr</code> table. We are going to unroll the first <code>10</code> types. If the type index is <code>0</code>, we are going to return the first type, if the type index is <code>1</code>, we going to return the second type and so forth. If, for example, you request for the type at index <code>5</code> or even index <code>9</code>, the function can directly return the type. If you request the type at index <code>10</code>, the function calls itself with the template argument list <code>get_nth_type&lt;10-10, T10&gt;()</code> and the template is instantiated again.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb12-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb12-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb12-3">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> type_lists<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb12-4">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> n<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb12-5">                  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T0 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb12-6">                  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb12-7">                  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb12-8">                  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T3 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb12-9">                  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T4 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb12-10">                  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T5 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb12-11">                  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T6 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb12-12">                  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T7 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb12-13">                  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T8 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb12-14">                  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T9 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb12-15">                  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb12-16">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> get_nth_type_impl<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb12-17">            <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/**/</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span> n <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>type_identity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T0<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;{};</span></span>
<span id="cb12-18">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span> n <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>type_identity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;{};</span></span>
<span id="cb12-19">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span> n <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>type_identity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;{};</span></span>
<span id="cb12-20">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span> n <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>type_identity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T3<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;{};</span></span>
<span id="cb12-21">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span> n <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>type_identity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T4<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;{};</span></span>
<span id="cb12-22">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span> n <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>type_identity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T5<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;{};</span></span>
<span id="cb12-23">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span> n <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>type_identity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T6<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;{};</span></span>
<span id="cb12-24">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span> n <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>type_identity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T7<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;{};</span></span>
<span id="cb12-25">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span> n <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>type_identity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T8<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;{};</span></span>
<span id="cb12-26">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span> n <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>type_identity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T9<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;{};</span></span>
<span id="cb12-27">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span>                         <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> get_nth_type_impl<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>n<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;();</span></span>
<span id="cb12-28">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb12-29">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// namespace type_lists</span></span>
<span id="cb12-30"></span>
<span id="cb12-31">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> n<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb12-32">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">requires</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>n <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">sizeof</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...(</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))</span></span>
<span id="cb12-33">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">get_nth_type_t</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">decltype</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>type_lists<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>get_nth_type_impl<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>n<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;())::</span>type<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb12-34"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// namespace tools</span></span>
<span id="cb12-35"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb12-36"></span>
<span id="cb12-37"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// -------------- tests ------------</span></span>
<span id="cb12-38"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>is_same_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span></span>
<span id="cb12-39">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">get_nth_type_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">short</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">long</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;,</span> </span>
<span id="cb12-40">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;);</span></span>
<span id="cb12-41"></span>
<span id="cb12-42"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>is_same_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span></span>
<span id="cb12-43">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">get_nth_type_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">short</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">long</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;,</span> </span>
<span id="cb12-44">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;);</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/1r8Pe9Ye8">Compiler Explorer</a></p>
<p>Generally, the compile-time performance depends upon the number of function template instantiations. If I would have a single <code>if constexpr(n == 0)</code> condition, and requested <code>get_nth_type&lt;4, char, short, int, float, double&gt;</code>, the function would instantiate itself <code>4</code> times. In our implementation, we instantiate only once for every ten types.</p>
<p>There is another interesting thing here. In the <code>uint_atleast_t</code> implementation, we just default constructed the types <code>uint8_t</code> etc. But, in the general case, you can’t just default construct the type. So, we wrap it up in the identity meta-function <code>std::type_identity&lt;T&gt;</code>.</p>
</section>
<section id="instance_of" class="level2">
<h2 class="anchored" data-anchor-id="instance_of"><code>instance_of</code></h2>
<p>The next utility we would like to build is <code>instance_of</code>. We want a concept that will tell us, if a concrete type is an instance of a certain templated type. For example, <code>vector&lt;int&gt;</code> is an instance of <code>vector&lt;T&gt;</code>. But, <code>int</code> is not an instance of a <code>vector</code>. A little bit of a tricky one is : <code>vector&lt;int&gt;&amp;</code> is not an instance of <code>vector</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb13-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// -------------- tests ------------</span></span>
<span id="cb13-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>instance_of<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;);</span></span>
<span id="cb13-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(!</span>dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>instance_of<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;);</span></span>
<span id="cb13-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(!</span>dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>instance_of<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&amp;,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;);</span></span></code></pre></div></div>
<p>How do we do that? First, we define the <code>concept</code>, which just calls into the implementation <code>impl</code>. The <code>impl</code> is a meta-function that accepts two parameters, a template and a concrete type.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb14-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> Template<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> What<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb14-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//       ^--------------------------------^       ^--------^</span></span>
<span id="cb14-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//       1st param: a template that accepts       2nd param: a</span></span>
<span id="cb14-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//       any number of args                       concrete type</span></span>
<span id="cb14-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> impl <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>false_type <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{};</span></span></code></pre></div></div>
<p>The default implementation of <code>impl</code> is to define as <code>std::false_type</code>. The partial specialization <code>impl&lt;What, What&lt;Ts...&gt;&gt;</code>, says, if we have a template <code>What</code> and <code>What&lt;Ts...&gt;</code> is an instantiation of the template, that inherit from <code>true_type</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb15-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> What<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb15-2">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> impl<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>What<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> What<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;&gt;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>true_type <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{};</span></span></code></pre></div></div>
<p>Together, we have:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb16-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;vector&gt;</span></span>
<span id="cb16-2"></span>
<span id="cb16-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb16-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb16-5">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> _instance_of<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb16-6">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Template<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> What<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb16-7">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//       ^--------------------------------^       ^--------^</span></span>
<span id="cb16-8">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//       1st param: a template that accepts       2nd param: a</span></span>
<span id="cb16-9">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//       any number of args                       concrete type        </span></span>
<span id="cb16-10">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> impl <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>false_type <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{};</span></span>
<span id="cb16-11"></span>
<span id="cb16-12">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> What<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb16-13">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> impl<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>What<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> What<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;&gt;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>true_type <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{};</span></span>
<span id="cb16-14">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb16-15"></span>
<span id="cb16-16">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Template<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb16-17">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">concept</span> instance_of <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> _instance_of<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>impl<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Template<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;::</span>value<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb16-18"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// namespace tools </span></span>
<span id="cb16-19"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb16-20"></span>
<span id="cb16-21"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// -------------- tests ------------</span></span>
<span id="cb16-22"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>instance_of<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;);</span></span>
<span id="cb16-23"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(!</span>dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>instance_of<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;);</span></span>
<span id="cb16-24"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(!</span>dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>instance_of<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&amp;,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;);</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/z3n4dPbnd">Compiler Explorer</a></p>
</section>
<section id="a-macro-for-forwarding-arguments" class="level2">
<h2 class="anchored" data-anchor-id="a-macro-for-forwarding-arguments">A macro for forwarding arguments</h2>
<p>We all know how <code>std::forward</code> works. It unconditionally casts the type of its argument <code>T</code> to <code>T&amp;&amp;</code>. Sometimes you have to specify the types of the arguments, so you use <code>decltype</code>. For example,</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb17-1"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>forward<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">decltype</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)&gt;(</span>x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span></code></pre></div></div>
<p>This can be annoying to type, people often use a macro for economy.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb18-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#define TOOLS_FWD</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(...)</span></span>
<span id="cb18-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_cast</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">decltype</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>__VA_ARGS__<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)&amp;&amp;&gt;(</span>__VA_ARGS__<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div></div>
</section>
</section>
<section id="union_-type-definition" class="level1">
<h1><code>union_</code> type definition</h1>
<p>The <code>union_</code> type is something which is used to store the data. It is similar to the built-in union but it allows unpacking. That is, you could, for example request to construct the element at index <code>2</code> or get the element at index <code>2</code>.</p>
<p>Let’s first understand how to write the <code>union_</code> type. A while back people just created a bunch of <code>char</code>s - a buffer area to accomodate the largest type and they would cast pointers to the alternative types in the union.</p>
<p>The modern approach is to write a recursive solution. Using some mathematical formalism, the union of <code>N+1</code> types <code>T0, T1, ..., TN</code> written <img src="https://latex.codecogs.com/png.latex?%5Cbigcup_%7Bi=0%7D%5E%7BN%7D%20%5Ctexttt%7BTi%7D"> is equivalent to pulling out the first type, union’ing with the union of the rest of the types, that is <img src="https://latex.codecogs.com/png.latex?%5Ctexttt%7BT0%7D%20%5Ccup%20%5Cleft(%5Cbigcup_%7Bi=1%7D%5EN%20%5Ctexttt%7BTi%7D%5Cright)">. In code:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb19" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb19-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> First<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Rest<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb19-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">union_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb19-3">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">union</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb19-4">        First head<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb19-5">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">union_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Rest<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;</span> tail<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> </span>
<span id="cb19-6">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb19-7"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>
<p>A union must contain atleast one type. This is the default case.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb20-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb20-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">union_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;{</span></span>
<span id="cb20-3">    T head<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb20-4"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>
<p>We implement some constructors. There is a default constructor, a constructor for the head and a constructor for the <code>I</code>th element.</p>
<p>The API of these constructors is templated by a parameter <code>size_t I</code> - the index of the element to be constructed. The first argument to the constructor is of the type <code>std::in_place_index_t</code>, which is simply a wrapper type for storing indexes at compile-time.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb21" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb21-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb21-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb21-3"></span>
<span id="cb21-4">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> First<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Rest<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb21-5">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">union_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb21-6">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">union</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb21-7">            First head<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb21-8">            <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">union_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Rest<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;</span> tail<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> </span>
<span id="cb21-9">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb21-10"></span>
<span id="cb21-11">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">union_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">default</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb21-12">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">union_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>in_place_index_t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">u</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;...</span> args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb21-13">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> head<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> TOOLS_FWD<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)...</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb21-14">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb21-15"></span>
<span id="cb21-16">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> I<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb21-17">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">union_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>in_place_index_t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>I<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> idx<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;...</span> args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb21-18">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> tail<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>in_place_index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>I <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;{},</span> TOOLS_FWD<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)...</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb21-19">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb21-20">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb21-21"></span>
<span id="cb21-22">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb21-23">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">union_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;{</span></span>
<span id="cb21-24">        T head<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb21-25"></span>
<span id="cb21-26">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">union_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">default</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb21-27">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">union_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>in_place_index_t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">u</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;...</span> args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb21-28">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> head<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> TOOLS_FWD<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)...</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb21-29">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb21-30">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb21-31"></span>
<span id="cb21-32"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// namespace tools</span></span>
<span id="cb21-33"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<section id="union_size" class="level2">
<h2 class="anchored" data-anchor-id="union_size"><code>union_size</code></h2>
<p>There is <code>union_size</code> to tell me, how many elements are there in the union. This is very simple. I have a base case and then have a partial specialization, where I say that <code>sizeof...(Ts)</code> is my template union size.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb22" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb22-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb22-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb22-3">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb22-4">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> union_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb22-5"></span>
<span id="cb22-6">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb22-7">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> union_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">union_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;&gt;</span></span>
<span id="cb22-8">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>integral_constant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">sizeof</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...(</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)&gt;</span></span>
<span id="cb22-9">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb22-10"></span>
<span id="cb22-11">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Union<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb22-12">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> union_size_v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> union_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Union<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;::</span>value<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb22-13"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// namespace tools</span></span>
<span id="cb22-14"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
</section>
<section id="get" class="level2">
<h2 class="anchored" data-anchor-id="get"><code>get</code></h2>
<p>The implementation of <code>get</code> is very simple. If the index equals <code>0</code>, get the head. If its not <code>0</code>, get the tail.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb23" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb23-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb23-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb23-3">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Self<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb23-4">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Self<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> self<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb23-5">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">requires</span> instance_of<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>remove_cvref_t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Self<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;,</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">union_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span></span>
<span id="cb23-6">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> union_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>remove_cvref_t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Self<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;)</span></span>
<span id="cb23-7">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb23-8">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb23-9">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> TOOLS_FWD<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>self<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">).</span>head<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb23-10">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span></span>
<span id="cb23-11">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>TOOLS_FWD<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>self<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">).</span>tail<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb23-12">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb23-13"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// namespace tools</span></span>
<span id="cb23-14"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>Note that, because of how perfect forwarding works, <code>Self</code> is sometimes not deduced as <code>union_</code>, but rather <code>union_&amp;</code>. Hence, to strip off the reference qualifiers, I call the meta-function <code>std::remove_cvref_t</code>.</p>
</section>
<section id="construct_at-and-destroy_at" class="level2">
<h2 class="anchored" data-anchor-id="construct_at-and-destroy_at"><code>construct_at</code> and <code>destroy_at</code></h2>
<p>Given a <code>union_&lt;T0,...,Ti,...,TN&gt;</code>, <code>construct_at</code>, <code>destroy_at</code> are used to construct/destroy an object of one of the possible alternatives <code>T0,T1,...Ti,...Tn</code> specified using an index <code>i</code>.</p>
<p>We use the STL algorithms <a href="https://en.cppreference.com/cpp/memory/construct_at"><code>std::construct_at</code></a> and <a href="https://en.cppreference.com/cpp/memory/destroy_at"><code>std::destroy_at</code></a>. These algorithms perform placement <code>new</code> at compile-time; they construct/destroy an object at a specified address.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb24" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb24-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb24-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb24-3">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb24-4">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> construct_at<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">union_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;&amp;</span> self<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;...</span> args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb24-5">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// std::construct_at(&lt;address&gt;, &lt;ctor args&gt;...)</span></span>
<span id="cb24-6">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>construct_at<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(&amp;</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>self<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>in_place_index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;,</span> TOOLS_FWD<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)...);</span></span>
<span id="cb24-7">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb24-8"></span>
<span id="cb24-9">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb24-10">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> destroy_at<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">union_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;&amp;</span> self<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb24-11">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// std::destroy_at(&lt;address&gt;)</span></span>
<span id="cb24-12">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>destroy_at<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(&amp;</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>self<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb24-13">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb24-14"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// namespace tools</span></span>
<span id="cb24-15"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
</section>
</section>
<section id="wrapping-it-up---the-variant-class" class="level1">
<h1>Wrapping it up - the <code>variant</code> class</h1>
<p>A basic implementation is listed below. Perhaps, the most challenging problem to solve is writing a destructor/copy ctor.</p>
<p>When implementing <code>~variant()</code> we know the active index, so we can use <code>std::get&lt;I&gt;</code> to get underlying T object. However, <code>template&lt;size_t I&gt; std::get()</code> and other meta-functions are designed to accept compile-time constants as template parameters. We don’t know, the active index until run-time.</p>
<p>The solution is to generate an array of if-conditionals, at compile-time using pack expansion of the form:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb25" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb25-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Generate if-conditionals sizeof...(Ts) times</span></span>
<span id="cb25-2"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_idx</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb25-3">&nbsp;&nbsp;&nbsp;&nbsp;tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>destroy_at<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb25-4"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_idx</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">===</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb25-5">&nbsp;&nbsp;&nbsp;&nbsp;tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>destroy_at<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb25-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//...</span></span></code></pre></div></div>
<p>We use <code>std::index_sequence</code> for this purpose, which represents a compile-time sequence of numbers. We construct the sequence <code>0,1,2,3,...,sizeof...(Ts)-1</code> and then define a lambda function that accepts this as a parameter pack <code>Indices</code>. Inside the lambda function, we use a ternary expression to check if the active index <code>m_idx == Indices</code> (the pack variable) and perform destruction in the true case. We apply C++17 fold expressions to expand <code>Indices</code> and generate multiple if statements.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb26" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb26-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Destructor</span></span>
<span id="cb26-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb26-3">   <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> idx_seq <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>make_index_sequence<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">sizeof</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...(</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)&gt;();</span></span>
<span id="cb26-4">   <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[&amp;]&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Indices<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>index_sequence<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Indices<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;){</span></span>
<span id="cb26-5">       <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(((</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_idx</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> Indices<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">?</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>destroy_at<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Indices<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...);</span></span>
<span id="cb26-6">   <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}(</span>idx_seq<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb26-7"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<section id="code-listing" class="level2">
<h2 class="anchored" data-anchor-id="code-listing">Code listing</h2>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb27" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb27-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb27-2"></span>
<span id="cb27-3">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb27-4">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb27-5"></span>
<span id="cb27-6">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Forward declaration </span></span>
<span id="cb27-7">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// so the friend declaration inside variant resolves</span></span>
<span id="cb27-8">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> I<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb27-9">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">decltype</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;&amp;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb27-10"></span>
<span id="cb27-11">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb27-12">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;&amp;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb27-13"></span>
<span id="cb27-14">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb27-15">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb27-16">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">index_type</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint_atleast_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">sizeof</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...(</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)&gt;;</span></span>
<span id="cb27-17">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">static</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> size <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">sizeof</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...(</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb27-18"></span>
<span id="cb27-19">        tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">union_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb27-20">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">index_type</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_idx</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb27-21"></span>
<span id="cb27-22">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb27-23">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/**</span></span>
<span id="cb27-24"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         * </span><span class="an" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@brief</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">: Constructs a variant holding the zero-initialized value </span></span>
<span id="cb27-25"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         * of the first alternative.</span></span>
<span id="cb27-26"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         */</span></span>
<span id="cb27-27">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb27-28">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb27-29">            tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>construct_at<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">get_nth_type_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;());</span></span>
<span id="cb27-30">            <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_idx</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb27-31">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb27-32"></span>
<span id="cb27-33">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/**</span></span>
<span id="cb27-34"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         * </span><span class="an" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@brief</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> Converting constructor. Constructs a variant holding the</span></span>
<span id="cb27-35"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         * alternative of type </span><span class="an" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@p</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> </span><span class="cv" style="color: #5E5E5E;
background-color: null;
font-style: italic;">T</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">, from </span><span class="an" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@p</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> </span><span class="cv" style="color: #5E5E5E;
background-color: null;
font-style: italic;">x</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span></span>
<span id="cb27-36"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         */</span></span>
<span id="cb27-37">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>exists<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb27-38">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">explicit</span> variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb27-39">            tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>construct_at<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>find_index_of_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;&gt;(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> TOOLS_FWD<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb27-40">            <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_idx</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>find_index_of_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;;</span></span>
<span id="cb27-41">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb27-42"></span>
<span id="cb27-43">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/**</span></span>
<span id="cb27-44"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         * </span><span class="an" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@brief</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> Copy constructor. Constructs a variant holding the same</span></span>
<span id="cb27-45"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         * alternative as </span><span class="an" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@p</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> </span><span class="cv" style="color: #5E5E5E;
background-color: null;
font-style: italic;">other</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">, copy-constructed from the contained value.        </span></span>
<span id="cb27-46"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         */</span></span>
<span id="cb27-47">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb27-48">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">index_type</span> idx <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_idx</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb27-49">            <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> idx_seq <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>make_index_sequence<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">sizeof</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...(</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)&gt;();</span></span>
<span id="cb27-50">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[&amp;]&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Indices<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>index_sequence<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Indices<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;){</span></span>
<span id="cb27-51">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(((</span>idx <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> Indices<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> </span>
<span id="cb27-52">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">?</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>construct_at<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Indices<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Indices<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> </span>
<span id="cb27-53">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...);</span></span>
<span id="cb27-54">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}(</span>idx_seq<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb27-55">            <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_idx</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> idx<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb27-56">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb27-57"></span>
<span id="cb27-58">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/**</span></span>
<span id="cb27-59"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         * </span><span class="an" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@brief</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> Move constructor. Steals data from </span><span class="an" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@p</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> </span><span class="cv" style="color: #5E5E5E;
background-color: null;
font-style: italic;">other</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">. </span></span>
<span id="cb27-60"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         * Constructs a variant holding the same</span></span>
<span id="cb27-61"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         * alternative as </span><span class="an" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@p</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> </span><span class="cv" style="color: #5E5E5E;
background-color: null;
font-style: italic;">other</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">, move-constructed from </span></span>
<span id="cb27-62"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         * the contained value.</span></span>
<span id="cb27-63"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         */</span></span>
<span id="cb27-64">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">noexcept</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb27-65">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">index_type</span> idx <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_idx</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb27-66">            <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> idx_seq <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>make_index_sequence<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">sizeof</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...(</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)&gt;();</span></span>
<span id="cb27-67">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[&amp;]&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Indices<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>index_sequence<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Indices<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;){</span></span>
<span id="cb27-68">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(((</span>idx <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> Indices<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> </span>
<span id="cb27-69">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">?</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>construct_at<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Indices<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Indices<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>move<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> </span>
<span id="cb27-70">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...);</span></span>
<span id="cb27-71">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}(</span>idx_seq<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb27-72">            <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_idx</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> idx<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb27-73">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb27-74"></span>
<span id="cb27-75">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/**</span></span>
<span id="cb27-76"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         * </span><span class="an" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@brief</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> Swaps the contents of two variants.</span></span>
<span id="cb27-77"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         *</span></span>
<span id="cb27-78"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         * If both variants hold the same alternative (index() == other.index()),</span></span>
<span id="cb27-79"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         * the contained values are swapped directly via </span><span class="an" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@c</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> </span><span class="cv" style="color: #5E5E5E;
background-color: null;
font-style: italic;">std::swap</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">. Otherwise,</span></span>
<span id="cb27-80"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         * the alternatives are exchanged by using a temporary.</span></span>
<span id="cb27-81"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         */</span></span>
<span id="cb27-82">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> swap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;&amp;</span> other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">noexcept</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb27-83">            <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>swap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb27-84">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_idx</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_idx</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb27-85">                <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//swap(get&lt;m_idx&gt;(*this), tools::get&lt;m_idx&gt;(other));</span></span>
<span id="cb27-86">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[&amp;]&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Idxs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>index_sequence<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Idxs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;){</span></span>
<span id="cb27-87">                    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(((</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_idx</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> Idxs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">?</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>swap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Idxs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(*</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Idxs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...);</span></span>
<span id="cb27-88">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>make_index_sequence<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">sizeof</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...(</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)&gt;());</span></span>
<span id="cb27-89">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb27-90">                <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>move<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb27-91">                <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>construct_at<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>move<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb27-92">                <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>construct_at<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(&amp;</span>other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>move<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb27-93">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb27-94">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb27-95"></span>
<span id="cb27-96">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/**</span></span>
<span id="cb27-97"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         * </span><span class="an" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@brief</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> Copy assignment operator.</span></span>
<span id="cb27-98"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         */</span>        </span>
<span id="cb27-99">        variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;&amp;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;&amp;</span> other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb27-100">            variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">).</span>swap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb27-101">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb27-102">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb27-103"></span>
<span id="cb27-104">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/**</span></span>
<span id="cb27-105"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         * </span><span class="an" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@brief</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> Move assignment operator.</span></span>
<span id="cb27-106"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         */</span>        </span>
<span id="cb27-107">        variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;&amp;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=(</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;&amp;&amp;</span> other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">noexcept</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb27-108">            variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>move<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)).</span>swap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb27-109">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb27-110">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb27-111"></span>
<span id="cb27-112">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/**</span></span>
<span id="cb27-113"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         * </span><span class="an" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@brief</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> Converting assignment operator. Assigns a value of type</span></span>
<span id="cb27-114"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         * </span><span class="an" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@p</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> </span><span class="cv" style="color: #5E5E5E;
background-color: null;
font-style: italic;">T</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> to the variant.</span></span>
<span id="cb27-115"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         */</span></span>
<span id="cb27-116">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>exists<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb27-117">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;&amp;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=(</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> element<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb27-118">            <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;~</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb27-119">            <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>find_index_of_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;;</span></span>
<span id="cb27-120">            tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>construct_at<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> TOOLS_FWD<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>element<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb27-121">            <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_idx</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb27-122">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb27-123">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb27-124"></span>
<span id="cb27-125">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/**</span></span>
<span id="cb27-126"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">        * </span><span class="an" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@brief</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> Destructor. Destroys the currently held alternative.</span></span>
<span id="cb27-127"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">        */</span></span>
<span id="cb27-128">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb27-129">            <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> idx_seq <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>make_index_sequence<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">sizeof</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...(</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)&gt;();</span></span>
<span id="cb27-130">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[&amp;]&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Indices<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>index_sequence<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Indices<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;){</span></span>
<span id="cb27-131">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(((</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_idx</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> Indices<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">?</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>destroy_at<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Indices<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...);</span></span>
<span id="cb27-132">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}(</span>idx_seq<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb27-133">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb27-134"></span>
<span id="cb27-135">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/**</span></span>
<span id="cb27-136"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         * </span><span class="an" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@brief</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> Returns the zero-based index of the alternative currently</span></span>
<span id="cb27-137"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         * held by the variant.</span></span>
<span id="cb27-138"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">         */</span></span>
<span id="cb27-139">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">noexcept</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb27-140">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_idx</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb27-141">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb27-142"></span>
<span id="cb27-143">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> I<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Us<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb27-144">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">friend</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">decltype</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Us<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;&amp;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb27-145"></span>
<span id="cb27-146">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Us<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb27-147">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">friend</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Us<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;&amp;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb27-148"></span>
<span id="cb27-149">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> I<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Us<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb27-150">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">friend</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">decltype</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Us<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;&amp;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb27-151"></span>
<span id="cb27-152">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Us<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb27-153">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">friend</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Us<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;&amp;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb27-154">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span> </span>
<span id="cb27-155"></span>
<span id="cb27-156">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> I<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb27-157">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">decltype</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;&amp;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb27-158">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>I<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb27-159">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb27-160"></span>
<span id="cb27-161">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb27-162">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;&amp;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb27-163">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>find_index_of_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;&gt;(</span>v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb27-164">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb27-165"></span>
<span id="cb27-166">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> I<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb27-167">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">decltype</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;&amp;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb27-168">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>I<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb27-169">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb27-170"></span>
<span id="cb27-171">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb27-172">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;&amp;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb27-173">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>find_index_of_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;&gt;(</span>v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb27-174">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb27-175"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/odKb9bYPW">Compiler Explorer</a></p>


</section>
</section>

 ]]></description>
  <category>C++</category>
  <guid>http://quantdev.blog/posts/implementing_variant/</guid>
  <pubDate>Thu, 09 Apr 2026 23:00:00 GMT</pubDate>
  <media:content url="http://quantdev.blog/posts/implementing_variant/cpp.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>Implementing std::string</title>
  <dc:creator>`dev::author` </dc:creator>
  <link>http://quantdev.blog/posts/implementing_string/</link>
  <description><![CDATA[ 





<section id="background" class="level1">
<h1>Background</h1>
<p>A <code>string</code> class is a container that stores and manipulates sequences of characters. The characters are stored contiguously in memory.</p>
<p>The book-keeping node for such a data-structure stores meta-information and is typically implemented as a triple (pointer-to T, size, capacity). <code>sizeof(std::string)</code> on a 64-bit machine is 24-bytes.</p>
<p>Recall, that C-style strings are just <code>char[]</code> arrays. We rely on the null termination character <code>\0</code> to detect the end of the string. So,<code>strlen()</code> has running-time.</p>
<p>In contrast, our string class has an m_size field to track the size of the character sequence.</p>
<p>To maintain backward compatibility with C-style strings, the string class stores any piece of text e.g.&nbsp;Bjarne Stroustrup as Bjarne Stroustrup\0.</p>
<pre><code>+=======================+
|       dev:string      |
+-----------------------+
| - char*  m_data    ---|-----------&gt; Pointer to buffer on the Heap
| - size_t m_size       |
| - size_t m_capacity   |
+=======================+</code></pre>
<p>In case of very small strings (smaller than 24-bytes), it might be optimal to store the string in the book-keeping node itself, so it is allocated on the instead of living on the heap. This is known as <strong>Small Buffer Optimization(SBO)</strong>.</p>
<p>We will define two layouts : string_long and string_short, and the actual string type would be the union of these two layouts.</p>
<p>For long strings (length &gt;= 24 bytes), the m_capacity will always be an integral multiple of 2. Hence, the LSB of Byte-24 for long strings is always 0.</p>
<p>For small strings upto length 23 bytes, we use the first 7-bits of Byte-24 to store the actual string length (this suffices, because ). We set the the last bit to 1 to indicate, this is a small string.</p>
<p>Based on the above suggestion, use the LSB(Least Significant Bit) of Byte 24 (last byte), as a bit-flag in the API to distinguish if we are in SBO-mode (short string) or otherwise (long string).</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb2-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/**</span></span>
<span id="cb2-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> * </span><span class="an" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@brief</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">: A string class</span></span>
<span id="cb2-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> * The capacity is usually a multiple of 2, so the</span></span>
<span id="cb2-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> * least significant bit of the m_capacity field</span></span>
<span id="cb2-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> * is set to 0, to indicate string_long format. And</span></span>
<span id="cb2-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> * if set to 1, it implies SSO.</span></span>
<span id="cb2-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> */</span></span>
<span id="cb2-8"></span>
<span id="cb2-9"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> string_long<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-10">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>       &nbsp;&nbsp;&nbsp;&nbsp;<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_buffer_ptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// 8 bytes</span></span>
<span id="cb2-11">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t &nbsp;&nbsp;&nbsp;&nbsp;<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_size</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// 8 bytes</span></span>
<span id="cb2-12">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t &nbsp;&nbsp;&nbsp;&nbsp;<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_capacity</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> &nbsp;&nbsp;&nbsp;&nbsp;   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// 8 bytes</span></span>
<span id="cb2-13"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb2-14"></span>
<span id="cb2-15"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> string_short<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>        </span>
<span id="cb2-16">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">static</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">23</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">uz</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb2-17">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span>  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_buffer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">];</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// 23 bytes</span></span>
<span id="cb2-18">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">unsigned</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_size</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// 1 byte</span></span>
<span id="cb2-19"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb2-20"></span>
<span id="cb2-21"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-22">&nbsp;&nbsp;&nbsp;&nbsp;union<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-23">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string_short s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-24">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string_long l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-25">&nbsp;&nbsp;&nbsp;&nbsp;<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-26"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>
</section>
<section id="implementing-a-basic-string-class" class="level1">
<h1>Implementing a basic <code>string</code> class</h1>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb3-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;cassert&gt;</span></span>
<span id="cb3-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;cstring&gt;</span></span>
<span id="cb3-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;iostream&gt;</span></span>
<span id="cb3-4"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;stdexcept&gt;</span></span>
<span id="cb3-5"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;utility&gt;</span></span>
<span id="cb3-6"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;cassert&gt;</span></span>
<span id="cb3-7"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;cstring&gt;</span></span>
<span id="cb3-8"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;gtest/gtest.h&gt;</span></span>
<span id="cb3-9"></span>
<span id="cb3-10"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/**</span></span>
<span id="cb3-11"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> * </span><span class="an" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@brief</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">: A string class</span></span>
<span id="cb3-12"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> * The capacity is usually a multiple of 2, so the</span></span>
<span id="cb3-13"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> * least significant bit of the m_capacity field</span></span>
<span id="cb3-14"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> * is set to 0, to indicate string_long format. And</span></span>
<span id="cb3-15"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> * if set to 1, it implies SSO.</span></span>
<span id="cb3-16"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> */</span></span>
<span id="cb3-17"></span>
<span id="cb3-18"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> dev <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-19">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> string_long <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-20">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_buffer_ptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// 8 bytes</span></span>
<span id="cb3-21">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_size</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>            <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// 8 bytes</span></span>
<span id="cb3-22">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_capacity</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// 8 bytes</span></span>
<span id="cb3-23">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb3-24"></span>
<span id="cb3-25">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> string_short <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-26">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">static</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">23</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">uz</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb3-27">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_buffer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">];</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// 23 bytes</span></span>
<span id="cb3-28">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">unsigned</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_size</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>            <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// 1 byte</span></span>
<span id="cb3-29">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb3-30"></span>
<span id="cb3-31">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> string <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-32">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> iterator <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*;</span></span>
<span id="cb3-33">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> const_iterator <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*;</span></span>
<span id="cb3-34"></span>
<span id="cb3-35">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">private</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb3-36">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">union</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-37">            string_short s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-38">            string_long l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-39">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-40"></span>
<span id="cb3-41">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">static</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> string_short_mask <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bn" style="color: #AD0000;
background-color: null;
font-style: inherit;">0x01</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-42">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">static</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> growth_factor <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-43"></span>
<span id="cb3-44">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">bool</span> is_short_string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_size</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> string_short_mask<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-45"></span>
<span id="cb3-46">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">bool</span> is_short_string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_size</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> string_short_mask<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-47"></span>
<span id="cb3-48">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">bool</span> is_long_string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!</span>is_short_string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-49">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">bool</span> is_long_string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!</span>is_short_string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-50"></span>
<span id="cb3-51">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> get_short_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_size</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-52">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> get_short_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_size</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-53">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> set_short_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_size</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>size <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> string_short_mask<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-54">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> get_long_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_size</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-55">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> get_long_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_size</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-56">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> set_long_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_size</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-57">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> set_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb3-58">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>is_short_string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">())</span></span>
<span id="cb3-59">                set_short_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-60">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span></span>
<span id="cb3-61">                set_long_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-62">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-63"></span>
<span id="cb3-64">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> set_sso_flag<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_size</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|=</span> string_short_mask<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-65"></span>
<span id="cb3-66">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> turn_off_sso_flag<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-67">            <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_capacity</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;=</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(~</span>string_short_mask<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-68">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-69"></span>
<span id="cb3-70">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> get_long_capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_capacity</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-71"></span>
<span id="cb3-72">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> get_short_capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span>  string_short<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-73"></span>
<span id="cb3-74">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> set_long_capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-75">            <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(!(</span>capacity <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> <span class="bn" style="color: #AD0000;
background-color: null;
font-style: inherit;">0x01</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// capacity in the long string format must be an</span></span>
<span id="cb3-76">                                                                    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// integral multiple of 2</span></span>
<span id="cb3-77">            <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_capacity</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-78">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-79"></span>
<span id="cb3-80">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>allocate_helper<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> new_capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-81">            <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(!(</span>new_capacity <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> <span class="bn" style="color: #AD0000;
background-color: null;
font-style: inherit;">0x01</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// new_capacity must be a multiple of 2</span></span>
<span id="cb3-82">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_cast</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*&gt;(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>new_capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb3-83">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-84"></span>
<span id="cb3-85">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> deallocate_helper<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>buffer_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">delete</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>buffer_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-86"></span>
<span id="cb3-87">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// helper function for allocating on the heap</span></span>
<span id="cb3-88">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> construct_slow_path<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>chars_array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> len<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-89">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> bytes_to_alloc <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span></span>
<span id="cb3-90">                    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">((</span>len <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> <span class="bn" style="color: #AD0000;
background-color: null;
font-style: inherit;">0x01</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">?</span> len <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> len <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// An extra byte for '\0'</span></span>
<span id="cb3-91">            <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_buffer_ptr</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> allocate_helper<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>bytes_to_alloc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-92">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">uz</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> len<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-93">                <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_buffer_ptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> chars_array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">];</span></span>
<span id="cb3-94">            <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_buffer_ptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>len<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-95">            set_long_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>len<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-96">            turn_off_sso_flag<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-97">            set_long_capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>bytes_to_alloc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-98">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-99"></span>
<span id="cb3-100">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// helper function for copying string to the buffer on the stack </span></span>
<span id="cb3-101">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> construct_fast_path<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>chars_array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> len<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-102">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">uz</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> len<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-103">                <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_buffer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> chars_array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">];</span></span>
<span id="cb3-104">            <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_buffer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>len<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-105">            set_short_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>len<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-106">            set_sso_flag<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-107">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-108"></span>
<span id="cb3-109">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">bool</span> is_full<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-110"></span>
<span id="cb3-111">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb3-112">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ---------------------------- constructors -------------------------</span></span>
<span id="cb3-113"></span>
<span id="cb3-114">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// default constructor</span></span>
<span id="cb3-115">        string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb3-116">            <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_buffer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-117">            set_short_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-118">            set_sso_flag<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-119">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-120"></span>
<span id="cb3-121">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// from literal constructor</span></span>
<span id="cb3-122">        string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>chars_array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-123">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> len <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> strlen<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>chars_array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-124">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>len <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> len <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>  string_short<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-125">                construct_fast_path<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>chars_array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> len<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-126">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-127">                construct_slow_path<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>chars_array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> len<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-128">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-129">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-130"></span>
<span id="cb3-131">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// copy constructor</span></span>
<span id="cb3-132">        string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> string <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb3-133">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>is_short_string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">())</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-134">                <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> len <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-135">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">uz</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>len<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-136">                    <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_buffer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">];</span></span>
<span id="cb3-137">                set_short_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>len<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-138">                <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_buffer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>len<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-139">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-140">                <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_buffer_ptr</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> allocate_helper<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_capacity</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-141">                <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> len <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>get_long_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-142">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">uz</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>len<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-143">                    <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_buffer_ptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">];</span></span>
<span id="cb3-144">                <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_size</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> len<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-145">                <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_capacity</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_capacity</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-146">                <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_buffer_ptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>len<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-147">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-148">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-149"></span>
<span id="cb3-150">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// move constructor</span></span>
<span id="cb3-151">        string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>string <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span>other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-152">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>is_short_string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">())</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-153">                <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> len <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-154">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">uz</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>len<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-155">                    <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_buffer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">];</span></span>
<span id="cb3-156">                set_short_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>len<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-157">                <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_buffer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>len<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-158">                other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_buffer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-159">                other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>set_short_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-160">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-161">                <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_buffer_ptr</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span></span>
<span id="cb3-162">                        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>exchange<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_buffer_ptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-163">                <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> len <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>get_long_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-164">                <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_size</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>exchange<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_size</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-165">                <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_capacity</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>exchange<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_capacity</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-166">                <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_buffer_ptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>len<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-167">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-168">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-169"></span>
<span id="cb3-170">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// swap</span></span>
<span id="cb3-171">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">friend</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> swap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>string <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>lhs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> string <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>rhs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-172">            <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// The lhs and the rhs could have different active members.</span></span>
<span id="cb3-173">            <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// You cannot swap two unions with different active members.</span></span>
<span id="cb3-174">            <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// In such cases, you have to use a temporary.</span></span>
<span id="cb3-175">            <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> temp <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>move<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>lhs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-176">            lhs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>move<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>rhs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-177">            rhs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>move<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>temp<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-178">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-179"></span>
<span id="cb3-180">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> swap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>string <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> </span>
<span id="cb3-181">            <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>swap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-182">            swap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> </span>
<span id="cb3-183">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-184"></span>
<span id="cb3-185">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// copy assignment</span></span>
<span id="cb3-186">        string <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> string <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-187">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-188">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-189">            string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">).</span>swap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-190">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-191">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-192"></span>
<span id="cb3-193">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// move assignment</span></span>
<span id="cb3-194">        string <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=(</span>string <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span>other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-195">            string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>move<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)).</span>swap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-196">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-197">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-198"></span>
<span id="cb3-199">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// construct a string from an arbitrary range [first, last)</span></span>
<span id="cb3-200">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> InputIt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb3-201">        string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>InputIt first<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> InputIt last<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb3-202">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> it<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>first<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span> it<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span>last<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span>it<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-203">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-204">                push_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span>it<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-205">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-206">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-207"></span>
<span id="cb3-208">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// construct a string from an initializer list</span></span>
<span id="cb3-209">        string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>initializer_list<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> list<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-210">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> list<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> list<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-211">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb3-212"></span>
<span id="cb3-213">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// constructs a string with count copies of the character ch</span></span>
<span id="cb3-214">        string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> count<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> ch<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb3-215">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">uz</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> count<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-216">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-217">                push_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>ch<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-218">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-219">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span>  </span>
<span id="cb3-220"></span>
<span id="cb3-221">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// destructor</span></span>
<span id="cb3-222">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-223">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>is_long_string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">())</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-224">                deallocate_helper<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_buffer_ptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-225">                <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_buffer_ptr</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-226">                <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_size</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-227">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-228">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-229"></span>
<span id="cb3-230">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ---------------------- capacity functions -------------------------</span></span>
<span id="cb3-231">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// size of the string</span></span>
<span id="cb3-232">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-233">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>is_short_string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">())</span></span>
<span id="cb3-234">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> get_short_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-235">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span></span>
<span id="cb3-236">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> get_long_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-237">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-238"></span>
<span id="cb3-239">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// const version</span></span>
<span id="cb3-240">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-241">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>is_short_string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">())</span></span>
<span id="cb3-242">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> get_short_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-243">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span></span>
<span id="cb3-244">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> get_long_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-245">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-246"></span>
<span id="cb3-247">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// capacity</span></span>
<span id="cb3-248">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-249">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>is_short_string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">())</span></span>
<span id="cb3-250">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> get_short_capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-251">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span></span>
<span id="cb3-252">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> get_long_capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-253">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-254"></span>
<span id="cb3-255">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// checks if string is empty</span></span>
<span id="cb3-256">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">bool</span> empty<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-257"></span>
<span id="cb3-258">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// allocate new storage</span></span>
<span id="cb3-259">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> reserve<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> new_capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-260">            <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// All existing iterators and references will be invalidated.</span></span>
<span id="cb3-261">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> current_capacity <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-262">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> current_size <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-263"></span>
<span id="cb3-264">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>new_capacity <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;=</span> current_capacity <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">||</span></span>
<span id="cb3-265">                    new_capacity <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> string_short<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-266">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-267"></span>
<span id="cb3-268">            <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// new_capacity request must be atleast 23 bytes and must be larger than</span></span>
<span id="cb3-269">            <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// current_capacity.</span></span>
<span id="cb3-270"></span>
<span id="cb3-271">            <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Book an extra byte for null termination character '\0'</span></span>
<span id="cb3-272">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span>new_capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-273"></span>
<span id="cb3-274">            <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// new_capacity must be an integral multiple of 2</span></span>
<span id="cb3-275">            new_capacity <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!(</span>new_capacity <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> <span class="bn" style="color: #AD0000;
background-color: null;
font-style: inherit;">0x01</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">?</span> new_capacity <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> new_capacity <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-276"></span>
<span id="cb3-277">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> mem <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> allocate_helper<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>new_capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-278">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> buffer_ptr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-279">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">uz</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> current_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-280">                mem<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> buffer_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">];</span></span>
<span id="cb3-281">    </span>
<span id="cb3-282">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>is_long_string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">())</span></span>
<span id="cb3-283">                deallocate_helper<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>buffer_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-284"></span>
<span id="cb3-285">            <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_buffer_ptr</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> mem<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-286">            <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_capacity</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> new_capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-287">            set_long_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>current_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-288">            turn_off_sso_flag<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-289">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-290"></span>
<span id="cb3-291">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ---------------------------- Element Access ------------------------</span></span>
<span id="cb3-292"></span>
<span id="cb3-293">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// data() return the pointer to the first character of the string</span></span>
<span id="cb3-294">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-295">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> is_short_string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">?</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_buffer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_buffer_ptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-296">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-297"></span>
<span id="cb3-298">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// const version</span></span>
<span id="cb3-299">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-300">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> is_short_string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">?</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_buffer</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_data</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>l<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_buffer_ptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-301">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-302"></span>
<span id="cb3-303">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Array subscript operator[]</span></span>
<span id="cb3-304">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> pos<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-305">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>buffer_ptr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-306">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> buffer_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>pos<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">];</span></span>
<span id="cb3-307">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-308"></span>
<span id="cb3-309">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Array subscript operator[]</span></span>
<span id="cb3-310">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> pos<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-311">            <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>buffer_ptr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-312">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> buffer_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>pos<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">];</span></span>
<span id="cb3-313">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span>    </span>
<span id="cb3-314"></span>
<span id="cb3-315">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// indexed access with bounds checking</span></span>
<span id="cb3-316">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>at<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> pos<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-317">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>pos <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">||</span> pos <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">())</span></span>
<span id="cb3-318">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">throw</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>out_of_range<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Index out of bounds!"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-319"></span>
<span id="cb3-320">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>buffer_ptr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-321">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> buffer_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>pos<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">];</span></span>
<span id="cb3-322">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-323"></span>
<span id="cb3-324">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Returns a reference to the first character of the string</span></span>
<span id="cb3-325">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>front<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-326">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>buffer_ptr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-327">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> buffer_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">];</span></span>
<span id="cb3-328">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-329"></span>
<span id="cb3-330">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Returns a reference to the last character of the string</span></span>
<span id="cb3-331">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-332">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>buffer_ptr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-333">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> buffer_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">];</span></span>
<span id="cb3-334">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-335"></span>
<span id="cb3-336">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ---------------------------------- Iterators -----------------------------</span></span>
<span id="cb3-337"></span>
<span id="cb3-338">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-339"></span>
<span id="cb3-340">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-341"></span>
<span id="cb3-342">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-343"></span>
<span id="cb3-344">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-345"></span>
<span id="cb3-346">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ------------------------------- Modifiers -----------------------------</span></span>
<span id="cb3-347"></span>
<span id="cb3-348">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Appends the given character ch to the end of the string</span></span>
<span id="cb3-349">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> push_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> ch<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-350">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> current_size <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-351">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>is_full<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">())</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-352">                <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> new_capacity <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> growth_factor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-353">                reserve<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>new_capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-354">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-355"></span>
<span id="cb3-356">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> buffer_ptr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-357">            buffer_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>current_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> ch<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-358">            buffer_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>current_size <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-359">            set_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>current_size <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-360">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-361"></span>
<span id="cb3-362">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// removes a character from the end of the string</span></span>
<span id="cb3-363">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> pop_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb3-364">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> new_size <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-365">            set_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>new_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-366">            data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()[</span>new_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-367">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-368"></span>
<span id="cb3-369">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// inserts the characters from the range [first, last)</span></span>
<span id="cb3-370">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// before the element (if any) pointed to by pos</span></span>
<span id="cb3-371">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> InputIt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb3-372">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> insert<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>const_iterator pos<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> InputIt first<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> InputIt last<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb3-373">            <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">pos_</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">const_cast</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>iterator<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>pos<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-374">            <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">first_</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> first<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-375">            <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">last_</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> last<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-376">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>first <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> last<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb3-377">                <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> offset <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>distance<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">pos_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-378">                <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> n <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>distance<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>first<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> last<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-379">                <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> num_elems_to_shift <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>distance<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">pos_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb3-380">                <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> remaining_capacity <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-381"></span>
<span id="cb3-382">                <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// handle self-referential insertion</span></span>
<span id="cb3-383">                string temp<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-384">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">first_</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">first_</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb3-385">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">last_</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">last_</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;=</span> end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">())</span></span>
<span id="cb3-386">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-387">                    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> it<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">first_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span> it<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">last_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span>it<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-388">                        temp<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>push_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span>it<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-389"></span>
<span id="cb3-390">                    <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">first_</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> temp<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-391">                    <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">last_</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> temp<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-392">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-393"></span>
<span id="cb3-394">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>n <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> remaining_capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-395">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-396">                    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> excess_capacity_reqd <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>max<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>n <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> remaining_capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">uz</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-397">                    reserve<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> excess_capacity_reqd<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-398">                    <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">pos_</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>next<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> offset<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-399">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-400"></span>
<span id="cb3-401">                <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// objects to displace from [begin(), end()) sequence</span></span>
<span id="cb3-402">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>n <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> num_elems_to_shift<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-403">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-404">                    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>copy<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> n<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb3-405">                    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>copy_backward<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">pos_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> n<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb3-406">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-407">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-408">                    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>copy<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">pos_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">pos_</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> n<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-409">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-410">                </span>
<span id="cb3-411">                <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>copy<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">first_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">last_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">pos_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-412">                set_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> n<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-413">                <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> buffer_ptr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-414">                buffer_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-415">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-416">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-417"></span>
<span id="cb3-418">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Removes the characters in the range [first, last)</span></span>
<span id="cb3-419">        iterator erase<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>const_iterator first<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> const_iterator last<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb3-420">            iterator <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">first_</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">const_cast</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>iterator<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>first<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-421">            iterator <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">last_</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">const_cast</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>iterator<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>last<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-422">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> offset <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>distance<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">first_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>     </span>
<span id="cb3-423">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> num_chars_to_shift_left <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>distance<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">last_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb3-424">            <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">last_</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>min<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">last_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb3-425">            string chars_to_remove<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">first_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">last_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-426">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> num_chars_erased <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>distance<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">first_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">last_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-427"></span>
<span id="cb3-428">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> buffer_ptr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-429">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">uz</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> num_chars_to_shift_left<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-430">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-431">                buffer_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>offset <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> buffer_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>offset <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> num_chars_erased<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">];</span></span>
<span id="cb3-432">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-433">            set_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> num_chars_erased<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-434">            </span>
<span id="cb3-435">            buffer_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-436">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> k<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">uz</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span> k <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> num_chars_erased<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span>k<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb3-437">                buffer_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> k<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> chars_to_remove<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>k<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">];</span></span>
<span id="cb3-438">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-439"></span>
<span id="cb3-440">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> buffer_ptr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> offset<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-441">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-442">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb3-443"></span>
<span id="cb3-444"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// namespace dev</span></span>
<span id="cb3-445"></span>
<span id="cb3-446"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-447"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// default constructor</span></span>
<span id="cb3-448"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-449">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>DefaultConstructor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> IsEmpty<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-450">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-451">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-452">    EXPECT_TRUE<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>empty<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb3-453">    EXPECT_GT<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-454"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-455"></span>
<span id="cb3-456"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-457"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// from literal constructor</span></span>
<span id="cb3-458"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-459">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>FromLiteralConstructor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> ShortString<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-460">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"hello"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-461">    EXPECT_FALSE<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>empty<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb3-462">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-463">    EXPECT_GT<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-464"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-465"></span>
<span id="cb3-466">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>FromLiteralConstructor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> LongString<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-467">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"C++ is a general-purpose programming language"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-468">    EXPECT_FALSE<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>empty<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb3-469">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">45</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-470">    EXPECT_GT<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-471"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-472"></span>
<span id="cb3-473">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>FromLiteralConstructor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> EmbeddedNull<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-474">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"hello</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">world"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-475">    EXPECT_FALSE<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>empty<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb3-476">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-477">    EXPECT_GT<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-478"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-479"></span>
<span id="cb3-480"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-481"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// copy constructor</span></span>
<span id="cb3-482"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-483">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>CopyConstructor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> ShortString<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-484">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Short"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-485">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string c1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-486">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>c1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-487"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-488"></span>
<span id="cb3-489">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>CopyConstructor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> LongString<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-490">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Long string for copying over the heap"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-491">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string c2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-492">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>c2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb3-493"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-494"></span>
<span id="cb3-495">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>CopyConstructor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> EmbeddedNull<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-496">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'a'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'b'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb3-497">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s3<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-498">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string c3<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s3<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-499">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>c3<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-500">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>c3<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-501"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-502"></span>
<span id="cb3-503"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-504"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// copy assignment</span></span>
<span id="cb3-505"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-506">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>CopyAssignment<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> SSOToSSO<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-507">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"A"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-508">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"B"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-509">    s1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-510">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-511">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'B'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-512">    EXPECT_NE<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb3-513"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-514"></span>
<span id="cb3-515">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>CopyAssignment<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> LongToLong<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-516">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"This is a very long string that currently lives on the heap."</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-517">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"And this is another long string, also on the heap, but different."</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-518">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> old_ptr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-519">    s1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-520">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb3-521">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>strcmp<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-522">    EXPECT_NE<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> old_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-523"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-524"></span>
<span id="cb3-525">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>CopyAssignment<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> LongToShort<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-526">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Long strings take up heap memory."</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-527">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Short"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-528">    s1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-529">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-530"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-531"></span>
<span id="cb3-532">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>CopyAssignment<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> ShortToLong<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-533">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Short"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-534">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Long strings take up heap memory."</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-535">    s1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-536">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb3-537"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-538"></span>
<span id="cb3-539">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>CopyAssignment<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> EmbeddedNull<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-540">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'x'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'y'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'z'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb3-541">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-542">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Placeholder"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-543">    s2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-544">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-545">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-546">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'y'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-547"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-548"></span>
<span id="cb3-549">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>CopyAssignment<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> SelfAssignment<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-550">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Self Assignment Test"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-551">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> ptr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-552">    s1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-553">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-554">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>strcmp<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Self Assignment Test"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-555"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-556"></span>
<span id="cb3-557"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-558"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// move constructor</span></span>
<span id="cb3-559"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-560">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>MoveConstructor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> ShortSSO<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-561">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string source<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Short SSO"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-562">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> original_data_addr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> source<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-563">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string destination<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>move<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>source<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb3-564">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>destination<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-565">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>strcmp<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>destination<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Short SSO"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-566">    EXPECT_NE<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>destination<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> original_data_addr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-567">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>source<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-568"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-569"></span>
<span id="cb3-570">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>MoveConstructor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> LongHeap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-571">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string source<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"This is a very long string that lives on the heap."</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-572">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> original_size <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> source<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-573">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> original_heap_ptr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> source<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-574">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string destination<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>move<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>source<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb3-575">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>destination<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> original_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-576">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>destination<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> original_heap_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-577">    EXPECT_TRUE<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>source<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">||</span> source<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-578"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-579"></span>
<span id="cb3-580">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>MoveConstructor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> EmbeddedNull<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-581">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> null_data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'m'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'v'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'e'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb3-582">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string source<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>null_data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> null_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-583">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string destination<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>move<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>source<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb3-584">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>destination<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-585">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>destination<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-586">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>memcmp<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>destination<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> null_data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-587"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-588"></span>
<span id="cb3-589"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-590"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// move assignment</span></span>
<span id="cb3-591"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-592">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>MoveAssignment<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> SSOToSSO<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-593">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Original"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-594">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"New"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-595">    s1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>move<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-596">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-597">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>strcmp<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"New"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-598">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-599"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-600"></span>
<span id="cb3-601">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>MoveAssignment<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> LongToLong<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-602">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"This is a very long string currently occupying the heap memory."</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-603">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Another extremely long string that we will move into the first one."</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-604">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> s2_heap_ptr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-605">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> s2_size <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-606">    s1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>move<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-607">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> s2_size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-608">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> s2_heap_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-609">    EXPECT_TRUE<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">||</span> s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-610"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-611"></span>
<span id="cb3-612">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>MoveAssignment<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> LongToShort<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-613">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"A long string that will be overwritten by a short moved string."</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-614">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Short"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-615">    s1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>move<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-616">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-617"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-618"></span>
<span id="cb3-619">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>MoveAssignment<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> EmbeddedNull<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-620">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'m'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'v'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'e'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb3-621">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-622">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Temporary"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-623">    s2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>move<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-624">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-625">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-626"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-627"></span>
<span id="cb3-628">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>MoveAssignment<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> SelfMove<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-629">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Don't break me"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-630">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> ptr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-631">    s1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>move<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span>ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-632">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">14</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-633">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>strcmp<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Don't break me"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-634"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-635"></span>
<span id="cb3-636"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-637"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// reserve</span></span>
<span id="cb3-638"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-639">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Reserve<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> ShortNoOp<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-640">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"A"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-641">    s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>reserve<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-642">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">22</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-643"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-644"></span>
<span id="cb3-645">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Reserve<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> LongGrowth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-646">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"A"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-647">    s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>reserve<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">50</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-648">    EXPECT_GE<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">50</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-649">    EXPECT_FALSE<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>empty<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb3-650">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-651">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'A'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-652"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-653"></span>
<span id="cb3-654">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Reserve<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> EmbeddedNull<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-655">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'x'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'y'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb3-656">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-657">    s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>reserve<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-658">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-659">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-660"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-661"></span>
<span id="cb3-662"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-663"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// push_back</span></span>
<span id="cb3-664"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-665">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>PushBack<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> ShortSSO<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-666">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-667">    s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>push_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'A'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-668">    s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>push_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'B'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-669">    s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>push_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'C'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-670">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-671">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'A'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-672">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'C'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-673">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-674"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-675"></span>
<span id="cb3-676">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>PushBack<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> SSOToHeapTransition<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-677">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-678">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">23</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-679">        s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>push_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'x'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-680">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">23</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-681">    s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>push_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'!'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-682">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">24</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-683">    EXPECT_GT<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">23</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-684">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'x'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-685">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">23</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'!'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-686">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">24</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-687"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-688"></span>
<span id="cb3-689">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>PushBack<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> EmbeddedNull<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-690">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Start"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-691">    s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>push_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-692">    s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>push_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'Z'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-693">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-694">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-695">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'Z'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-696">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-697"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-698"></span>
<span id="cb3-699"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-700"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// pop_back</span></span>
<span id="cb3-701"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-702">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>PopBack<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> ShortSSO<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-703">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ABC"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-704">    s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>pop_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-705">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-706">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'A'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-707">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'B'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-708">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-709"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-710"></span>
<span id="cb3-711">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>PopBack<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> LongHeap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-712">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"123456789012345678901234"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-713">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> original_size <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-714">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> original_capacity <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-715">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">uz</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">23</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-716">        s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>pop_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-717">        EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> original_size <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-718">        EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> original_capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-719">        EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()[</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-720">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-721"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-722"></span>
<span id="cb3-723">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>PopBack<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> EmbeddedNull<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-724">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> null_data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'a'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'b'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'c'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb3-725">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>null_data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> null_data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-726">    s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>pop_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-727">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-728">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-729">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-730"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-731"></span>
<span id="cb3-732"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-733"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// insert</span></span>
<span id="cb3-734"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-735">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Insert<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> ShortSSOExternalRange<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-736">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"AC"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-737">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> b <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'B'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-738">    s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>insert<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>b<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>b <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-739">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-740">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>strcmp<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ABC"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-741"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-742"></span>
<span id="cb3-743">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Insert<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> LongHeapExternalRange<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-744">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"This is a long string."</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-745">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> extra <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">" Indeed!"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-746">    s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>insert<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> extra<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> extra <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>strlen<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>extra<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb3-747">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">22</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-748">    EXPECT_TRUE<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>strstr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Indeed!."</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb3-749"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-750"></span>
<span id="cb3-751">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Insert<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> EmbeddedNull<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-752">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"a"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-753">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> nulls<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'b'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb3-754">    s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>insert<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> nulls<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> nulls <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-755">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-756">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-757">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'b'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-758"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-759"></span>
<span id="cb3-760">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Insert<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> SSOToHeapTransition<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-761">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Small"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-762">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string long_val<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">50</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'z'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-763">    s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>insert<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> long_val<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> long_val<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb3-764">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">55</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-765">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'S'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-766">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">uz</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">50</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-767">        EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'z'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-768">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">51</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'m'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-769">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">52</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'a'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-770">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">53</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'l'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-771">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">54</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'l'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-772">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">55</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-773"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-774"></span>
<span id="cb3-775">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Insert<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> SelfReferential<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-776">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Hello"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-777">    s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>insert<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb3-778">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-779">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>strcmp<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"HelloHello"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-780"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-781"></span>
<span id="cb3-782">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Insert<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> SelfReferentialWithReallocation<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-783">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Trigger"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-784">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string padding<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'!'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-785">    s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>insert<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> padding<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> padding<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb3-786">    s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>insert<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb3-787">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">54</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-788"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-789"></span>
<span id="cb3-790"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-791"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// erase</span></span>
<span id="cb3-792"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-793">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Erase<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> ShortSSOMiddle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-794">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ABXCD"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-795">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> it <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>erase<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-796">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-797">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>strcmp<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ABCD"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-798">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span>it<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'C'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-799">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-800"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-801"></span>
<span id="cb3-802">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Erase<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> LongHeapEraseToEnd<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-803">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"This is a long string that we will truncate."</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-804">    s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>erase<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">26</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb3-805">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">26</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-806">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>strcmp<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"This is a long string that"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-807">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">26</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-808"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-809"></span>
<span id="cb3-810">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Erase<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> EmbeddedNull<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-811">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'a'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'b'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'c'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'d'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb3-812">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-813">    s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>erase<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-814">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-815">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'c'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-816">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>memcmp<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"abcd"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-817"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-818"></span>
<span id="cb3-819">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Erase<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> FullErase<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-820">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Clear me"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-821">    s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>erase<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb3-822">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-823">    EXPECT_TRUE<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>empty<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb3-824">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-825"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-826"></span>
<span id="cb3-827"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-828"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// operator[]</span></span>
<span id="cb3-829"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-830">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>ElementAccess<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> ShortSSO<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-831">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Short"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-832">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'S'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-833">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'t'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-834">    s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'s'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-835">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'s'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-836"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-837"></span>
<span id="cb3-838">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>ElementAccess<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> LongHeap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-839">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"This is a very long string for indexing."</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-840">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'T'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-841">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'v'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-842">    s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'V'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-843">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'V'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-844"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-845"></span>
<span id="cb3-846">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>ElementAccess<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> EmbeddedNull<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-847">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'x'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'y'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb3-848">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-849">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-850">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'x'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-851">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-852"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-853"></span>
<span id="cb3-854"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-855"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// front and back</span></span>
<span id="cb3-856"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-857">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>FrontAndBack<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> ShortSSO<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-858">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Hi"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-859">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>front<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'H'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-860">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'i'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-861"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-862"></span>
<span id="cb3-863">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>FrontAndBack<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> LongHeap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-864">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Long strings need front/back too"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-865">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>front<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'L'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-866">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'o'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-867"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-868"></span>
<span id="cb3-869">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>FrontAndBack<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> EmbeddedNull<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-870">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'a'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb3-871">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-872">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>front<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-873">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-874"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-875"></span>
<span id="cb3-876"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-877"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// data()</span></span>
<span id="cb3-878"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-879">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>DataFunction<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> ShortSSO<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-880">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SSO"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-881">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> ptr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-882">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'S'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-883">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-884"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-885"></span>
<span id="cb3-886">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>DataFunction<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> LongHeap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-887">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"A long string to check pointer consistency"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-888">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> ptr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-889">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'A'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-890">    EXPECT_NE<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">reinterpret_cast</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*&gt;(&amp;</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb3-891"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-892"></span>
<span id="cb3-893">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>DataFunction<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> EmbeddedNull<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-894">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'A'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb3-895">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-896">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-897">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'A'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-898"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-899"></span>
<span id="cb3-900"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-901"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// size()</span></span>
<span id="cb3-902"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-903">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>SizeFunction<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> ZeroSize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-904">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">""</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-905">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-906"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-907"></span>
<span id="cb3-908">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>SizeFunction<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> MaxSSOSize<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-909">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"1234567890123456789012"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-910">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">22</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-911">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">22</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-912"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-913"></span>
<span id="cb3-914">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>SizeFunction<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> SSOToHeapTransition<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-915">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"1234567890123456789012"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-916">    s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>push_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'3'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-917">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">23</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-918">    EXPECT_GE<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">24</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-919"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-920"></span>
<span id="cb3-921">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>SizeFunction<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> EmbeddedNull<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-922">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'H'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'i'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'!'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb3-923">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> data <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-924">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-925"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-926"></span>
<span id="cb3-927"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-928"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// capacity()</span></span>
<span id="cb3-929"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-930">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>CapacityFunction<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> SSOCapacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-931">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Short"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-932">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">22</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-933"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-934"></span>
<span id="cb3-935">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>CapacityFunction<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> LongCapacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-936">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"This string is long enough to be on the heap."</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-937">    EXPECT_GE<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb3-938"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-939"></span>
<span id="cb3-940">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>CapacityFunction<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> GrowthOnPushBack<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-941">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"12345678901234567890123"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-942">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> cap_before <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-943">    s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>push_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'!'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-944">    EXPECT_GT<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> cap_before<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-945"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-946"></span>
<span id="cb3-947"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-948"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// empty()</span></span>
<span id="cb3-949"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ----------------------------------------------------------------</span></span>
<span id="cb3-950">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>EmptyFunction<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> TrulyEmpty<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-951">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-952">    EXPECT_TRUE<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>empty<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb3-953"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-954"></span>
<span id="cb3-955">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>EmptyFunction<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> NotEmptySSO<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-956">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"a"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-957">    EXPECT_FALSE<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>empty<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb3-958"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-959"></span>
<span id="cb3-960">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>EmptyFunction<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> NotEmptyLong<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-961">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"This is a very long string"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-962">    EXPECT_FALSE<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>empty<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb3-963"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-964"></span>
<span id="cb3-965">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>EmptyFunction<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> SingleEmbeddedNull<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-966">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> null_char <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\0</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-967">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(&amp;</span>null_char<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>null_char <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-968">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-969">    EXPECT_FALSE<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>empty<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb3-970"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-971"></span>
<span id="cb3-972"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> argc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">**</span> argv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-973">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>testing<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>InitGoogleTest<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(&amp;</span>argc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> argv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-974">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> RUN_ALL_TESTS<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-975"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/reYv768j4">Compiler Explorer</a></p>


</section>

 ]]></description>
  <category>C++</category>
  <guid>http://quantdev.blog/posts/implementing_string/</guid>
  <pubDate>Wed, 08 Apr 2026 23:00:00 GMT</pubDate>
  <media:content url="http://quantdev.blog/posts/implementing_string/cpp.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>The differences between std::make_tuple, std::tie and std::forward_as_tuple</title>
  <dc:creator>`dev::author` </dc:creator>
  <link>http://quantdev.blog/posts/make_tuple_and_close_cousins/</link>
  <description><![CDATA[ 





<section id="introduction" class="level1">
<h1>Introduction</h1>
<p><code>std::make_tuple(T&amp;&amp;)</code> applies a <code>std::decay</code> on each of the the types it receives, in order to determine the corresponding type to store in the tuple. <code>std::decay</code> removes all <code>const</code> and reference attributes of the type. The below example is instructive.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb1-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;iostream&gt;</span></span>
<span id="cb1-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;tuple&gt;</span></span>
<span id="cb1-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;print&gt;</span></span>
<span id="cb1-4"></span>
<span id="cb1-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> X<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{};</span></span>
<span id="cb1-6"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb1-7">    X x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-8">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">ref_</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> X<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb1-9">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>is_same_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">decltype</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>make_tuple<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)),</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>tuple<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>X<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;);</span></span>
<span id="cb1-10">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>is_same_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">decltype</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>make_tuple<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>move<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))),</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>tuple<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>X<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;);</span></span>
<span id="cb1-11">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>is_same_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">decltype</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>make_tuple<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>X<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{})),</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>tuple<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>X<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;);</span></span>
<span id="cb1-12">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>is_same_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">decltype</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>make_tuple<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>move<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">ref_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))),</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>tuple<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>X<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;);</span></span>
<span id="cb1-13">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-14"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://godbolt.org/z/z18savxoP">Compiler Explorer</a></p>
<p>As a result, if we pass lvalue references to <code>std::make_tuple</code>, <code>std::tuple</code> will store the corresponding decayed types. The tuple elements are copy constructed. If we pass any rvalue references <code>T&amp;&amp;</code> to <code>std::make_tuple</code>, <code>std::tuple</code> will again decay the type to <code>T</code>, THe tuple elements will move constructed at the corresponding indices.</p>
<p>There is one caveat here. A <code>reference_wrapper&lt;T&gt;</code> is a copy-constructible and copy-assignable wrapper class around a reference to the object <code>T&amp;</code>. For example, you can store references inside standard containers such as <code>std::vector</code>. If you pass <code>reference_wrapper&lt;T&gt;</code> to <code>make_tuple</code>, then the tuple will have <code>T&amp;</code> at the corresponding index.</p>


</section>

 ]]></description>
  <category>C++</category>
  <guid>http://quantdev.blog/posts/make_tuple_and_close_cousins/</guid>
  <pubDate>Fri, 27 Mar 2026 00:00:00 GMT</pubDate>
  <media:content url="http://quantdev.blog/posts/make_tuple_and_close_cousins/cpp.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>C++ 26 Reflections</title>
  <dc:creator>`dev::author` </dc:creator>
  <link>http://quantdev.blog/posts/reflections/</link>
  <description><![CDATA[ 





<section id="introduction" class="level1">
<h1>Introduction</h1>
<p>I recently attended a talk on reflections in C++26 by <a href="https://www.linkedin.com/in/sarthaksehgal99/">Sarthak Sehgal</a> and much of my code snippets here are inspired by his talk.</p>
</section>
<section id="what-is-a-reflection-really" class="level1">
<h1>What is a reflection really?</h1>
<p>A <em>reflection</em> is the ability of software to expose its internal structure. C++ reflections are static reflections - that is, the compiler exposes the structure at compile-time.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb1-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;iostream&gt;</span></span>
<span id="cb1-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;meta&gt;</span></span>
<span id="cb1-3"></span>
<span id="cb1-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">enum</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> Color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> Red<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Blue<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Green <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb1-5"></span>
<span id="cb1-6"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb1-7">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>meta::identifier_of<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(^^</span>Color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-8">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>meta::identifier_of<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb1-9">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>meta::enumerators_of<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(^^</span>Color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb1-10">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-11"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>Suppose you want to iterate over the elements of the <code>Color</code> enum class or we may want to convert an enum variant to its string representation - could be done using reflections. Or let’s say, you have a <code>struct</code> in C++ and you want to iterate over what the data-members of the <code>struct</code> are. We are essentially inspecting the C++ code that has been written. Essentially, our program is reflecting itself at compile-time.</p>
</section>
<section id="reflections-before-c26" class="level1">
<h1>Reflections before C++26</h1>
<p>Before C++26, there were various workarounds used to generate code to achieve reflection-like behavior. Boost Describe is a C++14 library that uses macro magic, that provides reflections in C++14.</p>
<section id="macro-magic" class="level2">
<h2 class="anchored" data-anchor-id="macro-magic">Macro magic</h2>
<p>Let’ say I define an <code>enum</code> for the three primary colors <code>Red</code>, <code>Green</code> and <code>Blue</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb2-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// I define a macro COLORS. This macro takes in a function FUNC</span></span>
<span id="cb2-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// and invokes FUNC() on three literals Red, Green and Blue.</span></span>
<span id="cb2-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// So, what this macro expects is the user to provide some sort </span></span>
<span id="cb2-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// of a function and it is going to invoke that on these </span></span>
<span id="cb2-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// 3 literals.</span></span>
<span id="cb2-6"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#define COLORS      </span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb2-7"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">    </span>FUNC<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Red<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">       </span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb2-8"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">    </span>FUNC<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Blue<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">      </span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb2-9"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">    </span>FUNC<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Green<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb2-10"></span>
<span id="cb2-11"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Next, we have this enum class Color. What I am doing in the body</span></span>
<span id="cb2-12"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// of this enum is, I am defining a function FUNC(arg), which always</span></span>
<span id="cb2-13"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// appends `,`(comma) to the argument. So, FUNC(Red) would return</span></span>
<span id="cb2-14"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Red,. I pass COLORS as a parameter to FUNC. So, all its going</span></span>
<span id="cb2-15"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// to do is, it will expand FUNC(Red) FUNC(Blue) FUNC(Green) as</span></span>
<span id="cb2-16"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Red, Blue, Green,.</span></span>
<span id="cb2-17"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">enum</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> Color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-18">    <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#define FUNC</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;"> </span>name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-19">        COLORS</span>
<span id="cb2-20">    <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#undef FUNC</span></span>
<span id="cb2-21"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/587qq7doq">Compiler Explorer</a></p>
<p>We can actually see the preprocessor output in Compiler Explorer.</p>
<p>We can now write our own <code>enum_to_string</code> function as follows:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb3-1"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string enum_to_string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Color color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb3-2">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">switch</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb3-3">        <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#define FUNC</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;"> </span><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">case</span><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;"> </span>Color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">    </span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb3-4"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">            </span><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;"> </span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(#</span>name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-5">            COLORS</span>
<span id="cb3-6">        <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#undef FUNC</span></span>
<span id="cb3-7">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">default</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb3-8">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"unknown"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> </span>
<span id="cb3-9">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-10"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
</section>
</section>
<section id="reflection-in-c26" class="level1">
<h1>Reflection in C++26</h1>
<p>In C++26, we will use the unibrow operator <code>^^</code> as the reflection operator. Reflection using the reflection operator maps its operand from the programming domain to the reflections domain. We can think of the code that we write, types we define as living in the programming domain. Reflections of these types live in the reflections domain. These are two different domains. We can reflect many different entities, for example, a variable, a type, an <code>enum</code>, a namespace, <code>struct</code> or a <code>class</code>.</p>
<section id="reflection-operator-and-the-splicer-operator." class="level2">
<h2 class="anchored" data-anchor-id="reflection-operator-and-the-splicer-operator.">Reflection operator <code>^^</code> and the splicer operator.</h2>
<p>Consider the following code snippet:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb4-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> r <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">^^</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[:</span>r<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:]</span> x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
<p>The caret-caret <code>^^</code> is the new reflection operator introduced in C++26. What this operator does is, it lifts the expression into the reflection domain. The entity being reflected can be a type, variable, function, namespace, <code>enum</code>. Its informally called the unibrow operator. (Because if you type two carets with dot in-between, it looks like a face <code>^.^</code>).</p>
<p>We are using the reflection expression on the right <code>^^int</code> in a <code>constexpr</code> context, so it will be evaluated at compile-time.</p>
<p>The type returned by the reflection operator is <code>std::meta::info</code>. This is the universal type returned from reflecting any type whatsoever.</p>
<p>We can go back from the reflection domain to the programming domain by using the splicer operator <code>[:r:]</code>.</p>
</section>
<section id="meta-functions" class="level2">
<h2 class="anchored" data-anchor-id="meta-functions">Meta functions</h2>
<p>We can write a simple meta-function to print all of the variants of an <code>enum</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb5-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span> </span>
<span id="cb5-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//                                                                      reflect the enum</span></span>
<span id="cb5-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//                                                                             |</span></span>
<span id="cb5-4"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> c <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>define_static_array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>meta::enumerators_of<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(^^</span>Color<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)))</span></span>
<span id="cb5-5"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb5-6">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>meta::identifier_of<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-7"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>The reflection operator <code>^^</code>applied to the <code>Color</code> enum reflects the <code>enum</code>. This reflection lives in the reflection domain. In the reflection domain, I can use some nice meta-functions such as <code>std::meta::enumerators_of()</code> which returns a list of reflections for each of the elements in the <code>enum</code>. Note that it does not return the elements themselves, but the reflection of the elements : <code>{^^Color::Red, ^^Color::Blue, ^^Color::Green }</code>.</p>
<p>The <code>template for</code> iterates for each element reflection at compile-time. <code>std::define_static_array</code> takes an array at compile time and promotes it to static storage duration for use at runtime.</p>
<p>To the reflection of each color, I can apply another metafunction <code>identifier_of</code> which takes in a reflection and returns a <code>string_view</code> which is the identifier of that reflection.</p>
</section>
</section>
<section id="what-really-is-a-reflection-under-the-hood" class="level1">
<h1>What really is a reflection under the hood?</h1>
<p>Consider the following code snippet:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb6-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> R<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb6-2"></span>
<span id="cb6-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>meta::info res1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">^^</span>R<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb6-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> print1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>meta::is_complete_type<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>res1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// false</span></span>
<span id="cb6-5"></span>
<span id="cb6-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> R<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-7">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> a<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb6-8"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb6-9"></span>
<span id="cb6-10"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>meta::info res2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">^^</span>R<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb6-11"></span>
<span id="cb6-12"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> print2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>meta::is_complete_type<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>res2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb6-13"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> print3 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>meta::is_complete_type<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>res1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb6-14"></span>
<span id="cb6-15"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb6-16">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"print1 : "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> print1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb6-17">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"print2 : "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> print2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb6-18">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"print3 : "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> print3 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb6-19"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/G7rob14Px">Compiler Explorer</a></p>
<p><code>res1</code> is the reflection of an incomplete type - <code>R</code> has only been declared. Hence, we all know that <code>print1</code> is <code>false</code>, because the type is not complete at this point. Once we define the <code>class R</code>, the type is complete. We now reflect the type <code>R</code> once again, <code>res2</code> is the reflection of the completed type. So, <code>print2</code> is <code>true</code>. <code>print3</code> is interesting. We use the same reflection <code>res1</code> defined before the type was completed. If we query it, for whether the type is complete, after <code>R</code> has been defined, now this returns <code>true</code>, which is surprising.</p>
<p>The C++ compiler constructs an AST(Abstract Syntax Tree) of the entire source code. <em>A reflection is a reference to a node in the AST</em>. This is why when the type is completed, <code>std::is_complete_type(res1)</code> returns <code>true</code>.</p>
</section>
<section id="splicers" class="level1">
<h1>Splicers</h1>
<p>The splicing operator produces a C++ expression evaluating to the entity represented by the reflection <code>r</code>. <code>typename[:r:]</code> produces a type specifier. <code>template[:r:]</code> produces a template name.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb7-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> r <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">^^</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[:</span>r<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:]</span> x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
<p>The splicer operator is used to go back from the reflection domain to the programming domain.</p>
</section>
<section id="writing-string_to_enum-and-enum_to_string-functions" class="level1">
<h1>Writing <code>string_to_enum</code> and <code>enum_to_string</code> functions</h1>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb8-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;iostream&gt;</span></span>
<span id="cb8-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;meta&gt;</span></span>
<span id="cb8-3"></span>
<span id="cb8-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// I define a macro COLORS. This macro takes in a function FUNC</span></span>
<span id="cb8-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// and invokes FUNC() on three literals Red, Green and Blue.</span></span>
<span id="cb8-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// So, what this macro expects is the user to provide some sort</span></span>
<span id="cb8-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// of a function and it is going to invoke that on these</span></span>
<span id="cb8-8"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// 3 literals.</span></span>
<span id="cb8-9"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#define COLORS </span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb8-10"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">    </span>FUNC<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Red<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">  </span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb8-11"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">    </span>FUNC<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Blue<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;"> </span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb8-12"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">    </span>FUNC<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Green<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb8-13"></span>
<span id="cb8-14"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Next, we have this enum class Color. What I am doing in the body</span></span>
<span id="cb8-15"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// of this enum is, I am defining a function FUNC(arg), which always</span></span>
<span id="cb8-16"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// appends `,`(comma) to the argument. So, FUNC(Red) would return</span></span>
<span id="cb8-17"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Red,. I pass COLORS as a parameter to FUNC. So, all its going</span></span>
<span id="cb8-18"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// to do is, it will expand FUNC(Red) FUNC(Blue) FUNC(Green) as</span></span>
<span id="cb8-19"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Red, Blue, Green,.</span></span>
<span id="cb8-20"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">enum</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> Color <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb8-21"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#define FUNC</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;"> </span>name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb8-22">    COLORS</span>
<span id="cb8-23"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#undef FUNC</span></span>
<span id="cb8-24"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb8-25"></span>
<span id="cb8-26"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> E<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb8-27"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string_view enum_to_string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>E e<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb8-28">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> I <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>define_static_array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>meta::enumerators_of<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(^^</span>E<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)))</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb8-29">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>e <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[:</span>I<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:])</span> </span>
<span id="cb8-30">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>meta::identifier_of<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>I<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb8-31">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb8-32">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"unknown"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb8-33"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb8-34"></span>
<span id="cb8-35"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> E<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb8-36"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>optional<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>E<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> string_to_enum<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string_view s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb8-37">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">static</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> enum_vals <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>define_static_array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>meta::enumerators_of<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(^^</span>E<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb8-38">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> I <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> enum_vals<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb8-39">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>meta::identifier_of<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>I<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))</span> </span>
<span id="cb8-40">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[:</span>I<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:];</span></span>
<span id="cb8-41">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb8-42">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>nullopt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb8-43"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb8-44"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/4qqbqdYsG">Compiler Explorer</a></p>
</section>
<section id="writing-an-elementary-class-serializer" class="level1">
<h1>Writing an elementary class serializer</h1>
<p>We can iterate over the non-static data-members of the class. Let’s write a simple class serializer using this logic.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb9-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;iostream&gt;</span></span>
<span id="cb9-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;meta&gt;</span></span>
<span id="cb9-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;optional&gt;</span></span>
<span id="cb9-4"></span>
<span id="cb9-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Point2D <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb9-6">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb9-7">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span> y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb9-8"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb9-9"></span>
<span id="cb9-10"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb9-11"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> format<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>T <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb9-12">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> identifier_of<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(^^</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"{ "</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb9-13">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> access_ctx <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>meta::access_context::unchecked<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb9-14"></span>
<span id="cb9-15">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> mem <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb9-16">                  <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>define_static_array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>nonstatic_data_members_of<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(^^</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> access_ctx<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)))</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb9-17">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>format<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> = </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">, "</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> identifier_of<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>mem<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.[:</span>mem<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:]);</span></span>
<span id="cb9-18">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb9-19"></span>
<span id="cb9-20">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"}"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb9-21"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb9-22"></span>
<span id="cb9-23"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> </span>
<span id="cb9-24">    format<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Point2D<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{.</span>x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">});</span> </span>
<span id="cb9-25"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/KrTaqYK5M">Compiler Explorer</a></p>
</section>
<section id="generating-code" class="level1">
<h1>Generating code</h1>
<p>The metafunction that’s used to generate code in C++26 is <code>define_aggregate</code>. <code>define_aggregate</code> takes the reflection of an incomplete class/struct/union type and a list of reflections of data member descriptions and completes the given class type with datab members as described in the given order.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb10-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>reflection_range R <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> initializer_list<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>meta::info<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;</span></span>
<span id="cb10-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">consteval</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> define_aggregate<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>info type_class<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> R<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>meta::info<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
<p>In order to provide the reflection of a data-member description, there is another metafunction <code>data_member_spec</code>. <code>data_member_spec</code> returns a reflection a data member description for the data-member of a given type.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb11-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">consteval</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> data_member_spec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>info type<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> data_member_options options<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> info<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
<p><code>info type</code> is the type we want, for example, <code>int</code> or <code>char</code>. <code>options</code> can be used to specify the alignment, bit-field width amongst other things.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb12-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;iostream&gt;</span></span>
<span id="cb12-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;meta&gt;</span></span>
<span id="cb12-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;string&gt;</span></span>
<span id="cb12-4"></span>
<span id="cb12-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Person<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb12-6"></span>
<span id="cb12-7"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">consteval</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb12-8">    define_aggregate<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(^^</span>Person<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb12-9">        data_member_spec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(^^</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>name <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"name"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}),</span></span>
<span id="cb12-10">        data_member_spec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(^^</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>name <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"age"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}),</span></span>
<span id="cb12-11">        data_member_spec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(^^</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>name <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"weight"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">})</span></span>
<span id="cb12-12">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">});</span></span>
<span id="cb12-13"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb12-14"></span>
<span id="cb12-15"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/xE6xPd9Tn">Compiler Explorer</a></p>
<p>In the above example, I take an incomplete type <code>Person</code> and then generate code to add various data-members to it.</p>
</section>
<section id="implementing-a-tuple" class="level1">
<h1>Implementing a <code>tuple</code></h1>
<section id="tuple-implementation-before-c26" class="level2">
<h2 class="anchored" data-anchor-id="tuple-implementation-before-c26"><code>tuple</code> implementation before C++26</h2>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb13-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;iostream&gt;</span></span>
<span id="cb13-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;string&gt;</span></span>
<span id="cb13-3"></span>
<span id="cb13-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> dev <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb13-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb13-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> tuple<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb13-7"></span>
<span id="cb13-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb13-9"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> tuple<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb13-10">    T head<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb13-11"></span>
<span id="cb13-12">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> tuple<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>T value<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> head<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>value<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb13-13"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb13-14"></span>
<span id="cb13-15"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Head<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Tail<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb13-16"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> tuple<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Head<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Tail<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb13-17">    Head head<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb13-18">    tuple<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Tail<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;</span> tail<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb13-19"></span>
<span id="cb13-20">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> tuple<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Head first<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Tail<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> rest<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> head<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>first<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span> tail<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>rest<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...}</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb13-21"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb13-22"></span>
<span id="cb13-23"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> N<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Types<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb13-24"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">nth_type</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb13-25"></span>
<span id="cb13-26"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> First<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Rest<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb13-27"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">nth_type</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> First<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Rest<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb13-28">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> type <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> First<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb13-29"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb13-30"></span>
<span id="cb13-31"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> N<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Head<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Tail<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb13-32"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">nth_type</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>N<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Head<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Tail<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb13-33">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> type <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">nth_type</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>N <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Tail<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;::</span>type<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb13-34"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb13-35"></span>
<span id="cb13-36"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> N<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb13-37"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">nth_type_t</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">nth_type</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>N<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;::</span>type<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb13-38"></span>
<span id="cb13-39"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> N<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Head<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Tail<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb13-40"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">nth_type_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>N<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Head<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Tail<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;</span> get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>tuple<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Head<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Tail<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;</span> tup<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb13-41">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>N <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb13-42">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> tup<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>head<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb13-43">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb13-44">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>N <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Tail<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;(</span>tup<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>tail<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb13-45">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb13-46"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb13-47"></span>
<span id="cb13-48"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb13-49">tuple<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> tuple<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;;</span></span>
<span id="cb13-50"></span>
<span id="cb13-51"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// namespace dev</span></span>
<span id="cb13-52"></span>
<span id="cb13-53"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb13-54">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>tuple tup<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Hello"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">123</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.14159</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb13-55">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>tup<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb13-56">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>tup<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb13-57">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>tup<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb13-58"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/P359abWKe">Compiler Explorer</a></p>
</section>
<section id="tuple-implementation-using-reflections" class="level2">
<h2 class="anchored" data-anchor-id="tuple-implementation-using-reflections"><code>tuple</code> implementation using reflections</h2>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb14-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;iostream&gt;</span></span>
<span id="cb14-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;meta&gt;</span></span>
<span id="cb14-3"></span>
<span id="cb14-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb14-5">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb14-6">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> tuple<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb14-7">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> storage<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb14-8">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">consteval</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb14-9">            define_aggregate<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(^^</span>storage<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb14-10">                data_member_spec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(^^</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)...</span></span>
<span id="cb14-11">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">});</span></span>
<span id="cb14-12">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb14-13"></span>
<span id="cb14-14">        storage data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb14-15">        </span>
<span id="cb14-16">        tuple<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb14-17">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb14-18">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span> </span>
<span id="cb14-19"></span>
<span id="cb14-20">        tuple<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Ts <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;...</span> values<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb14-21">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> data<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> values<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb14-22">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb14-23">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb14-24"></span>
<span id="cb14-25">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> N<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Types<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb14-26">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">nth_type</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb14-27">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">static</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>array types <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{^^</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...};</span></span>
<span id="cb14-28">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> type <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[:</span>types<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>N<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]:];</span></span>
<span id="cb14-29">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb14-30"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
</section>
</section>
<section id="references" class="level1">
<h1>References</h1>
<ul>
<li>Time to Introspect, a talk by Sarthak Sehgal at CppOnline 2026.</li>
<li><a href="https://digital-medium-co-uk.zoom.us/rec/play/tgoaK6PL6kyK5nee3WXj1sO4Q3dQtySn8GDlOLUZoEN6Ovmsrrjg21U9FTcsZsX3mzK1fcF0vQbX23yW.-j5rk04FL41RvpeN"><code>enum</code> to <code>string</code></a> C++26 P2996 Reflection Support</li>
</ul>


</section>

 ]]></description>
  <category>C++</category>
  <guid>http://quantdev.blog/posts/reflections/</guid>
  <pubDate>Fri, 13 Mar 2026 00:00:00 GMT</pubDate>
  <media:content url="http://quantdev.blog/posts/reflections/cpp.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>Different ways to write a filter function</title>
  <dc:creator>`dev::author` </dc:creator>
  <link>http://quantdev.blog/posts/writing_a_filter_function/</link>
  <description><![CDATA[ 





<section id="writing-a-filter-function" class="level1">
<h1>Writing a filter function</h1>
<p>A nice collection of techniques to filter elements in a range satisfying a predicate. The complete article can be found on <a href="https://www.cppstories.com/2021/filter-cpp-containers/">Bartlomiej Filipek’s blog</a>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb1-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;execution&gt;</span></span>
<span id="cb1-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;functional&gt;</span></span>
<span id="cb1-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;iostream&gt;</span></span>
<span id="cb1-4"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;iterator&gt;</span></span>
<span id="cb1-5"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;vector&gt;</span></span>
<span id="cb1-6"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;print&gt;</span></span>
<span id="cb1-7"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;algorithm&gt;</span></span>
<span id="cb1-8"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;ranges&gt;</span></span>
<span id="cb1-9"></span>
<span id="cb1-10"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Ref: 15 Different ways to Filter Containers </span></span>
<span id="cb1-11"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// in Modern C++ by Bartlomiej Filipek, cppstories.com</span></span>
<span id="cb1-12"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// https://www.cppstories.com/2021/filter-cpp-containers/</span></span>
<span id="cb1-13">    </span>
<span id="cb1-14"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// A filter function has the following interface:</span></span>
<span id="cb1-15"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// auto Filter(const Container&amp; cont, Predicate p)</span></span>
<span id="cb1-16"></span>
<span id="cb1-17"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// It returns all elements that satisfy the predicate.</span></span>
<span id="cb1-18">    </span>
<span id="cb1-19"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Raw loops.</span></span>
<span id="cb1-20"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// filter v1</span></span>
<span id="cb1-21"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Pred<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb1-22"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> FilterRaw<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&amp;</span> vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pred p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb1-23">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-24">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> elem <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-25">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>elem<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))</span></span>
<span id="cb1-26">            out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>push_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>elem<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-27"></span>
<span id="cb1-28">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-29"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-30"></span>
<span id="cb1-31"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Using std::copy_if(@begin, @end, @tgt_begin, f(element)-&gt;bool)</span></span>
<span id="cb1-32"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// filter v2</span></span>
<span id="cb1-33"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Pred<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb1-34"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> FilterCopyIf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&amp;</span> vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pred p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb1-35">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-36">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>copy_if<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>back_inserter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-37">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-38"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-39"></span>
<span id="cb1-40"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// std::remove_copy_if(@begin, @end, @tgt_begin, f(element)-&gt;bool)</span></span>
<span id="cb1-41"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// It copies all elements omitting those that do NOT satisfy </span></span>
<span id="cb1-42"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// the predicate.</span></span>
<span id="cb1-43"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// filter v3</span></span>
<span id="cb1-44"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Pred<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb1-45"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> FilterRemoveCopyIf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&amp;</span> vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pred p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb1-46">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-47">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// std::not_fn(func) is used to reverse the predicate.</span></span>
<span id="cb1-48">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>remove_copy_if<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>back_inserter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>not_fn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb1-49">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-50"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-51"></span>
<span id="cb1-52"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// The famous remove-erase idiom</span></span>
<span id="cb1-53"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// filter v4</span></span>
<span id="cb1-54"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// std::remove_if doesn't actually remove elements. It moves</span></span>
<span id="cb1-55"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// them to the end of the container. So, we use erase to do the final</span></span>
<span id="cb1-56"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// work.</span></span>
<span id="cb1-57"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Pred<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb1-58"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> FilterRemoveErase<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&amp;</span> vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pred p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb1-59">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// std::remove_if return @new_end</span></span>
<span id="cb1-60">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> vec <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb1-61">    out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>erase<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>remove_if<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>not_fn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)),</span> out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb1-62">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-63"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-64"></span>
<span id="cb1-65"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// std::erase_if</span></span>
<span id="cb1-66"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// filter v5</span></span>
<span id="cb1-67"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Pred<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb1-68"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> FilterEraseIf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&amp;</span> vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pred p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb1-69">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> vec <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb1-70">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>erase_if<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>not_fn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb1-71">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-72"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-73"></span>
<span id="cb1-74"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// A more generic approach</span></span>
<span id="cb1-75"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// filter v6</span></span>
<span id="cb1-76"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> ContainerType<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Pred<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb1-77"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> FilterEraseIfGen<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> ContainerType<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> cont<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pred p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb1-78">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> out <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> cont<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-79">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>erase_if<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>not_fn<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb1-80">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-81"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-82"></span>
<span id="cb1-83"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Another version for ranges</span></span>
<span id="cb1-84"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// filter v7 </span></span>
<span id="cb1-85"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// This can already work with other containers and not just</span></span>
<span id="cb1-86"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// std::vector.</span></span>
<span id="cb1-87"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> stdr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>ranges<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-88"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> ContainerType<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Pred<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb1-89"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> FilterRangeCopyIfGen<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> ContainerType<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pred p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb1-90">    ContainerType out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-91">    stdr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>copy_if<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>back_inserter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-92">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-93"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-94"></span>
<span id="cb1-95"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// The only problem with the above approach is that </span></span>
<span id="cb1-96"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// std::back_inserter(v) does not work with associative containers</span></span>
<span id="cb1-97"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// or containers that don't support push_back()</span></span>
<span id="cb1-98"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// In that case, we can fall back to std::inserter() adapter.</span></span>
<span id="cb1-99"></span>
<span id="cb1-100"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> ContainerType<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb1-101"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">concept</span> HasPushBack <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">requires</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>ContainerType container<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> ContainerType<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">value_type</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb1-102">    container<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>push_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-103"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb1-104"></span>
<span id="cb1-105"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// filter v8</span></span>
<span id="cb1-106"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>HasPushBack ContainerType<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Pred<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb1-107"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> FilterRangeCopyIfWithConcepts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> ContainerType<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pred p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb1-108">    ContainerType out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-109">    stdr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>copy_if<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>back_inserter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-110">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-111"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-112"></span>
<span id="cb1-113"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> ContainerType<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Pred<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb1-114"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> FilterRangeCopyIfWithConcepts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> ContainerType<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pred p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb1-115">    ContainerType out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-116">    stdr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>copy_if<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>inserter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()),</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-117">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-118"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-119"></span>
<span id="cb1-120"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Since C++17, we also had parallel algorithms, so why can try perform</span></span>
<span id="cb1-121"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// a parallel copy_if</span></span>
<span id="cb1-122"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// filter v9</span></span>
<span id="cb1-123"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> ContainerType<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Pred<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb1-124"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> FilterCopyIfParallel<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> ContainerType<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pred p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb1-125">    ContainerType out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-126">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>copy_if<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>execution::par<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> </span>
<span id="cb1-127">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>back_inserter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> p</span>
<span id="cb1-128">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-129">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-130"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-131"></span>
<span id="cb1-132"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> stdv <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>ranges::views<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-133"></span>
<span id="cb1-134"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// filter v10</span></span>
<span id="cb1-135"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Pred<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb1-136"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> FilterRangesFilter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&amp;</span> vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pred p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb1-137">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-138">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> elem <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> vec <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> stdv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>filter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))</span></span>
<span id="cb1-139">        out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>push_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>elem<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-140"></span>
<span id="cb1-141">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> out<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-142"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-143"></span>
<span id="cb1-144"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// We can use ranges::to to automatically create a container.</span></span>
<span id="cb1-145"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// filter v11</span></span>
<span id="cb1-146"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> ContainerType<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Pred<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb1-147"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> FilterRangesTo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> ContainerType<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Pred p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb1-148">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> vec <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> stdv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>filter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-149">               <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> stdr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>to<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>ContainerType<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;();</span></span>
<span id="cb1-150"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-151"></span>
<span id="cb1-152"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb1-153">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> vec <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb1-154">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> is_even <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!(</span>x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb1-155">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> out1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> FilterRaw<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> is_even<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-156">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> out2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> FilterCopyIf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> is_even<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-157">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> out3 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> FilterRemoveCopyIf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> is_even<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-158">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-159"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/TojsKvoWc">Compiler Explorer</a></p>
</section>
<section id="references" class="level1">
<h1>References</h1>
<ul>
<li><a href="https://www.cppstories.com/2021/filter-cpp-containers/">Different ways to filter containers in modern C++</a></li>
</ul>


</section>

 ]]></description>
  <category>C++</category>
  <guid>http://quantdev.blog/posts/writing_a_filter_function/</guid>
  <pubDate>Thu, 08 Jan 2026 00:00:00 GMT</pubDate>
  <media:content url="http://quantdev.blog/posts/writing_a_filter_function/cpp.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>Runtime complexity cheatsheet</title>
  <dc:creator>`dev::author` </dc:creator>
  <link>http://quantdev.blog/posts/runtime_complexity_cheatsheet/</link>
  <description><![CDATA[ 





<section id="sequential-containers" class="level1">

<table class="caption-top table">
<colgroup>
<col style="width: 25%">
<col style="width: 12%">
<col style="width: 34%">
<col style="width: 27%">
</colgroup>
<thead>
<tr class="header">
<th>Container</th>
<th><code>std::array</code></th>
<th><code>std::vector</code></th>
<th><code>std::list</code></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><strong>Low-level implementation</strong></td>
<td>Fixed capacity array.</td>
<td>A contiguous array that can grow in capacity dynamically.</td>
<td>Doubly linked list</td>
</tr>
<tr class="even">
<td><strong>Access: <code>front()</code></strong></td>
<td><img src="https://latex.codecogs.com/png.latex?O(1)"></td>
<td><img src="https://latex.codecogs.com/png.latex?O(1)"></td>
<td><img src="https://latex.codecogs.com/png.latex?O(1)"></td>
</tr>
<tr class="odd">
<td><strong>Access: <code>back()</code></strong></td>
<td><img src="https://latex.codecogs.com/png.latex?O(1)"></td>
<td><img src="https://latex.codecogs.com/png.latex?O(1)"></td>
<td><img src="https://latex.codecogs.com/png.latex?O(1)"> (not supported by <code>std::forward_list</code>)</td>
</tr>
<tr class="even">
<td><strong>Access: <code>at(idx)</code></strong></td>
<td><img src="https://latex.codecogs.com/png.latex?O(1)"></td>
<td><img src="https://latex.codecogs.com/png.latex?O(1)"></td>
<td>Not supported</td>
</tr>
<tr class="odd">
<td><strong>Search: <code>.find</code></strong></td>
<td><img src="https://latex.codecogs.com/png.latex?O(n)"></td>
<td><img src="https://latex.codecogs.com/png.latex?O(n)"></td>
<td><img src="https://latex.codecogs.com/png.latex?O(n)"></td>
</tr>
<tr class="even">
<td><strong>Insertion:</strong><br><code>insert(@begin,val)</code></td>
<td>—</td>
<td><img src="https://latex.codecogs.com/png.latex?O(n+m)"></td>
<td><img src="https://latex.codecogs.com/png.latex?O(1)"></td>
</tr>
<tr class="odd">
<td><strong>Insertion:</strong><br><code>insert(@pos,val)</code></td>
<td>—</td>
<td><img src="https://latex.codecogs.com/png.latex?O(n+m)"></td>
<td><img src="https://latex.codecogs.com/png.latex?O(1)"></td>
</tr>
<tr class="even">
<td><strong>Insertion:</strong><br><code>insert(@end,val)</code></td>
<td>—</td>
<td>Amortized <img src="https://latex.codecogs.com/png.latex?O(1)"></td>
<td><img src="https://latex.codecogs.com/png.latex?O(1)"></td>
</tr>
<tr class="odd">
<td><strong>Deletion:</strong><br><code>.erase</code></td>
<td>—</td>
<td><img src="https://latex.codecogs.com/png.latex?O(n+m)"></td>
<td><img src="https://latex.codecogs.com/png.latex?O(1)"></td>
</tr>
<tr class="even">
<td><strong>Deletion: Middle</strong></td>
<td>—</td>
<td><img src="https://latex.codecogs.com/png.latex?O(n+m)"></td>
<td><img src="https://latex.codecogs.com/png.latex?O(1)"></td>
</tr>
<tr class="odd">
<td><strong>Deletion: End</strong></td>
<td>—</td>
<td><img src="https://latex.codecogs.com/png.latex?O(1)"></td>
<td><img src="https://latex.codecogs.com/png.latex?O(1)"></td>
</tr>
</tbody>
</table>
</section>
<section id="associative-containers" class="level1">
<h1>Associative containers</h1>
<table class="caption-top table">
<colgroup>
<col style="width: 14%">
<col style="width: 18%">
<col style="width: 21%">
<col style="width: 22%">
<col style="width: 22%">
</colgroup>
<thead>
<tr class="header">
<th>Container</th>
<th><code>std::set</code></th>
<th><code>std::map</code></th>
<th><code>std::unordered_set</code></th>
<th><code>std::unordered_map</code></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><strong>Low-level implementation</strong></td>
<td>Red-Black Tree</td>
<td>Red-Black Tree</td>
<td>Hash-table</td>
<td>Hash-table</td>
</tr>
<tr class="even">
<td><strong>Access: <code>operator[](Key key)</code></strong></td>
<td><img src="https://latex.codecogs.com/png.latex?O(%5Clog%20n)"></td>
<td><img src="https://latex.codecogs.com/png.latex?O(%5Clog%20n)"></td>
<td>Average case - Amortized <img src="https://latex.codecogs.com/png.latex?O(1)"><br>Worst case - <img src="https://latex.codecogs.com/png.latex?O(n)"></td>
<td>Average case - Amortized <img src="https://latex.codecogs.com/png.latex?O(1)"><br>Worst case - <img src="https://latex.codecogs.com/png.latex?O(n)"></td>
</tr>
<tr class="odd">
<td><strong>Insertion</strong></td>
<td><img src="https://latex.codecogs.com/png.latex?O(%5Clog%20n)"></td>
<td><img src="https://latex.codecogs.com/png.latex?O(%5Clog%20n)"></td>
<td>Average case - Amortized <img src="https://latex.codecogs.com/png.latex?O(1)"><br>Worst case - <img src="https://latex.codecogs.com/png.latex?O(n)"></td>
<td>Average case - Amortized <img src="https://latex.codecogs.com/png.latex?O(1)"><br>Worst case - <img src="https://latex.codecogs.com/png.latex?O(n)"></td>
</tr>
<tr class="even">
<td><strong>Deletion</strong></td>
<td><img src="https://latex.codecogs.com/png.latex?O(%5Clog%20n)"><br>(Amortized <img src="https://latex.codecogs.com/png.latex?O(1)"> iterator)</td>
<td><img src="https://latex.codecogs.com/png.latex?O(%5Clog%20n)"> <br>(Amortized <img src="https://latex.codecogs.com/png.latex?O(1)"> with an iterator)</td>
<td>Average case - Amortized <img src="https://latex.codecogs.com/png.latex?O(1)"><br>Worst case - <img src="https://latex.codecogs.com/png.latex?O(n)"></td>
<td>Average case - Amortized <img src="https://latex.codecogs.com/png.latex?O(1)"><br>Worst case - <img src="https://latex.codecogs.com/png.latex?O(n)"></td>
</tr>
</tbody>
</table>


</section>

 ]]></description>
  <category>C++</category>
  <guid>http://quantdev.blog/posts/runtime_complexity_cheatsheet/</guid>
  <pubDate>Thu, 08 Jan 2026 00:00:00 GMT</pubDate>
  <media:content url="http://quantdev.blog/posts/runtime_complexity_cheatsheet/cpp.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>Constructing a 3D Array</title>
  <dc:creator>`dev::author` </dc:creator>
  <link>http://quantdev.blog/posts/constructing_a_3d_array/</link>
  <description><![CDATA[ 





<section id="coding-exercise" class="level1">
<h1>Coding Exercise</h1>
<section id="constructing-a-3d-array" class="level2">
<h2 class="anchored" data-anchor-id="constructing-a-3d-array">Constructing a 3D Array</h2>
<p>Implement a function <code>GetSpace</code> such that that it allocates a 3D array of ints of dimensions <code>x</code>, <code>y</code>, and <code>z</code> on the heap. You can find the original coding exercise <a href="https://getcracked.io/problem/8/3d-space?language=Cpp&amp;topic=LanguageKnowledge">here</a>.</p>
</section>
<section id="requirements" class="level2">
<h2 class="anchored" data-anchor-id="requirements">Requirements</h2>
<ul>
<li><p>Return an <code>int***</code>.</p></li>
<li><p>You cannot use any data structures (such as <code>vector</code>).</p></li>
<li><p>You must initialize all values to std::numeric_limits::min() during allocation without a for-loop. Cracked developers prefer STL algorithms to raw loops.</p></li>
<li><p>Consider edge-cases fully. Return <code>nullptr</code> when encountering invalid inputs.</p></li>
</ul>
</section>
<section id="test-cases" class="level2">
<h2 class="anchored" data-anchor-id="test-cases">Test Cases</h2>
<p>Test case inputs are formatted as <code>x</code>,<code>y</code>,<code>z</code> coordinates. For example, <code>4,5,6</code> is <code>size_t x = 4, y = 5, z = 6;</code>.</p>
<p>For more such puzzles, visit <a href="https://getcracked.io">getcracked.io</a>.</p>
</section>
<section id="my-implementation" class="level2">
<h2 class="anchored" data-anchor-id="my-implementation">My Implementation</h2>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb1-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Problem: https://getcracked.io/problem/8/3d-space?language=Cpp</span></span>
<span id="cb1-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Date: 06-Jan-2025</span></span>
<span id="cb1-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Compiler Explorer: https://compiler-explorer.com/z/d7PzdexEj</span></span>
<span id="cb1-4"></span>
<span id="cb1-5"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;cstdlib&gt;</span></span>
<span id="cb1-6"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;limits&gt;</span></span>
<span id="cb1-7"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;memory&gt;</span></span>
<span id="cb1-8"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;print&gt;</span></span>
<span id="cb1-9"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;iostream&gt;</span></span>
<span id="cb1-10"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;algorithm&gt;</span></span>
<span id="cb1-11"></span>
<span id="cb1-12"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">***</span> GetSpace<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> z<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-13">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">||</span> y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">||</span> z <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-14">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-15"></span>
<span id="cb1-16">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">***</span> A <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_cast</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">***&gt;(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>malloc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">sizeof</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">**)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> z<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb1-17">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>for_each<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>A<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> A <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> z<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[=](</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">**&amp;</span> pp<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb1-18">        pp <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_cast</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">**&gt;(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>malloc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">sizeof</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb1-19">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>for_each<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>pp<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> pp <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[=](</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*&amp;</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb1-20">            p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_cast</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*&gt;(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>malloc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">sizeof</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb1-21">            <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>uninitialized_fill<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> p <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>numeric_limits<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;::</span>min<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb1-22">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">});</span></span>
<span id="cb1-23">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">});</span></span>
<span id="cb1-24"></span>
<span id="cb1-25">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> A<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-26"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-27"></span>
<span id="cb1-28"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb1-29">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">***</span> arr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> GetSpace<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-30">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> arr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">][</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">][</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-31"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/d7PzdexEj">Compiler Explorer</a></p>
</section>
</section>
<section id="references" class="level1">
<h1>References</h1>
<ul>
<li>Coding exercises on <a href="https://getcracked.io">getcracked.io</a></li>
</ul>


</section>

 ]]></description>
  <category>C++</category>
  <guid>http://quantdev.blog/posts/constructing_a_3d_array/</guid>
  <pubDate>Tue, 06 Jan 2026 00:00:00 GMT</pubDate>
  <media:content url="http://quantdev.blog/posts/constructing_a_3d_array/cpp.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>Coding Exercise - Grouping lines together</title>
  <dc:creator>`dev::author` </dc:creator>
  <link>http://quantdev.blog/posts/grouping_lines_together/</link>
  <description><![CDATA[ 





<section id="coding-exercise." class="level1">
<h1>Coding Exercise.</h1>
<section id="group-lines-by-their-slope." class="level2">
<h2 class="anchored" data-anchor-id="group-lines-by-their-slope.">Group lines by their slope.</h2>
<p>You’ve been given several lines. You’re interested in finding how many lines share the same slope. You’re tasked with writing a method that does exactly that. — For example, if you have two lines with a slope of <code>2.0</code>, and one line with a slope of <code>1.0</code>, the result is <code>{ { 2.0 Slope Line, 2 }, { 1.0 Slope Line, 1 } }</code>. The coding exercise is <a href="https://getcracked.io/problem/20/we-re-stronger-together?language=Cpp&amp;topic=LanguageKnowledge">here</a>.</p>
</section>
<section id="requirements" class="level2">
<h2 class="anchored" data-anchor-id="requirements">Requirements</h2>
<p>Compute how many lines share the same slope, grouped by Line.</p>
<p>A line will never be made up of two points that share the same x coordinate. Test Cases</p>
<p>Your code will be run through a series of test cases. Consider edge-cases, such as an empty list of inputs.</p>
</section>
<section id="use-cases" class="level2">
<h2 class="anchored" data-anchor-id="use-cases">Use Cases</h2>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb1-1">Line line<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-2">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-3">      <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb1-4">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb1-5">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-6">      <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span></span>
<span id="cb1-7">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb1-8"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb1-9">Line line2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-10">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-11">      <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb1-12">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb1-13">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-14">      <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span></span>
<span id="cb1-15">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb1-16"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb1-17"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> groups <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> GroupPoints<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">({</span> line<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> line2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">});</span></span></code></pre></div></div>
</section>
<section id="my-implementation" class="level2">
<h2 class="anchored" data-anchor-id="my-implementation">My Implementation</h2>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb2-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;vector&gt;</span></span>
<span id="cb2-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;unordered_map&gt;</span></span>
<span id="cb2-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;algorithm&gt;</span></span>
<span id="cb2-4"></span>
<span id="cb2-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Point <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-6">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> X<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{};</span></span>
<span id="cb2-7">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> Y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{};</span></span>
<span id="cb2-8"></span>
<span id="cb2-9">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">bool</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> Point<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-10">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> Y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>     </span>
<span id="cb2-11">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span>     </span>
<span id="cb2-12"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb2-13"></span>
<span id="cb2-14"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Line <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-15">    Point A<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-16">    Point B<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-17">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span> GetSlope<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-18">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>A<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> B<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_cast</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>A<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> B<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>X<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb2-19">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-20"></span>
<span id="cb2-21">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">bool</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> Line<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-22">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> GetSlope<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>GetSlope<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span>    </span>
<span id="cb2-23">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-24"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb2-25"></span>
<span id="cb2-26"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> std<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-27">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&gt;</span></span>
<span id="cb2-28">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> hash<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Point<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;{</span></span>
<span id="cb2-29">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> Point<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> point<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-30">            <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t h1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> hash<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;{}(</span>point<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>X<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb2-31">            <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t h2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> hash<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;{}(</span>point<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb2-32">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>h1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">^</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>h2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb2-33">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-34">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb2-35"></span>
<span id="cb2-36">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&gt;</span></span>
<span id="cb2-37">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> hash<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Line<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;{</span></span>
<span id="cb2-38">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> Line<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> line<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-39">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>hash<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;{}(</span>line<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>GetSlope<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb2-40">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-41">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb2-42"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-43"></span>
<span id="cb2-44"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> Lines <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Line<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;;</span></span>
<span id="cb2-45"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> Slope <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-46"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> Bucket <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>pair<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Slope<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Line<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;;</span></span>
<span id="cb2-47"></span>
<span id="cb2-48"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-49">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> ForwardIterator<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb2-50">    ForwardIterator first_equal_to_or_less_than<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>ForwardIterator first<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> ForwardIterator last<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> T key<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb2-51">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> it <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>upper_bound<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>first<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> last<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> key<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb2-52">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> it <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> first <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">?</span> last <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">--</span>it<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-53">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-54"> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-55"></span>
<span id="cb2-56"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unordered_map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Line<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> GroupPoints<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> Lines<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> lines<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-57"></span>
<span id="cb2-58">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unordered_map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Line<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> groups<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-59">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unordered_map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Slope<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> slope_count<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-60">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>lines<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>empty<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">())</span></span>
<span id="cb2-61">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> groups<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-62"></span>
<span id="cb2-63">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>for_each<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>lines<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> lines<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[&amp;](</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> Line<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> line<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mutable</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-64">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span>groups<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>line<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">];</span></span>
<span id="cb2-65">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">});</span></span>
<span id="cb2-66"></span>
<span id="cb2-67">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> groups<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>     </span>
<span id="cb2-68"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-69"></span>
<span id="cb2-70"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb2-71"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-72">    Line line1</span>
<span id="cb2-73">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-74">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-75">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-76">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb2-77">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-78">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span></span>
<span id="cb2-79">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb2-80">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb2-81">    Line line2</span>
<span id="cb2-82">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-83">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-84">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-85">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb2-86">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-87">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>X <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span></span>
<span id="cb2-88">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb2-89">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb2-90">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> groups <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> GroupPoints<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">({</span>line1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> line2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">});</span></span>
<span id="cb2-91">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> group <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> groups<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb2-92">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>line<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> num_of_lines<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> group<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-93">        Point A <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> line<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>A<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-94">        Point B <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> line<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>B<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-95">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Line (</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">,</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">)--(</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">,</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">)"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> A<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>X<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> A<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> B<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>X<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> B<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb2-96">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Freq = </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> num_of_lines<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb2-97">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-98">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-99"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/3fPPY691E">Compiler Explorer</a></p>
</section>
</section>
<section id="references" class="level1">
<h1>References</h1>
<ul>
<li>Coding exercises on <a href="https://getcracked.io">getcracked.io</a></li>
</ul>


</section>

 ]]></description>
  <category>C++</category>
  <guid>http://quantdev.blog/posts/grouping_lines_together/</guid>
  <pubDate>Tue, 06 Jan 2026 00:00:00 GMT</pubDate>
  <media:content url="http://quantdev.blog/posts/grouping_lines_together/cpp.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>const, constexpr, consteval and constinit</title>
  <dc:creator>`dev::author` </dc:creator>
  <link>http://quantdev.blog/posts/const_vs_constexpr_consteval_vs_constinit/</link>
  <description><![CDATA[ 





<section id="const-ness" class="level1">
<h1><code>const</code>-ness</h1>
<p>Constants, by their simplest definition are values that do not change. <code>const</code> correctness is the practice of using the <code>const</code> keyword to prevent <code>const</code> objects from getting mutated.</p>
<blockquote class="blockquote">
<h3 id="just-make-everything-const-that-you-can" class="anchored">Just make everything <code>const</code> that you can!</h3>
</blockquote>
<p>We should add <code>const</code> early and often. Back-patching <code>const</code> correctness results in a snowball effect: every <code>const</code> over here requires four more to be added over there.</p>
<section id="const-member-functions" class="level2">
<h2 class="anchored" data-anchor-id="const-member-functions"><code>const</code> member functions</h2>
<p>You can declare a non-static member function <code>const</code> if it doesn’t change the value of the underlying object.</p>
</section>
</section>
<section id="constexpr" class="level1">
<h1><code>constexpr</code></h1>
<section id="constexpr-variables" class="level2">
<h2 class="anchored" data-anchor-id="constexpr-variables"><code>constexpr</code> variables</h2>
<p>Let’s review the definition of a literal type. According to the <a href="https://eel.is/c++draft/basic.types.general#10">standard</a>:</p>
<blockquote class="blockquote">
<p>A literal type is one whose layout can be determined at compile time. The following are the literal types:</p>
<ul>
<li><code>void</code></li>
<li>Scalar types</li>
<li>References</li>
<li>Arrays of void, scalar types or references</li>
<li>A class that has a <code>constexpr</code> destructor, and one or more constexpr constructors that are not move or copy constructors. Additionally, all its non-static data members and base classes must be literal types and not volatile.</li>
</ul>
</blockquote>
<p>A <code>const</code> variable is immutable. The initialization of a <code>const</code> variable may be deferred to run-time. A <code>constexpr</code> variable must be initialized with a value that is known at compile-time. All <code>constexpr</code> variables are <code>const</code>, but the converse is not true.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb1-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float</span> c <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.0e8</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float</span> G <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">6.67430e-11</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
</section>
<section id="constexpr-functions" class="level2">
<h2 class="anchored" data-anchor-id="constexpr-functions"><code>constexpr</code> functions</h2>
<p>A <code>constexpr</code> function <code>foo()</code> is one that may be evaluated at compile-time or run-time. If a function marked <code>constexpr</code> is called in a constant expression context, only then, the function is evaluted at compile-time. We have roughly four options for doing so:</p>
<ul>
<li>Assign the result of <code>foo</code> to a <code>constexpr</code> variable.</li>
<li>Use <code>foo</code> as a non-type template argument.</li>
<li>Use <code>foo</code> as the size of the array.</li>
<li>Call <code>foo</code> in another <code>constexpr</code> function that is evaluated in a constant evaluation.</li>
</ul>
<p>Here are the four cases in code:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb2-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t double_up<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t n<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb2-2">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> n<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-3"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-4"></span>
<span id="cb2-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t n<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb2-6">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> double_up<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>n<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb2-7"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-8"></span>
<span id="cb2-9"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t result <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> double_up<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb2-10"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> double_up<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)&gt;</span> a<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb2-11"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span> buffer<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>double_up<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)];</span></span>
<span id="cb2-12"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> value<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)};</span></span></code></pre></div></div>
</section>
</section>
<section id="if-constexpr" class="level1">
<h1><code>if constexpr</code></h1>
<p><code>if constexpr</code> is a <code>constexpr</code> if statement where the predicate is evaluated is compile-time. It can be used to modify the behavior of the enclosing function. So, the resulting binary will include one branch and not the other. Generally, you wouldn’t use this outside of a template function.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb3-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;cmath&gt;</span></span>
<span id="cb3-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;optional&gt;</span></span>
<span id="cb3-3"></span>
<span id="cb3-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb3-5"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">bool</span> isEqual<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>T a<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> T b<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>optional<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> epsilon <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1e-7</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb3-6">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>is_same_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">||</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>is_same_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;){</span></span>
<span id="cb3-7">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>abs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>a <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> b<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> epsilon<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-8">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-9">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> a <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> b<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-10">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-11"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://godbolt.org/z/r5vs64W8K">Compiler Explorer</a></p>
</section>
<section id="consteval-functions" class="level1">
<h1><code>consteval</code> functions</h1>
<p>A function marked <code>consteval</code> is called an <em>immediate function</em>. Immediate here means that the funtion is evaluated at the compiler front-end, yielding only a value that the compiler back-end uses. Such a function never goes into your binary. A <code>consteval</code>-function must be evaluated at compile-time or compilation fails.</p>
<p>A call to a <code>consteval</code> function must be a constant-expression.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb4-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">consteval</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> sqr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> n<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb4-2">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> n <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> n<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-3"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb4-4"></span>
<span id="cb4-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> r <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> sqr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Okay</span></span>
<span id="cb4-6"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// int r2 = sqr(x); //Error: Not a constant expression</span></span></code></pre></div></div>
<p>There is one exception to the rule that a call to a <code>consteval</code> function must be a constant-expression: if the call appears in another <code>consteval</code> function, it need not be a constant-expression (since the call to the enclosing function would ultimately have to produce a core constant expression).</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb5-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">consteval</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> sqrsqr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> n<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb5-2">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> sqr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>sqr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>n<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Not a constant-expression at this  point,</span></span>
<span id="cb5-3"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span>                     <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// but that's okay.</span></span>
<span id="cb5-4"></span>
<span id="cb5-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//constexpr int dblsqr(int n) {</span></span>
<span id="cb5-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//  return 2*sqr(n); // Error: Enclosing function is not</span></span>
<span id="cb5-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//}    </span></span></code></pre></div></div>
</section>
<section id="stdis_constant_evaluated" class="level1">
<h1><code>std::is_constant_evaluated()</code></h1>
<p><code>std::is_constant_evaluated()</code> is a magic library function to check if the current evaluation context is constant evaluation.</p>
<p>Despite the fact that support for both <code>consteval</code> functions and <code>std::is_constant_evaluation</code> were introduced in C++20, these features interact poorly.</p>
</section>
<section id="if-consteval" class="level1">
<h1><code>if consteval</code></h1>
<section id="interaction-between-constexpr-and-consteval" class="level2">
<h2 class="anchored" data-anchor-id="interaction-between-constexpr-and-consteval">Interaction between <code>constexpr</code> and <code>consteval</code></h2>
<p>Consider the interplay between the magic library function <code>std::is_constant_evaluated()</code> and the new <code>consteval</code>. Consider the following example:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb6-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">consteval</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-2"></span>
<span id="cb6-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// The constexpr function g() does not compile</span></span>
<span id="cb6-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// constexpr int g(int i) {</span></span>
<span id="cb6-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//     if (std::is_constant_evaluated()) {</span></span>
<span id="cb6-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//         return f(i) + 1; // &lt;==</span></span>
<span id="cb6-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//     } else {</span></span>
<span id="cb6-8"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//         return 42;</span></span>
<span id="cb6-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//     }</span></span>
<span id="cb6-10"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// }</span></span>
<span id="cb6-11"></span>
<span id="cb6-12"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">consteval</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> h<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-13">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb6-14"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://godbolt.org/z/K5TPG9nf9">Compiler Explorer</a></p>
<p>The function <code>h</code> here is basically a lifted, constant-evaluation-only version of the function <code>g</code>. At constant evaluation time, they do the same thing, except that during runtime, you cannot call <code>h</code>, and <code>g</code> has this extra path. Maybe this code started with just <code>h</code> and someone decided a runtime version would also be useful and turned it into <code>g</code>.</p>
<p>Unfortunately, <code>h</code> is well-formed, while <code>g</code> is ill-formed. The call to <code>f()</code> inside <code>g()</code> is an <em>immediate invocation</em>. You cannot make a call to <code>f</code> from inside of <code>g</code> (the location marked with an arrow). During the static analysis phase, the compiler front-end requires that the call to <code>f()</code> inside <code>g()</code>, an immediate invocation, must be a constant expression and it is not.</p>
</section>
<section id="the-if-constexprstdis_constant_evaluated-problem" class="level2">
<h2 class="anchored" data-anchor-id="the-if-constexprstdis_constant_evaluated-problem">The <code>if constexpr(std::is_constant_evaluated())</code> problem</h2>
<p>What happens, if we modify the simple <code>if</code> statement to <code>if constexpr</code>? Consider the below code: Because the predicate of <code>if constexpr</code> is evaluated at compile-time, <code>if constexpr(std::is_constant_evaluated())</code> is trivially true and is buggy code.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb7-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> foo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-2">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>is_constant_evaluated<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">())</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-3">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/* ... */</span></span>
<span id="cb7-4">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-5">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-6">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb7-7"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
</section>
<section id="the-if-consteval-statment" class="level2">
<h2 class="anchored" data-anchor-id="the-if-consteval-statment">The <code>if consteval</code> statment</h2>
<p>The <code>if consteval</code> is exactly the same as</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb8-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>is_constant_evaluated<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">())</span></span></code></pre></div></div>
<p>with one key difference: we can use <code>if consteval</code> to invoke immediate functions. According to the standard:</p>
<blockquote class="blockquote">
<p>An expression or conversion is in an immediate function context if it is potentially evaluated and its innermost non-block scope is a function parameter scope of an immediate function. An expression or conversion is an immediate invocation if it is an explicit or implicit invocation of an immediate function and is not in an immediate function context. An immediate invocation shall be a constant expression.</p>
</blockquote>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb9-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">consteval</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb9-2"></span>
<span id="cb9-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> g<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb9-4">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">consteval</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb9-5">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ok: immediate function context</span></span>
<span id="cb9-6">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb9-7">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb9-8">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb9-9"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb9-10"></span>
<span id="cb9-11"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">consteval</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> h<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb9-12">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ok: immediate function context</span></span>
<span id="cb9-13"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://godbolt.org/z/Gdroev6ox">Compiler Explorer</a></p>
</section>
<section id="challenge-puzzle" class="level2">
<h2 class="anchored" data-anchor-id="challenge-puzzle">Challenge puzzle</h2>
<p>Which line should we remove to make this program compile successfully?</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb10-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> second<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb10-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>c <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb10-3"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb10-4"></span>
<span id="cb10-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> first<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> b<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb10-6">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> result <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> second<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>b<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb10-7">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> result<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb10-8"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb10-9"></span>
<span id="cb10-10"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb10-11">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> a <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> first<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb10-12">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> a<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb10-13"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<ul>
<li><ol type="a">
<li><code>std::cout &lt;&lt; x;</code></li>
</ol></li>
<li><ol start="2" type="a">
<li><code>static_assert(c &gt; 0);</code></li>
</ol></li>
<li><ol start="3" type="a">
<li><code>constexpr int n = first(4);</code></li>
</ol></li>
<li><ol start="4" type="a">
<li><code>int result = second(b);</code></li>
</ol></li>
</ul>
<p>For more such puzzles, visit <a href="https://getcracked.io">getcracked.io</a></p>
</section>
</section>
<section id="constinit-keyword" class="level1">
<h1><code>constinit</code> keyword</h1>
<p><code>constinit</code> keyword can be used to force and ensure that a mutable <code>static</code> or global variable is initialized at compile-time. So, roughly speaking the effect is described as :</p>
<pre><code>constinit = constexpr - const</code></pre>
<p>A <code>constinit</code> variable is <strong><em>not <code>const</code></em></strong>. The keyword would be better named <code>compileinit</code> or something.</p>
<p>You can use <code>constinit</code> whenever you declare a static or a global variable. For example,</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb12-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constinit</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb12-2"></span>
<span id="cb12-3"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> incrementCounter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb12-4">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">static</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constinit</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> counter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb12-5">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span>counter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb12-6"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb12-7"></span>
<span id="cb12-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>array<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> getCollection<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb12-9">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb12-10"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb12-11"></span>
<span id="cb12-12"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constinit</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> globalCollection <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> getCollection<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span></code></pre></div></div>
<p>You can still modify the declared values. The effect of using <code>constinit</code> is that the initialization only compiles if the initial value is known at compile-time.</p>
<p>There are a couple of things to repect when using <code>constinit</code> in practice.</p>
<p>First, you cannot initialize a <code>constinit</code> value with another <code>constinit</code> value:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb13-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constinit</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//f() must be constexpr</span></span>
<span id="cb13-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constinit</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Error: x is not a constant initializer</span></span></code></pre></div></div>
<p>The reason is that the initial value must be a constant value known at compile time, but <code>constinit</code> values are not constant. So, <code>x</code> is open for modification at run-time, prior to assigning it to <code>y</code>. The next code snip compiles fine:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb14-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//f() must be a compile-time function</span></span>
<span id="cb14-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constinit</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ok</span></span></code></pre></div></div>
<p>When initializing objects, a compile-time constructor is required. However, a compile-time destructor is not required.</p>
<p><code>constinit</code> does not imply inline (this is different from <code>constexpr</code>).</p>
<section id="how-constinit-solves-the-static-initialization-order-fiasco" class="level2">
<h2 class="anchored" data-anchor-id="how-constinit-solves-the-static-initialization-order-fiasco">How <code>constinit</code> solves the static initialization order fiasco?</h2>
<p>In C++, there is a problem called the <em>static initialization order fiasco</em>, which <code>constinit</code> can solve. The problem is that the order of static and global initializations in different translation units is not defined.</p>
<p>Assume that we have a type with a constructor to initialize the objects and introduce an extern global object of this type:</p>
</section>
</section>
<section id="references" class="level1">
<h1>References</h1>
<ul>
<li><em><a href="https://isocpp.org/wiki/faq/const-correctness#const-ref-alt"><code>const</code> correctness</a>, C++ core guidelines</em>.</li>
<li><em>C++ 20 - The complete guide, by Nikolai Josuttis</em>.</li>
</ul>


</section>

 ]]></description>
  <category>C++</category>
  <guid>http://quantdev.blog/posts/const_vs_constexpr_consteval_vs_constinit/</guid>
  <pubDate>Mon, 29 Dec 2025 00:00:00 GMT</pubDate>
  <media:content url="http://quantdev.blog/posts/const_vs_constexpr_consteval_vs_constinit/cpp.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>Hash Tables</title>
  <dc:creator>`dev::author` </dc:creator>
  <link>http://quantdev.blog/posts/hash_tables/</link>
  <description><![CDATA[ 





<section id="introduction" class="level1">
<h1>Introduction</h1>
<p><code>std::unordered_map</code> is C++’s hash table container, providing amortized <img src="https://latex.codecogs.com/png.latex?O(1)"> constant-time search, insertion and deletion operations with unique keys on average. In this blog post, I explore the basic API of <code>unordered_map</code>.</p>
</section>
<section id="construction" class="level1">
<h1>Construction</h1>
<p><code>std::unordered_map</code> is a class template in the header <code>&lt;unordered_map&gt;</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb1-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Key<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Value<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> HashFunc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> KeyEqual<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Alloc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb1-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> unordered_map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
<p>It allows you specify a custom hash function <code>hash</code>, <code>equal</code> function to compare keys and <code>alloc</code> as a custom allocator.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb2-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;unordered_map&gt;</span></span>
<span id="cb2-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;print&gt;</span></span>
<span id="cb2-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;cstddef&gt;</span></span>
<span id="cb2-4"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;vector&gt;</span></span>
<span id="cb2-5"></span>
<span id="cb2-6"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb2-7">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Default construction</span></span>
<span id="cb2-8">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unordered_map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint32_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> word_count<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-9"></span>
<span id="cb2-10">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Initializer list construction</span></span>
<span id="cb2-11">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unordered_map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;</span> symbol_to_price_levels_map </span>
<span id="cb2-12">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-13">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"AAPL"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">100.0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">101.0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">102.0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}},</span></span>
<span id="cb2-14">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"GOOG"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1500.0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1505.0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1510.0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}}</span></span>
<span id="cb2-15">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb2-16"></span>
<span id="cb2-17">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// with bucket count hint</span></span>
<span id="cb2-18">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// atleast 100 buckets</span></span>
<span id="cb2-19">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unordered_map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint32_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb2-20"></span>
<span id="cb2-21">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Range construction (accepts a pair of iterators)</span></span>
<span id="cb2-22">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unordered_map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;</span> word_count_copy<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb2-23">        word_count<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> word_count<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb2-24">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb2-25"></span>
<span id="cb2-26">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// copy construction</span></span>
<span id="cb2-27">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unordered_map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> cache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-28">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Fedor Pikus"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Performance GOAT"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb2-29">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Herb Sutter"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"C++ Visionary"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb2-30">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"John Carmack"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Legendary programmer"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-31">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb2-32"></span>
<span id="cb2-33">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unordered_map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> cache_copy<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>cache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb2-34"></span>
<span id="cb2-35">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// move construction</span></span>
<span id="cb2-36">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unordered_map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint32_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> word_count2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>move<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>word_count<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)};</span></span>
<span id="cb2-37"></span>
<span id="cb2-38">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// with a custom hash function</span></span>
<span id="cb2-39">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Knuth's multiplicative hash</span></span>
<span id="cb2-40">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> CustomHash<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-41">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> key<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-42">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> key <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2654435761</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-43">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-44">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb2-45"></span>
<span id="cb2-46">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unordered_map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint32_t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> CustomHash<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> map_with_custom_hash<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-47"></span>
<span id="cb2-48">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// with a custom hash and custom equality</span></span>
<span id="cb2-49">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Point<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-50">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-51">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span> y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-52"></span>
<span id="cb2-53">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">bool</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> Point<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-54">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> other<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-55">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-56">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb2-57"></span>
<span id="cb2-58">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> point_equal <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> Point<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> a<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> Point<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>b<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">bool</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-59">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> a<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> b<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> a<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> b<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-60">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb2-61"></span>
<span id="cb2-62">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> point_hash <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span> y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb2-63">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t h1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>hash<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;{}(</span>x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb2-64">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t h2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>hash<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;{}(</span>y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb2-65">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> h1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">^</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>h2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb2-66">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb2-67"></span>
<span id="cb2-68">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unordered_map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Point<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> </span>
<span id="cb2-69">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">decltype</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>point_hash<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">decltype</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>point_equal<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)&gt;</span> points_map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-70"></span>
<span id="cb2-71">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// from a vector of pairs</span></span>
<span id="cb2-72">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb2-73"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/Ys83asq47">Compiler Explorer</a></p>
</section>
<section id="insertion" class="level1">
<h1>Insertion</h1>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb3-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;unordered_map&gt;</span></span>
<span id="cb3-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;print&gt;</span></span>
<span id="cb3-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;cstddef&gt;</span></span>
<span id="cb3-4"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;vector&gt;</span></span>
<span id="cb3-5"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;utility&gt;</span></span>
<span id="cb3-6"></span>
<span id="cb3-7"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb3-8">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unordered_map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-9"></span>
<span id="cb3-10">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// array index operator</span></span>
<span id="cb3-11">    map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Carl Gauss"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-12">    map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Augustin Louis Cauchy"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-13"></span>
<span id="cb3-14">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// insert(pair(k,v))</span></span>
<span id="cb3-15">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// returns pair&lt;iterator,bool&gt;. bool is true</span></span>
<span id="cb3-16">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// if the insert succeeds, else false</span></span>
<span id="cb3-17">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>it1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> success1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>insert<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>make_pair<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Joseph Fourier"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb3-18">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>it2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> success2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>insert<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>make_pair<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Josepph Lagrange"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb3-19">    </span>
<span id="cb3-20">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// void insert(initializer_list)</span></span>
<span id="cb3-21">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// insert from an initializer list</span></span>
<span id="cb3-22">    map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>insert<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb3-23">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-24">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Riemann"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb3-25">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Ada Lovelace"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-26">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">});</span></span>
<span id="cb3-27">    </span>
<span id="cb3-28">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// emplace(Args&amp;&amp; ...)</span></span>
<span id="cb3-29">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// inserts a new element into the container constructed</span></span>
<span id="cb3-30">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// in-place with the given args, if there is no element</span></span>
<span id="cb3-31">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// with the key in the container</span></span>
<span id="cb3-32">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>it3<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> success3<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>emplace<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Leonard Euler"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-33"></span>
<span id="cb3-34">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// The new element may be constructed even if there already</span></span>
<span id="cb3-35">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// is an element with the key in the container, in which case</span></span>
<span id="cb3-36">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// the newly constructed element will be destroyed immediately</span></span>
<span id="cb3-37">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> k <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb3-38">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"David Hilbert"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb3-39">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"emplace(</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">, </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">) called"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> k<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-40"></span>
<span id="cb3-41">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>it4<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> success4<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>emplace<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>k<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-42">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"success flag : </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> success4<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-43"></span>
<span id="cb3-44">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// try_emplace(Key&amp;&amp;, Args&amp;&amp;)</span></span>
<span id="cb3-45">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// if the key k already exists in the container, do nothing</span></span>
<span id="cb3-46">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Otherwise, insert a new element into the container</span></span>
<span id="cb3-47">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// with key k and value constructed with args</span></span>
<span id="cb3-48">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>it5<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> success5<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>try_emplace<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"David Hilbert"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-49"></span>
<span id="cb3-50">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// range insert - takes a pair of iterators</span></span>
<span id="cb3-51">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>pair<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;</span> vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-52">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Andrew Kolmogorov"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb3-53">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Emile Borel"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-54">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb3-55"></span>
<span id="cb3-56">    map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>insert<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> vec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb3-57"></span>
<span id="cb3-58">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// insert_range(R&amp;&amp; rg)</span></span>
<span id="cb3-59">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Inserts a copyn of each element in the range rg </span></span>
<span id="cb3-60">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// if and only if each of the keys are not </span></span>
<span id="cb3-61">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// already present in the map</span></span>
<span id="cb3-62">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> rg <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>pair<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Guido Cantelli"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Terrence Tao"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}};</span></span>
<span id="cb3-63">    map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>insert_range<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>rg<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-64"></span>
<span id="cb3-65">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// insert_or_assign(key, obj)</span></span>
<span id="cb3-66">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// If a key k already exists in the container, assigns</span></span>
<span id="cb3-67">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// obj to the key k. If the key k does not exist, </span></span>
<span id="cb3-68">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// it inserts the new value as if by insert.</span></span>
<span id="cb3-69">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>it6<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> success6<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>insert_or_assign<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"William Feller"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-70">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>it7<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> success7<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>insert_or_assign<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">13</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Andrew Wiles"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-71">    </span>
<span id="cb3-72">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-73"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/bhW3rz653">Compiler Explorer</a></p>
</section>
<section id="search" class="level1">
<h1>Search</h1>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb4-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;unordered_map&gt;</span></span>
<span id="cb4-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;print&gt;</span></span>
<span id="cb4-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;cstddef&gt;</span></span>
<span id="cb4-4"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;vector&gt;</span></span>
<span id="cb4-5"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;utility&gt;</span></span>
<span id="cb4-6"></span>
<span id="cb4-7"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> PhoneRecord<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb4-8">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string full_name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-9">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string address<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-10">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string phone<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-11">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string pin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-12"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb4-13"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb4-14">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unordered_map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> PhoneRecord<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> phone_book<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-15">    phone_book<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>insert<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">({</span></span>
<span id="cb4-16">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"John Smith"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"John Smith"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"123 Main Street, New York, NY 10001"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(212) 555-1234"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"1234"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}},</span></span>
<span id="cb4-17">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Mary Johnson"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Mary Johnson"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"456 Oak Avenue, Los Angeles, CA 90001"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(213) 555-2345"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"2345"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}},</span></span>
<span id="cb4-18">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Robert Williams"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Robert Williams"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"789 Pine Road, Chicago, IL 60601"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(312) 555-3456"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"3456"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}},</span></span>
<span id="cb4-19">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Patricia Brown"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Patricia Brown"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"321 Maple Drive, Houston, TX 77001"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(713) 555-4567"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"4567"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}},</span></span>
<span id="cb4-20">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Michael Jones"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Michael Jones"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"654 Cedar Lane, Phoenix, AZ 85001"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(602) 555-5678"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"5678"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}},</span></span>
<span id="cb4-21">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Linda Garcia"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Linda Garcia"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"987 Elm Court, Philadelphia, PA 19101"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(215) 555-6789"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"6789"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}},</span></span>
<span id="cb4-22">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"David Miller"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"David Miller"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"147 Birch Place, San Antonio, TX 78201"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(210) 555-7890"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"7890"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}},</span></span>
<span id="cb4-23">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Barbara Davis"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Barbara Davis"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"258 Walnut Boulevard, San Diego, CA 92101"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(619) 555-8901"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"8901"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}},</span></span>
<span id="cb4-24">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Richard Rodriguez"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Richard Rodriguez"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"369 Cherry Way, Dallas, TX 75201"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(214) 555-9012"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"9012"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}},</span></span>
<span id="cb4-25">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Susan Martinez"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Susan Martinez"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"741 Hickory Circle, San Jose, CA 95101"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(408) 555-0123"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"0123"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}},</span></span>
<span id="cb4-26">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Joseph Hernandez"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Joseph Hernandez"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"852 Willow Terrace, Austin, TX 78701"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(512) 555-1235"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"1235"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}},</span></span>
<span id="cb4-27">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Jessica Lopez"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Jessica Lopez"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"963 Poplar Parkway, Jacksonville, FL 32099"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(904) 555-2346"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"2346"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}},</span></span>
<span id="cb4-28">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Thomas Gonzalez"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Thomas Gonzalez"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"159 Sycamore Trail, Fort Worth, TX 76101"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(817) 555-3457"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"3457"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}},</span></span>
<span id="cb4-29">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Sarah Wilson"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Sarah Wilson"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"357 Ash Street, Columbus, OH 43085"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(614) 555-4568"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"4568"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}},</span></span>
<span id="cb4-30">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Charles Anderson"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Charles Anderson"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"486 Magnolia Avenue, Charlotte, NC 28201"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(704) 555-5679"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"5679"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}},</span></span>
<span id="cb4-31">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Karen Thomas"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Karen Thomas"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"753 Dogwood Road, San Francisco, CA 94101"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(415) 555-6780"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"6780"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}},</span></span>
<span id="cb4-32">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Christopher Taylor"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Christopher Taylor"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"951 Redwood Drive, Indianapolis, IN 46201"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(317) 555-7891"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"7891"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}},</span></span>
<span id="cb4-33">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Nancy Moore"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Nancy Moore"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"246 Sequoia Lane, Seattle, WA 98101"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(206) 555-8902"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"8902"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}},</span></span>
<span id="cb4-34">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Daniel Jackson"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Daniel Jackson"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"135 Fir Court, Denver, CO 80201"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(303) 555-9013"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"9013"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}},</span>        </span>
<span id="cb4-35">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">});</span></span>
<span id="cb4-36"></span>
<span id="cb4-37">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// iter = find(const Key&amp; key);</span></span>
<span id="cb4-38">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> it <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> phone_book<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>find<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Robert Williams"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb4-39">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>it <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> phone_book<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()){</span></span>
<span id="cb4-40">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> record<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>it<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-41">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Key = </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb4-42">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Full name = </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> record<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>full_name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb4-43">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Address = </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> record<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>address<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb4-44">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Phone = </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> record<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>phone<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb4-45">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb4-46"></span>
<span id="cb4-47">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// contains(), at()</span></span>
<span id="cb4-48">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string key <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Robert Williams"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb4-49">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>phone_book<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>contains<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>key<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))</span></span>
<span id="cb4-50">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb4-51">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Key exists: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> key<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb4-52">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> record <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> phone_book<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>at<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>key<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb4-53">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb4-54"></span>
<span id="cb4-55">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Array index operator</span></span>
<span id="cb4-56">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// operator[]() returns a reference to the value that</span></span>
<span id="cb4-57">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// is mapped to the key k, performing an insertion if</span></span>
<span id="cb4-58">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// such a key does not exist.</span></span>
<span id="cb4-59">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unordered_map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> letter_counts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{{</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'a'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">27</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'b'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'c'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}};</span></span>
<span id="cb4-60">    println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"letter_counts initially contains: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> letter_counts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb4-61">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> result1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> letter_counts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'a'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">];</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ok</span></span>
<span id="cb4-62">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> result2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> letter_counts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'d'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">];</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// just inserts the pair ('d', 0)</span></span>
<span id="cb4-63">    println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"letter_counts now contains: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> letter_counts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb4-64"></span>
<span id="cb4-65">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// at(Key&amp; key)</span></span>
<span id="cb4-66">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Returns a reference to the mapped value of the element</span></span>
<span id="cb4-67">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// with specified key. If no such element exists, an</span></span>
<span id="cb4-68">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// exception of the type std::out_of_range is thrown.</span></span>
<span id="cb4-69">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> result3 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> letter_counts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>at<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'a'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>   </span>
<span id="cb4-70">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">try</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb4-71">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> result4 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> letter_counts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>at<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'e'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb4-72">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">catch</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>out_of_range<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> ex<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb4-73">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Out of range exception occured!"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb4-74">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb4-75">    </span>
<span id="cb4-76">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-77"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/9E4d78n4E">Compiler Explorer</a></p>
</section>
<section id="deletion" class="level1">
<h1>Deletion</h1>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb5-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;unordered_map&gt;</span></span>
<span id="cb5-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;print&gt;</span></span>
<span id="cb5-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;cstddef&gt;</span></span>
<span id="cb5-4"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;vector&gt;</span></span>
<span id="cb5-5"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;utility&gt;</span></span>
<span id="cb5-6"></span>
<span id="cb5-7"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> PhoneRecord<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb5-8">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string full_name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-9">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string address<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-10">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string phone<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-11">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string pin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-12"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb5-13"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb5-14">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unordered_map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb5-15">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"one"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"two"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"three"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb5-16">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"four"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"five"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"six"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb5-17">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb5-18"></span>
<span id="cb5-19">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// erase(pos) by iterator</span></span>
<span id="cb5-20">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// It removes the specified element from the container</span></span>
<span id="cb5-21">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// and returns an iterator following the last modified</span></span>
<span id="cb5-22">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// element.</span></span>
<span id="cb5-23"></span>
<span id="cb5-24">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// The order of the remaining elements is preserved.</span></span>
<span id="cb5-25">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// This makes it possible to erase individual elements</span></span>
<span id="cb5-26">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// while iterating the container.</span></span>
<span id="cb5-27"></span>
<span id="cb5-28">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// pos is an iterator to the element to be removed.</span></span>
<span id="cb5-29">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Any references and iterators to erased elements </span></span>
<span id="cb5-30">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// are invalidated. </span></span>
<span id="cb5-31">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> it<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()};</span> it<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span>map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();){</span></span>
<span id="cb5-32">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>it<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>first <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb5-33">            it <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>erase<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>it<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb5-34">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span></span>
<span id="cb5-35">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span>it<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-36">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb5-37"></span>
<span id="cb5-38">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// erase(key) by key</span></span>
<span id="cb5-39">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// It removes the element (if one exists) with the key.</span></span>
<span id="cb5-40">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// It returns the number of elements removed (0 or 1).</span></span>
<span id="cb5-41">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t num_elements_removed <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>erase<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb5-42"></span>
<span id="cb5-43">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// clear</span></span>
<span id="cb5-44">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// clear() removes all elements</span></span>
<span id="cb5-45">    map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>clear<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb5-46"></span>
<span id="cb5-47">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// node_type extract(pos)</span></span>
<span id="cb5-48">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// unlinks the node that contains the element pointed to </span></span>
<span id="cb5-49">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// by pos and returns a node handle that owns it.</span></span>
<span id="cb5-50">    </span>
<span id="cb5-51">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// node_type extract(key)</span></span>
<span id="cb5-52">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// unlinks the node corresponding to key and returns</span></span>
<span id="cb5-53">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// a node_handle to it, else returns an empty node_handle</span></span>
<span id="cb5-54">    </span>
<span id="cb5-55"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/6TdzxM7Px">Compiler Explorer</a></p>
</section>
<section id="how-to-choose-a-good-hash-function" class="level1">
<h1>How to choose a good hash function?</h1>
<ul>
<li>Input data often has patterns and is <em>not random</em>. So, good hash functions should generate hash values that are uniformly distributed.</li>
<li>Avalanche effect. A small change in the input (e.g.&nbsp;flipping a single bit) should change the output hash-value significantly.</li>
<li>Hash functions should be fast. Cryptographic hash functions like SHA-1, SHA-256, SHA-512, MD-5 are extremely secure, and we use them everyday for encryption, checksumming etc. but they are slow to compute. They are designed such that it is maximally difficult to produce collisions.</li>
</ul>
<p>At it’s core, a hash function can simply be described as follows:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb6-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> hash_function(data: <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">bytes</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">int</span>:</span>
<span id="cb6-2">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> chunk <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> data:</span>
<span id="cb6-3">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">hash</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> cleverness(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">hash</span>, chunk)</span>
<span id="cb6-4"></span>
<span id="cb6-5">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">hash</span></span></code></pre></div></div>
<p>Basically, you have a rolling hash value, we can think of it as a context or a state, but its ultimately just a number and we have a block of input data <code>chunk</code> (perhaps <img src="https://latex.codecogs.com/png.latex?1"> byte or <img src="https://latex.codecogs.com/png.latex?4"> bytes), and you mix those and then you will generate another number. Now, you may have some pre- and post- processing depending on the function, but that’s pretty much how it works. The <code>cleverness</code> thing is actually what’s called a <em>mixing</em> function. If you ever see the word <em>mixing</em> function on the wikipedia page, this is what it refers to.</p>
<section id="how-do-you-implement-this-cleverness-function" class="level2">
<h2 class="anchored" data-anchor-id="how-do-you-implement-this-cleverness-function">How do you implement this cleverness function?</h2>
<p>In general you do it with unsigned, fixed length integers. You use:</p>
<ul>
<li>Bitwise operations (xor, rotation, unsigned bit shifts)</li>
<li>Multiplication</li>
<li>Usually, there is atleast one magic number e.g.&nbsp;a prime number.</li>
</ul>
<p>In hash table implementations, buckets are often a power of <img src="https://latex.codecogs.com/png.latex?2"> e.g.&nbsp;you might have <img src="https://latex.codecogs.com/png.latex?128"> buckets or <img src="https://latex.codecogs.com/png.latex?256">. If you have the same factorization of the number of buckets as some of the constants to manipulate the state of the hash function, you can end up bucketing everything actually into the same thing.</p>
<section id="fnv-1a" class="level3">
<h3 class="anchored" data-anchor-id="fnv-1a">FNV-1A</h3>
<p>FNV1-A is venerable hash function created by Fowler, Knoll and Vo in 1991 and has been improved a couple of times since. It’s still in wide use today.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb7-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;cstddef&gt;</span></span>
<span id="cb7-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;cstdint&gt;</span></span>
<span id="cb7-3"></span>
<span id="cb7-4"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint32_t</span> fnv1a32<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>byte<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> bytes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t num_bytes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb7-5">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// This is actually the hash of the email </span></span>
<span id="cb7-6">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// signatures of one of the creators of FNV.</span></span>
<span id="cb7-7">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">uint32_t</span> hash <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2166136261</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-8">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">uz</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>num_bytes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb7-9">        hash <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">^=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_cast</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>bytes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]);</span></span>
<span id="cb7-10">        hash <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">16777619</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-11"></span>
<span id="cb7-12">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb7-13">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> hash<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-14"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/z4a9nsPez">Compiler Explorer</a> Suppose that the input string is <code>"ab"</code>. We get the following hash code from the FNV algorithm:</p>
<pre class="shell"><code>hash(0) = 10000001000111001001110111000101
byte[0] =                          1100001
XOR     = 10000001000111001001110110100100
hash(1) = 11100100000011000010100100101100
byte[1] =                          1100010
XOR     = 11100100000011000010100101001110
hash(2) =  1001101001001010000010111001010</code></pre>
<p>The XOR changes only a few bits, so that’s why the multiplier is there. Actually, <img src="https://latex.codecogs.com/png.latex?16777619"> is the prime closest to <img src="https://latex.codecogs.com/png.latex?2%5E24">. It gives you bit-shifting behavior as well. FNV1a kind of hides this bit-shifting, but every other algorithm uses bit shifts heavily to get this avalanche behavior. So, what this is doing is, it’s going to shift everything and then its going add some noise to the lower end of the number.</p>
<p><code>16'777'619</code> in binary is <code>0b0000 0001 0000 0000 0000 0001 1001 0011</code>. When you multiply this number, you are essentially doing:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0Ahash%20%5Ctimes%2016777619%20=%20hash%20%5Ctimes%20(2%5E%7B24%7D%20+%202%5E8%20+%202%5E7%20+%202%5E4%20+%202%5E1%20+%202%5E0)%0A"></p>
<p>To keep things simple, consider the value <code>5 = 0b0101</code>. Assume we multiply <img src="https://latex.codecogs.com/png.latex?5%20%5Ctimes%208%20=%205%20%5Ctimes%202%5E3">. Using the rules of binary multiplication, we get:</p>
<pre class="shell"><code> 0b0000 0101
x0b0000 1000
------------
           0
          00
         000
 0b 010 1000
------------
 0b 010 1000</code></pre>
<p>Hence, <code>x * 2^3</code> is like <code>x &lt;&lt; 3</code>.</p>
<p>So, the first byte <code>a = 0b0110 0001</code> has a hash value of <code>0b1110 0100 0000 1100 0010 1001 0010 1100</code>. If we look at the next byte <code>b = 0b0110 0010</code>, it has just 2 bits different from the first byte, but the hash value is <code>0b0100 1101 0010 0101 0000 0101 1100 1010</code>.</p>
<pre class="shell"><code>0b1110 0100 0000 1100 0010 1001 0010 1100
0b0100 1101 0010 0101 0000 0101 1100 1010
  ^ ^  ^  ^   ^  ^  ^   ^  ^^   ^^^   ^^</code></pre>
<p>You can see how well distributed are two similar bytes. Every nibble has <img src="https://latex.codecogs.com/png.latex?1"> or <img src="https://latex.codecogs.com/png.latex?2"> bits that are being changed. So, we are already seeing a real avalanche behavior here. Things are getting moved, things are getting mutated, it all looks cool.</p>
<p>Let us look at few hash functions that are considered to be reasonably state-of-the-art.</p>
</section>
<section id="murmur-hash" class="level3">
<h3 class="anchored" data-anchor-id="murmur-hash">Murmur Hash</h3>
<pre><code>algorithm Murmur3_32 is
    // Note: In this version, all arithmetic is performed with unsigned 32-bit integers.
    //       In the case of overflow, the result is reduced modulo 232.
    input: data, len, seed

    c1 ← 0xcc9e2d51
    c2 ← 0x1b873593
    r1 ← 15
    r2 ← 13
    m ← 5
    n ← 0xe6546b64

    hash ← seed

    for each fourByteChunk of data do
        k ← fourByteChunk

        k ← k × c1
        k ← (k &lt;&lt; r1) | (k &gt;&gt; (32 - r1))
        k ← k × c2

        hash ← hash XOR k
        hash ← (hash &lt;&lt; r2) | (hash &gt;&gt; (32 - r2))
        hash ← (hash × m) + n

    with any remainingBytesInKey do
        remainingBytes ← SwapToLittleEndian(remainingBytesInKey)
        // Note: Endian swapping is only necessary on big-endian machines.
        //       The purpose is to place the meaningful digits towards the low end of the value,
        //       so that these digits have the greatest potential to affect the low range digits
        //       in the subsequent multiplication.  Consider that locating the meaningful digits
        //       in the high range would produce a greater effect upon the high digits of the
        //       multiplication, and notably, that such high digits are likely to be discarded
        //       by the modulo arithmetic under overflow.  We don't want that.

        remainingBytes ← remainingBytes × c1
        remainingBytes ← (remainingBytes &lt;&lt; r1) | (remainingBytes &gt;&gt; (32 - r1))
        remainingBytes ← remainingBytes × c2

        hash ← hash XOR remainingBytes

    hash ← hash XOR len

    hash ← hash XOR (hash &gt;&gt; 16)
    hash ← hash × 0x85ebca6b
    hash ← hash XOR (hash &gt;&gt; 13)
    hash ← hash × 0xc2b2ae35
    hash ← hash XOR (hash &gt;&gt; 16)</code></pre>
<p>Murmur3 hash has a few constants. Quite a few of those are primes. There is also a seed value that sometimes the user provides or is hardcoded at times. It also means that, if you want to generate different hash values for different users, you have a way to do it.</p>
<p>Then we start the mixing function. Murmur hash operates on <img src="https://latex.codecogs.com/png.latex?4"> bytes at a time, rather than <img src="https://latex.codecogs.com/png.latex?1"> byte. We multiply, do some bit shifting to try and get the values distributed more evenly, then again multiply, exclusive OR and then more stuff and it gets mutated.</p>
<p>If there are less than <img src="https://latex.codecogs.com/png.latex?4"> bytes, remaining then there is an alternative mixing function.</p>
<p>Finally, at the end we have, we have a series of post-processing steps to try and introduce more randomness into the whole thing. Again, we have multiplication with some constants and bit shifting to maximize distributing the hash.</p>
<pre class="shell"><code>hash ← hash XOR len

hash ← hash XOR (hash &gt;&gt; 16)
hash ← hash × 0x85ebca6b
hash ← hash XOR (hash &gt;&gt; 13)
hash ← hash × 0xc2b2ae35
hash ← hash XOR (hash &gt;&gt; 16)</code></pre>
</section>
</section>
</section>
<section id="the-theory-of-hashing" class="level1">
<h1>The theory of hashing</h1>
<p>The goal of hashing is to provide a solution that is faster than binary trees.</p>
<p>The formal setup for hashing is as follows:</p>
<ul>
<li><p>The keys come from some large universe <img src="https://latex.codecogs.com/png.latex?U">.</p></li>
<li><p>We will perform inserts and lookups by having an array of size <img src="https://latex.codecogs.com/png.latex?M">, and a hash function <img src="https://latex.codecogs.com/png.latex?h:U%20%5Cto%20%5C%7B0,%5Cldots,M-1%5C%7D">. Given an element <img src="https://latex.codecogs.com/png.latex?x">, the idea of hashing is we want to store it in <img src="https://latex.codecogs.com/png.latex?A%5Bh(x)%5D">.</p></li>
<li><p>We need a method for resolving collisions. A collision is when <img src="https://latex.codecogs.com/png.latex?h(x)%20=%20h(y)"> for two different <img src="https://latex.codecogs.com/png.latex?x"> and <img src="https://latex.codecogs.com/png.latex?y">. There are two methods to handle collisions:</p>
<ul>
<li>Separate chaining</li>
<li>Open addressing</li>
</ul></li>
</ul>
<section id="separate-chaining" class="level2">
<h2 class="anchored" data-anchor-id="separate-chaining">Separate chaining</h2>
<p>In the event, that multiple keys are hashed to the same slot, we store the keys in a linked list on that slot.</p>
<p>Let’s compute the mean and variance of the chain length. For slot <img src="https://latex.codecogs.com/png.latex?t">, let <img src="https://latex.codecogs.com/png.latex?C_t"> be the random variable equal to length of the linked list chain corresponding to slot <img src="https://latex.codecogs.com/png.latex?t">.</p>
<p>The expected chain length <img src="https://latex.codecogs.com/png.latex?%5Cmathbf%7BE%7D%5BC_t%5D"> is constant. We can write <img src="https://latex.codecogs.com/png.latex?I_j"> be the indicator random variable which is <img src="https://latex.codecogs.com/png.latex?1">, if the hash of <img src="https://latex.codecogs.com/png.latex?x_j"> falls in bucket <img src="https://latex.codecogs.com/png.latex?t">, else 0. Then, we have:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5Cbegin%7Balign*%7D%0AC_t%20&amp;=%20I_1%20+%20%5Cldots%20+%20I_n%20%5C%5C%0A%5Cmathbf%7BC_t%7D%20&amp;=%20%5Csum_%7Bj=1%7D%5E%7Bn%7D%5Cmathbf%7BE%7DI_j%20%5C%5C%0A&amp;=%20%5Csum_%7Bj=1%7D%5En%20P(h(x_j)%20=%20t)%20%5C%5C%0A&amp;=%20%5Csum_%7Bj=1%7D%5En%20%5Cfrac%7B1%7D%7Bm%7D%20%5C%5C%0A&amp;=%20%5Cfrac%7Bn%7D%7Bm%7D%0A%5Cend%7Balign*%7D%0A"></p>
<p>where <img src="https://latex.codecogs.com/png.latex?%5Calpha%20=%20n/m"> is frequently called the load factor. The load factor is constant if we assume that <img src="https://latex.codecogs.com/png.latex?c_1%20m%20%5Cleq%20n%20%5Cleq%20c_2%20n"> or equivalently <img src="https://latex.codecogs.com/png.latex?n%20=%20%5CTheta(n)">. This assumption can be kept satisfied by doubling the hash table size as needed.</p>
<p>Hence, our average case lookup time is <img src="https://latex.codecogs.com/png.latex?O(1+%5Calpha)%20=%20O(1+%5Cfrac%7Bn%7D%7Bm%7D)"></p>
</section>
<section id="open-addressing" class="level2">
<h2 class="anchored" data-anchor-id="open-addressing">Open addressing</h2>
<p>Open addressing is another collision resolution technique in which all <code>{key,value}</code> pairs are stored in hash table itself. Suppose our hash table has <img src="https://latex.codecogs.com/png.latex?m"> entries. We can think of the hash function as a function of <img src="https://latex.codecogs.com/png.latex?2"> parameters <img src="https://latex.codecogs.com/png.latex?h(k,i)"> where <img src="https://latex.codecogs.com/png.latex?k"> is the key, <img src="https://latex.codecogs.com/png.latex?i"> is the trial count.</p>
<p><img src="https://latex.codecogs.com/png.latex?%0Ah:%20%5Cunderbrace%7B%5Cmathcal%7BU%7D%7D_%7B%5Ctext%7BKey%20Universe%7D%7D%20%5Ctimes%20%5Cunderbrace%7B%5C%7B0,1,%5Cldots,m_1%5C%7D%7D_%7B%5Ctext%7Btrial%20count%7D%7D%20%5Cto%20%5Cunderbrace%7B%5C%7B0,1,%5Cldots,m-1%5C%7D%7D_%7B%5Ctext%7Bslot%20in%20table%7D%7D%0A"></p>
<p><img src="https://latex.codecogs.com/png.latex?%3Ch(k,0),%5Cldots,h(k,m-1)%3E"> is some permutation of <img src="https://latex.codecogs.com/png.latex?0,1,%5Cldots,m-1">. If we keep trying <img src="https://latex.codecogs.com/png.latex?h(k,i)"> for increasing <img src="https://latex.codecogs.com/png.latex?i">, we will eventually hit all slots of the table.</p>
<section id="inserting-items." class="level3">
<h3 class="anchored" data-anchor-id="inserting-items.">Inserting items.</h3>
<p>We keep probing until an empty slot is found. When an empty slot is found, we insert the key-value pair into that slot.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb13-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> insert(k, v):</span>
<span id="cb13-2">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> i <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">range</span>(m):</span>
<span id="cb13-3">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> T[h(k,i)] <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>:</span>
<span id="cb13-4">            T[h(k,i)] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> (k,v)</span>
<span id="cb13-5">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span></span>
<span id="cb13-6">    </span>
<span id="cb13-7">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">raise</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Full"</span></span></code></pre></div></div>
</section>
<section id="searching-items." class="level3">
<h3 class="anchored" data-anchor-id="searching-items.">Searching items.</h3>
<p>As long as the slots we encounter by probing are occupied by <img src="https://latex.codecogs.com/png.latex?keys%20%5Cneq%20k">, keep probing until you either encounter <img src="https://latex.codecogs.com/png.latex?k"> or find an empty slot - return <em>success</em> or *failure respectively.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb14-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> i <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">xrange</span>(m):</span>
<span id="cb14-2">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> T[h(k,i)] <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">is</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span>:</span>
<span id="cb14-3">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span></span>
<span id="cb14-4">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> T[h(k,i)][<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> k:</span>
<span id="cb14-5">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> T[h(k,i)]</span>
<span id="cb14-6"></span>
<span id="cb14-7"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">None</span></span></code></pre></div></div>
</section>
<section id="deleting-items" class="level3">
<h3 class="anchored" data-anchor-id="deleting-items">Deleting items</h3>
<p>We cannot just find an item and remove it from its slot (that is set <code>T[h(k,i)] = None</code>). For example, if we perfom <code>delete(586)</code> and mark the slot as <code>None</code>, then <code>search(496)</code> will fail. Instead, we replace a deleted item with a special flag : <code>DeleteMe</code>, which is a tombstone. <code>insert(k,v)</code> treats this as <code>None</code>, but <code>search(k)</code> doesnt.</p>
<pre><code>    +-------+
0   |       |
    |-------|
1   |  586  | probe h(496,1)
    |-------|
2   |  133  | probe h(496,0)
    |-------|
3   |       |
    |-------|
4   |  204  | probe h(496,2)
    |-------|
5   |  496  | probe h(496,3)
    |-------|
6   |  481  |
    |-------|
7   |       |
    |-------|
    |       |
    |-------|    
    |       |
    |-------|    
m-1 |       |
    +-------+</code></pre>
</section>
</section>
<section id="probing-strategies" class="level2">
<h2 class="anchored" data-anchor-id="probing-strategies">Probing Strategies</h2>
<section id="linear-probing" class="level3">
<h3 class="anchored" data-anchor-id="linear-probing">Linear Probing</h3>
<p>Linear probing is like street parking. Here the probe function is linear of the form <img src="https://latex.codecogs.com/png.latex?p(k,i)%20=%20c%20i">, where <img src="https://latex.codecogs.com/png.latex?c"> is a constant. We then have, <img src="https://latex.codecogs.com/png.latex?h(k,i)%20=%20(h(k)%20+%20p(k))%20%5Cmod%20m"> where <img src="https://latex.codecogs.com/png.latex?h(k)"> is a hash function. It suffers from clustering. If you have a large cluster, and <img src="https://latex.codecogs.com/png.latex?h(k,0)"> hashes to any of the slots that fall in this cluster, the cluster is more likely to grow further.</p>
</section>
<section id="double-hashing" class="level3">
<h3 class="anchored" data-anchor-id="double-hashing">Double Hashing</h3>
<p><img src="https://latex.codecogs.com/png.latex?h(k,i)%20=%20(h_1(k)%20+%20i%20%5Ccdot%20h_2(k))%20%5Cmod%20m"> where <img src="https://latex.codecogs.com/png.latex?h_1(k)"> and <img src="https://latex.codecogs.com/png.latex?h_2(k)"> are two ordinary hash functions.</p>
<p>If <img src="https://latex.codecogs.com/png.latex?h_2(k)"> is coprime to <img src="https://latex.codecogs.com/png.latex?m"> for all <img src="https://latex.codecogs.com/png.latex?k">, we will actually hit all slots (permutation) before exhausting. That’s because:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0Ah_1(k)%20+%20i%20%5Ccdot%20h_2(k)%20%5Cmod%20m%20=%20h_1(k)%20+%20j%20%5Ccdot%20h_2(k)%20%5Cmod%20m%20%5Cimplies%20m%20%5Ctext%7B%20divides%20%7D(i-j)%0A"></p>
</section>
<section id="pseudo-random-probing" class="level3">
<h3 class="anchored" data-anchor-id="pseudo-random-probing">Pseudo-random probing</h3>
<p>An ideal probe function would select the next position on the probe sequence at random from among the unvisited slots; that is, the probe sequence should be a random permutation of the hash table positions. Unfortunately, we cannot actually seelect the next position in the probe sequence at random, because we would not be able to replicate the same probe sequence when searching for the key. However, we can do something similar called <strong>pseudo-random probing</strong>. In pseudo-random probing, the <img src="https://latex.codecogs.com/png.latex?i">th slot in the probe sequence is <img src="https://latex.codecogs.com/png.latex?(h(K)%20+%20r_i)"> where <img src="https://latex.codecogs.com/png.latex?r_i"> is the <img src="https://latex.codecogs.com/png.latex?i">th value in a random permutation of the numbers <img src="https://latex.codecogs.com/png.latex?1,%5Cldots,%20m-1">. All inserts and searches use the same random number stream (sequence of random numbers).</p>
</section>
<section id="quadratic-probing" class="level3">
<h3 class="anchored" data-anchor-id="quadratic-probing">Quadratic Probing</h3>
<p>Another probe function that eliminates primary clustering is called <strong>quadratic probing</strong>. Here the probe function is some quadratic function <img src="https://latex.codecogs.com/png.latex?p(k,i)=c_1i%5E2%20+%20c_2%20i%20+%20c_3"> for some choice of constants <img src="https://latex.codecogs.com/png.latex?c_1,%20c_2,%20c_3">.</p>


</section>
</section>
</section>

 ]]></description>
  <category>C++</category>
  <guid>http://quantdev.blog/posts/hash_tables/</guid>
  <pubDate>Thu, 25 Dec 2025 00:00:00 GMT</pubDate>
  <media:content url="http://quantdev.blog/posts/hash_tables/cpp.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>Move semantics and perfect forwarding</title>
  <dc:creator>`dev::author` </dc:creator>
  <link>http://quantdev.blog/posts/move-semantics/</link>
  <description><![CDATA[ 





<section id="value-categories" class="level1">
<h1>Value Categories</h1>
<p>C++ defines the following value categories:</p>
<ul>
<li><em>lvalues</em>: expressions for locations of long-living objects or functions. These objects have identity, persist in memory and are addressable.</li>
<li><em>prvalues</em>: expressions for short-living values for initializations. <em>prvalues</em> themselves do not exist somewhere in memory, they do not denote objects. They are unmaterialized entities meant for initialization.</li>
<li><em>xvalue</em>: A special location, representing a (long-living) object, whose resources/values are no longer needed and can be reused. The guts of this object can be stolen.</li>
</ul>
<p>The moment a <em>prvalue</em> (conceptual temporary) becomes an <em>xvalue</em>(temporary object), it is called <em>materialization</em>. The temporary materialization conversion is usually an implicit <em>prvalue-to-xvalue</em> conversion.</p>
<p>Anytime a <em>prvalue</em> is used where a <em>lvalue</em> or <em>xvalue</em> is expected, a temporary object is created and initialized with the <em>prvalue</em>.</p>
</section>
<section id="rules-for-binding-references" class="level1">
<h1>Rules for binding references</h1>
<p>Define:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb1-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> X<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{};</span></span>
<span id="cb1-2">X v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-3"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> X c<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-4"></span>
<span id="cb1-5"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>X<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-6"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>X<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;);</span></span>
<span id="cb1-7"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> X<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;);</span></span>
<span id="cb1-8"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>X<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;);</span></span>
<span id="cb1-9"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> X<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;);</span></span></code></pre></div></div>
<ul>
<li><p>A non-<code>const</code> <em>lvalue</em> reference <code>X&amp;</code> takes only non-<code>const</code> <em>lvalues</em>.</p></li>
<li><p>A <em>rvalue</em> reference <code>X&amp;&amp;</code> takes only non-<code>const</code> <em>rvalues</em>.</p></li>
<li><p>A <code>const</code> <em>lvalue</em> reference <code>const X&amp;</code> can take everything and serves as a fallback mechanism for move semantics.</p></li>
<li><p>A <code>const</code> <em>rvalue</em> reference takes both modifiable and <code>const</code> <em>rvalues</em> (e.g.&nbsp;<code>std::move(c)</code>).</p></li>
<li><p>A universal reference binds to all value categories and are usually used to forward arguments.</p></li>
</ul>
<section id="overload-resolution-priority" class="level3">
<h3 class="anchored" data-anchor-id="overload-resolution-priority">Overload resolution priority</h3>
<table class="caption-top table">
<colgroup>
<col style="width: 24%">
<col style="width: 11%">
<col style="width: 18%">
<col style="width: 12%">
<col style="width: 20%">
<col style="width: 12%">
</colgroup>
<thead>
<tr class="header">
<th>Call</th>
<th><code>f(X&amp;)</code></th>
<th><code>f(const X&amp;)</code></th>
<th><code>f(X&amp;&amp;)</code></th>
<th><code>f(const X&amp;&amp;)</code></th>
<th><code>f(T&amp;&amp;)</code></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>f(v)</code></td>
<td>1</td>
<td>3</td>
<td>no</td>
<td>no</td>
<td>2</td>
</tr>
<tr class="even">
<td><code>f(c)</code></td>
<td>no</td>
<td>1</td>
<td>no</td>
<td>no</td>
<td>2</td>
</tr>
<tr class="odd">
<td><code>f(X{})</code></td>
<td>no</td>
<td>4</td>
<td>1</td>
<td>3</td>
<td>2</td>
</tr>
<tr class="even">
<td><code>f(std::move(v))</code></td>
<td>no</td>
<td>4</td>
<td>1</td>
<td>3</td>
<td>2</td>
</tr>
<tr class="odd">
<td><code>f(std::move(c))</code></td>
<td>no</td>
<td>3</td>
<td>no</td>
<td>1</td>
<td>2</td>
</tr>
</tbody>
</table>
<p>Note that, universal reference is always the second best option.</p>
</section>
<section id="universal-references-and-detail" class="level3">
<h3 class="anchored" data-anchor-id="universal-references-and-detail">Universal references and detail</h3>
<p>Note that, when we declare <code>arg</code> as <code>T&amp;&amp;</code> (pronounced <code>T</code>-ref-ref) where <code>T</code> is function template type parameter, this is a universal(forwarding reference). It does not follow the rules of <em>rvalue references</em>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb2-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb2-2"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> foo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> arg<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){}</span></span></code></pre></div></div>
<section id="reference-collapsing-rules" class="level4">
<h4 class="anchored" data-anchor-id="reference-collapsing-rules">Reference collapsing rules</h4>
<p>For a non-const object <code>v</code> and a const object <code>c</code> the type <code>T</code> and the type of <code>arg</code> is deduced as follows:</p>
<table class="caption-top table">
<colgroup>
<col style="width: 33%">
<col style="width: 22%">
<col style="width: 22%">
<col style="width: 22%">
</colgroup>
<thead>
<tr class="header">
<th></th>
<th><code>T</code></th>
<th><code>T&amp;&amp;</code></th>
<th><code>arg</code></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>foo(v)</code></td>
<td><code>X&amp;</code></td>
<td><code>X&amp; &amp;&amp;</code></td>
<td><code>X&amp;</code></td>
</tr>
<tr class="even">
<td><code>foo(c)</code></td>
<td><code>const X&amp;</code></td>
<td><code>const X&amp; &amp;&amp;</code></td>
<td><code>const X&amp;</code></td>
</tr>
<tr class="odd">
<td><code>foo(X{})</code></td>
<td><code>X</code></td>
<td><code>X &amp;&amp;</code></td>
<td><code>X&amp;&amp;</code></td>
</tr>
<tr class="even">
<td><code>foo(std::move(v))</code></td>
<td><code>X&amp;&amp;</code></td>
<td><code>X&amp;&amp; &amp;&amp;</code></td>
<td><code>X&amp;&amp;</code></td>
</tr>
<tr class="odd">
<td><code>foo(std::move(c))</code></td>
<td><code>const X&amp;&amp;</code></td>
<td><code>const X&amp;&amp; &amp;&amp;</code></td>
<td><code>const X&amp;&amp;</code></td>
</tr>
</tbody>
</table>
<ul>
<li><code>X&amp; &amp;</code> becomes <code>X&amp;</code>.</li>
<li><code>X&amp; &amp;&amp;</code> becomes <code>X&amp;</code>.</li>
<li><code>X&amp;&amp; &amp;</code> becomes <code>X&amp;</code>.</li>
<li><code>X&amp;&amp; &amp;&amp;</code> becomes <code>X&amp;&amp;</code>.</li>
</ul>
</section>
</section>
<section id="copy-elison" class="level2">
<h2 class="anchored" data-anchor-id="copy-elison">Copy elison</h2>
<p>Copy elison omits copy and move constructors, resulting in zero-copy pass-by-value semantics.</p>
<section id="mechanics" class="level3">
<h3 class="anchored" data-anchor-id="mechanics">Mechanics</h3>
<p>The basic mechanics of <strong>Return Value Optimization</strong>(RVO) is as follows:</p>
<ul>
<li>The caller allocates space on the stack for the return value, passes the address to the callee.</li>
<li>The callee constructs the result directly in that space.</li>
</ul>
<p>In the below code snip,</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb3-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;print&gt;</span></span>
<span id="cb3-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;iostream&gt;</span></span>
<span id="cb3-3"></span>
<span id="cb3-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> X<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-5">    X<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span> val<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_val</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>val<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"constructed at "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-6">    X<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> X<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;){</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"X(const X&amp;)"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-7">    X<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>X<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;){</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"X(X&amp;&amp;)"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-8">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span>X<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"destructed at "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-9">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_val</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-10"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb3-11"></span>
<span id="cb3-12"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>X arg<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb3-13">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"&amp;arg = "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>arg<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-14"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-15"></span>
<span id="cb3-16">X g<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb3-17">    X obj <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> X<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// copy elison initializing obj</span></span>
<span id="cb3-18">                    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// from temporary</span></span>
<span id="cb3-19">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> obj<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>     <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// NRVO</span></span>
<span id="cb3-20"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-21"></span>
<span id="cb3-22">X h<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb3-23">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> X<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// URVO</span></span>
<span id="cb3-24"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-25"></span>
<span id="cb3-26"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb3-27">    f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>X<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb3-28">    X v1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>g<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()};</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Copy elison initializing v1 from the result of g()</span></span>
<span id="cb3-29">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"&amp;v1 = "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>v1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-30">    X v2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>h<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()};</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Copy elison initializing v2 from the result of h()</span></span>
<span id="cb3-31">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"&amp;v2 = "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>v2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-32">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-33"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/oMr16KTof">Compiler Explorer</a></p>
<p>It is important to note that:</p>
<ul>
<li>When a temporary(<em>prvalue</em>) is used to initialize an object, or function parameter, a copy is elided.</li>
<li>Inside a function, when a <em>prvalue</em> is returned by value, URVO(unnamed return value optimization) is performed.</li>
<li>Inside a function, when a <em>lvalue</em> is returned by value, NRVO(named return value optimization) is performed.</li>
</ul>
</section>
</section>
<section id="challenge-puzzle" class="level2">
<h2 class="anchored" data-anchor-id="challenge-puzzle">Challenge puzzle</h2>
<p>Observe the below code snip. What is the output printed?</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb4-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;iostream&gt;</span></span>
<span id="cb4-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> A <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb4-3">    A<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb4-4">    A<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> A<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> a<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb4-5">    A<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>A<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> a<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb4-6">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-7"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb4-8"></span>
<span id="cb4-9"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> foo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>A t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb4-10">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-11"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb4-12"></span>
<span id="cb4-13">A bar<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb4-14">    A a<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb4-15">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> a<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-16"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb4-17"></span>
<span id="cb4-18">A foobar<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb4-19">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> A<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb4-20"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb4-21"></span>
<span id="cb4-22">A<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> baz<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>A<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> arg<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb4-23">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>move<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>arg<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb4-24"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb4-25"></span>
<span id="cb4-26"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb4-27">    A a<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb4-28">    foo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>a<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb4-29">    foo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>A<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb4-30">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> bar<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">().</span>x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-31">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> foobar<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">().</span>x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-32">    A result<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> baz<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>A<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb4-33">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> result<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-34"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://godbolt.org/z/zh91h7fr6">Compiler Explorer</a></p>
<p>For more such puzzles, visit <a href="https://getcracked.io/">getcracked.io</a></p>


</section>
</section>

 ]]></description>
  <category>C++</category>
  <guid>http://quantdev.blog/posts/move-semantics/</guid>
  <pubDate>Tue, 23 Dec 2025 00:00:00 GMT</pubDate>
  <media:content url="http://quantdev.blog/posts/move-semantics/cpp.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>Using std::variant</title>
  <dc:creator>`dev::author` </dc:creator>
  <link>http://quantdev.blog/posts/std_variant/</link>
  <description><![CDATA[ 





<section id="using-stdvariant" class="level1">
<h1>Using <code>std::variant</code></h1>
<p>A <code>std::variant</code> is a closed-discriminated union. Variants simply have internal memory for maximum size of the underlying types plus a fixed overhead to manage which alternative is used. No heap memory is allocated. The resulting object has value semantics. Copying a variant is implemented as a deep-copy, it creates a new variant object with the current value of the alternative in its own memory.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb1-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;iostream&gt;</span></span>
<span id="cb1-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;variant&gt;</span></span>
<span id="cb1-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;string&gt;</span></span>
<span id="cb1-4"></span>
<span id="cb1-5"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb1-6">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// initialized with string alternative</span></span>
<span id="cb1-7">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"hi"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span>   </span>
<span id="cb1-8">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-9"></span>
<span id="cb1-10">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// now holds int alternative</span></span>
<span id="cb1-11">    var <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-12">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-13"></span>
<span id="cb1-14">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">try</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-15">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// access by index</span></span>
<span id="cb1-16">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> j <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//access by type</span></span>
<span id="cb1-17">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string s <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//error</span></span>
<span id="cb1-18">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">catch</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>bad_variant_access<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> e<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb1-19">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cerr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Exception: "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> e<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>what<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-20">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-21">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-22"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/Ehqhq3T51">Compiler Explorer</a></p>
<p>Output:</p>
<pre class="shell"><code>Program returned: 0
Program stdout

1
0

Program stderr

Exception: std::get: wrong index for variant</code></pre>
<p>The default constructor for <code>std::variant</code> always initializes the first type with the default constructor. If there is no default constructor for the first type, calling the default constructor for the variant is a compile-time error.</p>
<p>If we still want to have a <code>std::variant</code>, we can use the helper type <code>std::monostate</code>. They serve as a first alternative type to make the variant type default constructible. Objects of type <code>std::monostate</code> only have <img src="https://latex.codecogs.com/png.latex?1"> state, so they always compare equal. To an extent, you can interprete this state as signalling emptiness.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb3-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Ref: C++17 - The complete guide</span></span>
<span id="cb3-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Nikolai Josuttis</span></span>
<span id="cb3-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;variant&gt;</span></span>
<span id="cb3-4"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;print&gt;</span></span>
<span id="cb3-5"></span>
<span id="cb3-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> NoDefConstr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-7">    NoDefConstr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">delete</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-8"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb3-9"></span>
<span id="cb3-10"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb3-11">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// different ways to check for monostate</span></span>
<span id="cb3-12">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>monostate<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> NoDefConstr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-13"></span>
<span id="cb3-14">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb3-15">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"has monostate"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-16">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-17">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(!</span>v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()){</span></span>
<span id="cb3-18">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"has monostate"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-19">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-20">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>holds_alternative<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>monostate<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)){</span></span>
<span id="cb3-21">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"has monostate"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-22">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-23">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// get_if accepts a pointer to a variant and returns</span></span>
<span id="cb3-24">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// a `T*` if the alternative is T, else return</span></span>
<span id="cb3-25">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// nullptr</span></span>
<span id="cb3-26">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>get_if<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(&amp;</span>v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)){</span></span>
<span id="cb3-27">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"has monostate"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-28">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-29">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>get_if<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>monostate<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(&amp;</span>v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)){</span></span>
<span id="cb3-30">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"has monostate"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-31">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-32">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-33"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/GbrEYWh7h">Compiler Explorer</a></p>
<p>You can assign any other alternative and even assign <code>std::monostate</code> to the variant again.</p>
<section id="stdvariant-types-and-operations" class="level2">
<h2 class="anchored" data-anchor-id="stdvariant-types-and-operations"><code>std::variant</code> types and operations</h2>
<section id="construction" class="level3">
<h3 class="anchored" data-anchor-id="construction">Construction</h3>
<p>There are several different ways to construct and initialize a <code>std::variant</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb4-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;variant&gt;</span></span>
<span id="cb4-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;print&gt;</span></span>
<span id="cb4-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;complex&gt;</span></span>
<span id="cb4-4"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;set&gt;</span></span>
<span id="cb4-5"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;initializer_list&gt;</span></span>
<span id="cb4-6"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;vector&gt;</span></span>
<span id="cb4-7"></span>
<span id="cb4-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> NoCopyConstr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb4-9">    NoCopyConstr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> NoCopyConstr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">delete</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-10"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb4-11"></span>
<span id="cb4-12"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb4-13">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// construction</span></span>
<span id="cb4-14">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// sets first int to 0, index() == 0</span></span>
<span id="cb4-15">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> v1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> </span>
<span id="cb4-16"></span>
<span id="cb4-17">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// if a value is passed for initialization,</span></span>
<span id="cb4-18">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// the best matching type is used</span></span>
<span id="cb4-19">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">long</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> v2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb4-20">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"v2.index() = </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> v2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb4-21"></span>
<span id="cb4-22">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// the call is ambiguous, if two types match equally well</span></span>
<span id="cb4-23">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//std::variant&lt;long, long&gt; v3{42};    // error</span></span>
<span id="cb4-24"></span>
<span id="cb4-25">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// 42.3 is a double and requires narrowing conversion</span></span>
<span id="cb4-26">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// when assigned to int or float.</span></span>
<span id="cb4-27">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Neither is better.</span></span>
<span id="cb4-28">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//std::variant&lt;int, float&gt; v4{42.3};  // error</span></span>
<span id="cb4-29"></span>
<span id="cb4-30"></span>
<span id="cb4-31">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//std::variant&lt;std::string, std::string_view&gt; v5{"hello"};  //error</span></span>
<span id="cb4-32">    </span>
<span id="cb4-33">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// std::in_place_type or std::in_place_index</span></span>
<span id="cb4-34">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// is used to pass more than one value for initialization</span></span>
<span id="cb4-35">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>complex<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;</span> v6<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb4-36">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>in_place_type<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>complex<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.0</span></span>
<span id="cb4-37">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb4-38"></span>
<span id="cb4-39">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>complex<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;</span> v7<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb4-40">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>in_place_index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.0</span></span>
<span id="cb4-41">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb4-42"></span>
<span id="cb4-43">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// in_place_index tags can be used to resolve</span></span>
<span id="cb4-44">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ambiguities or overrule priorities during </span></span>
<span id="cb4-45">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// initialization</span></span>
<span id="cb4-46">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> v8<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>in_place_index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">77</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb4-47">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"v8.index() = </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> v8<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">());</span></span>
<span id="cb4-48">    </span>
<span id="cb4-49">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// pass an initializer list followed by additional</span></span>
<span id="cb4-50">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// arguments</span></span>
<span id="cb4-51">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> sc <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb4-52">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>abs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>abs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb4-53">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb4-54"></span>
<span id="cb4-55">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;,</span> </span>
<span id="cb4-56">                 <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>set<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">decltype</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>sc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)&gt;&gt;</span> v9<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb4-57">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>in_place_index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span> sc</span>
<span id="cb4-58">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb4-59"></span>
<span id="cb4-60">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// there is no make_variant convenience function</span></span>
<span id="cb4-61"></span>
<span id="cb4-62">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// you can copy variants provided all alternatives</span></span>
<span id="cb4-63">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// support copying.</span></span>
<span id="cb4-64">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> v10<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">42.3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb4-65">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> v11<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>v10<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb4-66"></span>
<span id="cb4-67">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> NoCopyConstr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> v12<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-68">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// std::variant&lt;int, NoCopyConstr&gt; v13{v12};</span></span>
<span id="cb4-69">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-70"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/Kb4zGb5dx">Compiler Explorer</a></p>
</section>
<section id="accessing-the-stored-value" class="level3">
<h3 class="anchored" data-anchor-id="accessing-the-stored-value">Accessing the stored value</h3>
</section>
<section id="changing-the-value" class="level3">
<h3 class="anchored" data-anchor-id="changing-the-value">Changing the value</h3>
<p>There are <img src="https://latex.codecogs.com/png.latex?4"> ways to change the current value of the variant:</p>
<ul>
<li>the assignment operator</li>
<li><code>emplace</code></li>
<li><code>get</code> and then assign a new value for the currently active type.</li>
<li>a visitor.</li>
</ul>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb5-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;iostream&gt;</span></span>
<span id="cb5-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;variant&gt;</span></span>
<span id="cb5-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;string&gt;</span></span>
<span id="cb5-4"></span>
<span id="cb5-5"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb5-6">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// initialized with string alternative</span></span>
<span id="cb5-7">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"hi"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span>   </span>
<span id="cb5-8">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-9"></span>
<span id="cb5-10">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// now holds int alternative</span></span>
<span id="cb5-11">    var <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-12">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>index<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-13"></span>
<span id="cb5-14">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">try</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb5-15">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// access by index</span></span>
<span id="cb5-16">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> j <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//access by type</span></span>
<span id="cb5-17">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string s <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//error</span></span>
<span id="cb5-18">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">catch</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>bad_variant_access<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> e<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb5-19">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cerr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Exception: "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> e<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>what<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-20">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb5-21"></span>
<span id="cb5-22">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Changing the value</span></span>
<span id="cb5-23">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// assignment and emplace() operations can be used to</span></span>
<span id="cb5-24">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// modify the value in the variant. </span></span>
<span id="cb5-25">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// operator=() directly assigns the new value, </span></span>
<span id="cb5-26">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// if the variant currently holds the alternative.</span></span>
<span id="cb5-27">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// emplace() first destroys the old value and then assigns</span></span>
<span id="cb5-28">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// the new value.</span></span>
<span id="cb5-29"></span>
<span id="cb5-30">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//sets first int to 0, index() == 0</span></span>
<span id="cb5-31">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> var2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-32">    var2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"hello"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-33">    var2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>emplace<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb5-34"></span>
<span id="cb5-35">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// get&lt;&gt;() or get_if&lt;&gt;() can also be used to assign</span></span>
<span id="cb5-36">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// a new value to the current alternative.</span></span>
<span id="cb5-37">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>var2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">77</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-38">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>var2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">99</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-39">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-40"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/6WP6bGzPj">Compiler Explorer</a></p>
</section>
<section id="comparisons" class="level3">
<h3 class="anchored" data-anchor-id="comparisons">Comparisons</h3>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb6-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;iostream&gt;</span></span>
<span id="cb6-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;variant&gt;</span></span>
<span id="cb6-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;string&gt;</span></span>
<span id="cb6-4"></span>
<span id="cb6-5"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb6-6">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// for 2 variants of the same type (i.e. having</span></span>
<span id="cb6-7">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// the same alternatives), you can use the usual</span></span>
<span id="cb6-8">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// comparison operators. The following rules apply.</span></span>
<span id="cb6-9">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// - a variant with a value of an earlier alternative</span></span>
<span id="cb6-10">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// is less than a variant with value with a later alternative.</span></span>
<span id="cb6-11"></span>
<span id="cb6-12">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// if two variants have the same alternative, the corresponding</span></span>
<span id="cb6-13">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// operators for the type of the alternatives is invoked.</span></span>
<span id="cb6-14"></span>
<span id="cb6-15">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>monostate<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> v1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> v2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"hello"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span> v3<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb6-16">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>monostate<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> v4<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb6-17">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//std::cout &lt;&lt; v1 == v4;    // compile-time error</span></span>
<span id="cb6-18">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>v1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> v2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// false</span></span>
<span id="cb6-19">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>v1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> v2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>     <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// true</span></span>
<span id="cb6-20">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>v1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> v3<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>     <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// true</span></span>
<span id="cb6-21">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>v2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> v3<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>     <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// false</span></span>
<span id="cb6-22"></span>
<span id="cb6-23">    v1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"hello"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb6-24">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>v1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> v2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>     <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// false</span></span>
<span id="cb6-25">    v2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">41</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb6-26">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>v2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> v3<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb6-27">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb6-28"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/EsjonPejs">Compiler Explorer</a></p>
</section>
</section>
<section id="visitors" class="level2">
<h2 class="anchored" data-anchor-id="visitors">Visitors</h2>
<p>Visitors are simply objects that provide a function call operator <code>operator=()</code> for each possible type. When a visitor object visits a variant, they invoke the best matching function call operator for the actual value of the variant.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb7-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;variant&gt;</span></span>
<span id="cb7-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;string&gt;</span></span>
<span id="cb7-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;iostream&gt;</span></span>
<span id="cb7-4"></span>
<span id="cb7-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> MyVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-6">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-7">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"int: "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-8">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb7-9"></span>
<span id="cb7-10">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-11">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"string: "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> s <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-12">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb7-13"></span>
<span id="cb7-14">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-15">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"double: "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> d <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-16">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb7-17"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb7-18"></span>
<span id="cb7-19"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb7-20">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb7-21">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>MyVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// calls operator() for int</span></span>
<span id="cb7-22">    var <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"hello"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-23">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>MyVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb7-24">    var <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">42.7</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-25">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>MyVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb7-26">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-27"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/c5ejxco7n">Compiler Explorer</a></p>
<section id="using-generic-lambdas-as-visitors" class="level3">
<h3 class="anchored" data-anchor-id="using-generic-lambdas-as-visitors">Using generic lambdas as visitors</h3>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb8-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;variant&gt;</span></span>
<span id="cb8-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;string&gt;</span></span>
<span id="cb8-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;iostream&gt;</span></span>
<span id="cb8-4"></span>
<span id="cb8-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> printVisitor <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb8-6">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb8-7"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb8-8"></span>
<span id="cb8-9"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb8-10">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb8-11">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>printVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// calls operator() for int</span></span>
<span id="cb8-12">    var <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"hello"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb8-13">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>printVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb8-14">    var <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">42.7</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb8-15">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>printVisitor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb8-16">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb8-17"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/EqsqbGj1j">Compiler Explorer</a></p>
</section>
<section id="the-cracked-mans-match" class="level3">
<h3 class="anchored" data-anchor-id="the-cracked-mans-match">The cracked-man’s match</h3>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb9-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;variant&gt;</span></span>
<span id="cb9-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;string&gt;</span></span>
<span id="cb9-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;iostream&gt;</span></span>
<span id="cb9-4"></span>
<span id="cb9-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb9-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> overload <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...{</span></span>
<span id="cb9-7">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()...;</span></span>
<span id="cb9-8"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb9-9"></span>
<span id="cb9-10"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// base types are deduced from the passed arguments</span></span>
<span id="cb9-11"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb9-12">overload<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> overload<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Ts<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;;</span></span>
<span id="cb9-13"></span>
<span id="cb9-14"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb9-15">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb9-16"></span>
<span id="cb9-17">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>overload<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// calls best matching lambda for current alternative</span></span>
<span id="cb9-18">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"int: "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb9-19">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb9-20">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"string: "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> s <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> <span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb9-21">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb9-22">    var<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb9-23"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/KWf7nxsYd">Compiler Explorer</a></p>
<p>You might wonder why we need to bring the function call operators of the closure types (<code>__my_lambda_with_int_param_struct</code> and <code>__my_lambda_with_string_param_struct</code>) in scope.</p>
<p>As per <a href="https://en.cppreference.com/w/cpp/language/overload_resolution.html">overload resolution rules</a>, when we have a <code>Derived</code> class as a subtype of two base classes <code>Base1</code> and <code>Base2</code>, and <code>Base1</code> implements <code>operator()(int)</code>, whilst <code>Base2</code> implements <code>operator()(std::string)</code>, both these method are inherited by <code>Derived</code>. Whilst both these candidates are a part of the overload set, overload resolution for overloaded operators differs from regular functions. In the case of overloaded operators, the argument list for the purpose of overloaded resolution has the implied object argument of type <em>cv</em> <code>Derived</code>. In which case, all base class methods will also be present, when the candidate set is trimmed to the viable set, and the result is ambiguous.</p>
</section>
</section>
<section id="polymorphism-and-inhomogenous-collections-with-stdvariant" class="level2">
<h2 class="anchored" data-anchor-id="polymorphism-and-inhomogenous-collections-with-stdvariant">Polymorphism and inhomogenous collections with <code>std::variant</code></h2>
<p><code>std::variant</code> enables a new form polymorphism and allows dealing with inhomogenous collections. It is a form of compile-time polymorphism with a closed set of data-types.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb10-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;variant&gt;</span></span>
<span id="cb10-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;string&gt;</span></span>
<span id="cb10-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;iostream&gt;</span></span>
<span id="cb10-4"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;vector&gt;</span></span>
<span id="cb10-5"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;print&gt;</span></span>
<span id="cb10-6"></span>
<span id="cb10-7"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Point<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb10-8">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb10-9">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span> y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb10-10"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb10-11"></span>
<span id="cb10-12"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Line<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb10-13">    Point head<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb10-14">    Point tail<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb10-15">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> draw<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Rendering line"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb10-16"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb10-17"></span>
<span id="cb10-18"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Circle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb10-19">    Point center<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb10-20">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">double</span> radius<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb10-21">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> draw<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Rendering circle"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span>    </span>
<span id="cb10-22"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb10-23"></span>
<span id="cb10-24"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Rectangle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb10-25">    Point origin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb10-26">    Point size_vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb10-27"></span>
<span id="cb10-28">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> draw<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Rendering rectangle"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb10-29"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb10-30"></span>
<span id="cb10-31"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// common type of all geometric objects</span></span>
<span id="cb10-32"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> GeoObj <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>variant<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Line<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Circle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Rectangle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;;</span></span>
<span id="cb10-33"></span>
<span id="cb10-34"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>GeoObj<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> createFigure<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb10-35">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>GeoObj<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> fig<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{};</span></span>
<span id="cb10-36">    fig<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>push_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Line<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb10-37">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>head <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Point<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span> </span>
<span id="cb10-38">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>tail <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Point<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb10-39">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">});</span></span>
<span id="cb10-40"></span>
<span id="cb10-41">    fig<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>push_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Circle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb10-42">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>center <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Point<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb10-43">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>radius <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.0</span></span>
<span id="cb10-44">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">});</span></span>
<span id="cb10-45"></span>
<span id="cb10-46">    fig<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>push_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Rectangle<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb10-47">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>origin <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Point<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb10-48">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size_vector <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Point<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb10-49">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">});</span></span>
<span id="cb10-50">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> fig<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb10-51"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb10-52"></span>
<span id="cb10-53"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb10-54">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>GeoObj<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> figure <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> createFigure<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb10-55">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> GeoObj<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> geoobj <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> figure<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb10-56">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>visit<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">([](</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> obj<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb10-57">            obj<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>draw<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb10-58">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span> geoobj<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb10-59">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb10-60"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/G7cM7dqzd">Compiler Explorer</a></p>
<p>The three types <code>Line</code>, <code>Circle</code> and <code>Rectangle</code> don’t have any special relationship. In fact, they do not need to have a common base class, no virtual functions and their interfaces might even differ.</p>
<p>The code above would not be possible with runtime polymorphism, because then the types would need to have <code>GeoObj</code> as a common base class and we would need a vector of pointers of <code>GeoObj</code> elements. Moreover, runtime polymorphism is costly as memory needs to be dynamically allocated and there are two levels of indirection.</p>
<p>While compiling the <code>std::visit()</code> call, t the lambda gets instantiated into <img src="https://latex.codecogs.com/png.latex?3"> separate functions:</p>
</section>
<section id="the-pros-and-cons-of-stdvariant-polymorphism" class="level2">
<h2 class="anchored" data-anchor-id="the-pros-and-cons-of-stdvariant-polymorphism">The pros and cons of <code>std::variant</code> polymorphism</h2>
<p>Pros:</p>
<ul>
<li>You don’t need common base types.</li>
<li>You don’t have to use pointers for inhomogenous collections.</li>
<li>No need for <code>virtual</code> member functions.</li>
<li>Value semantics(no access of freed memory or memory leaks).</li>
<li>Elements in a vector are stored in contiguous memory locations. You don’t have to chase pointers in heap memory, resulting in fewer cache misses.</li>
</ul>
<p>Constraints and drawbacks:</p>
<ul>
<li>A closed set of types(you have to know all the alternatives at compile-time).</li>
<li>Elements of the vector all have the size of the biggest element type(an issue if the element sizes differ a lot).</li>
<li>Copying elements might be more expensive.</li>
</ul>
</section>
<section id="examples-of-using-stdvariant" class="level2">
<h2 class="anchored" data-anchor-id="examples-of-using-stdvariant">Examples of using <code>std::variant</code></h2>


</section>
</section>

 ]]></description>
  <category>C++</category>
  <guid>http://quantdev.blog/posts/std_variant/</guid>
  <pubDate>Tue, 23 Dec 2025 00:00:00 GMT</pubDate>
  <media:content url="http://quantdev.blog/posts/std_variant/cpp.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>Storage Duration and Linkage in C++</title>
  <dc:creator>`dev::author` </dc:creator>
  <link>http://quantdev.blog/posts/storage-duration/</link>
  <description><![CDATA[ 





<section id="names-and-attributes" class="level1">
<h1>Names and Attributes</h1>
<p>In C++, a declared name can have associated attributes:</p>
<ul>
<li>Type</li>
<li>Scope</li>
<li>Storage duration</li>
<li>Linkage</li>
</ul>
</section>
<section id="source-files-and-header-files" class="level1">
<h1>Source files and header files</h1>
<p>Each C++ application or library consists of one or more source files. The C++ compiler translates <code>.cpp</code> source files to object files <code>*.o</code>, one source file at a time.</p>
<p><img src="http://quantdev.blog/posts/storage-duration/compilation_model.png" style="width:80.0%;height:80.0%"></p>
<p>The translation unit(TU) is the basic unit of compilation in C++. It is a single implementation file (<code>*.cpp</code>) together with the contents of all it’s header files.</p>
</section>
<section id="storage-duration" class="level1">
<h1>Storage Duration</h1>
<p>The storage duration of an object defines the lifetime of the storage containing the object.</p>
<p>In C++, the storage duration of the object can be:</p>
<ul>
<li>Static</li>
<li>Thread</li>
<li>Automatic</li>
<li>Dynamic</li>
</ul>
<p>For an object with <em>static</em> storage duration: - The storage is allocated at program startup. - The storage persists until the program is terminated.</p>
<p>For an object with <em>thread</em> storage duration: - The storage is allocated when the thread begins. - THe storage persists until the thread terminates.</p>
<p>For an object with automatic storage duration: - The storage is allocated when the enclosing block begins executing. This is usually upon entering the enclosing function. - The storage persists until the block terminates. This is usally upon function return.</p>
<p>For an object with dynamic storage duration: - The storage is allocated on the heap by a call to a memory allocation function e.g.&nbsp;<code>std::malloc</code>, <code>operator new</code> or the new expression. - The storage on the heap is deallocated by <code>std::free</code>, <code>operator delete</code> or the delete expression.</p>
</section>
<section id="linkage" class="level1">
<h1>Linkage</h1>
<p>The <em>linkage</em> of a name is the extent to which that name might refer to a name declared elsewhere. C++ provides for three categories of linkage:</p>
<ul>
<li>external linkage</li>
<li>internal linkage</li>
<li>no linkage</li>
</ul>
<section id="external-linkage" class="level2">
<h2 class="anchored" data-anchor-id="external-linkage">External linkage</h2>
<p>A given name declared with external linkage denotes the same entity across all translation units in a program.</p>
<p>In the below example, <code>total</code> in each translation unit has external linkage:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb1-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//file1.cpp</span></span>
<span id="cb1-2"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">extern</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> total <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// definition</span></span>
<span id="cb1-3"></span>
<span id="cb1-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//file2.cpp</span></span>
<span id="cb1-5"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">extern</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> total<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>       <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// declaration for the same object</span></span></code></pre></div></div>
<p><code>total</code> is defined in <code>file1.cpp</code>. It has <code>extern</code> on it, which means external linkage. It is a definition, it does have an initial value <code>0</code>. In the second implementation file <code>file2.cpp</code>, it does not have an initializer, so its just a declaration. Those two things refer to the same variable. After separate compiling both <code>file1.cpp</code> and <code>file2.cpp</code> into <code>file1.o</code> and <code>file2.o</code> and linking them together, there’s going to be only one <code>total</code> in this executable.</p>
</section>
<section id="internal-linkage" class="level2">
<h2 class="anchored" data-anchor-id="internal-linkage">Internal linkage</h2>
<p>A given name declared with internal linkage denotes the same entity <strong><em>within a single translation unit</em></strong>.</p>
<p>A variable with internal linkage can be declared multiple times within a single translation unit and they all wind up referring to the same thing. But, nobody outside the translation unit can refer to those things with internal linkage.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb2-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// file1.cpp</span></span>
<span id="cb2-2"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">static</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> total <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// definition of total </span></span>
<span id="cb2-3">                        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// with internal linkage</span></span>
<span id="cb2-4">    </span>
<span id="cb2-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// file2.cpp</span></span>
<span id="cb2-6"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">extern</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> total<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>       <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// declaration for </span></span>
<span id="cb2-7">                        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// a different object</span></span></code></pre></div></div>
<p>In <code>file2.cpp</code> you have a declaration of <code>total</code> with external linkage and that says, *“Hey, I don’t have any storage, I need it from somewhere else!”. But, it can’t get it from <code>file1.cpp</code>. <code>file1.cpp</code> does not have external linkage. If you try to build this program, because that’s an unsatisfied reference <code>file2.cpp</code>, you’d probably get a link error. At link time, it would say, I don’t see a definition for <code>total</code> to satisfy.</p>
<p>So, what we need is a third one - <code>file3.cpp</code>. The previous example needs the <code>total</code> in <code>file3.cpp</code> to link:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb3-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// file1.cpp</span></span>
<span id="cb3-2"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">static</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> total <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// a definition for total</span></span>
<span id="cb3-3">                        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// with internal linkage</span></span>
<span id="cb3-4"></span>
<span id="cb3-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// file2.cpp</span></span>
<span id="cb3-6"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">extern</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> total<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>       <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// a declaration that refers to </span></span>
<span id="cb3-7">                        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// the total in file3.cpp</span></span>
<span id="cb3-8"></span>
<span id="cb3-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// file3.cpp</span></span>
<span id="cb3-10"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> total<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>              <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// a definition for the object</span></span>
<span id="cb3-11">                        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// referenced in file2.cpp</span></span></code></pre></div></div>
<p>The <code>total</code> in <code>file2.cpp</code> refers to the object in <code>file3.cpp</code>. To summarize, there are two <code>total</code> objects in all - one internal to <code>file1.cpp</code> and one that’s shared by <code>file2</code> and <code>file3</code> via external linkage.</p>
</section>
<section id="no-linkage" class="level2">
<h2 class="anchored" data-anchor-id="no-linkage">No linkage</h2>
<p>Local variables have no linkage. Suppose you have two functions <code>f()</code> and <code>g()</code>. Each have a local variable named <code>total</code>. Think about it. Is there any way, you can write a declaration for <code>total</code> anywhere else in the program that will at link time become a reference to one of those <code>total</code>s?</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb4-1"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb4-2">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> total<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// a definition</span></span>
<span id="cb4-3"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb4-4"></span>
<span id="cb4-5"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> g<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb4-6">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> total<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// a definition for a different object</span></span>
<span id="cb4-7"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>No, you can’t do that. Those <code>total</code>s have automatic storage. They are not statically allocated. Because they don’t have a fixed location, there’s no way the linker can can link them. The only things that can have linkage, are things that have a fixed location - functions and objects with static storage.</p>
</section>
</section>
<section id="a-conceptual-model" class="level1">
<h1>A conceptual model</h1>
<p>In a release build, the <strong><em>linker sees names only if they have external linkage.</em></strong> Names that have internal linkage or no linkage are useful for symbolic debugging, but the linker does not use them when it is combining <code>*.o</code> object files together to produce an executable.</p>
<ul>
<li><p>Names <strong><em>defined</em></strong> with external linkage in a translation unit become definitions in the compiled object module.</p></li>
<li><p>Names <strong><em>declared</em></strong> with external linkage but not defined in a translation unit become <strong><em>refs</em></strong> in the compiled object module. But, only if they are used in that translation unit.</p></li>
</ul>
<p>In a release build, the <strong><em>compiler discards names declared with internal or no linkage</em></strong> at the end of compilation.</p>
</section>
<section id="storage-class-specifiers-and-functions" class="level1">
<h1>Storage class specifiers and functions</h1>
<p>By default functions at namespace scope have external linkage.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb5-1"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span></code></pre></div></div>
<p>Adding the keyword <code>extern</code> to a function declaration at file or namespace(global) scope has no effect:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb6-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> demo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-2">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">extern</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb6-3"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>Class members in C++ have external linkage by default.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb7-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> Widget<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb7-3">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>     <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// f has external linkage</span></span>
<span id="cb7-4"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>You commonly place class definitions in header files. And you include those all over the place and create objects that type and call member functions on them and at nowhere did you say that these things were extern. You just implicitly treat them as if they are. They have <code>extern</code> linkage by default.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb8-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> Widget<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb8-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb8-3">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>     <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// f has external linkage</span></span>
<span id="cb8-4">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// extern int g(int);   // error: can't use extern here</span></span>
<span id="cb8-5"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>
<p>Adding an <code>extern</code> to a declaration at class scope is an error. Class member functions can never have anything but external linkage by default.</p>
<p>Declaring a free-standing function <strong><em><code>static</code> at file or namespace scope affects its linkage.</em></strong></p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb9-1"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">static</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>      <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// f has internal linkage</span></span></code></pre></div></div>
<p>This is not so for C++ class member functions.</p>
<p>Declaring a C++ class member function <code>static</code> <strong><em>does not</em></strong> affect its linkage.</p>
<p>It eliminates the function’s implicitly declared <strong><em><code>this</code> parameter.</em></strong></p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb10-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> Widget<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb10-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb10-3">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">static</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>      <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// f has external linkage</span></span>
<span id="cb10-4">                            <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// but has no `this`</span></span>
<span id="cb10-5"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>
</section>
<section id="storage-class-specifiers-and-objects" class="level1">
<h1>Storage class specifiers and objects</h1>
<p>Objects at file or namespace scope always have static storage:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb11-1">                    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// linkage=     storage=</span></span>
<span id="cb11-2"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">static</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> j<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>       <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// internal     static</span></span>
<span id="cb11-3"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">extern</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> j<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>       <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// external     static</span></span>
<span id="cb11-4"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> k<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>              <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// external     static</span></span>
<span id="cb11-5"></span>
<span id="cb11-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> demo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb11-7">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">static</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> j<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// internal     static</span></span>
<span id="cb11-8">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">extern</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> j<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// external     static</span></span>
<span id="cb11-9">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> k<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>          <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// external     static</span></span>
<span id="cb11-10"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>
<p>In this case, the storage-class specifier only affects the linkage.</p>
<p>Objects at local scope can have almost any storage duration or linkage:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb12-1"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb12-2"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb12-3">                    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// linkage=     storage=</span></span>
<span id="cb12-4">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">extern</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ?            static</span></span>
<span id="cb12-5">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">static</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> j<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// No           static</span></span>
<span id="cb12-6">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> m<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>          <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// No           automatic</span></span>
<span id="cb12-7"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>For a name declared as <code>extern</code> at the file, namespace or local scope:</p>
<ul>
<li>The name has <strong><em>internal linkage if previously declared with internal linkage in a visible declaration</em></strong>.</li>
<li>Otherwise, it has external linkage.</li>
</ul>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb13-1"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">static</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> foo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// internal linkage</span></span>
<span id="cb13-2"></span>
<span id="cb13-3"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb13-4">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">extern</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> foo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// internal linkage</span></span>
<span id="cb13-5">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">extern</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> bar<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// external linkage</span></span>
<span id="cb13-6"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
</section>
<section id="references" class="level1">
<h1>References</h1>
<ul>
<li><em><a href="https://www.youtube.com/watch?v=cpkDQaYttR4">Back to Basics: Compiling and Linking</a> by Ben Saks, CppCon 2021</em></li>
</ul>


</section>

 ]]></description>
  <category>C++</category>
  <guid>http://quantdev.blog/posts/storage-duration/</guid>
  <pubDate>Mon, 22 Dec 2025 00:00:00 GMT</pubDate>
  <media:content url="http://quantdev.blog/posts/storage-duration/cpp.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>auto type deduction rules</title>
  <dc:creator>`dev::author` </dc:creator>
  <link>http://quantdev.blog/posts/auto_type_deduction_rules/</link>
  <description><![CDATA[ 





<section id="introduction" class="level1">
<h1>Introduction</h1>
<p>This weekend, I tried to solve a fun puzzle - <a href="https://www.volatileint.dev/posts/auto-type-deduction-gauntlet/">the C++ <code>auto</code> type deduction gauntlet</a> and thought of creating a quick cheatsheet on <code>auto</code> type deduction rules. I encourage you to give it a shot.</p>
<p><code>auto</code> is a placeholder type that gets replaced typically by deduction from an initializer.</p>
<p>Whenever you have:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb1-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>some_modifiers<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> expression<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
<p>you have three general cases:</p>
<ul>
<li><code>auto x</code> : The object being assigned is allowed to decay. We strip the RHS <code>expression</code> of all CV-qualifiers such as <code>const</code> and reference modifiers <code>&amp;</code> to deduce the <em>by-value</em> type of <code>x</code>.</li>
<li><code>auto&amp; x</code> or <code>auto&amp;&amp; x</code> : It preserves references and CV-qualifiers.</li>
<li><code>const auto&amp; x</code> : We specify the qualifiers, <code>auto</code> simply deduces the base type.</li>
</ul>
<p>There is special treatment for expressions that are functions or arrays:</p>
<ul>
<li>When initializing a reference(<code>auto&amp;</code>), array/function types are preserved.</li>
<li>Otherwise, it <em>decays</em> to a pointer before type deduction.</li>
</ul>
</section>
<section id="exercises-to-flex-your-understanding-of-auto-deduction-rules" class="level1">
<h1>Exercises to flex your understanding of <code>auto</code> deduction rules</h1>
<p>Let’s determine for each of the problems:</p>
<ul>
<li>The deduced type</li>
<li>The value category</li>
<li>What CV qualifiers are applicable</li>
</ul>
<p>As the author of the puzzles states, let’s note that these are meant to test your understanding and some examples won’t compile.</p>
<section id="basics" class="level2">
<h2 class="anchored" data-anchor-id="basics">Basics</h2>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb2-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
<p>This is fairly straight-forward. The deduced type is <code>int</code>. The value category of <code>v</code> is <em>lvalue</em>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb3-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
<p>Floating-point values default to the larger <code>double</code>, rather than <code>float</code>. The value category of <code>v</code> is <em>lvalue</em>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb4-1"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb4-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
<p>The deduced type is <code>int</code> and the value category of <code>v</code> is <em>lvalue</em>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb5-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">uz</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>
<p>The <code>u</code> suffix is used for unsigned integer literals and the <code>z</code> suffix is used for the signed version of <code>std::size_t</code>. The suffix <code>uz</code> deduces to <code>std::size_t</code>.</p>
<p>The type <code>size_t</code> is an implementation-defined unsigned integer type that is large enough to contain the size in bytes of any object.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb6-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> w<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.1</span></span></code></pre></div></div>
<p>I didn’t get this puzzle. But, this will fail to compile. All types in an expression defined with <code>auto</code> have be the same.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb7-1"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
<p><code>&amp;</code> is the address-of operator. So, the type of <code>v</code> is deduced as pointer-to-int <code>int*</code>. The value category of <code>v</code> is <em>lvalue</em>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb8-1"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">];</span></span>
<span id="cb8-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
<p><code>x</code> is an array of <img src="https://latex.codecogs.com/png.latex?5"> <code>int</code>s, its type is <code>int [5]</code>. C-style arrays decay to a pointer. So, the type of <code>v</code> is <code>int*</code>. <code>v</code> is an <em>lvalue</em>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb9-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
<p><code>nullptr</code> is a value of type <code>std::nullptr_t</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb10-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>
<p><img src="https://latex.codecogs.com/png.latex?1">, <img src="https://latex.codecogs.com/png.latex?2"> and <img src="https://latex.codecogs.com/png.latex?3"> are <code>int</code>s. So, the type of <code>v</code> is deduced as <code>std::initializer_list&lt;int&gt;</code>. If the curly-braced initializer list were <code>{1, 2.5, 4}</code>, type deduction would fail, because we require all types in an initializer list to be the same.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb11-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>
<p>Curly braced direct initialization only works with a single scalar value e.g.&nbsp;<code>auto v{1}</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb12-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">17</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>
<p>The type of <code>x</code> is deduced as <code>std::initializer_list&lt;int&gt;</code>.</p>
<p>To summarize:</p>
<ul>
<li><code>auto</code> + copy list initialization : If all elements are of type <code>T</code>, <code>auto</code> is deduced as <code>std::initializer_list&lt;T&gt;</code>.</li>
<li><code>auto</code> + direct list initialization :
<ul>
<li><img src="https://latex.codecogs.com/png.latex?1"> element in braces <img src="https://latex.codecogs.com/png.latex?%5Cimplies"> <code>auto</code> deduces the type of element by-value.</li>
<li><img src="https://latex.codecogs.com/png.latex?%3E1"> element <img src="https://latex.codecogs.com/png.latex?%5Cimplies"> error(ill-formed).</li>
</ul></li>
</ul>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb13-1"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> foo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb13-2">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb13-3"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb13-4"></span>
<span id="cb13-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> foo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
<p><code>v</code> is deduced as a function pointer, <code>int (*) int</code>. According to the C++ standard, a function is an object that occupies memory storage and has a lifetime. Hence, <code>foo</code> is an <em>lvalue</em> expression.</p>
</section>
<section id="intermediate" class="level2">
<h2 class="anchored" data-anchor-id="intermediate">Intermediate</h2>
<p>We now explore how references and CV-qualifiers are handled.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb14-1"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">volatile</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb14-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
<p>We strip all modifiers off <code>x</code>, so that results in an <code>int</code>. Thus, <code>auto</code> is deduced as <code>int</code>. <code>auto</code> always drops top-level CV qualifiers.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb15-1"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">volatile</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb15-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
<p>I didn’t quite get this one. It turns out that CV qualifiers applied to pointed-to. So, type of <code>x</code> is deduced as <code>volatile const int*</code>. The next code snip also shows the same:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb16-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;cassert&gt;</span></span>
<span id="cb16-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;type_traits&gt;</span></span>
<span id="cb16-3"></span>
<span id="cb16-4"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb16-5">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb16-6">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb16-7">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static_assert</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>is_same_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">decltype</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&gt;);</span></span>
<span id="cb16-8">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb16-9"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/hb39vqYeE">Compiler Explorer</a></p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb17-1"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb17-2"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb17-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
<p><code>y</code> is an <em>lvalue reference</em> to <code>x</code>. The type of <code>y</code> decays to <code>int</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb18-1"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb18-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
<p>The type of <code>v</code> is deduced as <code>int&amp;</code>. <code>v</code> is an <em>lvalue reference</em>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb19" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb19-1"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">];</span></span>
<span id="cb19-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
<p><code>auto</code> is deduced as <code>int [5]</code>. The type of <code>v</code> is a reference to an array of <img src="https://latex.codecogs.com/png.latex?5"> <code>int</code>s.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb20-1"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> foo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb20-2">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb20-3"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb20-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> foo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
<p>Functions are <em>lvalues</em> and the function name is a pointer to function object in memory. CV-qualifiers on parameters are thrown away during function resolution. Hence, <code>auto</code> is deduced as <code>int (*)(int)</code>.</p>
</section>
<section id="advanced" class="level2">
<h2 class="anchored" data-anchor-id="advanced">Advanced</h2>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb21" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb21-1"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb21-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
<p><code>auto&amp;&amp; v</code> is a forwarding reference. <code>x</code> is an <em>lvalue</em> and <em>lvalues</em> bind to <em>lvalue</em> references. Here, we get an <em>lvalue reference</em>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb22" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb22-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> </span>
<span id="cb22-2">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb22-3"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb22-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span></code></pre></div></div>
<p>The return value of the function call is a <em>prvalue</em>. It will bind to an <em>rvalue reference</em>. So, the type of <code>v</code> is deduced as <code>int&amp;&amp;</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb23" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb23-1"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb23-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[&amp;]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> </span>
<span id="cb23-3">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb23-4"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb23-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span></code></pre></div></div>
<p>The result of the function call <code>y()</code> is an <em>lvalue</em>, so the type of <code>v</code> is deduced to be <code>int&amp;</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb24" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb24-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Foo <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{};</span></span>
<span id="cb24-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Foo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{};</span></span></code></pre></div></div>
<p>The call to the constructor <code>Foo{}</code> creates a temporary <code>Foo</code> instance - a <em>prvalue</em>. Hence, the type of <code>v</code> is deduced as <code>Foo&amp;&amp;</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb25" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb25-1"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> param<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb25-2"></span>
<span id="cb25-3"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">22</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb25-4"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> cx <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb25-5"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> rx <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb25-6"></span>
<span id="cb25-7">f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// [1]</span></span>
<span id="cb25-8">f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>cx<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// [2]</span></span>
<span id="cb25-9">f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>rx<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// [3]</span></span></code></pre></div></div>
<p><code>auto&amp;</code> preserves references and CV-qualifiers. In the function call <code>f(x)</code>, the type of param is deduced as <code>int&amp;</code>. In the function call <code>f(cx)</code>, the type of param is deduced as <code>const int&amp;</code>. In the function call <code>f(rx)</code>, the type of param is deduced as <code>const int&amp;</code>.</p>
<p>Solving these <code>auto</code> type deduction puzzles prompted me to go watch <a href="https://www.youtube.com/watch?v=wQxj20X-tIU&amp;t=1769s">Scott Meyer’s talk on type deduction from CppCon 2014</a>. At 25:10, he says:</p>
<blockquote class="blockquote">
<h5 id="it-is-important-to-distinguish-between-an-expression-that-is-const-and-an-expression-that-contains-const." class="anchored"><em>It is important to distinguish between an expression that is <code>const</code>, and an expression that contains <code>const</code>.</em></h5>
</blockquote>
<p>The most common place this issue occurs, is when we are dealing with pointers. Observe the following code snip:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb26" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb26-1"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> cpi<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb26-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> p1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> cpi<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb26-3"></span>
<span id="cb26-4"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> pci<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb26-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> p2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> pci<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb26-6"></span>
<span id="cb26-7"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> cpci<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb26-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> p3 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> cpci<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
<p>You can have a constant pointer-to-<code>int</code>, in which case the expression is a constant. Or you can have a pointer-to-<code>const</code>, in which case you have a expression containing <code>const</code>. And you can have a constant pointer to <code>const</code>, which is a constant expression that contains a <code>const</code>.</p>
<p>When deducing <code>auto</code>, we are deducing <em>by-value</em>. The top-level <code>const/volatile</code> is dropped. Applying this rule, we have the following:</p>
<ul>
<li>The type of <code>p1</code> is deduced as <code>int*</code>.</li>
<li>The type of <code>p2</code> is deduced as <code>const int*</code>.</li>
<li>The type of <code>p3</code> is deduced as <code>const int*</code>.</li>
</ul>
<p>THe fact that <code>p3</code> is <code>const</code> is ignored. The fact that <code>p3</code> contains <code>const</code> is not ignored.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb27" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb27-1"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">22</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb27-2"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> pcx <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb27-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> ppcx <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>pcx<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
<p>The expression <code>&amp;pcx</code> contains <code>const</code>. So, the type of <code>ppcx</code> is deduced as <code>const int**</code>.</p>
</section>
<section id="lambda-capture-type-deduction" class="level2">
<h2 class="anchored" data-anchor-id="lambda-capture-type-deduction">Lambda capture type deduction</h2>
<p>The captures of a <a href="https://quantdev.blog/posts/lambda_functions/">lambda expression</a> defines the outside variables that are accessible from within the lambda function body. There are three kinds of lambda capture:</p>
<ul>
<li><em>By reference</em>: Uses type deduction rules for reference parameters.</li>
<li><em>Init capture</em>: Uses <code>auto</code> type deduction rules.</li>
<li><em>By value</em>: CV qualifiers are retained.</li>
</ul>
<p>Recall that, C++14 allows <a href="https://quantdev.blog/posts/lambda_functions/#captures-with-an-initialiser">init-captures</a>. You can create new data members in the closure type on the fly. Then, we can access those variables inside the lambda.</p>
<p>The key takeaway is that the simple <em>by-value</em> capture <img src="https://latex.codecogs.com/png.latex?%5Cneq"> by-value init capture. Observe the following code snip:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb28" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb28-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb28-2">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> cx<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb28-3">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> func <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>cx<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">](){};</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// by-value capture</span></span>
<span id="cb28-4">                            <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// The type of `cx` is `const int`</span></span>
<span id="cb28-5"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb28-6"></span>
<span id="cb28-7"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb28-8">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> cx<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb28-9">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> func <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>cx <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> cx<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">](){};</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// init-capture</span></span>
<span id="cb28-10">                                 <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// The type of `cx` is `int`</span></span>
<span id="cb28-11"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>This is an interesting wrinkle that exists for <em>by-value</em> lambda captures.</p>
<p>Observe the following code snip:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb29" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb29-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb29-2">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> cx<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb29-3">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> func <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>cx<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]{</span> cx <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span>   <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// error</span></span>
<span id="cb29-4">    func<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb29-5"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>In this lambda expression, <code>cx</code> is captured by value. The type <code>cx</code> is deduced as <code>int</code>. Recall, that the function call operator is <code>const</code>. You can’t modify a non-<code>const</code> member variable inside a <code>const</code> member function. So, this would be a compile error.</p>
<p>If you declare your lambda as <code>mutable</code>, it means that the function call operator is not <code>const</code>. Observe the next code snip. If we have a local variable which is <code>const</code> and we capture it by value, then it will be copied into the class as a <code>const</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb30" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb30-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb30-2">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> cx<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb30-3">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> func <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>cx<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mutable</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> cx <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// still error</span></span>
<span id="cb30-4"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>My next example, is a real mind-bender borrowed from slide 31 of Scott Meyer’s talk. Observe the code snip below. What is the deduced type of <code>param</code>?</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb31" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb31-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb31-2"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> param<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb31-3"></span>
<span id="cb31-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Widget<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{};</span></span>
<span id="cb31-5"></span>
<span id="cb31-6"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>vector<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Widget<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> createVec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb31-7"></span>
<span id="cb31-8"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> vw <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> createVec<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb31-9"></span>
<span id="cb31-10"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(!</span>vw<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>empty<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()){</span></span>
<span id="cb31-11">    f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(&amp;</span>vw<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]);</span></span>
<span id="cb31-12"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>First, the function <code>createVec()</code> returns a <code>vector&lt;Widget&gt;</code> by value. <code>auto</code> deduction rules apply. So, the type of <code>vw</code> is deduced as <code>const std::vector&lt;Widget&gt;</code>. So, all elements of the vector are considered immutable and are of type <code>const Widget</code>. If the vector is not empty, <code>f</code> receives the address of the element of the vector. This is a pointer-to-<code>const</code> <code>Widget</code>, it contains <code>const</code>. Thus, the base type <code>T</code> is deduced as <code>Widget* const</code>. <code>param</code> is a <code>const</code> reference to <code>T</code>, so the type of <code>param</code> is deduced as <code>const Widget* const &amp;</code>.</p>
</section>
<section id="decltype-type-deduction" class="level2">
<h2 class="anchored" data-anchor-id="decltype-type-deduction"><code>decltype</code> type deduction</h2>
<ul>
<li>If you apply <code>decltype</code> to a (unparenthesized) name, it will give you the declared type of that name. It’s not the same as <code>auto</code>, because in <code>auto</code> deduction, top-level CV-qualifiers are dropped.</li>
<li>If the argument is any other expression of type <code>T</code>:
<ul>
<li>If the value category of the expression is <em>xvalue</em>, then <code>decltype</code> yields <code>T&amp;&amp;</code>.</li>
<li>If the value category of the expression is a <em>prvalue</em>, then <code>decltype</code> yield <code>T</code>.</li>
<li>If the value category of the expression is a <em>lvalue</em>, then <code>decltype</code> yields <code>T&amp;</code>.</li>
</ul></li>
</ul>
<p><code>decltype</code> merely inspects the type of the expression statically at compile-time. It does <strong>not</strong> evaluate the expression. Let’s try and solve a few more puzzles.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb32" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb32-1"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb32-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">decltype</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span></code></pre></div></div>
<p>The expression <code>(x)</code> is an <em>lvalue</em>, so <code>decltype(auto)</code> deduces to an lvalue reference of type <code>int&amp;</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb33" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb33-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Foo <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{};</span></span>
<span id="cb33-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">decltype</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Foo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{};</span></span></code></pre></div></div>
<p>The expression <code>Foo{}</code> is a <em>prvalue</em>. For any prvalue expression <code>e</code>, <code>decltype(e)</code> evaluates to the type of <code>e</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb34" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb34-1"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb34-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">decltype</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>move<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span></code></pre></div></div>
<p>The expression <code>std::move(x)</code> is an <em>xvalue</em>. The type of <code>v</code> is deduced as <code>int&amp;&amp;</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb35" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb35-1"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> foo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb35-2">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb35-3"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb35-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">decltype</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> foo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
<p><code>foo</code> is an <em>lvalue</em> of type <code>int (*) (int)</code>. So, the type of <code>v</code> is deduced as <code>int (*)(int)</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb36" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb36-1"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> foo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb36-2">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb36-3"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb36-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">decltype</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>foo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span></code></pre></div></div>
<p><code>(foo)</code> is an <em>lvalue</em> expression of type <code>int (*) (int)</code>. So, the type of <code>v</code> is deduced to be <code>int (*) (int) &amp;</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb37" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb37-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> Base <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb37-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb37-3">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> foo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb37-4">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">this</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb37-5">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb37-6"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb37-7"></span>
<span id="cb37-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> Derived <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> Base <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb37-9"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb37-10"></span>
<span id="cb37-11">Derived d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb37-12"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> v <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> d<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>foo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span></code></pre></div></div>
<p><code>Derived</code> inherits <code>foo()</code> from <code>Base</code>, so you can access <code>Base::foo()</code> using a <code>Derived</code> object. Further, <code>this</code> in <code>Base::foo()</code> returns a <code>Base*</code>, so the type of <code>v</code> is deduced as <code>Base*</code>.</p>
</section>
<section id="challenge-puzzle" class="level2">
<h2 class="anchored" data-anchor-id="challenge-puzzle">Challenge Puzzle</h2>
<p>Observe the code snippet below. What gets printed?</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb38" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb38-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Headers</span></span>
<span id="cb38-2"></span>
<span id="cb38-3"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb38-4">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb38-5">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">decltype</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">((</span>x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))</span> y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb38-6">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>cout <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;&lt;</span> x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb38-7"></span>
<span id="cb38-8">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb38-9"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>For more such puzzles, visit <a href="https://getcracked.io">getcracked.io</a>.</p>
</section>
</section>
<section id="references" class="level1">
<h1>References</h1>
<ul>
<li><em><a href="https://www.youtube.com/watch?v=wQxj20X-tIU&amp;t=1769s">Type deduction and why you care</a> by Scott Meyers</em>.</li>
<li><em><a href="https://www.youtube.com/watch?v=E5L66fkNlpE"><code>decltype(auto)</code>: An overview of How, Why and Where</a> by Jason Turner</em>.</li>
</ul>


</section>

 ]]></description>
  <category>C++</category>
  <guid>http://quantdev.blog/posts/auto_type_deduction_rules/</guid>
  <pubDate>Sun, 21 Dec 2025 00:00:00 GMT</pubDate>
  <media:content url="http://quantdev.blog/posts/auto_type_deduction_rules/cpp.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>C++ Type erasure</title>
  <dc:creator>`dev::author` </dc:creator>
  <link>http://quantdev.blog/posts/type-erasure/</link>
  <description><![CDATA[ 





<section id="introduction" class="level1">
<h1>Introduction</h1>
<p>Once you instantiate a <code>std::function</code> object, how is it, that <em>you are able to stick objects of different actual types e.g.&nbsp;an anonymous lambda, a free-standing function or a function-pointer (with only a common function signature)</em> to it? This is achieved through <strong>type erasure</strong>.</p>
<p>Type erasure is a programming technique by which the explicit type information is removed from the program. It is a type of <em>abstraction</em> that ensures that the program does not explicitly depend on some of the data-types. You might wonder, how is it, that a program is written in a strongly typed language but does not use the actual types?</p>
</section>
<section id="how-does-type-erasure-look-like" class="level1">
<h1>How does type erasure look like?</h1>
<p>The ultimate type-erased object in C++ is <code>std::function</code>. Another one is <code>std::any</code>. Consider the following code snip:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb1-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;print&gt;</span></span>
<span id="cb1-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;functional&gt;</span></span>
<span id="cb1-3"></span>
<span id="cb1-4"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> print_num<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb1-5">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-6"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-7"></span>
<span id="cb1-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> display_lambda <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb1-9">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-10"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb1-11"></span>
<span id="cb1-12"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> PrintFunctor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-13">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb1-14">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-15">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-16"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb1-17"></span>
<span id="cb1-18"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb1-19"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-20">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>function<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)&gt;</span> f_print_num <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> print_num<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-21">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>function<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)&gt;</span> f_display_lambda <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> display_lambda<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-22">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>function<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)&gt;</span> f_print_functor <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> PrintFunctor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{};</span></span>
<span id="cb1-23"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/1Tz7dWqM7">Compiler Explorer</a></p>
<p>The free-standing function <code>print_num</code>, the lambda function <code>diplay_lambda</code> and the functor <code>PrintFunctor</code> are objects with different types. So, the type of object being assigned to the <code>std::function</code> changed, but on the left hand side we have the same type. <code>std::function&lt;void(int)&gt;</code> can store any of these callable objects. Somehow, we can stick all these different types into it.</p>
<p>If you look at it from the design point of view, what it does is, it abstracts away all the behavior of the type you erase, except the set of behaviors you consider relevant. It’s a very flexible abstraction. In my case, I say, what’s relevant is, I can invoke this type with a <code>int</code> and I get back a <code>void</code>.</p>
</section>
<section id="type-erasure---the-basic-mechanics" class="level1">
<h1>Type erasure - the basic mechanics</h1>
<section id="step-1---how-to-write-a-container-that-holds-unrelated-types" class="level2">
<h2 class="anchored" data-anchor-id="step-1---how-to-write-a-container-that-holds-unrelated-types">Step 1 - How to write a container that holds unrelated types?</h2>
<p>On cppreference.com, <code>std::function</code> is defined as follows:</p>
<div class="callout callout-style-simple callout-none no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb2-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> R<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Args <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb2-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> function<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>R<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...)&gt;;</span></span></code></pre></div></div>
<p><em>The class template <code>std::function</code> is a general-purpose polymorphic function wrapper.</em></p>
</div>
</div>
</div>
<p><code>std::function</code> has to be polymorphic, meaning it has to be able to hold completely unrelated types. They don’t have to be bound by an inheritance-hierarchy or any other sort of thing.</p>
<p>Our end-goal looks something like this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb3-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> MagicFunctionContainer</span>
<span id="cb3-2"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{};</span></span>
<span id="cb3-3"></span>
<span id="cb3-4">MagicFunctionContainer f1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> print_num<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-5">MagicFunctionContainer f2 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">({},</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb3-6">MagicFunctionContainer f3 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> PrintFunctor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{};</span></span></code></pre></div></div>
<p>We should be able to assign different objects of types like a free-standing function, a lambda expression or a functor to this <code>MagicFunctionContainer</code>.</p>
<p>Let’s start with designing a container, which is constructible from completely unrelated types:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb4-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> MagicFunctionContainer<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb4-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Func<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb4-3">    MagicFunctionContainer<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Func<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> func<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb4-4">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_func</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>forward<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Func<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>func<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)}</span> </span>
<span id="cb4-5">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb4-6"></span>
<span id="cb4-7">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb4-8">        <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_func</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb4-9">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb4-10"></span>
<span id="cb4-11">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">private</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb4-12">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//void(*)(int) m_func;   // we need to think</span></span>
<span id="cb4-13">                             <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// of m_func's type</span></span>
<span id="cb4-14"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>
<p>We see that, there’s this container called <code>MagicFunctionContainer</code>. The most important thing to note is that, its constructor is now a templated constructor, so you can pass any type into the <code>MaginFunctionContainer</code> constructor, and it simply forwards the object <code>func</code> into <code>m_func</code>. We need to think, what the type of <code>m_func</code> is. We see that this function container also implements a function call operator <code>operator()</code>, which accepts an integer and returns type <code>void</code>. So, when this function container object is invoked with an integer <code>i</code>, it simply calls <code>m_func(i)</code> under the hood.</p>
<p>As long as we have defined the type of <code>m_func</code>, and its the correct type, this code satisfies our requirements. We now have a container, that can be constructed from completely unrelated types. How do we store these unrelated types? How do we now define what the type of <code>m_func</code> should be? The answer to this puzzle is step-2 of our design.</p>
</section>
<section id="step-2---can-m_func-be-a-polymorphic-pointer-to-a-place-on-the-heap-that-will-hold-these-unrelated-types" class="level2">
<h2 class="anchored" data-anchor-id="step-2---can-m_func-be-a-polymorphic-pointer-to-a-place-on-the-heap-that-will-hold-these-unrelated-types">Step 2 - Can <code>m_func</code> be a polymorphic pointer to a place on the heap that will hold these unrelated types?</h2>
<p>The classic type erasure pattern can be realized by first coding up a <em>type-agnostic interface</em> (a <code>Concept</code> class). Then we use an <code>Impl</code> class that wraps up the concrete type &amp; provides the <em>type-dependent implementation</em>. Finally, we use dynamic polymorphism via virtual functions, but the caller only sees the interface.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb5-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Type erasure 101</span></span>
<span id="cb5-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;iostream&gt;</span></span>
<span id="cb5-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;memory&gt;</span></span>
<span id="cb5-4"></span>
<span id="cb5-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb5-6">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Concept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb5-7">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">virtual</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-8">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">virtual</span> Concept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){}</span></span>
<span id="cb5-9">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb5-10"></span>
<span id="cb5-11">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Callable<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb5-12">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Impl<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb5-13"></span>
<span id="cb5-14">        Impl<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> Callable<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> callable<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> </span>
<span id="cb5-15">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_callable</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>callable<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb5-16">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb5-17"></span>
<span id="cb5-18">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb5-19">            <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_callable</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb5-20">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb5-21">        </span>
<span id="cb5-22">        Callable <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_callable</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-23">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb5-24"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>
<p>Each time I get any new type <code>Callable</code>, I am creating an implementation <code>Impl&lt;Callable&gt;</code>, and passing that object into this new type.</p>
<p>Any type <code>Callable</code> that implements <code>operator()(int)</code> can be stored in <code>Impl&lt;Callable&gt;</code>. And <code>Impl&lt;Callable&gt;</code> inherits from <code>Concept</code>.</p>
<p>Now, what we’ve achieved so far is, that any <code>Impl&lt;Callable&gt;</code> object, as long as <code>Callable</code> implements the function call operator <code>operator()</code>, accepts an <code>int</code>, returns <code>void</code> can be assigned to a pointer to <code>Concept</code>, <code>Concept*</code>. Remember, all types <code>Impl&lt;Callable_1&gt;</code>, <code>Impl&lt;Callable_2&gt;</code>, …, <code>Impl&lt;Callable_n&gt;</code> inherit from <code>Concept</code>.</p>
<p>We can now finish the revisit the definition of <code>MagicFunctionContainer</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb6-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> MagicFunctionContainer<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Func<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb6-3">    MagicFunctionContainer<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Func<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> func<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-4">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_func</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> Impl<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Func<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>func<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)}</span> </span>
<span id="cb6-5">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb6-6"></span>
<span id="cb6-7">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb6-8">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_func</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-9">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">throw</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>bad_function_call<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb6-10"></span>
<span id="cb6-11">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_func</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)(</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb6-12">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-13"></span>
<span id="cb6-14">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">private</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb6-15">    Concept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_func</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">nullptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span>   </span>
<span id="cb6-16"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>
<p>In the <code>MagicFunctionContainer</code>, I have still got the templated constructor. I have still got the function call operator. But, now I have type for <code>m_func</code>. <code>m_func</code> is a pointer to <code>Concept</code>. In the templated constructor, now what I’m doing is, each time I get any type <code>Func</code>, I am passing that object into this new type <code>Impl&lt;Func&gt;</code>. So, essentially a <code>Concept*</code> pointer is always pointing to an <code>Impl&lt;Func&gt;</code>.</p>
<p>As a result what happens is, although the <code>MagicFunctionContainer</code> is not templated itself, its constructor is templated and it’s <code>m_func</code> member variable is able to store different unrelated types.</p>
</section>
<section id="polishing-our-design-for-stdfunction-like-container" class="level2">
<h2 class="anchored" data-anchor-id="polishing-our-design-for-stdfunction-like-container">Polishing our design for <code>std::function</code> like container</h2>
<p>We can add some template magic and use concepts to constrain our template type parameter <code>Func</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb7-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;print&gt;</span></span>
<span id="cb7-2"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;functional&gt;</span></span>
<span id="cb7-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;memory&gt;</span></span>
<span id="cb7-4"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;concepts&gt;</span></span>
<span id="cb7-5"></span>
<span id="cb7-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-7">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> R<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb7-8">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Concept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-9">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">virtual</span> R <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()(</span>Args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-10">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">virtual</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span>Concept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){}</span></span>
<span id="cb7-11">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb7-12"></span>
<span id="cb7-13">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Func<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> R<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb7-14">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Impl <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> Concept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>R<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;{</span></span>
<span id="cb7-15">        Impl<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Func func<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb7-16">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_func</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> func <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb7-17">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb7-18"></span>
<span id="cb7-19">        R <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()(</span>Args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">override</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-20">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_func</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...);</span></span>
<span id="cb7-21">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb7-22"></span>
<span id="cb7-23">        Func <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_func</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-24">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb7-25"></span>
<span id="cb7-26">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> R<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> Args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb7-27">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> function<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-28">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb7-29">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Func<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb7-30">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">requires</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>invocable<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Func<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;</span></span>
<span id="cb7-31">        function<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Func func<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> </span>
<span id="cb7-32">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_func</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>make_unique<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Impl<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Func<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>R<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>Args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;&gt;(</span>func<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)}</span></span>
<span id="cb7-33">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb7-34"></span>
<span id="cb7-35">        R <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()(</span>Args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span> args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb7-36">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_func</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)(</span>args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...);</span></span>
<span id="cb7-37">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb7-38"></span>
<span id="cb7-39">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">private</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb7-40">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unique_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Concept<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>R<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...&gt;&gt;</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_func</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-41">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb7-42"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb7-43"></span>
<span id="cb7-44"></span>
<span id="cb7-45"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> print_num<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb7-46">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb7-47"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb7-48"></span>
<span id="cb7-49"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> display_lambda <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[](</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb7-50">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb7-51"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb7-52"></span>
<span id="cb7-53"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> PrintFunctor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-54">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb7-55">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb7-56">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb7-57"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb7-58"></span>
<span id="cb7-59"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb7-60"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-61">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>function<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> f_print_num <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> print_num<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-62">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>function<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> f_display_lambda <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> display_lambda<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-63">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>function<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> f_print_functor <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> PrintFunctor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{};</span></span>
<span id="cb7-64"></span>
<span id="cb7-65">    f_print_num<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">42</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb7-66">    f_display_lambda<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb7-67">    f_print_functor<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">17</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb7-68">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-69"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/e8rKhPzYK">Compiler Explorer</a></p>
</section>
</section>
<section id="type-safety-in-type-erasure" class="level1">
<h1>Type safety in type erasure</h1>
<p>The type erased container should have the ability to hold unrelated types. In addition to this, there is one other requirement. <em>The type erased container should retain the type information of the assigned object</em>.</p>
<p>Consider the following example:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb8-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Foo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb8-2">    Foo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Constructed Foo()"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb8-3">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span>Foo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Destructed ~Foo()"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb8-4"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb8-5"></span>
<span id="cb8-6"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> foo_ptr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> Foo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb8-7"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">delete</span> foo_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
<p>I have a type agnostic <code>foo_ptr</code> and I am assigning it an object of type <code>Foo</code>. When a <code>Foo</code> object is constructed, it prints the text <code>Constructed Foo()</code> to the console, when it is destructed, it prints <code>Destructed ~Foo()</code> to the console. Do you think this code compiles?</p>
<p><code>gcc</code> issues the following warning:</p>
<pre class="shell"><code>&lt;source&gt;: In function 'int main()':
&lt;source&gt;:11:12: warning: deleting 'void*' is undefined [-Wdelete-incomplete]
   11 |     delete foo_ptr;
      |            ^~~~~~~</code></pre>
<p>Let’s try something else:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb10-1"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unique_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> uptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> Foo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>
<p>Do you think this code builds?</p>
<p>It’s the same thing. As per the standard, deleteing a <code>void*</code> pointer is undefined behavior. In this particular case, <code>unique_ptr</code> has a static assertion built in to ensure that we don’t use a type-agnostic pointer.</p>
<pre class="shell"><code>&lt;source&gt;:11:43:   
   11 |     std::unique_ptr&lt;void&gt; uptr{ new Foo() };
      |                                           ^
/cefs/e6/e6c9babfba5a70d326be2358_gcc-trunk-20251219/include/c++/16.0.0/bits/unique_ptr.h:88:38: error: static assertion failed: can't delete pointer to incomplete type
   88 |         static_assert(!is_void&lt;_Tp&gt;::value,
      |                                      ^~~~~
  '!(bool)std::integral_constant&lt;bool, true&gt;::value' evaluates to false</code></pre>
<p>We’ve seen that raw-pointers and <code>unique_ptr</code> don’t work. How about a <code>shared_ptr</code>? Do you think this builds?</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb12-1"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>shared_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> sptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> Foo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>
<p>In this case, we see the following output:</p>
<pre class="shell"><code>Constructed Foo()
Destructed ~Foo()</code></pre>
<p>This is suprising! Is the <code>shared_ptr</code> not storing a raw pointer of <code>void*</code>, whilst the <code>unique_ptr</code> is? How does <code>shared_ptr</code> even able to delete the object correctly? Usually, once you assign a typed address <code>T*</code> to a pointer-to-void <code>void*</code>, you have lost the type information. How is <code>shared_ptr</code> still able to store the original type <code>Foo</code> in order to be able to destruct it correctly?</p>
<p>This is what we mean by type-safety in type erasure. From cppreference.com, if you look at the declarations for the <code>unique_ptr</code> and <code>shared_ptr</code>, they look something like this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb14-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> T <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> shared_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb14-2"></span>
<span id="cb14-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span></span>
<span id="cb14-4">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb14-5">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> Deleter <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>default_delete<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> unique_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div></div>
<p><code>shared_ptr</code> only has a template type parameter <code>T</code>. But, magically it also stores the object type information and called the correct destructor. <code>unique_ptr&lt;T&gt;</code> only stores the template type information.</p>
<p>The signature of the <code>shared_ptr</code> templated class kind of gives this away. It doesn’t have a deleter as a template type parameter. The deleter type is erased. In <code>shared_ptr</code> the deleter is based on the object type being passed during construction(and not the template type).</p>
</section>
<section id="type-erasure---adding-support-for-a-custom-deleter-to-the-shared_ptr" class="level1">
<h1>Type erasure - Adding support for a custom deleter to the <code>shared_ptr</code></h1>
<p>Let’s use our learnings above to add support for a custom deleter to the <code>shared_ptr</code>. The <code>shared_ptr</code> needs to be aware of the actual type being passed during construction in order to delete the object correctly. Let’s see how we can achieve that.</p>
<p>A <code>shared_ptr&lt;T1&gt;</code> can store objects of any type <code>T2</code> as long as <code>T2*</code> is convertible to <code>T1*</code>. It type erases <code>T2</code>. Upon destruction, the <code>shared_ptr</code> will call the correct destructor of type <code>T2</code>, that is the destructor of the actual object stored, instead of type <code>T1</code>.</p>
<p>Here is a quick overview of the <code>shared_ptr</code>. Typical implementations of <code>shared_ptr</code> look like as follows:</p>
<pre class="shell"><code>+-------------------+
|    shared_ptr&lt;T&gt;  |
+-------------------+
|                   |
|  +--------------+ |        +------------+
|  |   T* ptr     |-|-------&gt;|  T object  | 
|  +--------------+ |        |   (heap)   | 
|                   |        +------------+ 
|  +--------------+ |                       
|  | ControlBlock*| |        +------------------------------------------+               
|  |    cb_ptr    |-|-------&gt;|         Control Block (heap)             |
|  +--------------+ |        +------------------------------------------+
|                   |        |                                          |
+------------------+|        |  +------------------------------------+  |
                             |  |  size_t reference_count            |  |
                             |  +------------------------------------+  |
                             |                                          |
                             |  +------------------------------------+  |
                             |  |  size_t weak_count                 |  |
                             |  +------------------------------------+  |
                             |                                          |
                             |  +------------------------------------+  |
                             |  |  Deleter (custom or                |  |
                             |  |  default delete)                   |  |
                             |  +------------------------------------+  |
                             |                                          |
                             |  +------------------------------------+  |
                             |  |  Allocator (optional)              |  |
                             |  +------------------------------------+  |
                             |                                          |
                             +------------------------------------------+</code></pre>
<p>You have a <code>shared_ptr</code> of type <code>T</code>. It stores a raw underlying pointer-to-<code>T</code> and a pointer to a control block. The <code>control_block</code> is a different from the managed object. It stores the reference count, the weak count and some additional data. The custom deleter is going to delete the object type passed during <code>shared_ptr</code> construction and not the type <code>T</code>.</p>
<section id="step-1---code-up-a-container-that-can-hold-unrelated-different-types" class="level2">
<h2 class="anchored" data-anchor-id="step-1---code-up-a-container-that-can-hold-unrelated-different-types">Step 1 - Code up a container that can hold unrelated different types</h2>
<p>We start with thinking about our <code>shared_ptr</code> class. So, we write a templated constructor <code>shared_ptr(Y* ptr)</code>. You should be used to this by now - I can pass in any object to this. I later constrain this using the <code>std::is_convertible_v&lt;Y*, T*&gt;</code> type trait, to enforce that <code>Y*</code> is indeed convertible to <code>T*</code>.</p>
<p>We have another constructor that takes two parameters : a pointer to <code>Y</code> and a custom deleter.</p>
<p>Now, the pointer to <code>Y</code>, <code>Y*</code> is convertible to pointer to <code>T</code>, <code>T*</code>. So, the pointer(address) itself is simply stored in the class as a <code>T*</code> member variable. So, I have a member variable <code>T* m_underlying_ptr</code> at the bottom. The question is how do we store the original object type <code>Y*</code> and the deleter type <code>Deleter</code>. As soon as I assign <code>Y* ptr</code> to <code>T* m_underlying_ptr</code>, I have lost information about the original object type <code>Y*</code>. How do we store the deleter and the true object type <code>Y</code>?</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb16-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;iostream&gt;</span></span>
<span id="cb16-2"></span>
<span id="cb16-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb16-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> shared_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb16-5">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb16-6"></span>
<span id="cb16-7">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb16-8">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">requires</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>is_convertible_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*,</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*&gt;</span></span>
<span id="cb16-9">    shared_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb16-10">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> shared_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>default_delete<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;{})</span></span>
<span id="cb16-11">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb16-12"></span>
<span id="cb16-13">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Templated constructor</span></span>
<span id="cb16-14">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Deleter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb16-15">    shared_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Deleter deleter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb16-16">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_underlying_ptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb16-17">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ???  </span></span>
<span id="cb16-18">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb16-19"></span>
<span id="cb16-20">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Destructor</span></span>
<span id="cb16-21">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span>shared_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb16-22">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Decrement the ref-count. If m_ref_count == 0, </span></span>
<span id="cb16-23">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// delete m_underlying_ptr using deleter </span></span>
<span id="cb16-24">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb16-25"></span>
<span id="cb16-26">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Pointer like functions</span></span>
<span id="cb16-27">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;()</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb16-28">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_underlying_ptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb16-29">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb16-30"></span>
<span id="cb16-31">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">private</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb16-32">    T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_underlying_ptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb16-33"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>
</section>
<section id="step-2---coding-up-a-type-agnostic-interface-and-a-type-dependent-implementation" class="level2">
<h2 class="anchored" data-anchor-id="step-2---coding-up-a-type-agnostic-interface-and-a-type-dependent-implementation">Step 2 - Coding up a type-agnostic interface and a type-dependent implementation</h2>
<p>Let’s now write a <code>Concept</code> and <code>Impl</code> class that supports destruction using an instance of the custom <code>Impl&lt;ObjType, Deleter&gt;</code> type. We can actually define a <code>ControlBlockBase</code> and <code>ControlBlockImpl&lt;ObjType, Deleter&gt;</code> classes.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb17-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> dev <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb17-2">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Type-agnostic Concept class</span></span>
<span id="cb17-3">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> ControlBlockBase<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb17-4">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>atomic<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_ref_count</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">uz</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb17-5">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">virtual</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span>ControlBlockBase<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">default</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb17-6">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb17-7"></span>
<span id="cb17-8">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Type dependent Impl&lt;ObjType,Deleter&gt; implementation</span></span>
<span id="cb17-9">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> ObjType<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Deleter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb17-10">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> ControlBlock <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> ControlBlockBase<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb17-11">        ControlBlock<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span> ObjType<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> object_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Deleter deleter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb17-12">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_object_ptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> object_ptr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb17-13">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_deleter</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> deleter <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb17-14">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb17-15"></span>
<span id="cb17-16">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span>ControlBlock<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb17-17">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb17-18">            <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_deleter</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_object_ptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb17-19">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb17-20"></span>
<span id="cb17-21">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">private</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb17-22">        ObjType<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_object_ptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb17-23">        Deleter <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_deleter</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb17-24">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb17-25"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// namespace dev</span></span></code></pre></div></div>
<p>The <code>ControlBlock</code> inherits from <code>ControlBlockBase</code> and it is templated. <code>Concept</code> itself is not templated, but the implementation <code>control_block</code> class is. In this case, it is templated on the <code>ObjectType</code> and the <code>Deleter</code> type. The constructor <code>control_block(ObjectType*, Deleter)</code> takes two parameters - the object type and the deleter. <code>ObjectType</code> is not the type parameter of the <code>shared_ptr</code>, which is <code>T</code>, but the type of the object passed to the <code>shared_ptr()</code> during construction.</p>
<p>On destruction of the control block, it calls the deleter on a pointer to <code>ObjType</code> - the correct type. It’s not going to call the deleter on the template type. We can now, finish up with our definition of the <code>shared_ptr</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb18-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;iostream&gt;</span></span>
<span id="cb18-2"></span>
<span id="cb18-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb18-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> shared_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb18-5">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb18-6"></span>
<span id="cb18-7">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb18-8">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">requires</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>is_convertible_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*,</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*&gt;</span></span>
<span id="cb18-9">    shared_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb18-10">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> shared_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>default_delete<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;{})</span></span>
<span id="cb18-11">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb18-12"></span>
<span id="cb18-13">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Templated constructor</span></span>
<span id="cb18-14">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Deleter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb18-15">    shared_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Deleter deleter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb18-16">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_underlying_ptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb18-17">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_control_block_ptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> ControlBlock<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>Deleter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>deleter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb18-18">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb18-19"></span>
<span id="cb18-20">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Destructor</span></span>
<span id="cb18-21">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span>shared_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(){</span></span>
<span id="cb18-22">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Decrement the ref-count. If m_ref_count == 0, </span></span>
<span id="cb18-23">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// delete the control_block_ptr which will destroy the managed object </span></span>
<span id="cb18-24">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">delete</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_control_block_ptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb18-25">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb18-26"></span>
<span id="cb18-27">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Pointer like functions</span></span>
<span id="cb18-28">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">operator</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;()</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb18-29">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_underlying_ptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb18-30">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb18-31"></span>
<span id="cb18-32">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">private</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb18-33">    T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_underlying_ptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb18-34">    ControlBlockBase<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_control_block_ptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Concept* pointer</span></span>
<span id="cb18-35"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>
<p>Observe that, as long as the two <code>shared_ptr</code> types share the same signature, they can be assigned to each other and the destruction is going to be correct.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb19" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb19-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;memory&gt;</span></span>
<span id="cb19-2"></span>
<span id="cb19-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Foo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{};</span></span>
<span id="cb19-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> Bar<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{};</span></span>
<span id="cb19-5"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb19-6"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb19-7">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>shared_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> ptr1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> Foo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb19-8">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>shared_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> ptr2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> Bar<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb19-9">    ptr1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> ptr2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb19-10"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/xboYxMsYd">Compiler Explorer</a></p>
<p>I was explaining earlier why a <code>shared_ptr&lt;void&gt;</code> is allowed whereas a <code>unique_ptr&lt;void&gt;</code> won’t compile.</p>
<p>You can see that, what the <code>shared_ptr</code> design does is, in the single parameter constructor, when you don’t pass a deleter, it uses a default deleter of the actual object type. It retains the information of the actual object type. It does not use a default deleter of template type parameter <code>T</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb20-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;iostream&gt;</span></span>
<span id="cb20-2"></span>
<span id="cb20-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb20-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> shared_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb20-5">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb20-6"></span>
<span id="cb20-7">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb20-8">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">requires</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>is_convertible_v<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*,</span> T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*&gt;</span></span>
<span id="cb20-9">    shared_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb20-10">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> shared_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>default_delete<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;{})</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// default deleter of ObjType</span></span>
<span id="cb20-11">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb20-12"></span>
<span id="cb20-13">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Templated constructor</span></span>
<span id="cb20-14">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Deleter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb20-15">    shared_ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Deleter deleter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb20-16">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_underlying_ptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>ptr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb20-17">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_control_block_ptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> ControlBlock<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>Deleter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;(</span>deleter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb20-18">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb20-19"></span>
<span id="cb20-20">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// ...</span></span>
<span id="cb20-21"></span>
<span id="cb20-22">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">private</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb20-23">    T<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_underlying_ptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb20-24">    ControlBlockBase<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_control_block_ptr</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Concept* pointer</span></span>
<span id="cb20-25"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span></code></pre></div></div>


</section>
</section>

 ]]></description>
  <category>C++</category>
  <guid>http://quantdev.blog/posts/type-erasure/</guid>
  <pubDate>Thu, 18 Dec 2025 00:00:00 GMT</pubDate>
  <media:content url="http://quantdev.blog/posts/type-erasure/cpp.jpg" medium="image" type="image/jpeg"/>
</item>
<item>
  <title>Implementing LRU Cache</title>
  <dc:creator>`dev::author` </dc:creator>
  <link>http://quantdev.blog/posts/implementing_lru_cache/</link>
  <description><![CDATA[ 





<section id="introduction" class="level1">
<h1>Introduction</h1>
<p>A <em>least recently used</em>(LRU) cache is a fixed-size cache that behaves just like a regular lookup table, but remembers the order in which the elements are accessed. Once it’s user defined capacity is reached it uses the information to replace the least recently used element with a new one. This is ideal for caching function return values, where fast lookup of complex computations is favorable, but a memory blowup from caching all <code>(input, output)</code> pairs is to be avoided. We will first write a basic implementation of <code>LRUCache</code>.</p>
<p>We will then add functionality to connect all our caches to <em>statistics</em> objects that keep track of cache hits and misses for all keys and upon request, individual keys (similar to <code>functools.lrucache</code> in Python). You can also register arbitrary callbacks for hits, misses and accesses in general.</p>
<blockquote class="blockquote">
<h4 id="task" class="anchored" data-anchor-id="introduction">Task</h4>
</blockquote>
<p>Design a data structure that follows the constraints of a Least Recently Used (LRU) cache.</p>
<p>Implement the <code>LRUCache</code> class:</p>
<ul>
<li><code>LRUCache(int capacity)</code> Initialize the LRU cache with positive size <code>capacity</code>.</li>
<li><code>int get(int key)</code> Return the value of the key if the key exists, otherwise return <code>-1</code>.</li>
<li><code>void put(int key, int value)</code> Update the value of the key if the key exists. Otherwise, add the key-value pair to the cache. If the number of keys exceeds the capacity from this operation, evict the least recently used key.</li>
</ul>
<p>The functions <code>get</code> and <code>put</code> must each run in <img src="https://latex.codecogs.com/png.latex?O(1)"> average time complexity.</p>
</section>
<section id="basic-implementation" class="level1">
<h1>Basic implementation</h1>
<p>We will use a <code>std::list</code> to track the usage of the keys and a <code>std::unordered_map</code> to provide fast access to the key-value pair in the last.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode cpp code-with-copy"><code class="sourceCode cpp"><span id="cb1-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Write your solution here</span></span>
<span id="cb1-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// C++20 for C++</span></span>
<span id="cb1-3"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;gtest/gtest.h&gt;</span></span>
<span id="cb1-4"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;cstddef&gt;</span></span>
<span id="cb1-5"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;cstdint&gt;</span></span>
<span id="cb1-6"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;format&gt;</span></span>
<span id="cb1-7"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;print&gt;</span></span>
<span id="cb1-8"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;stdexcept&gt;</span></span>
<span id="cb1-9"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;utility&gt;</span></span>
<span id="cb1-10"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;unordered_map&gt;</span></span>
<span id="cb1-11"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;list&gt;</span></span>
<span id="cb1-12"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;tuple&gt;</span></span>
<span id="cb1-13"></span>
<span id="cb1-14"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">namespace</span> dev <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-15">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/**</span></span>
<span id="cb1-16"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    * </span><span class="an" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">@brief</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">: LRU (Least Recently Used) policy</span></span>
<span id="cb1-17"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    */</span></span>
<span id="cb1-18">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">template</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span></span>
<span id="cb1-19">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Key<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> </span>
<span id="cb1-20">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Value<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> </span>
<span id="cb1-21">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> Container<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>unordered_map<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Key<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">typename</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>list<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>pair<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Key<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>Value<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;::</span>iterator<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;</span></span>
<span id="cb1-22">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> LRUCache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-23">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> lru_list_iterator <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>list<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>pair<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Key<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>Value<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;::</span>iterator<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-24"></span>
<span id="cb1-25">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">private</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb1-26">        Container <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_dict</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-27">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>list<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>pair<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Key<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Value<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_lru_list</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> </span>
<span id="cb1-28">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_capacity</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-29"></span>
<span id="cb1-30">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb1-31">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// explicit single-parameter constructor</span></span>
<span id="cb1-32">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">explicit</span> LRUCache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> capacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-33">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_dict</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb1-34">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_lru_list</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb1-35">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_capacity</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> capacity <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-36">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb1-37"></span>
<span id="cb1-38">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> touch<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>lru_list_iterator it<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb1-39">            <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_lru_list</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>splice<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_lru_list</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_lru_list</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> it<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-40">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-41"></span>
<span id="cb1-42">        <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>optional<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Value<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Key key<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb1-43">            <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> it <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_dict</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>find<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>key<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-44">            <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>optional<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Value<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> result<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-45">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>it <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_dict</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()){</span></span>
<span id="cb1-46">                result <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>nullopt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-47">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-48">                <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>k<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>value<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*((*</span>it<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">).</span>second<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-49">                result <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> value<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-50">                touch<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>it<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-&gt;</span>second<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-51">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-52">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> result<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-53">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-54"></span>
<span id="cb1-55">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">void</span> put<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Key key<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> Value value<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb1-56">            <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> it <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_dict</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>find<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>key<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-57">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>it <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_dict</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">())</span></span>
<span id="cb1-58">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-59">                <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_lru_list</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>size<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_capacity</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-60">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-61">                    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//Evict the least recently used (k,v) pair</span></span>
<span id="cb1-62">                    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>lru_key<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> lru_value<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_lru_list</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb1-63">                    <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_dict</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>erase<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>lru_key<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-64">                    <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_lru_list</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>pop_back<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb1-65">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-66">                    </span>
<span id="cb1-67">                <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Insert the key-value pair</span></span>
<span id="cb1-68">                <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_lru_list</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>push_front<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>pair<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>key<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> value<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">});</span></span>
<span id="cb1-69">                <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_dict</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>key<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_lru_list</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>begin<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb1-70">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-71">                <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Update the key-value pair</span></span>
<span id="cb1-72">                <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">m_dict</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>key<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]-&gt;</span>second <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> value<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-73">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-74">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-75">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb1-76"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// namespace dev</span></span>
<span id="cb1-77"></span>
<span id="cb1-78"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">#include </span><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">&lt;array&gt;</span></span>
<span id="cb1-79"></span>
<span id="cb1-80">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>CacheTest<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> SimplePut<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-81"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-82">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>LRUCache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> cache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-83"></span>
<span id="cb1-84">    cache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>put<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"test"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">666</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-85"></span>
<span id="cb1-86">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>cache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"test"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">666</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-87"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-88"></span>
<span id="cb1-89">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>CacheTest<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> PutWithUpdate<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-90"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-91">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t TEST_CASE <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-92">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>LRUCache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>size_t<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> cache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>TEST_CASE<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb1-93"></span>
<span id="cb1-94">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> TEST_CASE<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-95">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-96">        cache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>put<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>to_string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-97"></span>
<span id="cb1-98">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> value <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> cache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>to_string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb1-99">        ASSERT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> value<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-100">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-101"></span>
<span id="cb1-102">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">size_t</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">uz</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> TEST_CASE<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-103">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-104">        ASSERT_TRUE<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>cache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>to_string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)));</span></span>
<span id="cb1-105">        cache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>put<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>to_string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-106"></span>
<span id="cb1-107">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">auto</span> value <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> cache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>to_string<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb1-108">        ASSERT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> value<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-109">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-110"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-111"></span>
<span id="cb1-112">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>CacheTest<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> KeepsAllValuesWithinCapacity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-113"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-114">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">constexpr</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> CACHE_CAP <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">50</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-115">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">const</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> TEST_RECORDS <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">100</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-116">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>LRUCache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> cache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>CACHE_CAP<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-117"></span>
<span id="cb1-118">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> TEST_RECORDS<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-119">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-120">        cache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>put<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-121">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-122"></span>
<span id="cb1-123">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> TEST_RECORDS <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> CACHE_CAP<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-124">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-125">        EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>cache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>nullopt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-126">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-127"></span>
<span id="cb1-128">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> TEST_RECORDS <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> CACHE_CAP<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> i <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> TEST_RECORDS<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">++</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-129">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-130">        EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> cache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>i<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb1-131">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-132"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-133"></span>
<span id="cb1-134">TEST<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>CacheTest<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> PutAndGet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb1-135">    dev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>LRUCache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> lru_cache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-136">    lru_cache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>put<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// cache is {1=1}</span></span>
<span id="cb1-137">    lru_cache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>put<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// cache is {2=2, 1=1}</span></span>
<span id="cb1-138">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>lru_cache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// return 1, cache is {1=1, 2=2} </span></span>
<span id="cb1-139">    lru_cache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>put<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// evicts key 2, cache is {3=3, 1=1}</span></span>
<span id="cb1-140">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>lru_cache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>nullopt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// returns std::nullopt (not found)</span></span>
<span id="cb1-141">    lru_cache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>put<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// LRU key was 1, evicts key 1, cache is {4=4, 3=3}</span></span>
<span id="cb1-142">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>lru_cache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">std::</span>nullopt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// return std::nullopt (not found)</span></span>
<span id="cb1-143">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>lru_cache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// return 3, cache is {3=3, 4=4}</span></span>
<span id="cb1-144">    EXPECT_EQ<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>lru_cache<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span>    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// return 4, cache is {4=4, 3=3}</span></span>
<span id="cb1-145"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-146"></span>
<span id="cb1-147"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span> argc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">char</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">**</span> argv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-148">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>testing<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span>InitGoogleTest<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(&amp;</span>argc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> argv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-149">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> RUN_ALL_TESTS<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb1-150"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><a href="https://compiler-explorer.com/z/snodGh33T">Compiler Explorer</a></p>


</section>

 ]]></description>
  <category>C++</category>
  <guid>http://quantdev.blog/posts/implementing_lru_cache/</guid>
  <pubDate>Wed, 17 Dec 2025 00:00:00 GMT</pubDate>
  <media:content url="http://quantdev.blog/posts/implementing_lru_cache/cpp.jpg" medium="image" type="image/jpeg"/>
</item>
</channel>
</rss>
