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