1 //
2 // detail/is_buffer_sequence.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot 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 
11 #ifndef BOOST_ASIO_DETAIL_IS_BUFFER_SEQUENCE_HPP
12 #define BOOST_ASIO_DETAIL_IS_BUFFER_SEQUENCE_HPP
13 
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17 
18 #include <boost/asio/detail/config.hpp>
19 #include <boost/asio/detail/type_traits.hpp>
20 
21 #include <boost/asio/detail/push_options.hpp>
22 
23 namespace boost {
24 namespace asio {
25 
26 class mutable_buffer;
27 class const_buffer;
28 
29 namespace detail {
30 
31 struct buffer_sequence_memfns_base
32 {
33   void begin();
34   void end();
35   void size();
36   void max_size();
37   void capacity();
38   void data();
39   void prepare();
40   void commit();
41   void consume();
42   void grow();
43   void shrink();
44 };
45 
46 template <typename T>
47 struct buffer_sequence_memfns_derived
48   : T, buffer_sequence_memfns_base
49 {
50 };
51 
52 template <typename T, T>
53 struct buffer_sequence_memfns_check
54 {
55 };
56 
57 #if defined(BOOST_ASIO_HAS_DECLTYPE)
58 
59 template <typename>
60 char buffer_sequence_begin_helper(...);
61 
62 template <typename T>
63 char (&buffer_sequence_begin_helper(T* t,
64     typename enable_if<!is_same<
65       decltype(boost::asio::buffer_sequence_begin(*t)),
66         void>::value>::type*))[2];
67 
68 #else // defined(BOOST_ASIO_HAS_DECLTYPE)
69 
70 template <typename>
71 char (&buffer_sequence_begin_helper(...))[2];
72 
73 template <typename T>
74 char buffer_sequence_begin_helper(T* t,
75     buffer_sequence_memfns_check<
76       void (buffer_sequence_memfns_base::*)(),
77       &buffer_sequence_memfns_derived<T>::begin>*);
78 
79 #endif // defined(BOOST_ASIO_HAS_DECLTYPE)
80 
81 #if defined(BOOST_ASIO_HAS_DECLTYPE)
82 
83 template <typename>
84 char buffer_sequence_end_helper(...);
85 
86 template <typename T>
87 char (&buffer_sequence_end_helper(T* t,
88     typename enable_if<!is_same<
89       decltype(boost::asio::buffer_sequence_end(*t)),
90         void>::value>::type*))[2];
91 
92 #else // defined(BOOST_ASIO_HAS_DECLTYPE)
93 
94 template <typename>
95 char (&buffer_sequence_end_helper(...))[2];
96 
97 template <typename T>
98 char buffer_sequence_end_helper(T* t,
99     buffer_sequence_memfns_check<
100       void (buffer_sequence_memfns_base::*)(),
101       &buffer_sequence_memfns_derived<T>::end>*);
102 
103 #endif // defined(BOOST_ASIO_HAS_DECLTYPE)
104 
105 template <typename>
106 char (&size_memfn_helper(...))[2];
107 
108 template <typename T>
109 char size_memfn_helper(
110     buffer_sequence_memfns_check<
111       void (buffer_sequence_memfns_base::*)(),
112       &buffer_sequence_memfns_derived<T>::size>*);
113 
114 template <typename>
115 char (&max_size_memfn_helper(...))[2];
116 
117 template <typename T>
118 char max_size_memfn_helper(
119     buffer_sequence_memfns_check<
120       void (buffer_sequence_memfns_base::*)(),
121       &buffer_sequence_memfns_derived<T>::max_size>*);
122 
123 template <typename>
124 char (&capacity_memfn_helper(...))[2];
125 
126 template <typename T>
127 char capacity_memfn_helper(
128     buffer_sequence_memfns_check<
129       void (buffer_sequence_memfns_base::*)(),
130       &buffer_sequence_memfns_derived<T>::capacity>*);
131 
132 template <typename>
133 char (&data_memfn_helper(...))[2];
134 
135 template <typename T>
136 char data_memfn_helper(
137     buffer_sequence_memfns_check<
138       void (buffer_sequence_memfns_base::*)(),
139       &buffer_sequence_memfns_derived<T>::data>*);
140 
141 template <typename>
142 char (&prepare_memfn_helper(...))[2];
143 
144 template <typename T>
145 char prepare_memfn_helper(
146     buffer_sequence_memfns_check<
147       void (buffer_sequence_memfns_base::*)(),
148       &buffer_sequence_memfns_derived<T>::prepare>*);
149 
150 template <typename>
151 char (&commit_memfn_helper(...))[2];
152 
153 template <typename T>
154 char commit_memfn_helper(
155     buffer_sequence_memfns_check<
156       void (buffer_sequence_memfns_base::*)(),
157       &buffer_sequence_memfns_derived<T>::commit>*);
158 
159 template <typename>
160 char (&consume_memfn_helper(...))[2];
161 
162 template <typename T>
163 char consume_memfn_helper(
164     buffer_sequence_memfns_check<
165       void (buffer_sequence_memfns_base::*)(),
166       &buffer_sequence_memfns_derived<T>::consume>*);
167 
168 template <typename>
169 char (&grow_memfn_helper(...))[2];
170 
171 template <typename T>
172 char grow_memfn_helper(
173     buffer_sequence_memfns_check<
174       void (buffer_sequence_memfns_base::*)(),
175       &buffer_sequence_memfns_derived<T>::grow>*);
176 
177 template <typename>
178 char (&shrink_memfn_helper(...))[2];
179 
180 template <typename T>
181 char shrink_memfn_helper(
182     buffer_sequence_memfns_check<
183       void (buffer_sequence_memfns_base::*)(),
184       &buffer_sequence_memfns_derived<T>::shrink>*);
185 
186 template <typename, typename>
187 char (&buffer_sequence_element_type_helper(...))[2];
188 
189 #if defined(BOOST_ASIO_HAS_DECLTYPE)
190 
191 template <typename T, typename Buffer>
192 char buffer_sequence_element_type_helper(T* t,
193     typename enable_if<is_convertible<
194       decltype(*boost::asio::buffer_sequence_begin(*t)),
195         Buffer>::value>::type*);
196 
197 #else // defined(BOOST_ASIO_HAS_DECLTYPE)
198 
199 template <typename T, typename Buffer>
200 char buffer_sequence_element_type_helper(
201     typename T::const_iterator*,
202     typename enable_if<is_convertible<
203       typename T::value_type, Buffer>::value>::type*);
204 
205 #endif // defined(BOOST_ASIO_HAS_DECLTYPE)
206 
207 template <typename>
208 char (&const_buffers_type_typedef_helper(...))[2];
209 
210 template <typename T>
211 char const_buffers_type_typedef_helper(
212     typename T::const_buffers_type*);
213 
214 template <typename>
215 char (&mutable_buffers_type_typedef_helper(...))[2];
216 
217 template <typename T>
218 char mutable_buffers_type_typedef_helper(
219     typename T::mutable_buffers_type*);
220 
221 template <typename T, typename Buffer>
222 struct is_buffer_sequence_class
223   : integral_constant<bool,
224       sizeof(buffer_sequence_begin_helper<T>(0, 0)) != 1 &&
225       sizeof(buffer_sequence_end_helper<T>(0, 0)) != 1 &&
226       sizeof(buffer_sequence_element_type_helper<T, Buffer>(0, 0)) == 1>
227 {
228 };
229 
230 template <typename T, typename Buffer>
231 struct is_buffer_sequence
232   : conditional<is_class<T>::value,
233       is_buffer_sequence_class<T, Buffer>,
234       false_type>::type
235 {
236 };
237 
238 template <>
239 struct is_buffer_sequence<mutable_buffer, mutable_buffer>
240   : true_type
241 {
242 };
243 
244 template <>
245 struct is_buffer_sequence<mutable_buffer, const_buffer>
246   : true_type
247 {
248 };
249 
250 template <>
251 struct is_buffer_sequence<const_buffer, const_buffer>
252   : true_type
253 {
254 };
255 
256 template <>
257 struct is_buffer_sequence<const_buffer, mutable_buffer>
258   : false_type
259 {
260 };
261 
262 template <typename T>
263 struct is_dynamic_buffer_class_v1
264   : integral_constant<bool,
265       sizeof(size_memfn_helper<T>(0)) != 1 &&
266       sizeof(max_size_memfn_helper<T>(0)) != 1 &&
267       sizeof(capacity_memfn_helper<T>(0)) != 1 &&
268       sizeof(data_memfn_helper<T>(0)) != 1 &&
269       sizeof(consume_memfn_helper<T>(0)) != 1 &&
270       sizeof(prepare_memfn_helper<T>(0)) != 1 &&
271       sizeof(commit_memfn_helper<T>(0)) != 1 &&
272       sizeof(const_buffers_type_typedef_helper<T>(0)) == 1 &&
273       sizeof(mutable_buffers_type_typedef_helper<T>(0)) == 1>
274 {
275 };
276 
277 template <typename T>
278 struct is_dynamic_buffer_v1
279   : conditional<is_class<T>::value,
280       is_dynamic_buffer_class_v1<T>,
281       false_type>::type
282 {
283 };
284 
285 template <typename T>
286 struct is_dynamic_buffer_class_v2
287   : integral_constant<bool,
288       sizeof(size_memfn_helper<T>(0)) != 1 &&
289       sizeof(max_size_memfn_helper<T>(0)) != 1 &&
290       sizeof(capacity_memfn_helper<T>(0)) != 1 &&
291       sizeof(data_memfn_helper<T>(0)) != 1 &&
292       sizeof(consume_memfn_helper<T>(0)) != 1 &&
293       sizeof(grow_memfn_helper<T>(0)) != 1 &&
294       sizeof(shrink_memfn_helper<T>(0)) != 1 &&
295       sizeof(const_buffers_type_typedef_helper<T>(0)) == 1 &&
296       sizeof(mutable_buffers_type_typedef_helper<T>(0)) == 1>
297 {
298 };
299 
300 template <typename T>
301 struct is_dynamic_buffer_v2
302   : conditional<is_class<T>::value,
303       is_dynamic_buffer_class_v2<T>,
304       false_type>::type
305 {
306 };
307 
308 } // namespace detail
309 } // namespace asio
310 } // namespace boost
311 
312 #include <boost/asio/detail/pop_options.hpp>
313 
314 #endif // BOOST_ASIO_DETAIL_IS_BUFFER_SEQUENCE_HPP
315