<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://ayaskovets.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://ayaskovets.github.io/" rel="alternate" type="text/html" /><updated>2024-11-24T07:12:18+00:00</updated><id>https://ayaskovets.github.io/feed.xml</id><title type="html">andrei yaskovets</title><subtitle>software engineer</subtitle><entry><title type="html">Uniform access to runtime and compile time values</title><link href="https://ayaskovets.github.io/uniform_access_to_runtime_and_compile_time_values/" rel="alternate" type="text/html" title="Uniform access to runtime and compile time values" /><published>2024-04-29T00:00:00+00:00</published><updated>2024-04-29T00:00:00+00:00</updated><id>https://ayaskovets.github.io/uniform_access_to_runtime_and_compile_time_values</id><content type="html" xml:base="https://ayaskovets.github.io/uniform_access_to_runtime_and_compile_time_values/"><![CDATA[<p>While writing some of the C++20 <a href="https://github.com/ayaskovets/matrix_views">code</a> related to NTTP I stumbled upon a rather minor but nonetheless interesting issue.</p>

<h2 id="illustrative-example">Illustrative example</h2>

<p>In C++20 we have <strong>std::span</strong> with <strong>T</strong> and <strong>Extent</strong> template parameters, where <strong>Extent</strong> can be either some <strong>size_t</strong> value known at compile time or <strong>std::dynamic_extent</strong> which is basically <strong>(size_t)(-1)</strong> that represents some runtime value.</p>

<p>Suppose we have our own type-container with optionally provided compile-time size:</p>

<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">Size</span><span class="p">&gt;</span>
<span class="k">class</span> <span class="nc">Container</span> <span class="p">{</span>
  <span class="p">...</span>
<span class="p">};</span>
</code></pre></div></div>

<p>And some deduction guides for the type:</p>

<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">Size</span><span class="p">&gt;</span>
<span class="n">Container</span><span class="p">(</span><span class="n">T</span> <span class="p">(</span><span class="o">&amp;</span><span class="p">)[</span><span class="n">Size</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="n">Container</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">Size</span><span class="o">&gt;</span><span class="p">;</span>

<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">Size</span><span class="p">&gt;</span>
<span class="n">Container</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Container</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">dynamic_extent</span><span class="o">&gt;</span><span class="p">;</span>
</code></pre></div></div>

<p>And a member function that returns the size of the container:</p>

<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">constexpr</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="nf">size</span><span class="p">()</span> <span class="p">{</span>
  <span class="k">if</span> <span class="k">constexpr</span> <span class="p">(</span><span class="n">Size</span> <span class="o">==</span> <span class="n">std</span><span class="o">::</span><span class="n">dynamic_extent</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="n">size_</span><span class="p">;</span> <span class="c1">// some member value that is set in the constructor</span>
  <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
    <span class="k">return</span> <span class="n">Size</span><span class="p">;</span>
  <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>This pattern of returning a value in case it is known at compile-time with <strong>if constexpr</strong> is pretty useful and simple but not very handy because <strong>if constexpr</strong> is not an expression that returns value and thus has to be wrapped into a function for each bit of the logic that requires reading the value. We can do better.</p>

<h2 id="wrapping-the-value">Wrapping the value</h2>

<p>A very simplified example of a wrapper that could simplify the code above is something like this:</p>

<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">,</span> <span class="n">T</span> <span class="n">Dynamic</span><span class="p">,</span> <span class="n">T</span> <span class="n">Value</span> <span class="o">=</span> <span class="n">Dynamic</span><span class="p">&gt;</span>
<span class="k">class</span> <span class="nc">CompileRuntimeValue</span> <span class="p">{</span>
  <span class="k">constexpr</span> <span class="k">static</span> <span class="kr">inline</span> <span class="kt">bool</span> <span class="n">kStatic</span> <span class="o">=</span> <span class="n">Value</span> <span class="o">!=</span> <span class="n">Dynamic</span><span class="p">;</span>
  <span class="k">constexpr</span> <span class="k">static</span> <span class="kr">inline</span> <span class="kt">bool</span> <span class="n">kDynamic</span> <span class="o">=</span> <span class="o">!</span><span class="n">kStatic</span><span class="p">;</span>

 <span class="nl">public:</span>
  <span class="k">constexpr</span> <span class="n">CompileRuntimeValue</span><span class="p">()</span>
    <span class="k">requires</span><span class="p">(</span><span class="n">kStatic</span><span class="p">)</span>
  <span class="o">=</span> <span class="k">default</span><span class="p">;</span>

  <span class="k">constexpr</span> <span class="n">CompileRuntimeValue</span><span class="p">()</span>
    <span class="k">requires</span><span class="p">(</span><span class="n">kDynamic</span><span class="p">)</span>
  <span class="o">=</span> <span class="k">delete</span><span class="p">;</span>

  <span class="k">constexpr</span> <span class="n">CompileRuntimeValue</span><span class="p">(</span><span class="n">T</span> <span class="n">value</span><span class="p">)</span>
    <span class="k">requires</span><span class="p">(</span><span class="n">kDynamic</span><span class="p">)</span>
  <span class="o">:</span> <span class="n">value_</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">move</span><span class="p">(</span><span class="n">value</span><span class="p">))</span> <span class="p">{}</span>

  <span class="k">constexpr</span> <span class="n">T</span> <span class="k">operator</span><span class="o">*</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">if</span> <span class="k">constexpr</span> <span class="p">{</span>
      <span class="k">return</span> <span class="n">value_</span><span class="p">;</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
      <span class="k">return</span> <span class="n">Value</span><span class="p">;</span>
    <span class="p">}</span>
  <span class="p">}</span>

 <span class="nl">private:</span>
  <span class="k">struct</span> <span class="nc">Empty</span><span class="p">{};</span>
  <span class="p">[[</span><span class="n">no_unique_address</span><span class="p">]]</span> <span class="n">std</span><span class="o">::</span><span class="n">conditional_t</span><span class="o">&lt;</span><span class="n">kDynamic</span><span class="p">,</span> <span class="n">T</span><span class="p">,</span> <span class="n">Empty</span><span class="o">&gt;</span> <span class="n">value_</span><span class="p">;</span>
<span class="p">};</span>
</code></pre></div></div>

<p>By wrapping the value into a type with a specific indicator that the value is dynamic allows to write the <strong>if constexpr</strong> once for all of the uses of compile/run time value.</p>

<p>Any <strong>CompileRuntimeValue</strong> object could also be marked with [[no_unique_address]] to hint the compiler that the value stored in the type itself. And applying that to the <strong>Container</strong> class:</p>

<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">Size</span><span class="p">&gt;</span>
<span class="k">class</span> <span class="nc">Container</span> <span class="p">{</span>
  <span class="p">...</span>
  <span class="k">constexpr</span> <span class="n">std</span><span class="o">::</span><span class="kt">size_t</span> <span class="n">size</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="o">*</span><span class="n">size_</span><span class="p">;</span>
  <span class="p">}</span>
  <span class="p">...</span>

 <span class="nl">private:</span>
  <span class="c1">// initialized only in 'runtime' constructors, takes no space when Size is a compile-time value</span>
  <span class="p">[[</span><span class="n">no_unique_address</span><span class="p">]]</span> <span class="n">CompileRuntimeValue</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kt">size_t</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">dynamic_extent</span><span class="p">,</span> <span class="n">Size</span><span class="o">&gt;</span> <span class="n">size_</span><span class="p">;</span>
<span class="p">};</span>
</code></pre></div></div>]]></content><author><name></name></author><summary type="html"><![CDATA[With just a few lines of code]]></summary></entry><entry><title type="html">Evolution of interfaces</title><link href="https://ayaskovets.github.io/evolution_of_interfaces/" rel="alternate" type="text/html" title="Evolution of interfaces" /><published>2021-11-05T00:00:00+00:00</published><updated>2021-11-05T00:00:00+00:00</updated><id>https://ayaskovets.github.io/evolution_of_interfaces</id><content type="html" xml:base="https://ayaskovets.github.io/evolution_of_interfaces/"><![CDATA[<p>Let’s try to figure out from bottom up how the simple idea of abstracting away the internal details of complex objects has evolved in the context of computer science and how much meaning the term ‘interface’ really has in this context.</p>

