is_buffer_sequence.hpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. //
  2. // detail/is_buffer_sequence.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2023 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. #ifndef ASIO_DETAIL_IS_BUFFER_SEQUENCE_HPP
  11. #define ASIO_DETAIL_IS_BUFFER_SEQUENCE_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include "asio/detail/config.hpp"
  16. #include "asio/detail/type_traits.hpp"
  17. #include "asio/detail/push_options.hpp"
  18. namespace asio {
  19. class mutable_buffer;
  20. class const_buffer;
  21. class mutable_registered_buffer;
  22. class const_registered_buffer;
  23. namespace detail {
  24. struct buffer_sequence_memfns_base
  25. {
  26. void begin();
  27. void end();
  28. void size();
  29. void max_size();
  30. void capacity();
  31. void data();
  32. void prepare();
  33. void commit();
  34. void consume();
  35. void grow();
  36. void shrink();
  37. };
  38. template <typename T>
  39. struct buffer_sequence_memfns_derived
  40. : T, buffer_sequence_memfns_base
  41. {
  42. };
  43. template <typename T, T>
  44. struct buffer_sequence_memfns_check
  45. {
  46. };
  47. template <typename>
  48. char buffer_sequence_begin_helper(...);
  49. template <typename T>
  50. char (&buffer_sequence_begin_helper(T* t,
  51. enable_if_t<!is_same<
  52. decltype(asio::buffer_sequence_begin(*t)),
  53. void>::value>*))[2];
  54. template <typename>
  55. char buffer_sequence_end_helper(...);
  56. template <typename T>
  57. char (&buffer_sequence_end_helper(T* t,
  58. enable_if_t<!is_same<
  59. decltype(asio::buffer_sequence_end(*t)),
  60. void>::value>*))[2];
  61. template <typename>
  62. char (&size_memfn_helper(...))[2];
  63. template <typename T>
  64. char size_memfn_helper(
  65. buffer_sequence_memfns_check<
  66. void (buffer_sequence_memfns_base::*)(),
  67. &buffer_sequence_memfns_derived<T>::size>*);
  68. template <typename>
  69. char (&max_size_memfn_helper(...))[2];
  70. template <typename T>
  71. char max_size_memfn_helper(
  72. buffer_sequence_memfns_check<
  73. void (buffer_sequence_memfns_base::*)(),
  74. &buffer_sequence_memfns_derived<T>::max_size>*);
  75. template <typename>
  76. char (&capacity_memfn_helper(...))[2];
  77. template <typename T>
  78. char capacity_memfn_helper(
  79. buffer_sequence_memfns_check<
  80. void (buffer_sequence_memfns_base::*)(),
  81. &buffer_sequence_memfns_derived<T>::capacity>*);
  82. template <typename>
  83. char (&data_memfn_helper(...))[2];
  84. template <typename T>
  85. char data_memfn_helper(
  86. buffer_sequence_memfns_check<
  87. void (buffer_sequence_memfns_base::*)(),
  88. &buffer_sequence_memfns_derived<T>::data>*);
  89. template <typename>
  90. char (&prepare_memfn_helper(...))[2];
  91. template <typename T>
  92. char prepare_memfn_helper(
  93. buffer_sequence_memfns_check<
  94. void (buffer_sequence_memfns_base::*)(),
  95. &buffer_sequence_memfns_derived<T>::prepare>*);
  96. template <typename>
  97. char (&commit_memfn_helper(...))[2];
  98. template <typename T>
  99. char commit_memfn_helper(
  100. buffer_sequence_memfns_check<
  101. void (buffer_sequence_memfns_base::*)(),
  102. &buffer_sequence_memfns_derived<T>::commit>*);
  103. template <typename>
  104. char (&consume_memfn_helper(...))[2];
  105. template <typename T>
  106. char consume_memfn_helper(
  107. buffer_sequence_memfns_check<
  108. void (buffer_sequence_memfns_base::*)(),
  109. &buffer_sequence_memfns_derived<T>::consume>*);
  110. template <typename>
  111. char (&grow_memfn_helper(...))[2];
  112. template <typename T>
  113. char grow_memfn_helper(
  114. buffer_sequence_memfns_check<
  115. void (buffer_sequence_memfns_base::*)(),
  116. &buffer_sequence_memfns_derived<T>::grow>*);
  117. template <typename>
  118. char (&shrink_memfn_helper(...))[2];
  119. template <typename T>
  120. char shrink_memfn_helper(
  121. buffer_sequence_memfns_check<
  122. void (buffer_sequence_memfns_base::*)(),
  123. &buffer_sequence_memfns_derived<T>::shrink>*);
  124. template <typename, typename>
  125. char (&buffer_sequence_element_type_helper(...))[2];
  126. template <typename T, typename Buffer>
  127. char buffer_sequence_element_type_helper(T* t,
  128. enable_if_t<is_convertible<
  129. decltype(*asio::buffer_sequence_begin(*t)),
  130. Buffer>::value>*);
  131. template <typename>
  132. char (&const_buffers_type_typedef_helper(...))[2];
  133. template <typename T>
  134. char const_buffers_type_typedef_helper(
  135. typename T::const_buffers_type*);
  136. template <typename>
  137. char (&mutable_buffers_type_typedef_helper(...))[2];
  138. template <typename T>
  139. char mutable_buffers_type_typedef_helper(
  140. typename T::mutable_buffers_type*);
  141. template <typename T, typename Buffer>
  142. struct is_buffer_sequence_class
  143. : integral_constant<bool,
  144. sizeof(buffer_sequence_begin_helper<T>(0, 0)) != 1 &&
  145. sizeof(buffer_sequence_end_helper<T>(0, 0)) != 1 &&
  146. sizeof(buffer_sequence_element_type_helper<T, Buffer>(0, 0)) == 1>
  147. {
  148. };
  149. template <typename T, typename Buffer>
  150. struct is_buffer_sequence
  151. : conditional<is_class<T>::value,
  152. is_buffer_sequence_class<T, Buffer>,
  153. false_type>::type
  154. {
  155. };
  156. template <>
  157. struct is_buffer_sequence<mutable_buffer, mutable_buffer>
  158. : true_type
  159. {
  160. };
  161. template <>
  162. struct is_buffer_sequence<mutable_buffer, const_buffer>
  163. : true_type
  164. {
  165. };
  166. template <>
  167. struct is_buffer_sequence<const_buffer, const_buffer>
  168. : true_type
  169. {
  170. };
  171. template <>
  172. struct is_buffer_sequence<const_buffer, mutable_buffer>
  173. : false_type
  174. {
  175. };
  176. template <>
  177. struct is_buffer_sequence<mutable_registered_buffer, mutable_buffer>
  178. : true_type
  179. {
  180. };
  181. template <>
  182. struct is_buffer_sequence<mutable_registered_buffer, const_buffer>
  183. : true_type
  184. {
  185. };
  186. template <>
  187. struct is_buffer_sequence<const_registered_buffer, const_buffer>
  188. : true_type
  189. {
  190. };
  191. template <>
  192. struct is_buffer_sequence<const_registered_buffer, mutable_buffer>
  193. : false_type
  194. {
  195. };
  196. template <typename T>
  197. struct is_dynamic_buffer_class_v1
  198. : integral_constant<bool,
  199. sizeof(size_memfn_helper<T>(0)) != 1 &&
  200. sizeof(max_size_memfn_helper<T>(0)) != 1 &&
  201. sizeof(capacity_memfn_helper<T>(0)) != 1 &&
  202. sizeof(data_memfn_helper<T>(0)) != 1 &&
  203. sizeof(consume_memfn_helper<T>(0)) != 1 &&
  204. sizeof(prepare_memfn_helper<T>(0)) != 1 &&
  205. sizeof(commit_memfn_helper<T>(0)) != 1 &&
  206. sizeof(const_buffers_type_typedef_helper<T>(0)) == 1 &&
  207. sizeof(mutable_buffers_type_typedef_helper<T>(0)) == 1>
  208. {
  209. };
  210. template <typename T>
  211. struct is_dynamic_buffer_v1
  212. : conditional<is_class<T>::value,
  213. is_dynamic_buffer_class_v1<T>,
  214. false_type>::type
  215. {
  216. };
  217. template <typename T>
  218. struct is_dynamic_buffer_class_v2
  219. : integral_constant<bool,
  220. sizeof(size_memfn_helper<T>(0)) != 1 &&
  221. sizeof(max_size_memfn_helper<T>(0)) != 1 &&
  222. sizeof(capacity_memfn_helper<T>(0)) != 1 &&
  223. sizeof(data_memfn_helper<T>(0)) != 1 &&
  224. sizeof(consume_memfn_helper<T>(0)) != 1 &&
  225. sizeof(grow_memfn_helper<T>(0)) != 1 &&
  226. sizeof(shrink_memfn_helper<T>(0)) != 1 &&
  227. sizeof(const_buffers_type_typedef_helper<T>(0)) == 1 &&
  228. sizeof(mutable_buffers_type_typedef_helper<T>(0)) == 1>
  229. {
  230. };
  231. template <typename T>
  232. struct is_dynamic_buffer_v2
  233. : conditional<is_class<T>::value,
  234. is_dynamic_buffer_class_v2<T>,
  235. false_type>::type
  236. {
  237. };
  238. } // namespace detail
  239. } // namespace asio
  240. #include "asio/detail/pop_options.hpp"
  241. #endif // ASIO_DETAIL_IS_BUFFER_SEQUENCE_HPP