title: C++ find encompassing type
body: <h2>Motivation</h2>
  
  <p>The motivation is, to a certain extent, mimic mathematical notions in C++, mostly to allow extremely generic algorithms to be written. More on the motivation later.</p>
  
  <p>First, some definitions. </p>
  
  <h2>Definition</h2>
  
  <ol>
  <li>A type <code>A</code> encompasses another type <code>B</code> if <code>B</code> is convertible to <code>A</code> at least almost without loss of information*. This is analogous to the mathematical notion of super-sets <code>B ⊆ A</code>.</li>
  <li>A type <code>C</code> is closed under <code>operatorX</code> if <code>C</code> encompasses <code>C X C</code>.</li>
  <li>The closure <code>C</code> of type <code>A</code> under <code>operatorX</code> is the type that encompasses <code>A</code> and is closed under <code>operatorX</code> itself. <code>C</code> might not be unique. <code>C</code> might not exist.</li>
  <li>The closure <code>C</code> of type <code>A</code> and <code>B</code> under <code>operatorX</code> and <code>operatorY</code> is the type that encompasses both <code>A</code> and <code>B</code> and is closed under <code>operatorX</code> and <code>operatorY</code> itself. This requires that <code>A X B</code>, <code>B Y A</code> and such are defined.</li>
  </ol>
  
  <p><strong>*Note</strong>: This is a pretty imprecise statement, but its hard to give a strict definition without lots of cumbersome restrictions. Just as examples: <code>int</code> encompasses <code>char</code>, <code>double</code> encompasses <code>float</code>, <code>double</code> encompasses <code>int32_t</code> since it has 52 bits of precision, but <code>float</code> doesn't encompass <code>int32_t</code> since it only has 23 bits of precision.</p>
  
  <h2>Problem</h2>
  
  <p>Given two types <code>T</code> and <code>U</code>, both having <code>operator+</code> and <code>operator*</code> defined. What is an efficient way to find their closure or emit an error if none can be found?</p>
  
  <p>Note that their operators should be considered to be absolutely insane, that is, <code>T</code> might not even be closed under <code>operator+</code>, <code>Σ(k ∈ [0, n)) T</code> might be a type dependent on <code>n</code>.</p>
  
  <p>For example, if we only want the closure under <code>operator+</code></p>
  
  <pre><code>closure&lt;unsigned, unsigned char&gt;::type  //unsigned
  </code></pre>
  
  <p>can be easily implemented as</p>
  
  <pre><code>template&lt;typename T, typename U&gt; struct closure {
      using type = decltype(std::declval&lt;T&gt;() + std::declval&lt;U&gt;());
  };
  </code></pre>
  
  <p>but this is not applicable to all types, since as mentioned, <code>decltype(std::declval&lt;T&gt;() + std::declval&lt;U&gt;())</code> might not be closed.</p>
  
  <h2>More on motivation</h2>
  
  <p>Say a certain generic algorithm requires manipulation of multiple different types. If we want to create a variable to store the intermediate values, its type should be their closure.</p>
  
  <p>The simplest example would be adding <code>int</code> to <code>float</code>, using <code>double</code> as the intermediate storage. In this case though, the language actually specifies that <code>float</code> is the closure of <code>int</code> and <code>float</code> which is sub-optimal in certain cases.</p>
  
  <p>Now since the algorithm is generic, we would need some way of finding the closure without knowing in advance what those types and their operators are.</p>
  
  <p>I might have gotten a bit carried away and in fact created something stupidly contrived.</p>
  
  <h3>Notes on title</h3>
  
  <p>I can't call it "find closure of types", closure normally means something else in programming :P . If someone would suggest a better name, I'd happily change it.</p>