| 1 | // <experimental/buffer> -*- C++ -*-
 | 
|---|
| 2 | 
 | 
|---|
| 3 | // Copyright (C) 2015-2021 Free Software Foundation, Inc.
 | 
|---|
| 4 | //
 | 
|---|
| 5 | // This file is part of the GNU ISO C++ Library.  This library is free
 | 
|---|
| 6 | // software; you can redistribute it and/or modify it under the
 | 
|---|
| 7 | // terms of the GNU General Public License as published by the
 | 
|---|
| 8 | // Free Software Foundation; either version 3, or (at your option)
 | 
|---|
| 9 | // any later version.
 | 
|---|
| 10 | 
 | 
|---|
| 11 | // This library is distributed in the hope that it will be useful,
 | 
|---|
| 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
|---|
| 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
|---|
| 14 | // GNU General Public License for more details.
 | 
|---|
| 15 | 
 | 
|---|
| 16 | // Under Section 7 of GPL version 3, you are granted additional
 | 
|---|
| 17 | // permissions described in the GCC Runtime Library Exception, version
 | 
|---|
| 18 | // 3.1, as published by the Free Software Foundation.
 | 
|---|
| 19 | 
 | 
|---|
| 20 | // You should have received a copy of the GNU General Public License and
 | 
|---|
| 21 | // a copy of the GCC Runtime Library Exception along with this program;
 | 
|---|
| 22 | // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 | 
|---|
| 23 | // <http://www.gnu.org/licenses/>.
 | 
|---|
| 24 | 
 | 
|---|
| 25 | /** @file experimental/buffer
 | 
|---|
| 26 |  *  This is a TS C++ Library header.
 | 
|---|
| 27 |  *  @ingroup networking-ts
 | 
|---|
| 28 |  */
 | 
|---|
| 29 | 
 | 
|---|
| 30 | #ifndef _GLIBCXX_EXPERIMENTAL_BUFFER
 | 
|---|
| 31 | #define _GLIBCXX_EXPERIMENTAL_BUFFER 1
 | 
|---|
| 32 | 
 | 
|---|
| 33 | #pragma GCC system_header
 | 
|---|
| 34 | 
 | 
|---|
| 35 | #if __cplusplus >= 201402L
 | 
|---|
| 36 | 
 | 
|---|
| 37 | #include <array>
 | 
|---|
| 38 | #include <string>
 | 
|---|
| 39 | #include <system_error>
 | 
|---|
| 40 | #include <vector>
 | 
|---|
| 41 | #include <cstring>
 | 
|---|
| 42 | #include <experimental/string_view>
 | 
|---|
| 43 | #include <experimental/bits/net.h>
 | 
|---|
| 44 | 
 | 
|---|
| 45 | namespace std _GLIBCXX_VISIBILITY(default)
 | 