<h2 id="electrons">Electrons</h2>

<p>In the beginning was an electron. I believe this is the best place to start since electrons are in a way the interface to electricity as a phenomenon. The mathematical model here is electrical field. Its the strength of the field that allows us predict the movement of electric charge. And along with electric charge the movement of energy and more importantly information.</p>

<p>Since the discovery of electron almost one and a half centuries ago electric current has become almost the one and only way to transmit and store information. On this level the interface consists of two operations:</p>

<ul>
  <li><strong>capacitance</strong> - to store electric charge and create <strong>voltage</strong>;</li>
  <li><strong>current</strong> - to move the charge from one place to another.</li>
</ul>

<p>There are many ways of manufacturing batteries, different types of wires, but that is really not important from the perspective of interfacing the electricity. The right point of view for now is that the laws of physics is the implementation detail. Or ultimately the Universe itself.</p>

<h2 id="atoms">Atoms</h2>

<p>One level up are atomic-level structures and crystalline solids. Thanks to Pauli exclusion principle, fermions and in particular electrons can not occupy the same quantum state part of which is the potential energy that an electron has relative to the nucleus.</p>

<p>This means that in some configurations of atoms there would be electrons on energy levels high enough that relatively small external amounts of energy or thermal exitations would be able to detach electron away from the nucleus. The act of electron ‘flying away from its temporary home’ is move from valency band to conduction band. And it is crucial as it is the basic principle behind one of the versatile inventions of the 20st century - semiconductors.</p>

<p>Between these two levels could be an energy gap of a particular size. This size is how much the energy of the solid needs to be increased to make it conduct. Different materials can be manufactured so that this energy gap is of specific size and therefore make the simplest logical element switch for electric current. The obvious property of this good abstraction is:</p>

<ul>
  <li><strong>switch</strong> - do or do not allow <strong>current</strong> to flow based on some external state.</li>
</ul>

<h2 id="transistors">Transistors</h2>

<p>Semiconductors are fine by themselves but along with some engineering tricks they are used to manufacture more intricate devices - transistors.</p>

<p>The basic structure needed to make a transistor is PN-junction which occurs on the boundary of two types of semiconductors. These include:</p>

<ul>
  <li>n-type. Manufactured by doping a crystal (silicon for ex. with four electrons in its valence band) with an element with a larger number of valence electrons (for silicon this number is five) which due to crystallic structure of the material makes the leftover electrons free (one that does not fit the four connections of the crystal). These electrons pass the charge when the crystal is connected to a battery;</li>
  <li>p-type. Here a crystal is doped with an element with a fewer valence electrons. This way the type of conductivity is via the free electron holes. These holes pass the charged electrons through when the semiconductor is connected to a battery.</li>
