123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- /*
- * Copyright (c) 2017-2023 zhllxt
- *
- * author : zhllxt
- * email : 37792738@qq.com
- *
- * Distributed under the Boost Software License, Version 1.0. (See accompanying
- * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- */
- #ifndef __ASIO2_RDC_OPTION_HPP__
- #define __ASIO2_RDC_OPTION_HPP__
- #if defined(_MSC_VER) && (_MSC_VER >= 1200)
- #pragma once
- #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
- #include <cstdint>
- #include <memory>
- #include <functional>
- #include <type_traits>
- #include <any>
- #include <asio2/base/error.hpp>
- #include <asio2/base/define.hpp>
- #include <asio2/base/detail/util.hpp>
- #include <asio2/base/detail/function_traits.hpp>
- #include <asio2/component/rdc/rdc_invoker.hpp>
- namespace asio2::rdc
- {
- struct option_base
- {
- virtual ~option_base() {}
- virtual std::any call_parser(bool is_send, void* data) = 0;
- virtual void emplace_request(std::any& k, void* v) = 0;
- virtual void execute_and_erase(std::any& k, std::function<void(void*)> cb) = 0;
- virtual void foreach_and_clear(std::function<void(void*, void*)> cb) = 0;
- };
- template<class IdT, class SendDataT, class RecvDataT = SendDataT>
- class option : public rdc::option_base
- {
- protected:
- using send_parser_fun = std::function<IdT(SendDataT)>;
- using recv_parser_fun = std::function<IdT(RecvDataT)>;
- send_parser_fun rdc_send_parser_;
- recv_parser_fun rdc_recv_parser_;
- using invoker_type = detail::rdc_invoker_t<IdT, SendDataT, RecvDataT>;
- using iterator_type = typename invoker_type::iterator_type;
- using key_type = IdT;
- using val_type = typename invoker_type::value_type;
- invoker_type rdc_invoker_;
- public:
- option(option&&) noexcept = default;
- option(option const&) = default;
- option& operator=(option&&) noexcept = default;
- option& operator=(option const&) = default;
- template<class ParserFun, std::enable_if_t<
- !std::is_base_of_v<option, detail::remove_cvref_t<ParserFun>>, int> = 0>
- explicit option(ParserFun&& parser)
- : rdc_send_parser_(std::forward<ParserFun>(parser))
- , rdc_recv_parser_(rdc_send_parser_)
- {
- }
- template<class SendParserFun, class RecvParserFun>
- explicit option(SendParserFun&& send_parser, RecvParserFun&& recv_parser)
- : rdc_send_parser_(std::forward<SendParserFun>(send_parser))
- , rdc_recv_parser_(std::forward<RecvParserFun>(recv_parser))
- {
- }
- template<class ParserFun>
- option& set_send_parser(ParserFun&& parser)
- {
- rdc_send_parser_ = std::forward<ParserFun>(parser);
- return (*this);
- }
- template<class ParserFun>
- option& set_recv_parser(ParserFun&& parser)
- {
- rdc_recv_parser_ = std::forward<ParserFun>(parser);
- return (*this);
- }
- send_parser_fun& get_send_parser() noexcept { return rdc_send_parser_; }
- recv_parser_fun& get_recv_parser() noexcept { return rdc_recv_parser_; }
- detail::rdc_invoker_t<IdT, SendDataT, RecvDataT>& invoker() noexcept { return rdc_invoker_; }
- virtual std::any call_parser(bool is_send, void* data) override
- {
- if (is_send)
- {
- typename detail::remove_cvref_t<SendDataT>& d = *((typename detail::remove_cvref_t<SendDataT>*)data);
- key_type id = rdc_send_parser_(d);
- return std::any(std::move(id));
- }
- else
- {
- typename detail::remove_cvref_t<RecvDataT>& d = *((typename detail::remove_cvref_t<RecvDataT>*)data);
- key_type id = rdc_recv_parser_(d);
- return std::any(std::move(id));
- }
- }
- virtual void emplace_request(std::any& k, void* v) override
- {
- key_type& key = *std::any_cast<key_type>(std::addressof(k));
- val_type& val = *((val_type*)v);
- // 2023-07-11 bug fix : can't use std::move(key), beacuse the key will be used at later.
- rdc_invoker_.emplace(key, std::move(val));
- }
- virtual void execute_and_erase(std::any& k, std::function<void(void*)> cb) override
- {
- key_type& key = *std::any_cast<key_type>(std::addressof(k));
- if (auto iter = rdc_invoker_.find(key); iter != rdc_invoker_.end())
- {
- cb((void*)(std::addressof(iter->second)));
- rdc_invoker_.erase(iter);
- }
- }
- virtual void foreach_and_clear(std::function<void(void*, void*)> cb) override
- {
- for (auto& [k, v] : rdc_invoker_.reqs())
- {
- cb((void*)std::addressof(k), (void*)std::addressof(v));
- }
- rdc_invoker_.reqs().clear();
- }
- };
- // C++17 class template argument deduction guides
- template<class ParserFun>
- option(ParserFun)->option<
- typename detail::function_traits<detail::remove_cvref_t<ParserFun>>::return_type,
- typename detail::function_traits<detail::remove_cvref_t<ParserFun>>::template args<0>::type,
- typename detail::function_traits<detail::remove_cvref_t<ParserFun>>::template args<0>::type
- >;
- template<class SendParserFun, class RecvParserFun>
- option(SendParserFun, RecvParserFun)->option<
- typename detail::function_traits<detail::remove_cvref_t<SendParserFun>>::return_type,
- typename detail::function_traits<detail::remove_cvref_t<SendParserFun>>::template args<0>::type,
- typename detail::function_traits<detail::remove_cvref_t<RecvParserFun>>::template args<0>::type
- >;
- }
- #endif // !__ASIO2_RDC_OPTION_HPP__
|