Telnet++  3.1.0.2
A C++ library for interacting with Telnet streams
router.hpp
1 #pragma once
2 
3 #include "telnetpp/detail/return_default.hpp"
4 
5 #include <functional>
6 #include <unordered_map>
7 #include <utility>
8 
9 namespace telnetpp::detail {
10 
11 //* =========================================================================
48 //* =========================================================================
49 template <class Key, class Message, class Function, class KeyFromMessagePolicy>
50 class router
51 {
52 public:
53  using key_type = Key;
54  using message_type = Message;
55  using function_type = std::function<Function>;
56  using result_type = typename function_type::result_type;
57  using registered_functions_map_type =
58  std::unordered_map<key_type, function_type>;
59 
60  //* =====================================================================
65  //* =====================================================================
66  template <typename KeyType, typename Continuation>
67  void register_route(KeyType &&key, Continuation &&cont)
68  {
69  registered_functions_[std::forward<KeyType>(key)] =
70  std::forward<Continuation>(cont);
71  }
72 
73  //* =====================================================================
78  //* =====================================================================
79  template <typename KeyType>
80  void unregister_route(KeyType &&key)
81  {
82  registered_functions_.erase(std::forward<KeyType>(key));
83  }
84 
85  //* =====================================================================
90  //* =====================================================================
91  template <typename Continuation>
92  void set_unregistered_route(Continuation &&cont)
93  {
94  unregistered_route_ = std::forward<Continuation>(cont);
95  }
96 
97  //* =====================================================================
104  //* =====================================================================
105  template <typename MessageType, typename... Args>
106  result_type operator()(MessageType &&message, Args &&...args) const
107  {
108  if (auto iter = registered_functions_.find(
109  KeyFromMessagePolicy::key_from_message(message));
110  iter != registered_functions_.end())
111  {
112  return iter->second(
113  std::forward<MessageType>(message),
114  std::forward<Args>(args)...);
115  }
116  else if (unregistered_route_)
117  {
118  return unregistered_route_(
119  std::forward<MessageType>(message),
120  std::forward<Args>(args)...);
121  }
122 
123  // This garbage is just to return either a default-constructed Result,
124  // or void if Result is void.
125  return detail::return_default_constructed<result_type>{}();
126  }
127 
128 private:
129  registered_functions_map_type registered_functions_;
130  function_type unregistered_route_;
131 };
132 
133 } // namespace telnetpp::detail