</ul>

<p>Connecting anode to the p-type end of a semiconductor and catode to the n-type end (forward bias), we get a diode. Diode acts as a one-way conductor because the internal flow of electrons from n-type to p-type parts of the whole semiconductor creates an area around the PN-junction which acts as an insulator. This way, when anode is connected the n-type end and catode to the p-type end (reverse bias), only high-energy electrons are able to surpass the insulation layer thus requiring a large voltage.</p>

<p>Now things need to be only a bit more complex. We need to make a semiconductor out of three parts and it can be done in a couple of ways:</p>

<ul>
  <li>n-type connected to p-type connected to n-type;</li>
  <li>p-type connected to p-type connected to p-type.</li>
</ul>

<p>Both do not conduct electricity in neither forward nor reverse bias. To make this structure useful we need to add a third terminal which would either inject electrons to the middle part of the semiconductor or shrink the insulation area by changing voltage between the two PN-junctions. Thus the main function of a transistor is:</p>

<ul>
  <li><strong>amplify</strong> - regulate the amount of <strong>current</strong> or act like a switch depending on control <strong>current</strong> or <strong>voltage</strong></li>
</ul>

<h2 id="logical-circuits">Logical circuits</h2>

<p>This tier makes a bit larger leap through the levels of abstraction. The reason is that we are slowly moving away from the necessary physical devices towards the vast possibilities of an abstract design space. There are many ways of manufacturing logic gates either based on transistors or not, but the main goal of this operation is to create a set of binary logical elements which satisfies the criteria functional completeness. Inputs and outputs for these elements are represented by voltage.</p>

<p>The most basic devices are the unary NOT (inverter) and binary AND (conjunction) and OR (disjunction) and XOR (exclusive disjunction) gates. These represent the basic functions of binary logic and could be visualized via truth tables. To achieve functional completeness (which means having a set of gates that can be used to construct any binary function with any number of arguments) we need only a single gate. And none of the above is sufficient enough.</p>

<p>The bases for the binary logic in electric devices are NAND and NOR gates. One can proof that any binary function could be implemented in terms of one of these gates. And this is pretty much the main function of the logical circuits - being building blocks for more complex operations, so interface here is something like:</p>

<ul>
  <li><strong>perform arbitrary operations</strong> on binary numbers represented by distinct <strong>voltage</strong> levels using <strong>voltage</strong> or <strong>current</strong> as a controller</li>
</ul>

<p>Some of the more specific applications of the logical gates include:</p>

<ul>
  <li>flip-flops or latches - simplest stateful gate. Two inputs are used to manipulate the state bit on the output. The “stateful” here implies some clocking device that defines the possible frequency of the state transitions;</li>
  <li>counters and registers - a combination of flip-flops that represents a stored binary number which can be loaded or read;</li>
  <li>ALU (arithmetic logic unit) - general purpouse circuit that is designed to perform arithmetic operations on binary numbers.</li>
</ul>

<h2 id="processors-memory-networking-other-hardware">Processors, memory, networking, other hardware</h2>

<p>There it is. Out of the previous beautiful abstractions something more general-purpouse could be created. Again, specific CPU architectures here are not important. The principle is using stateful logical circuits to store a fixed amount of information and having a computing circuit to read from and write into the memory. Everything else here is a matter of interpretation.</p>

<ul>
  <li><strong>store</strong> information in binary form</li>
  <li><strong>manipulate</strong> information in binary form</li>
</ul>

<p>A specific CPU architecture exposes a set of instructions generic enough to express pretty much any computation. Instructions are represented by binary operation codes stored in memory. Basically this gives us a way to write a program and later execute it on a CPU or another hardware designed for different problems like displaying information or proxying it to other devices. There is also a lot more to unpack on this layer of abstraction by going deeper (c) into the specifics: memory management unit, caches, hardware parallelism etc.</p>

<p>The other hardware function that belongs to this section is networking. This is also a gargantuous topic that comes with its own abstraction layers like OSI, TCP/IP, wide variety of protocols. But to make the point of this discussion, we would only need a method of exchanging the information between processors. By providing a transmission medium like wires, air or optical fiber and a way of representing bits like different <strong>voltage</strong> levels, a modulated property of a electromagnetic wave, and photon detectors correspondingly, we unlock the next necessary part of the interface:</p>

<ul>
  <li><strong>send</strong> and <strong>receive</strong> information in binary</li>
</ul>

<h2 id="general-purpouse-computers-apis">General-purpouse computers, APIs</h2>

<p>The next and the most recent level is programs. Having got the variety of the tools to manipulate binary numbers we can abstract further and finally implement specific ideas in digital space. I think it is better to treat compilers, interpreters or programming languages as an implementation detail and to better focus on inter-application communication.</p>

<p>Now that there are programs that have some intelligence on their own, their communication protocols are the interface themselves. Let’s consider the main unit of work in the global network of computers currently - something like a web-server which is capable of handling a specific set of requests. Here the main decisions to make are the structure of a message passing between applications and the properties of the set of requests that the application could handle. The restrictions are that the message as well as the application interface has to be dynamic and flexible enough although that impacts performance a lot. It seems like the way to go for the modern apps is either binary format like protocol buffers along with gRPC or REST + JSON.</p>

<p>With all of that we can easily represent real-world actions by application-like actors and have basically achieved the complexity that allows to think about computations declaratively. The pinnacle of all the ladder of abstractions above is something like:</p>

