intermediate_handler.hpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. //
  2. // Copyright (c) 2019-2025 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. #ifndef BOOST_MYSQL_DETAIL_INTERMEDIATE_HANDLER_HPP
  8. #define BOOST_MYSQL_DETAIL_INTERMEDIATE_HANDLER_HPP
  9. #include <boost/asio/associator.hpp>
  10. #include <utility>
  11. namespace boost {
  12. namespace mysql {
  13. namespace detail {
  14. // An intermediate handler that propagates associated characteristics.
  15. // HandlerFn must be a function void(Handler&&, args...) that calls the handler
  16. template <class HandlerFn, class FinalHandler>
  17. struct intermediate_handler
  18. {
  19. HandlerFn fn;
  20. FinalHandler handler;
  21. template <class... Args>
  22. void operator()(Args&&... args)
  23. {
  24. fn(std::move(handler), std::forward<Args>(args)...);
  25. }
  26. };
  27. template <class HandlerFn, class FinalHandler>
  28. intermediate_handler<typename std::decay<HandlerFn>::type, typename std::decay<FinalHandler>::type> make_intermediate_handler(
  29. HandlerFn&& fn,
  30. FinalHandler&& handler
  31. )
  32. {
  33. return {std::forward<HandlerFn>(fn), std::forward<FinalHandler>(handler)};
  34. }
  35. } // namespace detail
  36. } // namespace mysql
  37. namespace asio {
  38. template <
  39. template <typename, typename>
  40. class Associator,
  41. class HandlerFn,
  42. class FinalHandler,
  43. typename DefaultCandidate>
  44. struct associator<Associator, mysql::detail::intermediate_handler<HandlerFn, FinalHandler>, DefaultCandidate>
  45. : Associator<FinalHandler, DefaultCandidate>
  46. {
  47. static typename Associator<FinalHandler, DefaultCandidate>::type get(
  48. const mysql::detail::intermediate_handler<HandlerFn, FinalHandler>& h
  49. ) noexcept
  50. {
  51. return Associator<FinalHandler, DefaultCandidate>::get(h.handler);
  52. }
  53. static auto get(
  54. const mysql::detail::intermediate_handler<HandlerFn, FinalHandler>& h,
  55. const DefaultCandidate& c
  56. ) noexcept -> decltype(Associator<FinalHandler, DefaultCandidate>::get(h.handler, c))
  57. {
  58. return Associator<FinalHandler, DefaultCandidate>::get(h.handler, c);
  59. }
  60. };
  61. } // namespace asio
  62. } // namespace boost
  63. #endif