Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>So far all solutions have drawbacks, unnecessary dependencies, unnecessary helpers and all are restricted to the Cartesian power of two. The following solution has no such drawbacks and supports:</p> <ol> <li>Any cartesian power including 0.</li> <li>Returning the empty set if any of the factors is an empty set.</li> <li>The code is self contained and does not depend on any include files.</li> <li>The inputs of the function can be of any template type.</li> <li>The type of the output list can be specified via the first template parameter.</li> </ol> <p>It was actually to harder to implement (but good as homework) then I thought. I am actually thinking about creating a little generator which allows me an extended template syntax which makes these things really easy. </p> <p>Simplified the code works as follows: <code>product</code> converts an input list <code>tuple&lt;A...&gt;,tuple&lt;B...&gt;,tuple&lt;C...&gt;</code> into <code>tuple&lt;tuple&lt;A&gt;...&gt;, tuple&lt;B...&gt;, tuple&lt;C...&gt;</code>. This second list is then passed to <code>product_helper</code> which does the recursive Cartesian product computation.</p> <pre><code>template &lt;typename... T&gt; struct cat2; template &lt;template&lt;typename...&gt; class R, typename... As, typename... Bs&gt; struct cat2 &lt;R&lt;As...&gt;, R&lt;Bs...&gt; &gt; { using type = R &lt;As..., Bs...&gt;; }; template &lt;typename... Ts&gt; struct product_helper; template &lt;template&lt;typename...&gt; class R, typename... Ts&gt; struct product_helper &lt; R&lt;Ts...&gt; &gt; { // stop condition using type = R&lt; Ts...&gt;; }; template &lt;template&lt;typename...&gt; class R, typename... Ts&gt; struct product_helper &lt; R&lt;R&lt;&gt; &gt;, Ts... &gt; { // catches first empty tuple using type = R&lt;&gt;; }; template &lt;template&lt;typename...&gt; class R, typename... Ts, typename... Rests&gt; struct product_helper &lt; R&lt;Ts...&gt;, R&lt;&gt;, Rests... &gt; { // catches any empty tuple except first using type = R&lt;&gt;; }; template &lt;template&lt;typename...&gt; class R, typename... X, typename H, typename... Rests&gt; struct product_helper &lt; R&lt;X...&gt;, R&lt;H&gt;, Rests... &gt; { using type1 = R &lt;typename cat2&lt;X,R&lt;H&gt; &gt;::type...&gt;; using type = typename product_helper&lt;type1, Rests...&gt;::type; }; template &lt;template&lt;typename...&gt; class R, typename... X, template&lt;typename...&gt; class Head, typename T, typename... Ts, typename... Rests&gt; struct product_helper &lt; R&lt;X...&gt;, Head&lt;T, Ts...&gt;, Rests... &gt; { using type1 = R &lt;typename cat2&lt;X,R&lt;T&gt; &gt;::type...&gt;; using type2 = typename product_helper&lt;R&lt;X...&gt; , R&lt;Ts...&gt; &gt;::type; using type3 = typename cat2&lt;type1,type2&gt;::type; using type = typename product_helper&lt;type3, Rests...&gt;::type; }; template &lt;template&lt;typename...&gt; class R, typename... Ts&gt; struct product; template &lt;template&lt;typename...&gt; class R&gt; struct product &lt; R &gt; { // no input, R specifies the return type using type = R&lt;&gt;; }; template &lt;template&lt;typename...&gt; class R, template&lt;typename...&gt; class Head, typename... Ts, typename... Tail&gt; struct product &lt;R, Head&lt;Ts...&gt;, Tail... &gt; { // R is the return type, Head&lt;A...&gt; is the first input list using type = typename product_helper&lt; R&lt;R&lt;Ts&gt;...&gt;, Tail... &gt;::type; }; </code></pre> <p>Here is a <a href="https://stackoverflow.com/a/19922797/2712726">compilable example</a> of how the code can be used.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload