rdc_option.hpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /*
  2. * Copyright (c) 2017-2023 zhllxt
  3. *
  4. * author : zhllxt
  5. * email : 37792738@qq.com
  6. *
  7. * Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. */
  10. #ifndef __ASIO2_RDC_OPTION_HPP__
  11. #define __ASIO2_RDC_OPTION_HPP__
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. #pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <cstdint>
  16. #include <memory>
  17. #include <functional>
  18. #include <type_traits>
  19. #include <any>
  20. #include <asio2/base/error.hpp>
  21. #include <asio2/base/define.hpp>
  22. #include <asio2/base/detail/util.hpp>
  23. #include <asio2/base/detail/function_traits.hpp>
  24. #include <asio2/component/rdc/rdc_invoker.hpp>
  25. namespace asio2::rdc
  26. {
  27. struct option_base
  28. {
  29. virtual ~option_base() {}
  30. virtual std::any call_parser(bool is_send, void* data) = 0;
  31. virtual void emplace_request(std::any& k, void* v) = 0;
  32. virtual void execute_and_erase(std::any& k, std::function<void(void*)> cb) = 0;
  33. virtual void foreach_and_clear(std::function<void(void*, void*)> cb) = 0;
  34. };
  35. template<class IdT, class SendDataT, class RecvDataT = SendDataT>
  36. class option : public rdc::option_base
  37. {
  38. protected:
  39. using send_parser_fun = std::function<IdT(SendDataT)>;
  40. using recv_parser_fun = std::function<IdT(RecvDataT)>;
  41. send_parser_fun rdc_send_parser_;
  42. recv_parser_fun rdc_recv_parser_;
  43. using invoker_type = detail::rdc_invoker_t<IdT, SendDataT, RecvDataT>;
  44. using iterator_type = typename invoker_type::iterator_type;
  45. using key_type = IdT;
  46. using val_type = typename invoker_type::value_type;
  47. invoker_type rdc_invoker_;
  48. public:
  49. option(option&&) noexcept = default;
  50. option(option const&) = default;
  51. option& operator=(option&&) noexcept = default;
  52. option& operator=(option const&) = default;
  53. template<class ParserFun, std::enable_if_t<
  54. !std::is_base_of_v<option, detail::remove_cvref_t<ParserFun>>, int> = 0>
  55. explicit option(ParserFun&& parser)
  56. : rdc_send_parser_(std::forward<ParserFun>(parser))
  57. , rdc_recv_parser_(rdc_send_parser_)
  58. {
  59. }
  60. template<class SendParserFun, class RecvParserFun>
  61. explicit option(SendParserFun&& send_parser, RecvParserFun&& recv_parser)
  62. : rdc_send_parser_(std::forward<SendParserFun>(send_parser))
  63. , rdc_recv_parser_(std::forward<RecvParserFun>(recv_parser))
  64. {
  65. }
  66. template<class ParserFun>
  67. option& set_send_parser(ParserFun&& parser)
  68. {
  69. rdc_send_parser_ = std::forward<ParserFun>(parser);
  70. return (*this);
  71. }
  72. template<class ParserFun>
  73. option& set_recv_parser(ParserFun&& parser)
  74. {
  75. rdc_recv_parser_ = std::forward<ParserFun>(parser);
  76. return (*this);
  77. }
  78. send_parser_fun& get_send_parser() noexcept { return rdc_send_parser_; }
  79. recv_parser_fun& get_recv_parser() noexcept { return rdc_recv_parser_; }
  80. detail::rdc_invoker_t<IdT, SendDataT, RecvDataT>& invoker() noexcept { return rdc_invoker_; }
  81. virtual std::any call_parser(bool is_send, void* data) override
  82. {
  83. if (is_send)
  84. {
  85. typename detail::remove_cvref_t<SendDataT>& d = *((typename detail::remove_cvref_t<SendDataT>*)data);
  86. key_type id = rdc_send_parser_(d);
  87. return std::any(std::move(id));
  88. }
  89. else
  90. {
  91. typename detail::remove_cvref_t<RecvDataT>& d = *((typename detail::remove_cvref_t<RecvDataT>*)data);
  92. key_type id = rdc_recv_parser_(d);
  93. return std::any(std::move(id));
  94. }
  95. }
  96. virtual void emplace_request(std::any& k, void* v) override
  97. {
  98. key_type& key = *std::any_cast<key_type>(std::addressof(k));
  99. val_type& val = *((val_type*)v);
  100. // 2023-07-11 bug fix : can't use std::move(key), beacuse the key will be used at later.
  101. rdc_invoker_.emplace(key, std::move(val));
  102. }
  103. virtual void execute_and_erase(std::any& k, std::function<void(void*)> cb) override
  104. {
  105. key_type& key = *std::any_cast<key_type>(std::addressof(k));
  106. if (auto iter = rdc_invoker_.find(key); iter != rdc_invoker_.end())
  107. {
  108. cb((void*)(std::addressof(iter->second)));
  109. rdc_invoker_.erase(iter);
  110. }
  111. }
  112. virtual void foreach_and_clear(std::function<void(void*, void*)> cb) override
  113. {
  114. for (auto& [k, v] : rdc_invoker_.reqs())
  115. {
  116. cb((void*)std::addressof(k), (void*)std::addressof(v));
  117. }
  118. rdc_invoker_.reqs().clear();
  119. }
  120. };
  121. // C++17 class template argument deduction guides
  122. template<class ParserFun>
  123. option(ParserFun)->option<
  124. typename detail::function_traits<detail::remove_cvref_t<ParserFun>>::return_type,
  125. typename detail::function_traits<detail::remove_cvref_t<ParserFun>>::template args<0>::type,
  126. typename detail::function_traits<detail::remove_cvref_t<ParserFun>>::template args<0>::type
  127. >;
  128. template<class SendParserFun, class RecvParserFun>
  129. option(SendParserFun, RecvParserFun)->option<
  130. typename detail::function_traits<detail::remove_cvref_t<SendParserFun>>::return_type,
  131. typename detail::function_traits<detail::remove_cvref_t<SendParserFun>>::template args<0>::type,
  132. typename detail::function_traits<detail::remove_cvref_t<RecvParserFun>>::template args<0>::type
  133. >;
  134. }
  135. #endif // !__ASIO2_RDC_OPTION_HPP__