#include <cstddef>
#include <iostream>

class MenuItem {
    public:
		constexpr MenuItem (const char* label, size_t subitems)
			: m_label (label), m_subitems (subitems) { }

		virtual void onKey () const = 0;
		virtual void onEvent () const = 0;
		virtual void onDraw () const = 0;

		const char* const m_label;
		size_t m_subitems;
//		int m_flags;	// Keine Ahnung was das in deinem Code macht, hier würde man das Äquivalent hinpacken
//		void  *Data;
};

template <typename... Rest>
class MenuContainer {};

template <typename First, typename... Rest>
class MenuContainer<First, Rest...> {
	public:
		constexpr MenuContainer (const First& src, const Rest&... rest) : m_item (src), m_rest (rest...) {
			static_assert (sizeof (First) == sizeof (MenuItem), "All menu items classes must have the same size!");
		}
	private:
		const First m_item;
		const MenuContainer<Rest...> m_rest;
};

template <>
class MenuContainer<> {};

template <typename... Items>
class Menu {
	public:
		constexpr Menu (const Items&... items) : m_items (items...) {}

		const MenuItem& operator [] (size_t index) const { return ptr () [index]; }

		size_t getSize () const { return sizeof...(Items); }

		const MenuItem* begin () const { return ptr (); }
		const MenuItem* end () const { return ptr ()+getSize (); }
	private:
		const MenuContainer<Items...> m_items;
		const MenuItem* ptr () const { return reinterpret_cast<const MenuItem*>(&m_items); }
};



class MyMenuItem1 : public MenuItem {
	public:
		constexpr MyMenuItem1 (const char* label, size_t subitems)
			: MenuItem (label, subitems) { }

		virtual void onKey () const {
			std::cout << "MyMenuAction1::onKey\n";
		}
		virtual void onEvent () const {
			std::cout << "MyMenuAction1::onEvent\n";
		}
		virtual void onDraw () const {
			std::cout << "MyMenuAction1::onDraw\n";
		}
};

class MyMenuItem2 : public MenuItem {
	public:
		constexpr MyMenuItem2 (const char* label, size_t subitems)
			: MenuItem (label, subitems) { }

		virtual void onKey () const {
			std::cout << "MyMenuAction2::onKey\n";
		}
		virtual void onEvent () const {
			std::cout << "MyMenuAction2::onEvent\n";
		}
		virtual void onDraw () const {
			std::cout << "MyMenuAction2::onDraw\n";
		}
};

template <typename... Items>
constexpr const Menu<Items...> makeMenu (const Items&... items) {
	return Menu<Items...> (items...);
}

constexpr const auto myMainMenu = makeMenu (MyMenuItem1 {"Hello", 0}, MyMenuItem2 {"World", 0});

int main () {
	for (auto& item : myMainMenu) {
		std::cout << item.m_label << std::endl;
	}
	myMainMenu [0].onDraw ();
	myMainMenu [1].onKey ();
}
