async_mqtt 9.0.1
Loading...
Searching...
No Matches
stream_traits.hpp
1// Copyright Takatoshi Kondo 2022
2//
3// Distributed under the Boost Software License, Version 1.0.
4// (See accompanying file LICENSE_1_0.txt or copy at
5// http://www.boost.org/LICENSE_1_0.txt)
6
7#if !defined(ASYNC_MQTT_UTIL_STREAM_TRAITS_HPP)
8#define ASYNC_MQTT_UTIL_STREAM_TRAITS_HPP
9
10#include <type_traits>
11#include <vector>
12
13#include <boost/asio/buffer.hpp>
14#include <boost/asio/any_completion_handler.hpp>
15#include <boost/asio/any_io_executor.hpp>
16
17#include <async_mqtt/error.hpp>
18
19namespace async_mqtt {
20
21namespace as = boost::asio;
22
23namespace detail {
24
25template <typename T>
26std::false_type has_next_layer_impl(void*);
27
28template <typename T>
29auto has_next_layer_impl(decltype(nullptr)) ->
30 decltype(std::declval<T&>().next_layer(), std::true_type{});
31
32} // namespace detail
33
34template <typename T>
35using has_next_layer = decltype(detail::has_next_layer_impl<T>(nullptr));
36
37
38namespace detail {
39
40template<typename T, bool = has_next_layer<T>::value>
41struct lowest_layer_type_impl {
42 using type = typename std::remove_reference<T>::type;
43};
44
45template<typename T>
46struct lowest_layer_type_impl<T, true> {
47 using type = typename lowest_layer_type_impl<
48 decltype(std::declval<T&>().next_layer())>::type;
49};
50
51} // namespace detail
52
53template<typename T>
54using lowest_layer_type = typename detail::lowest_layer_type_impl<T>::type;
55
56namespace detail {
57
58template<typename T>
59T&
60get_lowest_layer_impl(T& t, std::false_type) noexcept {
61 return t;
62}
63
64template<typename T>
65lowest_layer_type<T>&
66get_lowest_layer_impl(T& t, std::true_type) noexcept {
67 return
68 get_lowest_layer_impl(
69 t.next_layer(),
70 has_next_layer<typename std::decay<decltype(t.next_layer())>::type>{}
71 );
72}
73
74} // namespace detail
75
76
77template<typename T>
78using executor_type = decltype(std::declval<T>().get_executor());
79
80template<typename T>
81lowest_layer_type<T>& get_lowest_layer(T& t) noexcept {
82 return
83 detail::get_lowest_layer_impl(
84 t,
85 has_next_layer<T>{}
86 );
87}
88
100template <typename Layer>
102
103// initialze
104
105template <typename Layer, typename = void>
106struct has_initialize : std::false_type {};
107
108template <typename Layer>
109struct has_initialize<
110 Layer,
111 std::void_t<
112 decltype(layer_customize<Layer>::initialize(std::declval<Layer&>()))
113 >
114> : std::true_type {};
115
116// async_read
117
118template <typename Layer, typename = void>
119struct has_async_read : std::false_type {};
120
121template <typename Layer>
122struct has_async_read<
123 Layer,
124 std::void_t<
125 decltype(
126 layer_customize<Layer>::async_read(
127 std::declval<Layer&>(),
128 std::declval<as::mutable_buffer const&>(),
129 std::declval<as::any_completion_handler<void(error_code const&, std::size_t)>>()
130 )
131 )
132 >
133> : std::true_type {};
134
135// async_read_some
136
137template <typename Layer, typename = void>
138struct has_async_read_some : std::false_type {};
139
140template <typename Layer>
141struct has_async_read_some<
142 Layer,
143 std::void_t<
144 decltype(
145 layer_customize<Layer>::async_read_some(
146 std::declval<Layer&>(),
147 std::declval<as::mutable_buffer const&>(),
148 std::declval<as::any_completion_handler<void(error_code const&, std::size_t)>>()
149 )
150 )
151 >
152> : std::true_type {};
153
154// async_write
155
156template <typename Layer, typename = void>
157struct has_async_write : std::false_type {};
158
159template <typename Layer>
160struct has_async_write<
161 Layer,
162 std::void_t<
163 decltype(
164 layer_customize<Layer>::async_write(
165 std::declval<Layer&>(),
166 std::declval<std::vector<as::const_buffer> const&>(),
167 std::declval<as::any_completion_handler<void(error_code const&, std::size_t)>>()
168 )
169 )
170 >
171> : std::true_type {};
172
173// async_close
174
175template <typename Layer, typename = void>
176struct has_async_close : std::false_type {};
177
178template <typename Layer>
179struct has_async_close<
180 Layer,
181 std::void_t<
182 decltype(
183 layer_customize<Layer>::async_close(
184 std::declval<Layer&>(),
185 std::declval<as::any_completion_handler<void(error_code const&)>>()
186 )
187 )
188 >
189> : std::true_type {};
190
191} // namespace async_mqtt
192
193#endif // ASYNC_MQTT_UTIL_STREAM_TRAITS_HPP
customization class template for underlying layer In order to adapt your layer to async_mqtt,...
Definition stream_traits.hpp:101