<ul>
  <li><strong>perform arbitrary actions</strong> in an abstract space that also could be mappped onto the real world</li>
</ul>

<h2 id="ai">…AI?</h2>

<p>Well, actually it seems like the structure of application interfaces at the moment is still too rigid to become an implementation detail.</p>

<p>Maybe we will come together and develop a protocol generic enough to allow to easily integrate different independent applications without them knowing about each other. Maybe we will, as well as with many other hard tasks, employ neural networks to pass the responsibility for the answer onto the statistics. Maybe even the current solutions will proof to be sufficient enough.</p>

<p>Or maybe we will just discover a way to make strong AI. In any case, the greater goal of a good interface is to be transparent, understandable and obvious for all its consumers: for hardware, for software. And for us.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[In the most general sense one could think of an interface as a collection of ways a thing allows other things to interact with it. But how abstract this idea really is?]]></summary></entry><entry><title type="html">Laziness in C</title><link href="https://ayaskovets.github.io/laziness-in-c/" rel="alternate" type="text/html" title="Laziness in C" /><published>2021-10-10T00:00:00+00:00</published><updated>2021-10-10T00:00:00+00:00</updated><id>https://ayaskovets.github.io/laziness-in-c</id><content type="html" xml:base="https://ayaskovets.github.io/laziness-in-c/"><![CDATA[<h2 id="strict-evaluation">Strict evaluation</h2>

<p>The C language has strict semantics for most of its expressions. That means pretty much any complex expression gets evaluated first and then the evaluated result is used as the value of the expression. For example, in the following snippet the function call gets evaluated even though its result is never used:</p>

<h3 id="example1h">example1.h:</h3>
<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
</span>
<span class="kt">int</span> <span class="nf">a_or_b</span><span class="p">(</span><span class="kt">int</span> <span class="n">a</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="n">a</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="o">?</span> <span class="n">a</span> <span class="o">:</span> <span class="n">b</span><span class="p">;</span>
<span class="p">}</span>

<span class="kt">int</span> <span class="nf">get_a</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">puts</span><span class="p">(</span><span class="n">__func__</span><span class="p">);</span>
    <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>

<span class="kt">int</span> <span class="nf">get_b</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">puts</span><span class="p">(</span><span class="n">__func__</span><span class="p">);</span>
    <span class="cm">/* some expensive computation */</span>
    <span class="k">return</span> <span class="mi">2</span><span class="p">;</span>
<span class="p">}</span>

<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">a_or_b</span><span class="p">(</span><span class="n">get_a</span><span class="p">(),</span> <span class="n">get_b</span><span class="p">());</span>
    <span class="cm">/*
     * will print
        get_a
        get_b
     * in unspecified order
     */</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Since all the functions here are computed in runtime and have external linkage, there is no way for compiler to know whether it is legitimate to remove a call from an expression.</p>

<p>There are languages which have lazy semantics by default and we could use one language construction to emulate it in plain C. This construction is logical short-circuiting.</p>

<p>The idea consists of:</p>
<ul>
  <li>Separating the state we operate on in a number of objects which can besides store some information for error handling etc.</li>
  <li>Having operations on the state specified in terms of function that may fail (e.g. returning bool or anything which can indicate whether an arbitrary operation succeeded)</li>
</ul>

<h3 id="example2h">example2.h:</h3>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;stdbool.h&gt;</span><span class="cp">
</span>
<span class="k">struct</span> <span class="n">Calculation</span> <span class="p">{</span>
    <span class="kt">int</span> <span class="n">state</span><span class="p">;</span>
    <span class="kt">char</span> <span class="n">error</span><span class="p">[</span><span class="mi">128</span><span class="p">];</span>
<span class="p">};</span>

<span class="n">bool</span> <span class="nf">operation1</span><span class="p">(</span><span class="k">struct</span> <span class="n">Calculation</span><span class="o">*</span> <span class="n">calculation</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">puts</span><span class="p">(</span><span class="n">__func__</span><span class="p">);</span>
    <span class="k">return</span> <span class="nb">true</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">bool</span> <span class="nf">operation2</span><span class="p">(</span><span class="k">struct</span> <span class="n">Calculation</span><span class="o">*</span> <span class="n">calculation</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">puts</span><span class="p">(</span><span class="n">__func__</span><span class="p">);</span>
    <span class="k">return</span> <span class="nb">false</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">bool</span> <span class="nf">operation3</span><span class="p">(</span><span class="k">struct</span> <span class="n">Calculation</span><span class="o">*</span> <span class="n">calculation</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">puts</span><span class="p">(</span><span class="n">__func__</span><span class="p">);</span>
    <span class="k">return</span> <span class="nb">true</span><span class="p">;</span>
<span class="p">}</span>

