map.cpp 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. // Copyright Louis Dionne 2013-2017
  2. // Distributed under the Boost Software License, Version 1.0.
  3. #include <boost/hana/assert.hpp>
  4. #include <boost/hana/at_key.hpp>
  5. #include <boost/hana/contains.hpp>
  6. #include <boost/hana/map.hpp>
  7. #include <boost/hana/pair.hpp>
  8. #include <boost/hana/string.hpp>
  9. #include <functional>
  10. #include <string>
  11. #include <vector>
  12. namespace hana = boost::hana;
  13. template <typename ...Events>
  14. struct event_system {
  15. using Callback = std::function<void()>;
  16. hana::map<hana::pair<Events, std::vector<Callback>>...> map_;
  17. template <typename Event, typename F>
  18. void on(Event e, F handler) {
  19. auto is_known_event = hana::contains(map_, e);
  20. static_assert(is_known_event,
  21. "trying to add a handler to an unknown event");
  22. map_[e].push_back(handler);
  23. }
  24. template <typename Event>
  25. void trigger(Event e) const {
  26. auto is_known_event = hana::contains(map_, e);
  27. static_assert(is_known_event,
  28. "trying to trigger an unknown event");
  29. for (auto& handler : this->map_[e])
  30. handler();
  31. }
  32. };
  33. template <typename ...Events>
  34. event_system<Events...> make_event_system(Events ...events) {
  35. return {};
  36. }
  37. int main() {
  38. auto events = make_event_system(
  39. BOOST_HANA_STRING("foo"),
  40. BOOST_HANA_STRING("bar"),
  41. BOOST_HANA_STRING("baz")
  42. );
  43. std::vector<std::string> triggered_events;
  44. events.on(BOOST_HANA_STRING("foo"), [&] {
  45. triggered_events.push_back("foo:1");
  46. });
  47. events.on(BOOST_HANA_STRING("foo"), [&] {
  48. triggered_events.push_back("foo:2");
  49. });
  50. events.on(BOOST_HANA_STRING("bar"), [&] {
  51. triggered_events.push_back("bar:1");
  52. });
  53. events.on(BOOST_HANA_STRING("baz"), [&] {
  54. triggered_events.push_back("baz:1");
  55. });
  56. events.trigger(BOOST_HANA_STRING("foo"));
  57. events.trigger(BOOST_HANA_STRING("bar"));
  58. events.trigger(BOOST_HANA_STRING("baz"));
  59. BOOST_HANA_RUNTIME_CHECK(triggered_events == std::vector<std::string>{
  60. "foo:1", "foo:2", "bar:1", "baz:1"
  61. });
  62. }