Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>After consulting with comp.lang.c++.moderated I came up with the code detailed below. The <code>PushBack()</code> macro is used to add new items to the list, one can iterate through the items by using the <code>Next()</code> macro, and the last item can be recognized from that its 'next item' is itself. So a very basic example code: </p> <pre><code>struct A {}; namespace NS1 { struct B {}; struct C {}; struct D {}; // building up the compile-time list struct Head; PushBack(Head, A); PushBack(Head, B); } PushBack(NS1::Head, NS1::C); namespace NS1 { PushBack(Head, D); } // iterate through the list namespace NS2 { // end of the list reached (recognized from PrevItem == Item) template &lt;class ListId, class Item&gt; void print(Wrapper&lt;Item&gt;, Wrapper&lt;Item&gt;) {} // process Item and advance to the next element template &lt;class ListId, class PrevItem, class Item&gt; void print(Wrapper&lt;PrevItem&gt;, Wrapper&lt;Item&gt;) { cout &lt;&lt; typeid(Item).name() &lt;&lt; endl; print&lt;ListId&gt;(Wrapper&lt;Item&gt;(), Wrapper&lt; Next(ListId, Item) &gt;()); } } </code></pre> <p>A more detailed example that also contains an iterator to ease the use of the list can be found <a href="http://ideone.com/UNDDA" rel="nofollow">here</a> or <a href="http://dl.dropbox.com/u/3095355/CompileTimeList.cpp" rel="nofollow">here</a>. </p> <p>The most important part of the 'library':</p> <pre><code>/// Helper class to wrap incomplete types and avoid instantiation of T template&lt;class T&gt; struct Wrapper {}; namespace CTList { /// The front of compile-time lists struct Nil {}; } /// Compile-time list helper template&lt; typename ListId, typename Item &gt; Item NextInListHelper( ::Wrapper&lt;ListId&gt;, ::Wrapper&lt;Item&gt; ); /// The last element of the list #define Back(ListId) \ decltype( NextInListHelper( ::Wrapper&lt;ListId&gt;(), ::Wrapper&lt;\ decltype( NextInListHelper( ::Wrapper&lt;ListId&gt;(), ::Wrapper&lt;\ decltype( NextInListHelper( ::Wrapper&lt;ListId&gt;(), ::Wrapper&lt;\ decltype( NextInListHelper( ::Wrapper&lt;ListId&gt;(), ::Wrapper&lt;\ decltype( NextInListHelper( ::Wrapper&lt;ListId&gt;(), ::Wrapper&lt;\ decltype( NextInListHelper( ::Wrapper&lt;ListId&gt;(), ::Wrapper&lt;\ decltype( NextInListHelper( ::Wrapper&lt;ListId&gt;(), ::Wrapper&lt;\ decltype( NextInListHelper( ::Wrapper&lt;ListId&gt;(), ::Wrapper&lt;\ decltype( NextInListHelper( ::Wrapper&lt;ListId&gt;(), ::Wrapper&lt;\ decltype( NextInListHelper( ::Wrapper&lt;ListId&gt;(), ::Wrapper&lt;\ CTList::Nil \ &gt;())) \ &gt;())) \ &gt;())) \ &gt;())) \ &gt;())) \ &gt;())) \ &gt;())) \ &gt;())) \ &gt;())) \ &gt;())) /// Add a new element (type) to the list #define PushBack( ListId, item) \ item NextInListHelper( ::Wrapper&lt; ListId &gt;, ::Wrapper&lt; Back(ListId) &gt; ) /// The next element in the ('ListId') list after 'item' #define Next(ListId, item) decltype(NextInListHelper(::Wrapper&lt;ListId&gt;(), ::Wrapper&lt;item&gt;() )) </code></pre> <p>It uses <code>NextInListHelper</code> function declarations and Argument Dependent (Name)Look-up to record the list. The last element of the list can be referenced using the <code>Back</code> macro.</p> <p>The first element of the list can be accessed as: <code>Next(ListId, CTList::Nil)</code>, the last element of the list can be recognized from that it is the same as its next element (<code>LastItem == Next(ListId, LastItem)</code>). </p> <p>I tested it only with gcc 4.6.3, but it is intended to be fully C++11 compliant. </p> <p>A few words about the solution:</p> <ul> <li>in this form it can handle type lists up to 10 elements, but this can be extended by adding extra lines to the <code>Back()</code> macro</li> <li>the 'list' can contain a type only once</li> <li>the additional <code>ListId</code> type used in <code>NextInListHelper</code> declarations is there to allow types to be contained in multiple lists simultaneously </li> <li><code>Wrapper</code> is used to avoid actual instantiation of list element types and to support incomplete types as ListId </li> <li><code>PushBack()</code> 'calls' must be in the namespace of <code>ListId</code> (<code>NS1</code>) or <code>Wrapper</code> (the global scope) </li> <li>The processing of the list can be put in any namespace (<code>NS2</code>) </li> </ul>
    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. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      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