<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">struct</span> <span class="n">Calculation</span> <span class="n">calculation</span><span class="p">;</span>

    <span class="p">(</span><span class="n">operation1</span><span class="p">(</span><span class="o">&amp;</span><span class="n">calculation</span><span class="p">),</span> <span class="n">operation2</span><span class="p">(</span><span class="o">&amp;</span><span class="n">calculation</span><span class="p">))</span> <span class="o">&amp;&amp;</span> <span class="n">operation3</span><span class="p">(</span><span class="o">&amp;</span><span class="n">calculation</span><span class="p">);</span>
    <span class="cm">/*
     * will print
        operation1
        operation2
     */</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The logical operations along with comma operator can help express complex chains of computations. In the example above operation1 is performed unconditionally and operation3 evaluation depends on the success of the operation2.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[Achieving lazy evaluation in C by unnecessary complex means]]></summary></entry><entry><title type="html">Applications of scoped enums (part 2)</title><link href="https://ayaskovets.github.io/applications_of_scoped_enums_2/" rel="alternate" type="text/html" title="Applications of scoped enums (part 2)" /><published>2021-05-25T00:00:00+00:00</published><updated>2021-05-25T00:00:00+00:00</updated><id>https://ayaskovets.github.io/applications_of_scoped_enums_2</id><content type="html" xml:base="https://ayaskovets.github.io/applications_of_scoped_enums_2/"><![CDATA[<h2 id="example-three-c14-pattern-matching">Example three (C++14): pattern matching</h2>

<p>The enumeration could also be a means to pass runtime info to to type level with minimal overhead.
<br />
The both previous examples are focused on compile-time values, but with by adding a couple of runtime checks we can achieve more by taking some inspiration from a common pattern functional programming idea of implementing functions in terms of pattern matching.</p>

<h3 id="atypehpp">atype.hpp:</h3>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/* let's pretend that this is a type we want to match on */</span>
<span class="k">using</span> <span class="n">type</span> <span class="o">=</span> <span class="kt">int</span><span class="p">;</span>

<span class="cm">/* pattern matching is basically determining the state of a variable
   we'll need a list of possible states we are going to handle */</span>
<span class="k">enum</span> <span class="k">class</span> <span class="nc">int_state</span>
<span class="p">{</span>
    <span class="n">positive</span><span class="p">,</span>
    <span class="n">negative</span><span class="p">,</span>

    <span class="n">other</span>
<span class="p">};</span>

<span class="cm">/* helper utility to associate types with state enums */</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">&gt;</span>
<span class="k">struct</span> <span class="nc">get_state_t</span><span class="p">;</span>

<span class="cm">/* associate int with int_state */</span>
<span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span>
<span class="k">struct</span> <span class="nc">get_state_t</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="p">{</span> <span class="k">using</span> <span class="n">type</span> <span class="o">=</span> <span class="n">int_state</span><span class="p">;</span> <span class="p">};</span>

<span class="cm">/* convenience routine */</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">&gt;</span>
<span class="k">using</span> <span class="n">state_t</span> <span class="o">=</span> <span class="k">typename</span> <span class="n">get_state_t</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;::</span><span class="n">type</span><span class="p">;</span>

