fork download
  1. #include <cstddef>
  2. #include <iostream>
  3.  
  4. class MenuItem {
  5. public:
  6. constexpr MenuItem (const char* label, size_t subitems)
  7. : m_label (label), m_subitems (subitems) { }
  8.  
  9. virtual void onKey () const = 0;
  10. virtual void onEvent () const = 0;
  11. virtual void onDraw () const = 0;
  12.  
  13. const char* const m_label;
  14. size_t m_subitems;
  15. // int m_flags; // Keine Ahnung was das in deinem Code macht, hier würde man das Äquivalent hinpacken
  16. // void *Data;
  17. };
  18.  
  19. template <typename... Rest>
  20. class MenuContainer {};
  21.  
  22. template <typename First, typename... Rest>
  23. class MenuContainer<First, Rest...> {
  24. public:
  25. constexpr MenuContainer (const First& src, const Rest&... rest) : m_item (src), m_rest (rest...) {
  26. static_assert (sizeof (First) == sizeof (MenuItem), "All menu items classes must have the same size!");
  27. }
  28. private:
  29. const First m_item;
  30. const MenuContainer<Rest...> m_rest;
  31. };
  32.  
  33. template <>
  34. class MenuContainer<> {};
  35.  
  36. template <typename... Items>
  37. class Menu {
  38. public:
  39. constexpr Menu (const Items&... items) : m_items (items...) {}
  40.  
  41. const MenuItem& operator [] (size_t index) const { return ptr () [index]; }
  42.  
  43. size_t getSize () const { return sizeof...(Items); }
  44.  
  45. const MenuItem* begin () const { return ptr (); }
  46. const MenuItem* end () const { return ptr ()+getSize (); }
  47. private:
  48. const MenuContainer<Items...> m_items;
  49. const MenuItem* ptr () const { return reinterpret_cast<const MenuItem*>(&m_items); }
  50. };
  51.  
  52.  
  53.  
  54. class MyMenuItem1 : public MenuItem {
  55. public:
  56. constexpr MyMenuItem1 (const char* label, size_t subitems)
  57. : MenuItem (label, subitems) { }
  58.  
  59. virtual void onKey () const {
  60. std::cout << "MyMenuAction1::onKey\n";
  61. }
  62. virtual void onEvent () const {
  63. std::cout << "MyMenuAction1::onEvent\n";
  64. }
  65. virtual void onDraw () const {
  66. std::cout << "MyMenuAction1::onDraw\n";
  67. }
  68. };
  69.  
  70. class MyMenuItem2 : public MenuItem {
  71. public:
  72. constexpr MyMenuItem2 (const char* label, size_t subitems)
  73. : MenuItem (label, subitems) { }
  74.  
  75. virtual void onKey () const {
  76. std::cout << "MyMenuAction2::onKey\n";
  77. }
  78. virtual void onEvent () const {
  79. std::cout << "MyMenuAction2::onEvent\n";
  80. }
  81. virtual void onDraw () const {
  82. std::cout << "MyMenuAction2::onDraw\n";
  83. }
  84. };
  85.  
  86. template <typename... Items>
  87. constexpr const Menu<Items...> makeMenu (const Items&... items) {
  88. return Menu<Items...> (items...);
  89. }
  90.  
  91. constexpr const auto myMainMenu = makeMenu (MyMenuItem1 {"Hello", 0}, MyMenuItem2 {"World", 0});
  92.  
  93. int main () {
  94. for (auto& item : myMainMenu) {
  95. std::cout << item.m_label << std::endl;
  96. }
  97. myMainMenu [0].onDraw ();
  98. myMainMenu [1].onKey ();
  99. }
  100.  
Success #stdin #stdout 0s 3340KB
stdin
Standard input is empty
stdout
Hello
World
MyMenuAction1::onDraw
MyMenuAction2::onKey