|---|
| 46 | {
 | 
|---|
| 47 | _GLIBCXX_BEGIN_NAMESPACE_VERSION
 | 
|---|
| 48 | namespace experimental
 | 
|---|
| 49 | {
 | 
|---|
| 50 | namespace net
 | 
|---|
| 51 | {
 | 
|---|
| 52 | inline namespace v1
 | 
|---|
| 53 | {
 | 
|---|
| 54 | 
 | 
|---|
| 55 |   /** @addtogroup networking-ts
 | 
|---|
| 56 |    *  @{
 | 
|---|
| 57 |    */
 | 
|---|
| 58 | 
 | 
|---|
| 59 |   enum class stream_errc {    // TODO decide values
 | 
|---|
| 60 |     eof = 1,
 | 
|---|
| 61 |     not_found = 2
 | 
|---|
| 62 |   };
 | 
|---|
| 63 | 
 | 
|---|
| 64 |   const error_category& stream_category() noexcept // TODO not inline
 | 
|---|
| 65 |   {
 | 
|---|
| 66 |     struct __cat : error_category
 | 
|---|
| 67 |     {
 | 
|---|
| 68 |       const char* name() const noexcept { return "stream"; }
 | 
|---|
| 69 | 
 | 
|---|
| 70 |       std::string message(int __e) const
 | 
|---|
| 71 |       {
 | 
|---|
| 72 |         if (__e == (int)stream_errc::eof)
 | 
|---|
| 73 |           return "EOF";
 | 
|---|
| 74 |         else if (__e == (int)stream_errc::not_found)
 | 
|---|
| 75 |           return "not found";
 | 
|---|
| 76 |         return "stream";
 | 
|---|
| 77 |       }
 | 
|---|
| 78 | 
 | 
|---|
| 79 |       virtual void __message(int) { } // TODO dual ABI XXX
 | 
|---|
| 80 |     };
 | 
|---|
| 81 |     static __cat __c;
 | 
|---|
| 82 |     return __c;
 | 
|---|
| 83 |   }
 | 
|---|
| 84 | 
 | 
|---|
| 85 |   inline error_code
 | 
|---|
| 86 |   make_error_code(stream_errc __e) noexcept
 | 
|---|
| 87 |   { return error_code(static_cast<int>(__e), stream_category()); }
 | 
|---|
| 88 | 
 | 
|---|
| 89 |   inline error_condition
 | 
|---|
| 90 |   make_error_condition(stream_errc __e) noexcept
 | 
|---|
| 91 |   { return error_condition(static_cast<int>(__e), stream_category()); }
 | 
|---|
| 92 | 
 | 
|---|
| 93 |   class mutable_buffer
 | 
|---|
| 94 |   {
 | 
|---|
| 95 |   public:
 | 
|---|
| 96 |     // constructors:
 | 
|---|
| 97 |     mutable_buffer() noexcept : _M_data(), _M_size() { }
 | 
|---|
| 98 | 
 | 
|---|
| 99 |     mutable_buffer(void* __p, size_t __n) noexcept
 | 
|---|
| 100 |     : _M_data(__p), _M_size(__n) { }
 | 
|---|
| 101 | 
 | 
|---|
| 102 |     // members:
 | 
|---|
| 103 |     void* data() const noexcept { return _M_data; }
 | 
|---|
| 104 |     size_t size() const noexcept { return _M_size; }
 | 
|---|
| 105 | 
 | 
|---|
| 106 |   private:
 | 
|---|
| 107 |     void*       _M_data;
 | 
|---|
| 108 |     size_t      _M_size;
 | 
|---|
| 109 |   };
 | 
|---|
| 110 | 
 | 
|---|
| 111 |   class const_buffer
 | 
|---|
| 112 |   {
 | 
|---|
| 113 |   public:
 | 
|---|
| 114 |     // constructors:
 | 
|---|
| 115 |     const_buffer() noexcept : _M_data(), _M_size() { }
 | 
|---|
| 116 | 
 | 
|---|
| 117 |     const_buffer(const void* __p, size_t __n) noexcept
 | 
|---|
| 118 |     : _M_data(__p), _M_size(__n) { }
 | 
|---|
| 119 | 
 | 
|---|
| 120 |     const_buffer(const mutable_buffer& __b) noexcept
 | 
|---|
| 121 |     : _M_data(__b.data()), _M_size(__b.size()) { }
 | 
|---|
| 122 | 
 | 
|---|
| 123 |     // members:
 | 
|---|
| 124 |     const void* data() const noexcept { return _M_data; }
 | 
|---|
| 125 |     size_t size() const noexcept { return _M_size; }
 | 
|---|
| 126 | 
 | 
|---|
| 127 |   private:
 | 
|---|
| 128 |     const void* _M_data;
 | 
|---|
| 129 |     size_t      _M_size;
 | 
|---|
| 130 |   };
 | 
|---|
| 131 | 
 | 
|---|
| 132 | 
 | 
|---|
| 133 |   /** @brief buffer sequence access
 | 
|---|
| 134 |    *
 | 
|---|
| 135 |    * Uniform access to types that meet the BufferSequence requirements.
 | 
|---|
| 136 |    * @{
 | 
|---|
| 137 |    */
 | 
|---|
| 138 | 
 | 
|---|
| 139 |   inline const mutable_buffer*
 | 
|---|
| 140 |   buffer_sequence_begin(const mutable_buffer& __b)
 | 
|---|
| 141 |   { return std::addressof(__b); }
 | 
|---|
| 142 | 
 | 
|---|
| 143 |   inline const const_buffer*
 | 
|---|
| 144 |   buffer_sequence_begin(const const_buffer& __b)
 | 
|---|
| 145 |   { return std::addressof(__b); }
 | 
|---|
| 146 | 
 | 
|---|
| 147 |   inline const mutable_buffer*
 | 
|---|
| 148 |   buffer_sequence_end(const mutable_buffer& __b)
 | 
|---|
| 149 |   { return std::addressof(__b) + 1; }
 | 
|---|
| 150 | 
 | 
|---|
| 151 |   inline const const_buffer*
 | 
|---|
| 152 |   buffer_sequence_end(const const_buffer& __b)
 | 
|---|
| 153 |   { return std::addressof(__b) + 1; }
 | 
|---|
| 154 | 
 | 
|---|
| 155 |   template<typename _Cont>
 | 
|---|
| 156 |     auto
 | 
|---|
| 157 |     buffer_sequence_begin(_Cont& __c) -> decltype(__c.begin())
 | 
|---|
| 158 |     { return __c.begin(); }
 | 
|---|
| 159 | 
 | 
|---|
| 160 |   template<typename _Cont>
 | 
|---|
| 161 |     auto
 | 
|---|
| 162 |     buffer_sequence_begin(const _Cont& __c) -> decltype(__c.begin())
 | 
|---|
| 163 |     { return __c.begin(); }
 | 
|---|
| 164 | 
 | 
|---|
| 165 |   template<typename _Cont>
 | 
|---|
| 166 |     auto
 | 
|---|
| 167 |     buffer_sequence_end(_Cont& __c) -> decltype(__c.end())
 | 
|---|
| 168 |     { return __c.end(); }
 | 
|---|
| 169 | 
 | 
|---|
| 170 |   template<typename _Cont>
 | 
|---|
| 171 |     auto
 | 
|---|
| 172 |     buffer_sequence_end(const _Cont& __c) -> decltype(__c.end())
 | 
|---|
| 173 |     { return __c.end(); }
 | 
|---|
| 174 | 
 | 
|---|
| 175 |   /// @}
 | 
|---|
| 176 | 
 | 
|---|
| 177 | 
 | 
|---|
| 178 |   /** @brief buffer type traits
 | 
|---|
| 179 |    *
 | 
|---|
| 180 |    * @{
 | 
|---|
| 181 |    */
 | 
|---|
| 182 | 
 | 
|---|
| 183 |   template<typename _Tp, typename _Buffer,
 | 
|---|
| 184 |            typename _Begin
 | 
|---|
| 185 |             = decltype(net::buffer_sequence_begin(std::declval<_Tp&>())),
 | 
|---|
| 186 |            typename _End
 | 
|---|
| 187 |             = decltype(net::buffer_sequence_end(std::declval<_Tp&>()))>
 | 
|---|
| 188 |     using __buffer_sequence = enable_if_t<__and_<
 | 
|---|
| 189 |       __is_value_constructible<_Tp>, is_same<_Begin, _End>,
 | 
|---|
| 190 |       is_convertible<typename iterator_traits<_Begin>::value_type, _Buffer>
 | 
|---|
| 191 |       >::value>;
 | 
|---|
| 192 | 
 | 
|---|
| 193 |   template<typename _Tp, typename _Buffer, typename = void>
 | 
|---|
| 194 |     struct __is_buffer_sequence : false_type
 | 
|---|
| 195 |     { };
 | 
|---|
| 196 | 
 | 
|---|
| 197 |   template<typename _Tp, typename _Buffer>
 | 
|---|
| 198 |     struct __is_buffer_sequence<_Tp, _Buffer, __buffer_sequence<_Tp, _Buffer>>
 | 
|---|
| 199 |     : true_type
 | 
|---|
| 200 |     { };
 | 
|---|
| 201 | 
 | 
|---|
| 202 |   template<typename _Tp>
 | 
|---|
| 203 |     struct is_mutable_buffer_sequence
 | 
|---|
| 204 |     : __is_buffer_sequence<_Tp, mutable_buffer>::type
 | 
|---|
| 205 |     { };
 | 
|---|
| 206 | 
 | 
|---|
| 207 |   template<typename _Tp>
 | 
|---|
| 208 |     struct is_const_buffer_sequence
 | 
|---|
| 209 |     : __is_buffer_sequence<_Tp, const_buffer>::type
 | 
|---|
| 210 |     { };
 | 
|---|
| 211 | 
 | 
|---|
| 212 |   template<typename _Tp>
 | 
|---|
| 213 |     constexpr bool is_mutable_buffer_sequence_v
 | 
|---|
| 214 |       = is_mutable_buffer_sequence<_Tp>::value;
 | 
|---|
| 215 | 
 | 
|---|
| 216 |   template<typename _Tp>
 | 
|---|
| 217 |     constexpr bool is_const_buffer_sequence_v
 | 
|---|
| 218 |       = is_const_buffer_sequence<_Tp>::value;
 | 
|---|
| 219 | 
 | 
|---|
| 220 |   template<typename _Tp, typename = void>
 | 
|---|
| 221 |     struct __is_dynamic_buffer_impl : false_type
 | 
|---|
| 222 |     { };
 | 
|---|
| 223 | 
 | 
|---|
| 224 |   // Check DynamicBuffer requirements.
 | 
|---|
| 225 |   template<typename _Tp, typename _Up = remove_const_t<_Tp>>
 | 
|---|
| 226 |     auto
 | 
|---|
| 227 |     __dynamic_buffer_reqs(_Up* __x = 0, const _Up* __x1 = 0, size_t __n = 0)
 | 
|---|
| 228 |     -> enable_if_t<__and_<
 | 
|---|
| 229 |       is_move_constructible<_Up>,
 | 
|---|
| 230 |       is_const_buffer_sequence<typename _Tp::const_buffers_type>,
 | 
|---|
| 231 |       is_mutable_buffer_sequence<typename _Tp::mutable_buffers_type>,
 | 
|---|
| 232 |       is_same<decltype(__x1->size()), size_t>,
 | 
|---|
| 233 |       is_same<decltype(__x1->max_size()), size_t>,
 | 
|---|
| 234 |       is_same<decltype(__x1->capacity()), size_t>,
 | 
|---|
| 235 |       is_same<decltype(__x1->data()), typename _Tp::const_buffers_type>,
 | 
|---|
| 236 |       is_same<decltype(__x->prepare(__n)), typename _Tp::mutable_buffers_type>,
 | 
|---|
| 237 |       is_void<decltype(__x->commit(__n), __x->consume(__n), void())>
 | 
|---|
| 238 |     >::value>;
 | 
|---|
| 239 | 
 | 
|---|
| 240 |   template<typename _Tp>
 | 
|---|
| 241 |     struct __is_dynamic_buffer_impl<_Tp,
 | 
|---|
| 242 |                                     decltype(__dynamic_buffer_reqs<_Tp>())>
 | 
|---|
| 243 |     : true_type
 | 
|---|
| 244 |     { };
 | 
|---|
| 245 | 
 | 
|---|
| 246 |   template<typename _Tp>
 | 
|---|
| 247 |     struct is_dynamic_buffer : __is_dynamic_buffer_impl<_Tp>::type
 | 
|---|
| 248 |     { };
 | 
|---|
| 249 | 
 | 
|---|
| 250 |   template<typename _Tp>
 | 
|---|
| 251 |     constexpr bool is_dynamic_buffer_v = is_dynamic_buffer<_Tp>::value;
 | 
|---|
| 252 | 
 | 
|---|
| 253 |   /// @}
 | 
|---|
| 254 | 
 | 
|---|
| 255 |   /// buffer size
 | 
|---|
| 256 |   template<typename _ConstBufferSequence>
 | 
|---|
| 257 |     size_t
 | 
|---|
| 258 |     buffer_size(const _ConstBufferSequence& __buffers) noexcept
 | 
|---|
| 259 |     {
 | 
|---|
| 260 |       size_t __total_size = 0;
 | 
|---|
| 261 |       auto __i = net::buffer_sequence_begin(__buffers);
 | 
|---|
| 262 |       const auto __end = net::buffer_sequence_end(__buffers);
 | 
|---|
| 263 |       for (; __i != __end; ++__i)
 | 
|---|
| 264 |         __total_size += const_buffer(*__i).size();
 | 
|---|
| 265 |       return __total_size;
 | 
|---|
| 266 |     }
 | 
|---|
| 267 | 
 | 
|---|
| 268 |   template<typename _ConstBufferSequence>
 | 
|---|
| 269 |     bool
 | 
|---|
| 270 |     __buffer_empty(const _ConstBufferSequence& __buffers) noexcept
 | 
|---|
| 271 |     {
 | 
|---|
| 272 |       auto __i = net::buffer_sequence_begin(__buffers);
 | 
|---|
| 273 |       const auto __end = net::buffer_sequence_end(__buffers);
 | 
|---|
| 274 |       for (; __i != __end; ++__i)
 | 
|---|
| 275 |         if (const_buffer(*__i).size() != 0)
 | 
|---|
| 276 |           return false;
 | 
|---|
| 277 |       return true;
 | 
|---|
| 278 |     }
 | 
|---|
| 279 | 
 | 
|---|
| 280 |   // buffer copy:
 | 
|---|
| 281 | 
 | 
|---|
| 282 |   template<typename _MutableBufferSequence, typename _ConstBufferSequence>
 | 
|---|
| 283 |     size_t
 | 
|---|
| 284 |     buffer_copy(const _MutableBufferSequence& __dest,
 | 
|---|
| 285 |                 const _ConstBufferSequence& __source,
 | 
|---|
| 286 |                 size_t __max_size) noexcept
 | 
|---|
| 287 |     {
 | 
|---|
| 288 |       size_t __total_size = 0;
 | 
|---|
| 289 |       auto __to_i = net::buffer_sequence_begin(__dest);
 | 
|---|
| 290 |       const auto __to_end = net::buffer_sequence_end(__dest);
 | 
|---|
| 291 |       auto __from_i = net::buffer_sequence_begin(__source);
 | 
|---|
| 292 |       const auto __from_end = net::buffer_sequence_end(__source);
 | 
|---|
| 293 |       mutable_buffer __to;
 | 
|---|
| 294 |       const_buffer __from;
 | 
|---|
| 295 |       while (((__from_i != __from_end && __to_i != __to_end)
 | 
|---|
| 296 |             || (__from.size() && __to.size()))
 | 
|---|
| 297 |           && __total_size < __max_size)
 | 
|---|
| 298 |         {
 | 
|---|
| 299 |           if (__from.size() == 0)
 | 
|---|
| 300 |             __from = const_buffer{*__from_i++};
 | 
|---|
| 301 |           if (__to.size() == 0)
 | 
|---|
| 302 |             __to = mutable_buffer{*__to_i++};
 | 
|---|
| 303 | 
 | 
|---|
| 304 |           size_t __n = std::min(__from.size(), __to.size());
 | 
|---|
| 305 |           __n = std::min(__n, __max_size - __total_size);
 | 
|---|
| 306 |           std::memcpy(__to.data(), __from.data(), __n);
 | 
|---|
| 307 |           __from = { (const char*)__from.data() + __n, __from.size() - __n };
 | 
|---|
| 308 |           __to = { (char*)__to.data() + __n, __to.size() - __n };
 | 
|---|
| 309 |           __total_size += __n;
 | 
|---|
| 310 |         }
 | 
|---|
| 311 |       return __total_size;
 | 
|---|
| 312 |     }
 | 
|---|
| 313 | 
 | 
|---|
| 314 |   template<typename _MutableBufferSequence, typename _ConstBufferSequence>
 | 
|---|
| 315 |     inline size_t
 | 
|---|
| 316 |     buffer_copy(const _MutableBufferSequence& __dest,
 | 
|---|
| 317 |                 const _ConstBufferSequence& __source) noexcept
 | 
|---|
| 318 |     { return net::buffer_copy(__dest, __source, size_t(-1)); }
 | 
|---|
| 319 | 
 | 
|---|
| 320 | 
 | 
|---|
| 321 |   // buffer arithmetic:
 | 
|---|
| 322 | 
 | 
|---|
| 323 |   inline mutable_buffer
 | 
|---|
| 324 |   operator+(const mutable_buffer& __b, size_t __n) noexcept
 | 
|---|
| 325 |   {
 | 
|---|
| 326 |     if (__n > __b.size())
 | 
|---|
| 327 |       __n = __b.size();
 | 
|---|
| 328 |     return { static_cast<char*>(__b.data()) + __n, __b.size() - __n };
 | 
|---|
| 329 |   }
 | 
|---|
| 330 | 
 | 
|---|
| 331 |   inline mutable_buffer
 | 
|---|
| 332 |   operator+(size_t __n, const mutable_buffer& __b) noexcept
 | 
|---|
| 333 |   { return __b + __n; }
 | 
|---|
| 334 | 
 | 
|---|
| 335 |   inline const_buffer
 | 
|---|
| 336 |   operator+(const const_buffer& __b, size_t __n) noexcept
 | 
|---|
| 337 |   {
 | 
|---|
| 338 |     if (__n > __b.size())
 | 
|---|
| 339 |       __n = __b.size();
 | 
|---|
| 340 |     return { static_cast<const char*>(__b.data()) + __n, __b.size() - __n };
 | 
|---|
| 341 |   }
 | 
|---|
| 342 | 
 | 
|---|
| 343 |   inline const_buffer
 | 
|---|
| 344 |   operator+(size_t __n, const const_buffer& __b) noexcept
 | 
|---|
| 345 |   { return __b + __n; }
 | 
|---|
| 346 | 
 | 
|---|
| 347 |   // buffer creation:
 | 
|---|
| 348 | 
 | 
|---|
| 349 |   inline mutable_buffer
 | 
|---|
| 350 |   buffer(void* __p, size_t __n) noexcept
 | 
|---|
| 351 |   { return { __p, __n }; }
 | 
|---|
| 352 | 
 | 
|---|
| 353 |   inline const_buffer
 | 
|---|
| 354 |   buffer(const void* __p, size_t __n) noexcept
 | 
|---|
| 355 |   { return { __p, __n }; }
 | 
|---|
| 356 | 
 | 
|---|
| 357 |   inline mutable_buffer
 | 
|---|
| 358 |   buffer(const mutable_buffer& __b) noexcept
 | 
|---|
| 359 |   { return __b; }
 | 
|---|
| 360 | 
 | 
|---|
| 361 |   inline mutable_buffer
 | 
|---|
| 362 |   buffer(const mutable_buffer& __b, size_t __n) noexcept
 | 
|---|
| 363 |   { return { __b.data(), std::min(__b.size(), __n) }; }
 | 
|---|
| 364 | 
 | 
|---|
| 365 |   inline const_buffer
 | 
|---|
| 366 |   buffer(const const_buffer& __b) noexcept
 | 
|---|
| 367 |   { return __b; }
 | 
|---|
| 368 | 
 | 
|---|
| 369 |   inline const_buffer
 | 
|---|
| 370 |   buffer(const const_buffer& __b, size_t __n) noexcept
 | 
|---|
| 371 |   { return { __b.data(), std::min(__b.size(), __n) }; }
 | 
|---|
| 372 | 
 | 
|---|
| 373 |   template<typename _Tp>
 | 
|---|
| 374 |     inline mutable_buffer
 | 
|---|
| 375 |     __to_mbuf(_Tp* __data, size_t __n)
 | 
|---|
| 376 |     { return { __n ? __data : nullptr, __n * sizeof(_Tp) }; }
 | 
|---|
| 377 | 
 | 
|---|
| 378 |   template<typename _Tp>
 | 
|---|
| 379 |     inline const_buffer
 | 
|---|
| 380 |     __to_cbuf(const _Tp* __data, size_t __n)
 | 
|---|
| 381 |     { return { __n ? __data : nullptr, __n * sizeof(_Tp) }; }
 | 
|---|
| 382 | 
 | 
|---|
| 383 |   template<typename _Tp, size_t _Nm>
 | 
|---|
| 384 |     inline mutable_buffer
 | 
|---|
| 385 |     buffer(_Tp (&__data)[_Nm]) noexcept
 | 
|---|
| 386 |     { return net::__to_mbuf(__data, _Nm); }
 | 
|---|
| 387 | 
 | 
|---|
| 388 |   template<typename _Tp, size_t _Nm>
 | 
|---|
| 389 |     inline const_buffer
 | 
|---|
| 390 |     buffer(const _Tp (&__data)[_Nm]) noexcept
 | 
|---|
| 391 |     { return net::__to_cbuf(__data, _Nm); }
 | 
|---|
| 392 | 
 | 
|---|
| 393 |   template<typename _Tp, size_t _Nm>
 | 
|---|
| 394 |     inline mutable_buffer
 | 
|---|
| 395 |     buffer(array<_Tp, _Nm>& __data) noexcept
 | 
|---|
| 396 |     { return net::__to_mbuf(__data.data(), _Nm); }
 | 
|---|
| 397 | 
 | 
|---|
| 398 |   template<typename _Tp, size_t _Nm>
 | 
|---|
| 399 |     inline const_buffer
 | 
|---|
| 400 |     buffer(array<const _Tp, _Nm>& __data) noexcept
 | 
|---|
| 401 |     { return net::__to_cbuf(__data.data(), __data.size()); }
 | 
|---|
| 402 | 
 | 
|---|
| 403 |   template<typename _Tp, size_t _Nm>
 | 
|---|
| 404 |     inline const_buffer
 | 
|---|
| 405 |     buffer(const array<_Tp, _Nm>& __data) noexcept
 | 
|---|
| 406 |     { return net::__to_cbuf(__data.data(), __data.size()); }
 | 
|---|
| 407 | 
 | 
|---|
| 408 |   template<typename _Tp, typename _Allocator>
 | 
|---|
| 409 |     inline mutable_buffer
 | 
|---|
| 410 |     buffer(vector<_Tp, _Allocator>& __data) noexcept
 | 
|---|
| 411 |     { return net::__to_mbuf(__data.data(), __data.size()); }
 | 
|---|
| 412 | 
 | 
|---|
| 413 |   template<typename _Tp, typename _Allocator>
 | 
|---|
| 414 |     inline const_buffer
 | 
|---|
| 415 |     buffer(const vector<_Tp, _Allocator>& __data) noexcept
 | 
|---|
| 416 |     { return net::__to_cbuf(__data.data(), __data.size()); }
 | 
|---|
| 417 | 
 | 
|---|
| 418 |   template<typename _CharT, typename _Traits, typename _Allocator>
 | 
|---|
| 419 |     inline mutable_buffer
 | 
|---|
| 420 |     buffer(basic_string<_CharT, _Traits, _Allocator>& __data) noexcept
 | 
|---|
| 421 |     { return net::__to_mbuf(&__data.front(), __data.size()); }
 | 
|---|
| 422 | 
 | 
|---|
| 423 |   template<typename _CharT, typename _Traits, typename _Allocator>
 | 
|---|
| 424 |     inline const_buffer
 | 
|---|
| 425 |     buffer(const basic_string<_CharT, _Traits, _Allocator>& __data) noexcept
 | 
|---|
| 426 |     { return net::__to_cbuf(&__data.front(), __data.size()); }
 | 
|---|
| 427 | 
 | 
|---|
| 428 |   template<typename _CharT, typename _Traits>
 | 
|---|
| 429 |     inline const_buffer
 | 
|---|
| 430 |     buffer(basic_string_view<_CharT, _Traits> __data) noexcept
 | 
|---|
| 431 |     { return net::__to_cbuf(__data.data(), __data.size()); }
 | 
|---|
| 432 | 
 | 
|---|
| 433 |   template<typename _Tp, size_t _Nm>
 | 
|---|
| 434 |     inline mutable_buffer
 | 
|---|
| 435 |     buffer(_Tp (&__data)[_Nm], size_t __n) noexcept
 | 
|---|
| 436 |     { return buffer(net::buffer(__data), __n * sizeof(_Tp)); }
 | 
|---|
| 437 | 
 | 
|---|
| 438 |   template<typename _Tp, size_t _Nm>
 | 
|---|
| 439 |     inline const_buffer
 | 
|---|
| 440 |     buffer(const _Tp (&__data)[_Nm], size_t __n) noexcept
 | 
|---|
| 441 |     { return buffer(net::buffer(__data), __n * sizeof(_Tp)); }
 | 
|---|
| 442 | 
 | 
|---|
| 443 |   template<typename _Tp, size_t _Nm>
 | 
|---|
| 444 |     inline mutable_buffer
 | 
|---|
| 445 |     buffer(array<_Tp, _Nm>& __data, size_t __n) noexcept
 | 
|---|
| 446 |     { return buffer(net::buffer(__data), __n * sizeof(_Tp)); }
 | 
|---|
| 447 | 
 | 
|---|
| 448 |   template<typename _Tp, size_t _Nm>
 | 
|---|
| 449 |     inline const_buffer
 | 
|---|
| 450 |     buffer(array<const _Tp, _Nm>& __data, size_t __n) noexcept
 | 
|---|
| 451 |     { return buffer(net::buffer(__data), __n * sizeof(_Tp)); }
 | 
|---|
| 452 | 
 | 
|---|
| 453 |   template<typename _Tp, size_t _Nm>
 | 
|---|
| 454 |     inline const_buffer
 | 
|---|
| 455 |     buffer(const array<_Tp, _Nm>& __data, size_t __n) noexcept
 | 
|---|
| 456 |     { return buffer(net::buffer(__data), __n * sizeof(_Tp)); }
 | 
|---|
| 457 | 
 | 
|---|
| 458 |   template<typename _Tp, typename _Allocator>
 | 
|---|
| 459 |     inline mutable_buffer
 | 
|---|
| 460 |     buffer(vector<_Tp, _Allocator>& __data, size_t __n) noexcept
 | 
|---|
| 461 |     { return buffer(net::buffer(__data), __n * sizeof(_Tp)); }
 | 
|---|
| 462 | 
 | 
|---|
| 463 |   template<typename _Tp, typename _Allocator>
 | 
|---|
| 464 |     inline const_buffer
 | 
|---|
| 465 |     buffer(const vector<_Tp, _Allocator>& __data, size_t __n) noexcept
 | 
|---|
| 466 |     { return buffer(net::buffer(__data), __n * sizeof(_Tp)); }
 | 
|---|
| 467 | 
 | 
|---|
| 468 |   template<typename _CharT, typename _Traits, typename _Allocator>
 | 
|---|
| 469 |     inline mutable_buffer
 | 
|---|
| 470 |     buffer(basic_string<_CharT, _Traits, _Allocator>& __data,
 | 
|---|
| 471 |            size_t __n) noexcept
 | 
|---|
| 472 |     { return buffer(net::buffer(__data), __n * sizeof(_CharT)); }
 | 
|---|
| 473 | 
 | 
|---|
| 474 |   template<typename _CharT, typename _Traits, typename _Allocator>
 | 
|---|
| 475 |     inline const_buffer
 | 
|---|
| 476 |     buffer(const basic_string<_CharT, _Traits, _Allocator>& __data,
 | 
|---|
| 477 |            size_t __n) noexcept
 | 
|---|
| 478 |     { return buffer(net::buffer(__data), __n * sizeof(_CharT)); }
 | 
|---|
| 479 | 
 | 
|---|
| 480 |   template<typename _CharT, typename _Traits>
 | 
|---|
| 481 |     inline const_buffer
 | 
|---|
| 482 |     buffer(basic_string_view<_CharT, _Traits> __data, size_t __n) noexcept
 | 
|---|
| 483 |     { return buffer(net::buffer(__data), __n * sizeof(_CharT)); }
 | 
|---|
| 484 | 
 | 
|---|
| 485 | 
 | 
|---|
| 486 |   template<typename _Sequence>
 | 
|---|
| 487 |     class __dynamic_buffer_base
 | 
|---|
| 488 |     {
 | 
|---|
| 489 |     public:
 | 
|---|
| 490 |       // types:
 | 
|---|
| 491 |       using const_buffers_type = const_buffer;
 | 
|---|
| 492 |       using mutable_buffers_type = mutable_buffer;
 | 
|---|
| 493 | 
 | 
|---|
| 494 |       // constructors:
 | 
|---|
| 495 |       explicit
 | 
|---|
| 496 |       __dynamic_buffer_base(_Sequence& __seq) noexcept
 | 
|---|
| 497 |       : _M_seq(__seq), _M_size(__seq.size()), _M_max_size(__seq.max_size())
 | 
|---|
| 498 |       { }
 | 
|---|
| 499 | 
 | 
|---|
| 500 |       __dynamic_buffer_base(_Sequence& __seq, size_t __maximum_size) noexcept
 | 
|---|
| 501 |       : _M_seq(__seq), _M_size(__seq.size()), _M_max_size(__maximum_size)
 | 
|---|
| 502 |       { __glibcxx_assert(__seq.size() <= __maximum_size); }
 | 
|---|
| 503 | 
 | 
|---|
| 504 |       __dynamic_buffer_base(__dynamic_buffer_base&&) = default;
 | 
|---|
| 505 | 
 | 
|---|
| 506 |       // members:
 | 
|---|
| 507 |       size_t size() const noexcept { return _M_size; }
 | 
|---|
| 508 |       size_t max_size() const noexcept { return _M_max_size; }
 | 
|---|
| 509 |       size_t capacity() const noexcept { return _M_seq.capacity(); }
 | 
|---|
| 510 | 
 | 
|---|
| 511 |       const_buffers_type
 | 
|---|
| 512 |       data() const noexcept
 | 
|---|
| 513 |       { return net::buffer(_M_seq, _M_size); }
 | 
|---|
| 514 | 
 | 
|---|
| 515 |       mutable_buffers_type
 | 
|---|
| 516 |       prepare(size_t __n)
 | 
|---|
| 517 |       {
 | 
|---|
| 518 |         if ((_M_size + __n) > _M_max_size)
 | 
|---|
| 519 |           __throw_length_error("dynamic_vector_buffer::prepare");
 | 
|---|
| 520 | 
 | 
|---|
| 521 |         _M_seq.resize(_M_size + __n);
 | 
|---|
| 522 |         return buffer(net::buffer(_M_seq) + _M_size, __n);
 | 
|---|
| 523 |       }
 | 
|---|
| 524 | 
 | 
|---|
| 525 |       void
 | 
|---|
| 526 |       commit(size_t __n)
 | 
|---|
| 527 |       {
 | 
|---|
| 528 |         _M_size += std::min(__n, _M_seq.size() - _M_size);
 | 
|---|
| 529 |         _M_seq.resize(_M_size);
 | 
|---|
| 530 |       }
 | 
|---|
| 531 | 
 | 
|---|
| 532 |       void
 | 
|---|
| 533 |       consume(size_t __n)
 | 
|---|
| 534 |       {
 | 
|---|
| 535 |         size_t __m = std::min(__n, _M_size);
 | 
|---|
| 536 |         _M_seq.erase(_M_seq.begin(), _M_seq.begin() + __m);
 | 
|---|
| 537 |         _M_size -= __m;
 | 
|---|
| 538 |       }
 | 
|---|
| 539 | 
 | 
|---|
| 540 |     private:
 | 
|---|
| 541 |       _Sequence&        _M_seq;
 | 
|---|
| 542 |       size_t            _M_size;
 | 
|---|
| 543 |       const size_t      _M_max_size;
 | 
|---|
| 544 |     };
 | 
|---|
| 545 | 
 | 
|---|
| 546 |   template<typename _Tp, typename _Allocator>
 | 
|---|
| 547 |     class dynamic_vector_buffer
 | 
|---|
| 548 |     : public __dynamic_buffer_base<vector<_Tp, _Allocator>>
 | 
|---|
| 549 |     {
 | 
|---|
| 550 |     public:
 | 
|---|
| 551 |       using __dynamic_buffer_base<vector<_Tp, _Allocator>>::__dynamic_buffer_base;
 | 
|---|
| 552 |     };
 | 
|---|
| 553 | 
 | 
|---|
| 554 |   template<typename _CharT, typename _Traits, typename _Allocator>
 | 
|---|
| 555 |     class dynamic_string_buffer
 | 
|---|
| 556 |     : public __dynamic_buffer_base<basic_string<_CharT, _Traits, _Allocator>>
 | 
|---|
| 557 |     {
 | 
|---|
| 558 |     public:
 | 
|---|
| 559 |       using __dynamic_buffer_base<basic_string<_CharT, _Traits, _Allocator>>::
 | 
|---|
| 560 |         __dynamic_buffer_base;
 | 
|---|
| 561 |     };
 | 
|---|
| 562 | 
 | 
|---|
| 563 |   // dynamic buffer creation:
 | 
|---|
| 564 | 
 | 
|---|
| 565 |   template<typename _Tp, typename _Allocator>
 | 
|---|
| 566 |     inline dynamic_vector_buffer<_Tp, _Allocator>
 | 
|---|
| 567 |     dynamic_buffer(vector<_Tp, _Allocator>& __vec) noexcept
 | 
|---|
| 568 |     { return dynamic_vector_buffer<_Tp, _Allocator>{__vec}; }
 | 
|---|
| 569 | 
 | 
|---|
| 570 |   template<typename _Tp, typename _Allocator>
 | 
|---|
| 571 |     inline dynamic_vector_buffer<_Tp, _Allocator>
 | 
|---|
| 572 |     dynamic_buffer(vector<_Tp, _Allocator>& __vec, size_t __n) noexcept
 | 
|---|
| 573 |     { return {__vec, __n}; }
 | 
|---|
| 574 | 
 | 
|---|
| 575 |   template<typename _CharT, typename _Traits, typename _Allocator>
 | 
|---|
| 576 |     inline dynamic_string_buffer<_CharT, _Traits, _Allocator>
 | 
|---|
| 577 |     dynamic_buffer(basic_string<_CharT, _Traits, _Allocator>& __str) noexcept
 | 
|---|
| 578 |     { return dynamic_string_buffer<_CharT, _Traits, _Allocator>{__str}; }
 | 
|---|
| 579 | 
 | 
|---|
| 580 |   template<typename _CharT, typename _Traits, typename _Allocator>
 | 
|---|
| 581 |     inline dynamic_string_buffer<_CharT, _Traits, _Allocator>
 | 
|---|
| 582 |     dynamic_buffer(basic_string<_CharT, _Traits, _Allocator>& __str,
 | 
|---|
| 583 |                    size_t __n) noexcept
 | 
|---|
| 584 |     { return {__str, __n}; }
 | 
|---|
| 585 | 
 | 
|---|
| 586 |   class transfer_all
 | 
|---|
| 587 |   {
 | 
|---|
| 588 |   public:
 | 
|---|
| 589 |     size_t operator()(const error_code& __ec, size_t) const
 | 
|---|
| 590 |     { return !__ec ? 1500 : 0; }
 | 
|---|
| 591 |   };
 | 
|---|
| 592 | 
 | 
|---|
| 593 |   class transfer_at_least
 | 
|---|
| 594 |   {
 | 
|---|
| 595 |   public:
 | 
|---|
| 596 |     explicit transfer_at_least(size_t __m) : _M_minimum(__m) { }
 | 
|---|
| 597 | 
 | 
|---|
| 598 |     size_t operator()(const error_code& __ec, size_t __n) const
 | 
|---|
| 599 |     { return !__ec  && __n < _M_minimum ? _M_minimum - __n : 0; }
 | 
|---|
| 600 | 
 | 
|---|
| 601 |   private:
 | 
|---|
| 602 |     size_t _M_minimum;
 | 
|---|
| 603 |   };
 | 
|---|
| 604 | 
 | 
|---|
| 605 |   class transfer_exactly
 | 
|---|
| 606 |   {
 | 
|---|
| 607 |   public:
 | 
|---|
| 608 |     explicit transfer_exactly(size_t __e) : _M_exact(__e) { }
 | 
|---|
| 609 | 
 | 
|---|
| 610 |     size_t operator()(const error_code& __ec, size_t __n) const
 | 
|---|
| 611 |     {
 | 
|---|
| 612 |       size_t _Nm = -1;
 | 
|---|
| 613 |       return !__ec  && __n < _M_exact ? std::min(_M_exact - __n, _Nm) : 0;
 | 
|---|
| 614 |     }
 | 
|---|
| 615 | 
 | 
|---|
| 616 |   private:
 | 
|---|
| 617 |     size_t _M_exact;
 | 
|---|
| 618 |   };
 | 
|---|
| 619 | 
 | 
|---|
| 620 |   /** @brief synchronous read operations
 | 
|---|
| 621 |    * @{
 | 
|---|
| 622 |    */
 | 
|---|
| 623 | 
 | 
|---|
| 624 |   template<typename _SyncReadStream, typename _MutableBufferSequence,
 | 
|---|
| 625 |            typename _CompletionCondition>
 | 
|---|
| 626 |     enable_if_t<is_mutable_buffer_sequence<_MutableBufferSequence>::value,
 | 
|---|
| 627 |                 size_t>
 | 
|---|
| 628 |     read(_SyncReadStream& __stream, const _MutableBufferSequence& __buffers,
 | 
|---|
| 629 |          _CompletionCondition __completion_condition, error_code& __ec)
 | 
|---|
| 630 |     {
 | 
|---|
| 631 |       __ec.clear();
 | 
|---|
| 632 |       auto __i = net::buffer_sequence_begin(__buffers);
 | 
|---|
| 633 |       auto __end = net::buffer_sequence_end(__buffers);
 | 
|---|
| 634 |       mutable_buffer __to;
 | 
|---|
| 635 |       size_t __total = 0;
 | 
|---|
| 636 |       size_t __n;
 | 
|---|
| 637 |       while ((__n = __completion_condition(__ec, __total))
 | 
|---|
| 638 |           && (__i != __end || __to.size()))
 | 
|---|
| 639 |         {
 | 
|---|
| 640 |           if (__to.size() == 0)
 | 
|---|
| 641 |             __to = mutable_buffer(*__i++);
 | 
|---|
| 642 |           __n = __stream.read_some(buffer(__to, __n), __ec);
 | 
|---|
| 643 |           __to = __to + __n;
 | 
|---|
| 644 |           __total += __n;
 | 
|---|
| 645 |         }
 | 
|---|
| 646 |       return __total;
 | 
|---|
| 647 |     }
 | 
|---|
| 648 | 
 | 
|---|
| 649 |   template<typename _SyncReadStream, typename _MutableBufferSequence>
 | 
|---|
| 650 |     inline
 | 
|---|
| 651 |     enable_if_t<is_mutable_buffer_sequence<_MutableBufferSequence>::value,
 | 
|---|
| 652 |                 size_t>
 | 
|---|
| 653 |     read(_SyncReadStream& __stream, const _MutableBufferSequence& __buffers)
 | 
|---|
| 654 |     {
 | 
|---|
| 655 |       error_code __ec;
 | 
|---|
| 656 |       return net::read(__stream, __buffers, transfer_all{}, __ec);
 | 
|---|
| 657 |     }
 | 
|---|
| 658 | 
 | 
|---|
| 659 |   template<typename _SyncReadStream, typename _MutableBufferSequence>
 | 
|---|
| 660 |     inline
 | 
|---|
| 661 |     enable_if_t<is_mutable_buffer_sequence<_MutableBufferSequence>::value,
 | 
|---|
| 662 |                 size_t>
 | 
|---|
| 663 |     read(_SyncReadStream& __stream, const _MutableBufferSequence& __buffers,
 | 
|---|
| 664 |          error_code& __ec)
 | 
|---|
| 665 |     { return net::read(__stream, __buffers, transfer_all{}, __ec); }
 | 
|---|
| 666 | 
 | 
|---|
| 667 |   template<typename _SyncReadStream, typename _MutableBufferSequence,
 | 
|---|
| 668 |            typename _CompletionCondition>
 | 
|---|
| 669 |     inline
 | 
|---|
| 670 |     enable_if_t<is_mutable_buffer_sequence<_MutableBufferSequence>::value,
 | 
|---|
| 671 |                 size_t>
 | 
|---|
| 672 |     read(_SyncReadStream& __stream, const _MutableBufferSequence& __buffers,
 | 
|---|
| 673 |          _CompletionCondition __completion_condition)
 | 
|---|
| 674 |     {
 | 
|---|
| 675 |       error_code __ec;
 | 
|---|
| 676 |       return net::read(__stream, __buffers, __completion_condition, __ec);
 | 
|---|
| 677 |     }
 | 
|---|
| 678 | 
 | 
|---|
| 679 | 
 | 
|---|
| 680 |   template<typename _SyncReadStream, typename _DynamicBuffer,
 | 
|---|
| 681 |            typename _CompletionCondition>
 | 
|---|
| 682 |     enable_if_t<is_dynamic_buffer<decay_t<_DynamicBuffer>>::value, size_t>
 | 
|---|
| 683 |     read(_SyncReadStream& __stream, _DynamicBuffer&& __b,
 | 
|---|
| 684 |          _CompletionCondition __completion_condition, error_code& __ec)
 | 
|---|
| 685 |     {
 | 
|---|
| 686 |       const size_t __limit = 64;
 | 
|---|
| 687 |       __ec.clear();
 | 
|---|
| 688 |       size_t __cap = std::max(__b.capacity() - __b.size(), __limit);
 | 
|---|
| 689 |       size_t __total = 0;
 | 
|---|
| 690 |       size_t __n;
 | 
|---|
| 691 |       while ((__n = __completion_condition(__ec, __total))
 | 
|---|
| 692 |           && __b.size() != __b.max_size())
 | 
|---|
| 693 |         {
 | 
|---|
| 694 |           __n =  std::min(__n, __b.max_size() - __b.size());
 | 
|---|
| 695 |           size_t __cap = std::max(__b.capacity() - __b.size(), __limit);
 | 
|---|
| 696 |           mutable_buffer __to = __b.prepare(std::min(__cap, __n));
 | 
|---|
| 697 |           __n = __stream.read_some(__to, __ec);
 | 
|---|
| 698 |           __to = __to + __n;
 | 
|---|
| 699 |           __total += __n;
 | 
|---|
| 700 |           __b.commit(__n);
 | 
|---|
| 701 |         }
 | 
|---|
| 702 |       return __total;
 | 
|---|
| 703 |     }
 | 
|---|
| 704 | 
 | 
|---|
| 705 |   template<typename _SyncReadStream, typename _DynamicBuffer>
 | 
|---|
| 706 |     inline enable_if_t<is_dynamic_buffer<_DynamicBuffer>::value, size_t>
 | 
|---|
| 707 |     read(_SyncReadStream& __stream, _DynamicBuffer&& __b)
 | 
|---|
| 708 |     {
 | 
|---|
| 709 |       error_code __ec;
 | 
|---|
| 710 |       return net::read(__stream, __b, transfer_all{}, __ec);
 | 
|---|
| 711 |     }
 | 
|---|
| 712 | 
 | 
|---|
| 713 |   template<typename _SyncReadStream, typename _DynamicBuffer>
 | 
|---|
| 714 |     inline enable_if_t<is_dynamic_buffer<_DynamicBuffer>::value, size_t>
 | 
|---|
| 715 |     read(_SyncReadStream& __stream, _DynamicBuffer&& __b, error_code& __ec)
 | 
|---|
| 716 |     {
 | 
|---|
| 717 |       return net::read(__stream, __b, transfer_all{}, __ec);
 | 
|---|
| 718 |     }
 | 
|---|
| 719 | 
 | 
|---|
| 720 |   template<typename _SyncReadStream, typename _DynamicBuffer,
 | 
|---|
| 721 |            typename _CompletionCondition>
 | 
|---|
| 722 |     inline enable_if_t<is_dynamic_buffer<_DynamicBuffer>::value, size_t>
 | 
|---|
| 723 |     read(_SyncReadStream& __stream, _DynamicBuffer&& __b,
 | 
|---|
| 724 |          _CompletionCondition __completion_condition)
 | 
|---|
| 725 |     {
 | 
|---|
| 726 |       error_code __ec;
 | 
|---|
| 727 |       return net::read(__stream, __b, __completion_condition, __ec);
 | 
|---|
| 728 |     }
 | 
|---|
| 729 | 
 | 
|---|
| 730 |   /// @}
 | 
|---|
| 731 | 
 | 
|---|
| 732 |   /** @brief asynchronous read operations
 | 
|---|
| 733 |    * @{
 | 
|---|
| 734 |    */
 | 
|---|
| 735 | 
 | 
|---|
| 736 |   template<typename _AsyncReadStream, typename _MutableBufferSequence,
 | 
|---|
| 737 |            typename _CompletionCondition, typename _CompletionToken>
 | 
|---|
| 738 |     __deduced_t<_CompletionToken, void(error_code, size_t)>
 | 
|---|
| 739 |     async_read(_AsyncReadStream& __stream,
 | 
|---|
| 740 |                const _MutableBufferSequence& __buffers,
 | 
|---|
| 741 |                _CompletionCondition __completion_condition,
 | 
|---|
| 742 |                _CompletionToken&& __token)
 | 
|---|
| 743 |     {
 | 
|---|
| 744 |       error_code __ec;
 | 
|---|
| 745 |     }
 | 
|---|
| 746 | 
 | 
|---|
| 747 |   template<typename _AsyncReadStream, typename _MutableBufferSequence,
 | 
|---|
| 748 |            typename _CompletionToken>
 | 
|---|
| 749 |     inline __deduced_t<_CompletionToken, void(error_code, size_t)>
 | 
|---|
| 750 |     async_read(_AsyncReadStream& __stream,
 | 
|---|
| 751 |                const _MutableBufferSequence& __buffers,
 | 
|---|
| 752 |                _CompletionToken&& __token)
 | 
|---|
| 753 |     {
 | 
|---|
| 754 |       return net::async_read(__stream, __buffers, transfer_all{},
 | 
|---|
| 755 |                              std::forward<_CompletionToken>(__token));
 | 
|---|
| 756 |     }
 | 
|---|
| 757 | 
 | 
|---|
| 758 |   template<typename _AsyncReadStream, typename _DynamicBuffer,
 | 
|---|
| 759 |            typename _CompletionCondition, typename _CompletionToken>
 | 
|---|
| 760 |     __deduced_t<_CompletionToken, void(error_code, size_t)>
 | 
|---|
| 761 |     async_read(_AsyncReadStream& __stream, _DynamicBuffer&& __b,
 | 
|---|
| 762 |                _CompletionCondition __completion_condition,
 | 
|---|
| 763 |                _CompletionToken&& __token)
 | 
|---|
| 764 |     {
 | 
|---|
| 765 |       error_code __ec;
 | 
|---|
| 766 |     }
 | 
|---|
| 767 | 
 | 
|---|
| 768 |   template<typename _AsyncReadStream, typename _DynamicBuffer,
 | 
|---|
| 769 |            typename _CompletionToken>
 | 
|---|
| 770 |     inline __deduced_t<_CompletionToken, void(error_code, size_t)>
 | 
|---|
| 771 |     async_read(_AsyncReadStream& __stream, _DynamicBuffer&& __b,
 | 
|---|
| 772 |                _CompletionToken&& __token)
 | 
|---|
| 773 |     {
 | 
|---|
| 774 |       return net::async_read(__stream, __b, transfer_all{},
 | 
|---|
| 775 |                              std::forward<_CompletionToken>(__token));
 | 
|---|
| 776 |     }
 | 
|---|
| 777 | 
 | 
|---|
| 778 |   /// @}
 | 
|---|
| 779 | 
 | 
|---|
| 780 | #if 0
 | 
|---|
| 781 |   /** @brief synchronous write operations:
 | 
|---|
| 782 |    * @{
 | 
|---|
| 783 |    */
 | 
|---|
| 784 | 
 | 
|---|
| 785 |   template<typename _SyncWriteStream, typename _ConstBufferSequence>
 | 
|---|
| 786 |     size_t write(_SyncWriteStream& __stream,
 | 
|---|
| 787 |                  const _ConstBufferSequence& __buffers);
 | 
|---|
| 788 |   template<typename _SyncWriteStream, typename _ConstBufferSequence>
 | 
|---|
| 789 |     size_t write(_SyncWriteStream& __stream,
 | 
|---|
| 790 |                  const _ConstBufferSequence& __buffers, error_code& __ec);
 | 
|---|
| 791 |   template<typename _SyncWriteStream, typename _ConstBufferSequence,
 | 
|---|
| 792 |     typename _CompletionCondition>
 | 
|---|
| 793 |       size_t write(_SyncWriteStream& __stream,
 | 
|---|
| 794 |                    const _ConstBufferSequence& __buffers,
 | 
|---|
| 795 |                    _CompletionCondition __completion_condition);
 | 
|---|
| 796 |   template<typename _SyncWriteStream, typename _ConstBufferSequence,
 | 
|---|
| 797 |     typename _CompletionCondition>
 | 
|---|
| 798 |       size_t write(_SyncWriteStream& __stream,
 | 
|---|
| 799 |                    const _ConstBufferSequence& __buffers,
 | 
|---|
| 800 |                    _CompletionCondition __completion_condition,
 | 
|---|
| 801 |                    error_code& __ec);
 | 
|---|
| 802 | 
 | 
|---|
| 803 |   template<typename _SyncWriteStream, typename _DynamicBuffer>
 | 
|---|
| 804 |     size_t write(_SyncWriteStream& __stream, _DynamicBuffer&& __b);
 | 
|---|
| 805 |   template<typename _SyncWriteStream, typename _DynamicBuffer>
 | 
|---|
| 806 |     size_t write(_SyncWriteStream& __stream, _DynamicBuffer&& __b, error_code& __ec);
 | 
|---|
| 807 |   template<typename _SyncWriteStream, typename _DynamicBuffer, typename _CompletionCondition>
 | 
|---|
| 808 |     size_t write(_SyncWriteStream& __stream, _DynamicBuffer&& __b,
 | 
|---|
| 809 |                  _CompletionCondition __completion_condition);
 | 
|---|
| 810 |   template<typename _SyncWriteStream, typename _DynamicBuffer, typename _CompletionCondition>
 | 
|---|
| 811 |     size_t write(_SyncWriteStream& __stream, _DynamicBuffer&& __b,
 | 
|---|
| 812 |                  _CompletionCondition __completion_condition, error_code& __ec);
 | 
|---|
| 813 | 
 | 
|---|
| 814 |   /// @}
 | 
|---|
| 815 | 
 | 
|---|
| 816 |   /** @brief asynchronous write operations
 | 
|---|
| 817 |    * @{
 | 
|---|
| 818 |    */
 | 
|---|
| 819 | 
 | 
|---|
| 820 |   template<typename _AsyncWriteStream, typename _ConstBufferSequence,
 | 
|---|
| 821 |     typename _CompletionToken>
 | 
|---|
| 822 |       DEDUCED async_write(_AsyncWriteStream& __stream,
 | 
|---|
| 823 |                        const _ConstBufferSequence& __buffers,
 | 
|---|
| 824 |                        _CompletionToken&& __token);
 | 
|---|
| 825 |   template<typename _AsyncWriteStream, typename _ConstBufferSequence,
 | 
|---|
| 826 |     typename _CompletionCondition, typename _CompletionToken>
 | 
|---|
| 827 |       DEDUCED async_write(_AsyncWriteStream& __stream,
 | 
|---|
| 828 |                        const _ConstBufferSequence& __buffers,
 | 
|---|
| 829 |                        _CompletionCondition __completion_condition,
 | 
|---|
| 830 |                        _CompletionToken&& __token);
 | 
|---|
| 831 | 
 | 
|---|
| 832 |   template<typename _AsyncWriteStream, typename _DynamicBuffer, typename _CompletionToken>
 | 
|---|
| 833 |     DEDUCED async_write(_AsyncWriteStream& __stream,
 | 
|---|
| 834 |                      _DynamicBuffer&& __b, _CompletionToken&& __token);
 | 
|---|
| 835 |   template<typename _AsyncWriteStream, typename _DynamicBuffer,
 | 
|---|
| 836 |     typename _CompletionCondition, typename _CompletionToken>
 | 
|---|
| 837 |       DEDUCED async_write(_AsyncWriteStream& __stream,
 | 
|---|
| 838 |                        _DynamicBuffer&& __b,
 | 
|---|
| 839 |                        _CompletionCondition __completion_condition,
 | 
|---|
| 840 |                        _CompletionToken&& __token);
 | 
|---|
| 841 | 
 | 
|---|
| 842 |   /// @}
 | 
|---|
| 843 | 
 | 
|---|
| 844 |   /** @brief synchronous delimited read operations
 | 
|---|
| 845 |    * @{
 | 
|---|
| 846 |    */
 | 
|---|
| 847 | 
 | 
|---|
| 848 |   template<typename _SyncReadStream, typename _DynamicBuffer>
 | 
|---|
| 849 |     size_t read_until(_SyncReadStream& __s, _DynamicBuffer&& __b, char __delim);
 | 
|---|
| 850 |   template<typename _SyncReadStream, typename _DynamicBuffer>
 | 
|---|
| 851 |     size_t read_until(_SyncReadStream& __s, _DynamicBuffer&& __b,
 | 
|---|
| 852 |                       char __delim, error_code& __ec);
 | 
|---|
| 853 |   template<typename _SyncReadStream, typename _DynamicBuffer>
 | 
|---|
| 854 |     size_t read_until(_SyncReadStream& __s, _DynamicBuffer&& __b, string_view __delim);
 | 
|---|
| 855 |   template<typename _SyncReadStream, typename _DynamicBuffer>
 | 
|---|
| 856 |     size_t read_until(_SyncReadStream& __s, _DynamicBuffer&& __b,
 | 
|---|
| 857 |                       string_view __delim, error_code& __ec);
 | 
|---|
| 858 | 
 | 
|---|
| 859 |   /// @}
 | 
|---|
| 860 | 
 | 
|---|
| 861 |   /** @brief asynchronous delimited read operations
 | 
|---|
| 862 |    * @{
 | 
|---|
| 863 |    */
 | 
|---|
| 864 | 
 | 
|---|
| 865 |   template<typename _AsyncReadStream, typename _DynamicBuffer, typename _CompletionToken>
 | 
|---|
| 866 |     DEDUCED async_read_until(_AsyncReadStream& __s,
 | 
|---|
| 867 |                           _DynamicBuffer&& __b, char __delim,
 | 
|---|
| 868 |                           _CompletionToken&& __token);
 | 
|---|
| 869 |   template<typename _AsyncReadStream, typename _DynamicBuffer, typename _CompletionToken>
 | 
|---|
| 870 |     DEDUCED async_read_until(_AsyncReadStream& __s,
 | 
|---|
| 871 |                           _DynamicBuffer&& __b, string_view __delim,
 | 
|---|
| 872 |                           _CompletionToken&& __token);
 | 
|---|
| 873 | 
 | 
|---|
| 874 |   /// @}
 | 
|---|
| 875 | 
 | 
|---|
| 876 | #endif
 | 
|---|
| 877 |   /// @}
 | 
|---|
| 878 | 
 | 
|---|
| 879 | } // namespace v1
 | 
|---|
| 880 | } // namespace net
 | 
|---|
| 881 | } // namespace experimental
 | 
|---|
| 882 | 
 | 
|---|
| 883 |   template<>
 | 
|---|
| 884 |     struct is_error_code_enum<experimental::net::v1::stream_errc>
 | 
|---|
| 885 |     : public true_type {};
 | 
|---|
| 886 | 
 | 
|---|
| 887 | _GLIBCXX_END_NAMESPACE_VERSION
 | 
|---|
| 888 | } // namespace std
 | 
|---|
| 889 | 
 | 
|---|
| 890 | #endif // C++14
 | 
|---|
| 891 | 
 | 
|---|
| 892 | #endif // _GLIBCXX_EXPERIMENTAL_BUFFER
 | 
|---|