<span class="cm">/* mapper from type value to its state */</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">&gt;</span>
<span class="k">auto</span> <span class="n">stateof</span><span class="p">(</span><span class="k">const</span> <span class="n">T</span><span class="o">&amp;</span> <span class="n">value</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">state_t</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">;</span>
</code></pre></div></div>

<h3 id="atypecpp"><strong>atype.cpp</strong>:</h3>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/* definition of the state mapper for our type */</span>
<span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span>
<span class="k">auto</span> <span class="n">stateof</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="k">const</span> <span class="kt">int</span> <span class="o">&amp;</span><span class="n">value</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">state_t</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span>
<span class="p">{</span>
    <span class="k">return</span> <span class="n">value</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="o">?</span> <span class="n">int_state</span><span class="o">::</span><span class="n">positive</span>
         <span class="o">:</span> <span class="n">value</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">?</span> <span class="n">int_state</span><span class="o">::</span><span class="n">negative</span>
         <span class="o">:</span> <span class="n">int_state</span><span class="o">::</span><span class="n">other</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="example3hpp">example3.hpp:</h3>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/* an interface visible to client code */</span>
<span class="k">auto</span> <span class="n">magic</span><span class="p">(</span><span class="kt">int</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">int</span><span class="p">;</span>
</code></pre></div></div>

<h3 id="somewhere-in-example3cpp">Somewhere in example3.cpp:</h3>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/* the real magic implementation */</span>
<span class="k">template</span><span class="o">&lt;</span><span class="n">int_state</span><span class="p">&gt;</span>
<span class="k">auto</span> <span class="n">true_magic</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">int</span><span class="p">;</span>

<span class="cm">/* implement the function in terms of pattern matching */</span>
<span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span>
<span class="k">auto</span> <span class="n">true_magic</span><span class="o">&lt;</span><span class="n">int_state</span><span class="o">::</span><span class="n">positive</span><span class="o">&gt;</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">int</span>
<span class="p">{</span>
    <span class="k">return</span> <span class="n">i</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span>
<span class="k">auto</span> <span class="n">true_magic</span><span class="o">&lt;</span><span class="n">int_state</span><span class="o">::</span><span class="n">negative</span><span class="o">&gt;</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">int</span>
<span class="p">{</span>
    <span class="k">return</span> <span class="o">-</span><span class="n">i</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span>
<span class="k">auto</span> <span class="n">true_magic</span><span class="o">&lt;</span><span class="n">int_state</span><span class="o">::</span><span class="n">other</span><span class="o">&gt;</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">int</span>
<span class="p">{</span>
    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>

<span class="cm">/* interface implementation via simple switch
   that can be auto-generated, for each unhandled case
   compiler generates a warning */</span>
<span class="k">auto</span> <span class="n">magic</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">int</span>
<span class="p">{</span>
    <span class="k">switch</span> <span class="p">(</span><span class="n">stateof</span><span class="p">(</span><span class="n">i</span><span class="p">))</span>
    <span class="p">{</span>
    <span class="k">case</span> <span class="n">int_state</span><span class="o">::</span><span class="n">positive</span><span class="p">:</span> <span class="k">return</span> <span class="n">true_magic</span><span class="o">&lt;</span><span class="n">int_state</span><span class="o">::</span><span class="n">positive</span><span class="o">&gt;</span><span class="p">(</span><span class="n">i</span><span class="p">);</span>
    <span class="k">case</span> <span class="n">int_state</span><span class="o">::</span><span class="n">negative</span><span class="p">:</span> <span class="k">return</span> <span class="n">true_magic</span><span class="o">&lt;</span><span class="n">int_state</span><span class="o">::</span><span class="n">negative</span><span class="o">&gt;</span><span class="p">(</span><span class="n">i</span><span class="p">);</span>
    <span class="nl">default:</span> <span class="k">return</span> <span class="n">true_magic</span><span class="o">&lt;</span><span class="n">int_state</span><span class="o">::</span><span class="n">other</span><span class="o">&gt;</span><span class="p">(</span><span class="n">i</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>That’s for sure a lot of boilerplate for such a simple function but the overall pattern is very simple - by doing a few runtime checks we can acquire additional information about runtime values and carry this information to type level. This is especially useful when objects are immutable because the state can be calculated on construction.</p>

<p>All of the examples (except the one with <strong>static_assert</strong>) do not require modern language features and by sacrificing some type-safety can be used even with C++03-supporting compiler.</p>]]></content><author><name></name></author><summary type="html"><![CDATA[Some abstractions to mimic pattern matching in plain old C++]]></summary></entry><entry><title type="html">Applications of scoped enums (part 1)</title><link href="https://ayaskovets.github.io/applications_of_scoped_enums_1/" rel="alternate" type="text/html" title="Applications of scoped enums (part 1)" /><published>2021-05-23T00:00:00+00:00</published><updated>2021-05-23T00:00:00+00:00</updated><id>https://ayaskovets.github.io/applications_of_scoped_enums_1</id><content type="html" xml:base="https://ayaskovets.github.io/applications_of_scoped_enums_1/"><![CDATA[<h2 id="for-starters">For starters</h2>

<p><strong>enum class</strong> is a great feature of C++11 and has many uses. Some of which are:</p>

<ul>
  <li>type-safe enumerations;</li>
  <li>ability to share the same name between multiple <strong>enum class</strong>‘es contrary to plain C enums;</li>
  <li>a finite set of values that can abstract away anything.</li>
</ul>

<p>Here and below we are going to focus on the latter which is basically the main reason behind enumeration types in general. The idea is that <strong>enum class</strong> being type-checked represents a bare bones set of values - <em>a type</em>.
<br />
Beyond that templates have a nice capability of being specialized not only on types but on compile time variables which <strong>enum class</strong> constants are. Other than enums we can use any intergal values but the fact that enum values can be given explicit names comes in handy. With a couple of abstractions we’ll try to implement Rust-like enums with attached data.</p>

<h2 id="example-one-c14-overloading-return-type">Example one (C++14): ‘overloading’ return type</h2>

<p>The enumeration could mean a way for client code to specify an additional parameter to a function which in turn can be specialized on that parameter.
<br />
The simplest example here is a common construction or access point for multiple types - a factory, application settings storage etc.</p>

<h3 id="example1hpp">example1.hpp:</h3>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/* explicit list of values of our so called type */</span>
<span class="k">enum</span> <span class="k">class</span> <span class="nc">overloader</span>
<span class="p">{</span>
    <span class="n">caseA</span><span class="p">,</span>
    <span class="n">caseB</span>
<span class="p">};</span>

<span class="cm">/* set of types which associate with the overloader values
   the key point is that a single type can associate with multiple enum values */</span>
<span class="k">struct</span> <span class="nc">typeA</span>
<span class="p">{</span>
    <span class="kt">void</span> <span class="n">a</span><span class="p">();</span>
<span class="p">};</span>
<span class="k">struct</span> <span class="nc">typeB</span>
<span class="p">{</span>
    <span class="kt">void</span> <span class="n">b</span><span class="p">();</span>
<span class="p">};</span>

<span class="cm">/* mapping between the values and types of overloader */</span>
<span class="k">template</span><span class="o">&lt;</span><span class="n">overloader</span><span class="p">&gt;</span>
<span class="k">struct</span> <span class="nc">get_return_t</span><span class="p">;</span>

<span class="cm">/* concrete type mappings */</span>
<span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span>
<span class="k">struct</span> <span class="nc">get_return_t</span><span class="o">&lt;</span><span class="n">overloader</span><span class="o">::</span><span class="n">caseA</span><span class="o">&gt;</span> <span class="p">{</span> <span class="k">using</span> <span class="n">type</span> <span class="o">=</span> <span class="n">typeA</span><span class="p">;</span> <span class="p">};</span>
<span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span>
<span class="k">struct</span> <span class="nc">get_return_t</span><span class="o">&lt;</span><span class="n">overloader</span><span class="o">::</span><span class="n">caseB</span><span class="o">&gt;</span> <span class="p">{</span> <span class="k">using</span> <span class="n">type</span> <span class="o">=</span> <span class="n">typeB</span><span class="p">;</span> <span class="p">};</span>

<span class="cm">/* convenience routine */</span>
<span class="k">template</span><span class="o">&lt;</span><span class="n">overloader</span> <span class="n">O</span><span class="p">&gt;</span>
<span class="k">using</span> <span class="n">return_t</span> <span class="o">=</span> <span class="k">typename</span> <span class="n">get_return_t</span><span class="o">&lt;</span><span class="n">O</span><span class="o">&gt;::</span><span class="n">type</span><span class="p">;</span>

<span class="cm">/* this way the interface is clealy defined and extendable in exactly one place - the enum */</span>
<span class="k">template</span><span class="o">&lt;</span><span class="n">overloader</span> <span class="n">O</span><span class="p">&gt;</span>
<span class="k">auto</span> <span class="n">get</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">return_t</span><span class="o">&lt;</span><span class="n">O</span><span class="o">&gt;</span><span class="p">;</span>
</code></pre></div></div>

<h3 id="somewhere-in-example1cpp">Somewhere in example1.cpp:</h3>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="n">typeA</span><span class="o">::</span><span class="n">a</span><span class="p">()</span> <span class="p">{}</span>
<span class="kt">void</span> <span class="n">typeB</span><span class="o">::</span><span class="n">b</span><span class="p">()</span> <span class="p">{}</span>

<span class="cm">/* the definitions are modular because of the template specialization */</span>
<span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span>
<span class="k">auto</span> <span class="n">get</span><span class="o">&lt;</span><span class="n">overloader</span><span class="o">::</span><span class="n">caseA</span><span class="o">&gt;</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">return_t</span><span class="o">&lt;</span><span class="n">overloader</span><span class="o">::</span><span class="n">caseA</span><span class="o">&gt;</span>
<span class="p">{</span>
    <span class="k">auto</span> <span class="n">value</span> <span class="o">=</span> <span class="n">typeA</span><span class="p">{};</span>
    <span class="c1">// ...</span>
    <span class="k">return</span> <span class="n">value</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span>
<span class="k">auto</span> <span class="n">get</span><span class="o">&lt;</span><span class="n">overloader</span><span class="o">::</span><span class="n">caseB</span><span class="o">&gt;</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">return_t</span><span class="o">&lt;</span><span class="n">overloader</span><span class="o">::</span><span class="n">caseB</span><span class="o">&gt;</span>
<span class="p">{</span>
    <span class="k">auto</span> <span class="n">value</span> <span class="o">=</span> <span class="n">typeB</span><span class="p">{};</span>
    <span class="c1">// ...</span>
    <span class="k">return</span> <span class="n">value</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="client-code">Client code</h3>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/* only an 'overloader' value could be passed */</span>
<span class="k">auto</span> <span class="n">valueA</span> <span class="o">=</span> <span class="n">get</span><span class="o">&lt;</span><span class="n">overloader</span><span class="o">::</span><span class="n">caseA</span><span class="o">&gt;</span><span class="p">();</span>
<span class="n">valueA</span><span class="p">.</span><span class="n">a</span><span class="p">();</span>
<span class="k">auto</span> <span class="n">valueB</span> <span class="o">=</span> <span class="n">get</span><span class="o">&lt;</span><span class="n">overloader</span><span class="o">::</span><span class="n">caseB</span><span class="o">&gt;</span><span class="p">();</span>
<span class="n">valueB</span><span class="p">.</span><span class="n">b</span><span class="p">();</span>
</code></pre></div></div>

<p>In C++14 there is auto return type deduction for functions but that forces us to write the definition in header.</p>

<h2 id="example-two-c14-implementing-crtp--a-family-of-mixins">Example two (C++14): implementing CRTP / a family of mixins</h2>

<p>The enumeration could also mean a way to list a family of implementation or mixin types.</p>

<h3 id="example2hpp">example2.hpp:</h3>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/* for std::is_same */</span>
<span class="cp">#include</span> <span class="cpf">&lt;utility&gt;</span><span class="cp">
</span>
<span class="cm">/* list of scenarios */</span>
<span class="k">enum</span> <span class="k">class</span> <span class="nc">family</span>
<span class="p">{</span>
    <span class="n">caseA</span><span class="p">,</span>
    <span class="n">caseB</span>
<span class="p">};</span>

<span class="cm">/* type specifier for interface methods */</span>
<span class="k">template</span><span class="o">&lt;</span><span class="n">family</span><span class="p">,</span> <span class="k">class</span><span class="p">&gt;</span>
<span class="k">struct</span> <span class="nc">get_method_t</span><span class="p">;</span>

<span class="cm">/* explicit user-defined types for interface methods */</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">C</span><span class="p">&gt;</span>
<span class="k">struct</span> <span class="nc">get_method_t</span><span class="o">&lt;</span><span class="n">family</span><span class="o">::</span><span class="n">caseA</span><span class="p">,</span> <span class="n">C</span><span class="o">&gt;</span> <span class="p">{</span> <span class="k">using</span> <span class="n">type</span> <span class="o">=</span> <span class="kt">int</span><span class="p">(</span><span class="n">C</span><span class="o">::*</span><span class="p">)(</span><span class="kt">int</span><span class="p">,</span> <span class="kt">char</span><span class="p">);</span> <span class="p">};</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">class</span> <span class="nc">C</span><span class="p">&gt;</span>
<span class="k">struct</span> <span class="nc">get_method_t</span><span class="o">&lt;</span><span class="n">family</span><span class="o">::</span><span class="n">caseB</span><span class="p">,</span> <span class="n">C</span><span class="o">&gt;</span> <span class="p">{</span> <span class="k">using</span> <span class="n">type</span> <span class="o">=</span> <span class="kt">void</span><span class="p">(</span><span class="n">C</span><span class="o">::*</span><span class="p">)(</span><span class="kt">double</span><span class="p">);</span> <span class="p">};</span>

<span class="cm">/* convenience routine */</span>
<span class="k">template</span><span class="o">&lt;</span><span class="n">family</span> <span class="n">F</span><span class="p">,</span> <span class="k">class</span> <span class="nc">C</span><span class="p">&gt;</span>
<span class="k">using</span> <span class="n">method_t</span> <span class="o">=</span> <span class="k">typename</span> <span class="n">get_method_t</span><span class="o">&lt;</span><span class="n">F</span><span class="p">,</span> <span class="n">C</span><span class="o">&gt;::</span><span class="n">type</span><span class="p">;</span>

<span class="cm">/* implementation class */</span>
<span class="k">template</span><span class="o">&lt;</span><span class="n">family</span> <span class="n">F</span><span class="p">&gt;</span>
<span class="k">struct</span> <span class="nc">implementation</span><span class="p">;</span>

<span class="cm">/* implementation types specifications */</span>
<span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span>
<span class="k">struct</span> <span class="nc">implementation</span><span class="o">&lt;</span><span class="n">family</span><span class="o">::</span><span class="n">caseA</span><span class="o">&gt;</span>
<span class="p">{</span>
    <span class="k">auto</span> <span class="n">foo</span><span class="p">(</span><span class="kt">int</span><span class="p">,</span> <span class="kt">char</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">int</span><span class="p">;</span>
    <span class="cm">/* caseA-specific methods */</span>
<span class="p">};</span>
<span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span>
<span class="k">struct</span> <span class="nc">implementation</span><span class="o">&lt;</span><span class="n">family</span><span class="o">::</span><span class="n">caseB</span><span class="o">&gt;</span>
<span class="p">{</span>
    <span class="k">auto</span> <span class="n">foo</span><span class="p">(</span><span class="kt">double</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">void</span><span class="p">;</span>
    <span class="cm">/* caseB-specific methods */</span>
<span class="p">};</span>

<span class="cm">/* common interface for implementation types */</span>
<span class="k">template</span><span class="o">&lt;</span><span class="n">family</span> <span class="n">F</span><span class="p">&gt;</span>
<span class="k">struct</span> <span class="nc">interface</span> <span class="o">:</span> <span class="n">implementation</span><span class="o">&lt;</span><span class="n">F</span><span class="o">&gt;</span>
<span class="p">{</span>
    <span class="cm">/* enforce method 'foo' in implementation&lt;F&gt; with the specified signature */</span>
    <span class="k">static_assert</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">is_same_v</span><span class="o">&lt;</span>
        <span class="k">decltype</span><span class="p">(</span><span class="o">&amp;</span><span class="n">implementation</span><span class="o">&lt;</span><span class="n">F</span><span class="o">&gt;::</span><span class="n">foo</span><span class="p">),</span>
        <span class="n">method_t</span><span class="o">&lt;</span><span class="n">F</span><span class="p">,</span> <span class="n">implementation</span><span class="o">&lt;</span><span class="n">F</span><span class="o">&gt;&gt;&gt;</span><span class="p">);</span>
<span class="p">};</span>
</code></pre></div></div>

<h3 id="somewhere-in-example2cpp">Somewhere in example2.cpp:</h3>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">auto</span> <span class="n">implementation</span><span class="o">&lt;</span><span class="n">family</span><span class="o">::</span><span class="n">caseA</span><span class="o">&gt;::</span><span class="n">foo</span><span class="p">(</span><span class="kt">int</span><span class="p">,</span> <span class="kt">char</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">int</span>
<span class="p">{</span>
    <span class="cm">/* caseA implementation details */</span>
<span class="p">}</span>
<span class="k">auto</span> <span class="n">implementation</span><span class="o">&lt;</span><span class="n">family</span><span class="o">::</span><span class="n">caseB</span><span class="o">&gt;::</span><span class="n">foo</span><span class="p">(</span><span class="kt">double</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">void</span>
<span class="p">{</span>
    <span class="cm">/* caseB implementation details */</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="client-code-1">Client code</h3>
<div class="language-c++ highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">auto</span> <span class="n">valueA</span> <span class="o">=</span> <span class="n">interface</span><span class="o">&lt;</span><span class="n">family</span><span class="o">::</span><span class="n">caseA</span><span class="o">&gt;</span><span class="p">{};</span>
<span class="n">valueA</span><span class="p">.</span><span class="n">foo</span><span class="p">(</span><span class="mi">42</span><span class="p">,</span> <span class="sc">'e'</span><span class="p">);</span>

<span class="k">auto</span> <span class="n">valueB</span> <span class="o">=</span> <span class="n">interface</span><span class="o">&lt;</span><span class="n">family</span><span class="o">::</span><span class="n">caseB</span><span class="o">&gt;</span><span class="p">{};</span>
<span class="n">valueB</span><span class="p">.</span><span class="n">foo</span><span class="p">(</span><span class="mf">42.0</span><span class="p">);</span>
</code></pre></div></div>

<p>The common benefit of all these applications is simplification of the interface for client code by using a small number of key entities all defined in one place. Most of these things can be implemented using the regular CRTP, inheritance etc. But in some cases putting a collection of something under an enumeration can help express restrictions in your code.</p>

<p>For more see <a href="/applications_of_scoped_enums_2">part 2</a></p>]]></content><author><name></name></author><summary type="html"><![CDATA[Emulating functions overloads by return type]]></summary></entry></feed>