fork download
  1. template<typename E, E v>
  2. struct EnumValue
  3. {
  4. static const E value = v;
  5. };
  6.  
  7. template<typename h, typename t>
  8. struct StaticList
  9. {
  10. typedef h head;
  11. typedef t tail;
  12. };
  13.  
  14. template<typename list, typename first>
  15. struct CyclicHead
  16. {
  17. typedef typename list::head item;
  18. };
  19.  
  20. template<typename first>
  21. struct CyclicHead<void,first>
  22. {
  23. typedef first item;
  24. };
  25.  
  26. template<typename E, typename list, typename first = typename list::head>
  27. struct Advance
  28. {
  29. typedef typename list::head lh;
  30. typedef typename list::tail lt;
  31. typedef typename CyclicHead<lt, first>::item next;
  32.  
  33. static void advance(E& value)
  34. {
  35. if(value == lh::value)
  36. value = next::value;
  37. else
  38. Advance<E, typename list::tail, first>::advance(value);
  39. }
  40. };
  41.  
  42. template<typename E, typename f>
  43. struct Advance<E,void,f>
  44. {
  45. static void advance(E& value)
  46. {
  47. }
  48. };
  49.  
  50. /// Test enum
  51. enum class Fruit
  52. {
  53. apple,
  54. banana,
  55. orange,
  56. pineapple,
  57. lemon
  58. };
  59.  
  60. /// Scalable way, C++03-ish
  61. typedef StaticList<EnumValue<Fruit,Fruit::apple>,
  62. StaticList<EnumValue<Fruit,Fruit::banana>,
  63. StaticList<EnumValue<Fruit,Fruit::orange>,
  64. StaticList<EnumValue<Fruit,Fruit::pineapple>,
  65. StaticList<EnumValue<Fruit,Fruit::lemon>,
  66. void
  67. > > > > > Fruit_values;
  68.  
  69. Fruit& operator++(Fruit& f)
  70. {
  71. Advance<Fruit, Fruit_values>::advance(f);
  72. return f;
  73. }
  74.  
  75.  
  76.  
  77. #include <iostream>
  78. std::ostream& operator<<(std::ostream& os, Fruit f)
  79. {
  80. switch(f)
  81. {
  82. case Fruit::apple: os << "Fruit::apple"; return os;
  83. case Fruit::banana: os << "Fruit::banana"; return os;
  84. case Fruit::orange: os << "Fruit::orange"; return os;
  85. case Fruit::pineapple: os << "Fruit::pineapple"; return os;
  86. case Fruit::lemon: os << "Fruit::lemon"; return os;
  87. }
  88. }
  89.  
  90. int main()
  91. {
  92. Fruit f = Fruit::banana;
  93. std::cout << "f = " << f << ";\n";
  94. std::cout << "++f = " << ++f << ";\n";
  95. }
Success #stdin #stdout 0s 2852KB
stdin
Standard input is empty
stdout
f = Fruit::banana;
++f = Fruit::orange;