channel_traits.hpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. //
  2. // Copyright (c) 2023-2025 Ivica Siladic, Bruno Iljazovic, Korina Simicevic
  3. //
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. #ifndef BOOST_MQTT5_CHANNEL_TRAITS_HPP
  8. #define BOOST_MQTT5_CHANNEL_TRAITS_HPP
  9. #include <boost/asio/error.hpp>
  10. #include <deque>
  11. #include <type_traits>
  12. namespace boost::mqtt5::detail {
  13. namespace asio = boost::asio;
  14. using error_code = boost::system::error_code;
  15. template <typename Element>
  16. class bounded_deque {
  17. std::deque<Element> _buffer;
  18. static constexpr size_t MAX_SIZE = 65535;
  19. public:
  20. bounded_deque() = default;
  21. bounded_deque(size_t n) : _buffer(n) {}
  22. size_t size() const {
  23. return _buffer.size();
  24. }
  25. template <typename E>
  26. void push_back(E&& e) {
  27. if (_buffer.size() == MAX_SIZE)
  28. _buffer.pop_front();
  29. _buffer.push_back(std::forward<E>(e));
  30. }
  31. void pop_front() {
  32. _buffer.pop_front();
  33. }
  34. void clear() {
  35. _buffer.clear();
  36. }
  37. const auto& front() const noexcept {
  38. return _buffer.front();
  39. }
  40. auto& front() noexcept {
  41. return _buffer.front();
  42. }
  43. };
  44. template <typename... Signatures>
  45. struct channel_traits {
  46. template <typename... NewSignatures>
  47. struct rebind {
  48. using other = channel_traits<NewSignatures...>;
  49. };
  50. };
  51. template <typename R, typename... Args>
  52. struct channel_traits<R(error_code, Args...)> {
  53. static_assert(sizeof...(Args) > 0);
  54. template <typename... NewSignatures>
  55. struct rebind {
  56. using other = channel_traits<NewSignatures...>;
  57. };
  58. template <typename Element>
  59. struct container {
  60. using type = bounded_deque<Element>;
  61. };
  62. using receive_cancelled_signature = R(error_code, Args...);
  63. template <typename F>
  64. static void invoke_receive_cancelled(F f) {
  65. std::forward<F>(f)(
  66. asio::error::operation_aborted,
  67. typename std::decay_t<Args>()...
  68. );
  69. }
  70. using receive_closed_signature = R(error_code, Args...);
  71. template <typename F>
  72. static void invoke_receive_closed(F f) {
  73. std::forward<F>(f)(
  74. asio::error::operation_aborted,
  75. typename std::decay_t<Args>()...
  76. );
  77. }
  78. };
  79. } // namespace boost::mqtt5::detail
  80. #endif // !BOOST_MQTT5_CHANNEL_TRAITS_HPP