Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>To add to <em>@StackedCrooked</em> answer, you can overload <code>operator++</code>, <code>operator--</code> and <code>operator*</code> and have iterator like functionality. </p> <pre><code>enum Color { Color_Begin, Color_Red = Color_Begin, Color_Orange, Color_Yellow, Color_Green, Color_Blue, Color_Indigo, Color_Violet, Color_End }; namespace std { template&lt;&gt; struct iterator_traits&lt;Color&gt; { typedef Color value_type; typedef int difference_type; typedef Color *pointer; typedef Color &amp;reference; typedef std::bidirectional_iterator_tag iterator_category; }; } Color &amp;operator++(Color &amp;c) { assert(c != Color_End); c = static_cast&lt;Color&gt;(c + 1); return c; } Color operator++(Color &amp;c, int) { assert(c != Color_End); ++c; return static_cast&lt;Color&gt;(c - 1); } Color &amp;operator--(Color &amp;c) { assert(c != Color_Begin); return c = static_cast&lt;Color&gt;(c - 1); } Color operator--(Color &amp;c, int) { assert(c != Color_Begin); --c; return static_cast&lt;Color&gt;(c + 1); } Color operator*(Color c) { assert(c != Color_End); return c; } </code></pre> <p>Let's test with some <code>&lt;algorithm&gt;</code> template</p> <pre><code>void print(Color c) { std::cout &lt;&lt; c &lt;&lt; std::endl; } int main() { std::for_each(Color_Begin, Color_End, &amp;print); } </code></pre> <p>Now, <code>Color</code> is a constant bidirectional iterator. Here is a reusable class i coded while doing it manually above. I noticed it could work for many more enums, so repeating the same code all over again is quite tedious</p> <pre><code>// Code for testing enum_iterator // -------------------------------- namespace color_test { enum Color { Color_Begin, Color_Red = Color_Begin, Color_Orange, Color_Yellow, Color_Green, Color_Blue, Color_Indigo, Color_Violet, Color_End }; Color begin(enum_identity&lt;Color&gt;) { return Color_Begin; } Color end(enum_identity&lt;Color&gt;) { return Color_End; } } void print(color_test::Color c) { std::cout &lt;&lt; c &lt;&lt; std::endl; } int main() { enum_iterator&lt;color_test::Color&gt; b = color_test::Color_Begin, e; while(b != e) print(*b++); } </code></pre> <p>Implementation follows.</p> <pre><code>template&lt;typename T&gt; struct enum_identity { typedef T type; }; namespace details { void begin(); void end(); } template&lt;typename Enum&gt; struct enum_iterator : std::iterator&lt;std::bidirectional_iterator_tag, Enum&gt; { enum_iterator():c(end()) { } enum_iterator(Enum c):c(c) { assert(c &gt;= begin() &amp;&amp; c &lt;= end()); } enum_iterator &amp;operator=(Enum c) { assert(c &gt;= begin() &amp;&amp; c &lt;= end()); this-&gt;c = c; return *this; } static Enum begin() { using details::begin; // re-enable ADL return begin(enum_identity&lt;Enum&gt;()); } static Enum end() { using details::end; // re-enable ADL return end(enum_identity&lt;Enum&gt;()); } enum_iterator &amp;operator++() { assert(c != end() &amp;&amp; "incrementing past end?"); c = static_cast&lt;Enum&gt;(c + 1); return *this; } enum_iterator operator++(int) { assert(c != end() &amp;&amp; "incrementing past end?"); enum_iterator cpy(*this); ++*this; return cpy; } enum_iterator &amp;operator--() { assert(c != begin() &amp;&amp; "decrementing beyond begin?"); c = static_cast&lt;Enum&gt;(c - 1); return *this; } enum_iterator operator--(int) { assert(c != begin() &amp;&amp; "decrementing beyond begin?"); enum_iterator cpy(*this); --*this; return cpy; } Enum operator*() { assert(c != end() &amp;&amp; "cannot dereference end iterator"); return c; } Enum get_enum() const { return c; } private: Enum c; }; template&lt;typename Enum&gt; bool operator==(enum_iterator&lt;Enum&gt; e1, enum_iterator&lt;Enum&gt; e2) { return e1.get_enum() == e2.get_enum(); } template&lt;typename Enum&gt; bool operator!=(enum_iterator&lt;Enum&gt; e1, enum_iterator&lt;Enum&gt; e2) { return !(e1 == e2); } </code></pre>
    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.
 

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