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