1627f7eb2Smrg// <experimental/buffer> -*- C++ -*- 2627f7eb2Smrg 3*4c3eb207Smrg// Copyright (C) 2015-2020 Free Software Foundation, Inc. 4627f7eb2Smrg// 5627f7eb2Smrg// This file is part of the GNU ISO C++ Library. This library is free 6627f7eb2Smrg// software; you can redistribute it and/or modify it under the 7627f7eb2Smrg// terms of the GNU General Public License as published by the 8627f7eb2Smrg// Free Software Foundation; either version 3, or (at your option) 9627f7eb2Smrg// any later version. 10627f7eb2Smrg 11627f7eb2Smrg// This library is distributed in the hope that it will be useful, 12627f7eb2Smrg// but WITHOUT ANY WARRANTY; without even the implied warranty of 13627f7eb2Smrg// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14627f7eb2Smrg// GNU General Public License for more details. 15627f7eb2Smrg 16627f7eb2Smrg// Under Section 7 of GPL version 3, you are granted additional 17627f7eb2Smrg// permissions described in the GCC Runtime Library Exception, version 18627f7eb2Smrg// 3.1, as published by the Free Software Foundation. 19627f7eb2Smrg 20627f7eb2Smrg// You should have received a copy of the GNU General Public License and 21627f7eb2Smrg// a copy of the GCC Runtime Library Exception along with this program; 22627f7eb2Smrg// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23627f7eb2Smrg// <http://www.gnu.org/licenses/>. 24627f7eb2Smrg 25627f7eb2Smrg/** @file experimental/buffer 26627f7eb2Smrg * This is a TS C++ Library header. 27*4c3eb207Smrg * @ingroup networking-ts 28627f7eb2Smrg */ 29627f7eb2Smrg 30627f7eb2Smrg#ifndef _GLIBCXX_EXPERIMENTAL_BUFFER 31627f7eb2Smrg#define _GLIBCXX_EXPERIMENTAL_BUFFER 1 32627f7eb2Smrg 33627f7eb2Smrg#pragma GCC system_header 34627f7eb2Smrg 35627f7eb2Smrg#if __cplusplus >= 201402L 36627f7eb2Smrg 37627f7eb2Smrg#include <array> 38627f7eb2Smrg#include <string> 39627f7eb2Smrg#include <system_error> 40627f7eb2Smrg#include <vector> 41627f7eb2Smrg#include <cstring> 42627f7eb2Smrg#include <experimental/string_view> 43627f7eb2Smrg#include <experimental/bits/net.h> 44627f7eb2Smrg 45627f7eb2Smrgnamespace std _GLIBCXX_VISIBILITY(default) 46627f7eb2Smrg{ 47627f7eb2Smrg_GLIBCXX_BEGIN_NAMESPACE_VERSION 48627f7eb2Smrgnamespace experimental 49627f7eb2Smrg{ 50627f7eb2Smrgnamespace net 51627f7eb2Smrg{ 52627f7eb2Smrginline namespace v1 53627f7eb2Smrg{ 54627f7eb2Smrg 55*4c3eb207Smrg /** @addtogroup networking-ts 56627f7eb2Smrg * @{ 57627f7eb2Smrg */ 58627f7eb2Smrg 59627f7eb2Smrg enum class stream_errc { // TODO decide values 60627f7eb2Smrg eof = 1, 61627f7eb2Smrg not_found = 2 62627f7eb2Smrg }; 63627f7eb2Smrg 64627f7eb2Smrg const error_category& stream_category() noexcept // TODO not inline 65627f7eb2Smrg { 66627f7eb2Smrg struct __cat : error_category 67627f7eb2Smrg { 68627f7eb2Smrg const char* name() const noexcept { return "stream"; } 69627f7eb2Smrg 70627f7eb2Smrg std::string message(int __e) const 71627f7eb2Smrg { 72627f7eb2Smrg if (__e == (int)stream_errc::eof) 73627f7eb2Smrg return "EOF"; 74627f7eb2Smrg else if (__e == (int)stream_errc::not_found) 75627f7eb2Smrg return "not found"; 76627f7eb2Smrg return "stream"; 77627f7eb2Smrg } 78627f7eb2Smrg 79627f7eb2Smrg virtual void __message(int) { } // TODO dual ABI XXX 80627f7eb2Smrg }; 81627f7eb2Smrg static __cat __c; 82627f7eb2Smrg return __c; 83627f7eb2Smrg } 84627f7eb2Smrg 85627f7eb2Smrg inline error_code 86627f7eb2Smrg make_error_code(stream_errc __e) noexcept 87627f7eb2Smrg { return error_code(static_cast<int>(__e), stream_category()); } 88627f7eb2Smrg 89627f7eb2Smrg inline error_condition 90627f7eb2Smrg make_error_condition(stream_errc __e) noexcept 91627f7eb2Smrg { return error_condition(static_cast<int>(__e), stream_category()); } 92627f7eb2Smrg 93627f7eb2Smrg class mutable_buffer 94627f7eb2Smrg { 95627f7eb2Smrg public: 96627f7eb2Smrg // constructors: 97627f7eb2Smrg mutable_buffer() noexcept : _M_data(), _M_size() { } 98627f7eb2Smrg 99627f7eb2Smrg mutable_buffer(void* __p, size_t __n) noexcept 100627f7eb2Smrg : _M_data(__p), _M_size(__n) { } 101627f7eb2Smrg 102627f7eb2Smrg // members: 103627f7eb2Smrg void* data() const noexcept { return _M_data; } 104627f7eb2Smrg size_t size() const noexcept { return _M_size; } 105627f7eb2Smrg 106627f7eb2Smrg private: 107627f7eb2Smrg void* _M_data; 108627f7eb2Smrg size_t _M_size; 109627f7eb2Smrg }; 110627f7eb2Smrg 111627f7eb2Smrg class const_buffer 112627f7eb2Smrg { 113627f7eb2Smrg public: 114627f7eb2Smrg // constructors: 115627f7eb2Smrg const_buffer() noexcept : _M_data(), _M_size() { } 116627f7eb2Smrg 117627f7eb2Smrg const_buffer(const void* __p, size_t __n) noexcept 118627f7eb2Smrg : _M_data(__p), _M_size(__n) { } 119627f7eb2Smrg 120627f7eb2Smrg const_buffer(const mutable_buffer& __b) noexcept 121627f7eb2Smrg : _M_data(__b.data()), _M_size(__b.size()) { } 122627f7eb2Smrg 123627f7eb2Smrg // members: 124627f7eb2Smrg const void* data() const noexcept { return _M_data; } 125627f7eb2Smrg size_t size() const noexcept { return _M_size; } 126627f7eb2Smrg 127627f7eb2Smrg private: 128627f7eb2Smrg const void* _M_data; 129627f7eb2Smrg size_t _M_size; 130627f7eb2Smrg }; 131627f7eb2Smrg 132627f7eb2Smrg 133627f7eb2Smrg /** @brief buffer sequence access 134627f7eb2Smrg * 135627f7eb2Smrg * Uniform access to types that meet the BufferSequence requirements. 136627f7eb2Smrg * @{ 137627f7eb2Smrg */ 138627f7eb2Smrg 139627f7eb2Smrg inline const mutable_buffer* 140627f7eb2Smrg buffer_sequence_begin(const mutable_buffer& __b) 141627f7eb2Smrg { return std::addressof(__b); } 142627f7eb2Smrg 143627f7eb2Smrg inline const const_buffer* 144627f7eb2Smrg buffer_sequence_begin(const const_buffer& __b) 145627f7eb2Smrg { return std::addressof(__b); } 146627f7eb2Smrg 147627f7eb2Smrg inline const mutable_buffer* 148627f7eb2Smrg buffer_sequence_end(const mutable_buffer& __b) 149627f7eb2Smrg { return std::addressof(__b) + 1; } 150627f7eb2Smrg 151627f7eb2Smrg inline const const_buffer* 152627f7eb2Smrg buffer_sequence_end(const const_buffer& __b) 153627f7eb2Smrg { return std::addressof(__b) + 1; } 154627f7eb2Smrg 155627f7eb2Smrg template<typename _Cont> 156627f7eb2Smrg auto 157627f7eb2Smrg buffer_sequence_begin(_Cont& __c) -> decltype(__c.begin()) 158627f7eb2Smrg { return __c.begin(); } 159627f7eb2Smrg 160627f7eb2Smrg template<typename _Cont> 161627f7eb2Smrg auto 162627f7eb2Smrg buffer_sequence_begin(const _Cont& __c) -> decltype(__c.begin()) 163627f7eb2Smrg { return __c.begin(); } 164627f7eb2Smrg 165627f7eb2Smrg template<typename _Cont> 166627f7eb2Smrg auto 167627f7eb2Smrg buffer_sequence_end(_Cont& __c) -> decltype(__c.end()) 168627f7eb2Smrg { return __c.end(); } 169627f7eb2Smrg 170627f7eb2Smrg template<typename _Cont> 171627f7eb2Smrg auto 172627f7eb2Smrg buffer_sequence_end(const _Cont& __c) -> decltype(__c.end()) 173627f7eb2Smrg { return __c.end(); } 174627f7eb2Smrg 175*4c3eb207Smrg /// @} 176627f7eb2Smrg 177627f7eb2Smrg 178627f7eb2Smrg /** @brief buffer type traits 179627f7eb2Smrg * 180627f7eb2Smrg * @{ 181627f7eb2Smrg */ 182627f7eb2Smrg 183627f7eb2Smrg template<typename _Tp, typename _Buffer, 184627f7eb2Smrg typename _Begin 185627f7eb2Smrg = decltype(net::buffer_sequence_begin(std::declval<_Tp&>())), 186627f7eb2Smrg typename _End 187627f7eb2Smrg = decltype(net::buffer_sequence_end(std::declval<_Tp&>()))> 188627f7eb2Smrg using __buffer_sequence = enable_if_t<__and_< 189627f7eb2Smrg __is_value_constructible<_Tp>, is_same<_Begin, _End>, 190627f7eb2Smrg is_convertible<typename iterator_traits<_Begin>::value_type, _Buffer> 191627f7eb2Smrg >::value>; 192627f7eb2Smrg 193627f7eb2Smrg template<typename _Tp, typename _Buffer, typename = void> 194627f7eb2Smrg struct __is_buffer_sequence : false_type 195627f7eb2Smrg { }; 196627f7eb2Smrg 197627f7eb2Smrg template<typename _Tp, typename _Buffer> 198627f7eb2Smrg struct __is_buffer_sequence<_Tp, _Buffer, __buffer_sequence<_Tp, _Buffer>> 199627f7eb2Smrg : true_type 200627f7eb2Smrg { }; 201627f7eb2Smrg 202627f7eb2Smrg template<typename _Tp> 203627f7eb2Smrg struct is_mutable_buffer_sequence 204627f7eb2Smrg : __is_buffer_sequence<_Tp, mutable_buffer>::type 205627f7eb2Smrg { }; 206627f7eb2Smrg 207627f7eb2Smrg template<typename _Tp> 208627f7eb2Smrg struct is_const_buffer_sequence 209627f7eb2Smrg : __is_buffer_sequence<_Tp, const_buffer>::type 210627f7eb2Smrg { }; 211627f7eb2Smrg 212627f7eb2Smrg template<typename _Tp> 213627f7eb2Smrg constexpr bool is_mutable_buffer_sequence_v 214627f7eb2Smrg = is_mutable_buffer_sequence<_Tp>::value; 215627f7eb2Smrg 216627f7eb2Smrg template<typename _Tp> 217627f7eb2Smrg constexpr bool is_const_buffer_sequence_v 218627f7eb2Smrg = is_const_buffer_sequence<_Tp>::value; 219627f7eb2Smrg 220627f7eb2Smrg template<typename _Tp, typename = void> 221627f7eb2Smrg struct __is_dynamic_buffer_impl : false_type 222627f7eb2Smrg { }; 223627f7eb2Smrg 224627f7eb2Smrg // Check DynamicBuffer requirements. 225627f7eb2Smrg template<typename _Tp, typename _Up = remove_const_t<_Tp>> 226627f7eb2Smrg auto 227627f7eb2Smrg __dynamic_buffer_reqs(_Up* __x = 0, const _Up* __x1 = 0, size_t __n = 0) 228627f7eb2Smrg -> enable_if_t<__and_< 229627f7eb2Smrg is_move_constructible<_Up>, 230627f7eb2Smrg is_const_buffer_sequence<typename _Tp::const_buffers_type>, 231627f7eb2Smrg is_mutable_buffer_sequence<typename _Tp::mutable_buffers_type>, 232627f7eb2Smrg is_same<decltype(__x1->size()), size_t>, 233627f7eb2Smrg is_same<decltype(__x1->max_size()), size_t>, 234627f7eb2Smrg is_same<decltype(__x1->capacity()), size_t>, 235627f7eb2Smrg is_same<decltype(__x1->data()), typename _Tp::const_buffers_type>, 236627f7eb2Smrg is_same<decltype(__x->prepare(__n)), typename _Tp::mutable_buffers_type>, 237627f7eb2Smrg is_void<decltype(__x->commit(__n), __x->consume(__n), void())> 238627f7eb2Smrg >::value>; 239627f7eb2Smrg 240627f7eb2Smrg template<typename _Tp> 241627f7eb2Smrg struct __is_dynamic_buffer_impl<_Tp, 242627f7eb2Smrg decltype(__dynamic_buffer_reqs<_Tp>())> 243627f7eb2Smrg : true_type 244627f7eb2Smrg { }; 245627f7eb2Smrg 246627f7eb2Smrg template<typename _Tp> 247627f7eb2Smrg struct is_dynamic_buffer : __is_dynamic_buffer_impl<_Tp>::type 248627f7eb2Smrg { }; 249627f7eb2Smrg 250627f7eb2Smrg template<typename _Tp> 251627f7eb2Smrg constexpr bool is_dynamic_buffer_v = is_dynamic_buffer<_Tp>::value; 252627f7eb2Smrg 253*4c3eb207Smrg /// @} 254627f7eb2Smrg 255627f7eb2Smrg /// buffer size 256627f7eb2Smrg template<typename _ConstBufferSequence> 257627f7eb2Smrg size_t 258627f7eb2Smrg buffer_size(const _ConstBufferSequence& __buffers) noexcept 259627f7eb2Smrg { 260627f7eb2Smrg size_t __total_size = 0; 261627f7eb2Smrg auto __i = net::buffer_sequence_begin(__buffers); 262627f7eb2Smrg const auto __end = net::buffer_sequence_end(__buffers); 263627f7eb2Smrg for (; __i != __end; ++__i) 264627f7eb2Smrg __total_size += const_buffer(*__i).size(); 265627f7eb2Smrg return __total_size; 266627f7eb2Smrg } 267627f7eb2Smrg 268627f7eb2Smrg template<typename _ConstBufferSequence> 269627f7eb2Smrg bool 270627f7eb2Smrg __buffer_empty(const _ConstBufferSequence& __buffers) noexcept 271627f7eb2Smrg { 272627f7eb2Smrg auto __i = net::buffer_sequence_begin(__buffers); 273627f7eb2Smrg const auto __end = net::buffer_sequence_end(__buffers); 274627f7eb2Smrg for (; __i != __end; ++__i) 275627f7eb2Smrg if (const_buffer(*__i).size() != 0) 276627f7eb2Smrg return false; 277627f7eb2Smrg return true; 278627f7eb2Smrg } 279627f7eb2Smrg 280627f7eb2Smrg // buffer copy: 281627f7eb2Smrg 282627f7eb2Smrg template<typename _MutableBufferSequence, typename _ConstBufferSequence> 283627f7eb2Smrg size_t 284627f7eb2Smrg buffer_copy(const _MutableBufferSequence& __dest, 285627f7eb2Smrg const _ConstBufferSequence& __source, 286627f7eb2Smrg size_t __max_size) noexcept 287627f7eb2Smrg { 288627f7eb2Smrg size_t __total_size = 0; 289627f7eb2Smrg auto __to_i = net::buffer_sequence_begin(__dest); 290627f7eb2Smrg const auto __to_end = net::buffer_sequence_end(__dest); 291627f7eb2Smrg auto __from_i = net::buffer_sequence_begin(__source); 292627f7eb2Smrg const auto __from_end = net::buffer_sequence_end(__source); 293627f7eb2Smrg mutable_buffer __to; 294627f7eb2Smrg const_buffer __from; 295627f7eb2Smrg while (((__from_i != __from_end && __to_i != __to_end) 296627f7eb2Smrg || (__from.size() && __to.size())) 297627f7eb2Smrg && __total_size < __max_size) 298627f7eb2Smrg { 299627f7eb2Smrg if (__from.size() == 0) 300627f7eb2Smrg __from = const_buffer{*__from_i++}; 301627f7eb2Smrg if (__to.size() == 0) 302627f7eb2Smrg __to = mutable_buffer{*__to_i++}; 303627f7eb2Smrg 304627f7eb2Smrg size_t __n = std::min(__from.size(), __to.size()); 305627f7eb2Smrg __n = std::min(__n, __max_size - __total_size); 306627f7eb2Smrg std::memcpy(__to.data(), __from.data(), __n); 307627f7eb2Smrg __from = { (const char*)__from.data() + __n, __from.size() - __n }; 308627f7eb2Smrg __to = { (char*)__to.data() + __n, __to.size() - __n }; 309627f7eb2Smrg __total_size += __n; 310627f7eb2Smrg } 311627f7eb2Smrg return __total_size; 312627f7eb2Smrg } 313627f7eb2Smrg 314627f7eb2Smrg template<typename _MutableBufferSequence, typename _ConstBufferSequence> 315627f7eb2Smrg inline size_t 316627f7eb2Smrg buffer_copy(const _MutableBufferSequence& __dest, 317627f7eb2Smrg const _ConstBufferSequence& __source) noexcept 318627f7eb2Smrg { return net::buffer_copy(__dest, __source, size_t{-1}); } 319627f7eb2Smrg 320627f7eb2Smrg 321627f7eb2Smrg // buffer arithmetic: 322627f7eb2Smrg 323627f7eb2Smrg inline mutable_buffer 324627f7eb2Smrg operator+(const mutable_buffer& __b, size_t __n) noexcept 325627f7eb2Smrg { 326627f7eb2Smrg if (__n > __b.size()) 327627f7eb2Smrg __n = __b.size(); 328627f7eb2Smrg return { static_cast<char*>(__b.data()) + __n, __b.size() - __n }; 329627f7eb2Smrg } 330627f7eb2Smrg 331627f7eb2Smrg inline mutable_buffer 332627f7eb2Smrg operator+(size_t __n, const mutable_buffer& __b) noexcept 333627f7eb2Smrg { return __b + __n; } 334627f7eb2Smrg 335627f7eb2Smrg inline const_buffer 336627f7eb2Smrg operator+(const const_buffer& __b, size_t __n) noexcept 337627f7eb2Smrg { 338627f7eb2Smrg if (__n > __b.size()) 339627f7eb2Smrg __n = __b.size(); 340627f7eb2Smrg return { static_cast<const char*>(__b.data()) + __n, __b.size() - __n }; 341627f7eb2Smrg } 342627f7eb2Smrg 343627f7eb2Smrg inline const_buffer 344627f7eb2Smrg operator+(size_t __n, const const_buffer& __b) noexcept 345627f7eb2Smrg { return __b + __n; } 346627f7eb2Smrg 347627f7eb2Smrg // buffer creation: 348627f7eb2Smrg 349627f7eb2Smrg inline mutable_buffer 350627f7eb2Smrg buffer(void* __p, size_t __n) noexcept 351627f7eb2Smrg { return { __p, __n }; } 352627f7eb2Smrg 353627f7eb2Smrg inline const_buffer 354627f7eb2Smrg buffer(const void* __p, size_t __n) noexcept 355627f7eb2Smrg { return { __p, __n }; } 356627f7eb2Smrg 357627f7eb2Smrg inline mutable_buffer 358627f7eb2Smrg buffer(const mutable_buffer& __b) noexcept 359627f7eb2Smrg { return __b; } 360627f7eb2Smrg 361627f7eb2Smrg inline mutable_buffer 362627f7eb2Smrg buffer(const mutable_buffer& __b, size_t __n) noexcept 363627f7eb2Smrg { return { __b.data(), std::min(__b.size(), __n) }; } 364627f7eb2Smrg 365627f7eb2Smrg inline const_buffer 366627f7eb2Smrg buffer(const const_buffer& __b) noexcept 367627f7eb2Smrg { return __b; } 368627f7eb2Smrg 369627f7eb2Smrg inline const_buffer 370627f7eb2Smrg buffer(const const_buffer& __b, size_t __n) noexcept 371627f7eb2Smrg { return { __b.data(), std::min(__b.size(), __n) }; } 372627f7eb2Smrg 373627f7eb2Smrg template<typename _Tp> 374627f7eb2Smrg inline mutable_buffer 375627f7eb2Smrg __to_mbuf(_Tp* __data, size_t __n) 376627f7eb2Smrg { return { __n ? __data : nullptr, __n * sizeof(_Tp) }; } 377627f7eb2Smrg 378627f7eb2Smrg template<typename _Tp> 379627f7eb2Smrg inline const_buffer 380627f7eb2Smrg __to_cbuf(const _Tp* __data, size_t __n) 381627f7eb2Smrg { return { __n ? __data : nullptr, __n * sizeof(_Tp) }; } 382627f7eb2Smrg 383627f7eb2Smrg template<typename _Tp, size_t _Nm> 384627f7eb2Smrg inline mutable_buffer 385627f7eb2Smrg buffer(_Tp (&__data)[_Nm]) noexcept 386627f7eb2Smrg { return net::__to_mbuf(__data, _Nm); } 387627f7eb2Smrg 388627f7eb2Smrg template<typename _Tp, size_t _Nm> 389627f7eb2Smrg inline const_buffer 390627f7eb2Smrg buffer(const _Tp (&__data)[_Nm]) noexcept 391627f7eb2Smrg { return net::__to_cbuf(__data, _Nm); } 392627f7eb2Smrg 393627f7eb2Smrg template<typename _Tp, size_t _Nm> 394627f7eb2Smrg inline mutable_buffer 395627f7eb2Smrg buffer(array<_Tp, _Nm>& __data) noexcept 396627f7eb2Smrg { return net::__to_mbuf(__data.data(), _Nm); } 397627f7eb2Smrg 398627f7eb2Smrg template<typename _Tp, size_t _Nm> 399627f7eb2Smrg inline const_buffer 400627f7eb2Smrg buffer(array<const _Tp, _Nm>& __data) noexcept 401627f7eb2Smrg { return net::__to_cbuf(__data.data(), __data.size()); } 402627f7eb2Smrg 403627f7eb2Smrg template<typename _Tp, size_t _Nm> 404627f7eb2Smrg inline const_buffer 405627f7eb2Smrg buffer(const array<_Tp, _Nm>& __data) noexcept 406627f7eb2Smrg { return net::__to_cbuf(__data.data(), __data.size()); } 407627f7eb2Smrg 408627f7eb2Smrg template<typename _Tp, typename _Allocator> 409627f7eb2Smrg inline mutable_buffer 410627f7eb2Smrg buffer(vector<_Tp, _Allocator>& __data) noexcept 411627f7eb2Smrg { return net::__to_mbuf(__data.data(), __data.size()); } 412627f7eb2Smrg 413627f7eb2Smrg template<typename _Tp, typename _Allocator> 414627f7eb2Smrg inline const_buffer 415627f7eb2Smrg buffer(const vector<_Tp, _Allocator>& __data) noexcept 416627f7eb2Smrg { return net::__to_cbuf(__data.data(), __data.size()); } 417627f7eb2Smrg 418627f7eb2Smrg template<typename _CharT, typename _Traits, typename _Allocator> 419627f7eb2Smrg inline mutable_buffer 420627f7eb2Smrg buffer(basic_string<_CharT, _Traits, _Allocator>& __data) noexcept 421627f7eb2Smrg { return net::__to_mbuf(&__data.front(), __data.size()); } 422627f7eb2Smrg 423627f7eb2Smrg template<typename _CharT, typename _Traits, typename _Allocator> 424627f7eb2Smrg inline const_buffer 425627f7eb2Smrg buffer(const basic_string<_CharT, _Traits, _Allocator>& __data) noexcept 426627f7eb2Smrg { return net::__to_cbuf(&__data.front(), __data.size()); } 427627f7eb2Smrg 428627f7eb2Smrg template<typename _CharT, typename _Traits> 429627f7eb2Smrg inline const_buffer 430627f7eb2Smrg buffer(basic_string_view<_CharT, _Traits> __data) noexcept 431627f7eb2Smrg { return net::__to_cbuf(__data.data(), __data.size()); } 432627f7eb2Smrg 433627f7eb2Smrg template<typename _Tp, size_t _Nm> 434627f7eb2Smrg inline mutable_buffer 435627f7eb2Smrg buffer(_Tp (&__data)[_Nm], size_t __n) noexcept 436627f7eb2Smrg { return buffer(net::buffer(__data), __n * sizeof(_Tp)); } 437627f7eb2Smrg 438627f7eb2Smrg template<typename _Tp, size_t _Nm> 439627f7eb2Smrg inline const_buffer 440627f7eb2Smrg buffer(const _Tp (&__data)[_Nm], size_t __n) noexcept 441627f7eb2Smrg { return buffer(net::buffer(__data), __n * sizeof(_Tp)); } 442627f7eb2Smrg 443627f7eb2Smrg template<typename _Tp, size_t _Nm> 444627f7eb2Smrg inline mutable_buffer 445627f7eb2Smrg buffer(array<_Tp, _Nm>& __data, size_t __n) noexcept 446627f7eb2Smrg { return buffer(net::buffer(__data), __n * sizeof(_Tp)); } 447627f7eb2Smrg 448627f7eb2Smrg template<typename _Tp, size_t _Nm> 449627f7eb2Smrg inline const_buffer 450627f7eb2Smrg buffer(array<const _Tp, _Nm>& __data, size_t __n) noexcept 451627f7eb2Smrg { return buffer(net::buffer(__data), __n * sizeof(_Tp)); } 452627f7eb2Smrg 453627f7eb2Smrg template<typename _Tp, size_t _Nm> 454627f7eb2Smrg inline const_buffer 455627f7eb2Smrg buffer(const array<_Tp, _Nm>& __data, size_t __n) noexcept 456627f7eb2Smrg { return buffer(net::buffer(__data), __n * sizeof(_Tp)); } 457627f7eb2Smrg 458627f7eb2Smrg template<typename _Tp, typename _Allocator> 459627f7eb2Smrg inline mutable_buffer 460627f7eb2Smrg buffer(vector<_Tp, _Allocator>& __data, size_t __n) noexcept 461627f7eb2Smrg { return buffer(net::buffer(__data), __n * sizeof(_Tp)); } 462627f7eb2Smrg 463627f7eb2Smrg template<typename _Tp, typename _Allocator> 464627f7eb2Smrg inline const_buffer 465627f7eb2Smrg buffer(const vector<_Tp, _Allocator>& __data, size_t __n) noexcept 466627f7eb2Smrg { return buffer(net::buffer(__data), __n * sizeof(_Tp)); } 467627f7eb2Smrg 468627f7eb2Smrg template<typename _CharT, typename _Traits, typename _Allocator> 469627f7eb2Smrg inline mutable_buffer 470627f7eb2Smrg buffer(basic_string<_CharT, _Traits, _Allocator>& __data, 471627f7eb2Smrg size_t __n) noexcept 472627f7eb2Smrg { return buffer(net::buffer(__data), __n * sizeof(_CharT)); } 473627f7eb2Smrg 474627f7eb2Smrg template<typename _CharT, typename _Traits, typename _Allocator> 475627f7eb2Smrg inline const_buffer 476627f7eb2Smrg buffer(const basic_string<_CharT, _Traits, _Allocator>& __data, 477627f7eb2Smrg size_t __n) noexcept 478627f7eb2Smrg { return buffer(net::buffer(__data), __n * sizeof(_CharT)); } 479627f7eb2Smrg 480627f7eb2Smrg template<typename _CharT, typename _Traits> 481627f7eb2Smrg inline const_buffer 482627f7eb2Smrg buffer(basic_string_view<_CharT, _Traits> __data, size_t __n) noexcept 483627f7eb2Smrg { return buffer(net::buffer(__data), __n * sizeof(_CharT)); } 484627f7eb2Smrg 485627f7eb2Smrg 486627f7eb2Smrg template<typename _Sequence> 487627f7eb2Smrg class __dynamic_buffer_base 488627f7eb2Smrg { 489627f7eb2Smrg public: 490627f7eb2Smrg // types: 491627f7eb2Smrg typedef const_buffer const_buffers_type; 492627f7eb2Smrg typedef mutable_buffer mutable_buffers_type; 493627f7eb2Smrg 494627f7eb2Smrg // constructors: 495627f7eb2Smrg explicit 496627f7eb2Smrg __dynamic_buffer_base(_Sequence& __seq) noexcept 497627f7eb2Smrg : _M_seq(__seq), _M_size(__seq.size()), _M_max_size(__seq.max_size()) 498627f7eb2Smrg { } 499627f7eb2Smrg 500627f7eb2Smrg __dynamic_buffer_base(_Sequence& __seq, size_t __maximum_size) noexcept 501627f7eb2Smrg : _M_seq(__seq), _M_size(__seq.size()), _M_max_size(__maximum_size) 502627f7eb2Smrg { __glibcxx_assert(__seq.size() <= __maximum_size); } 503627f7eb2Smrg 504627f7eb2Smrg __dynamic_buffer_base(__dynamic_buffer_base&&) = default; 505627f7eb2Smrg 506627f7eb2Smrg // members: 507627f7eb2Smrg size_t size() const noexcept { return _M_size; } 508627f7eb2Smrg size_t max_size() const noexcept { return _M_max_size; } 509627f7eb2Smrg size_t capacity() const noexcept { return _M_seq.capacity(); } 510627f7eb2Smrg 511627f7eb2Smrg const_buffers_type 512627f7eb2Smrg data() const noexcept 513627f7eb2Smrg { return net::buffer(_M_seq, _M_size); } 514627f7eb2Smrg 515627f7eb2Smrg mutable_buffers_type 516627f7eb2Smrg prepare(size_t __n) 517627f7eb2Smrg { 518627f7eb2Smrg if ((_M_size + __n) > _M_max_size) 519627f7eb2Smrg __throw_length_error("dynamic_vector_buffer::prepare"); 520627f7eb2Smrg 521627f7eb2Smrg _M_seq.resize(_M_size + __n); 522627f7eb2Smrg return buffer(net::buffer(_M_seq) + _M_size, __n); 523627f7eb2Smrg } 524627f7eb2Smrg 525627f7eb2Smrg void 526627f7eb2Smrg commit(size_t __n) 527627f7eb2Smrg { 528627f7eb2Smrg _M_size += std::min(__n, _M_seq.size() - _M_size); 529627f7eb2Smrg _M_seq.resize(_M_size); 530627f7eb2Smrg } 531627f7eb2Smrg 532627f7eb2Smrg void 533627f7eb2Smrg consume(size_t __n) 534627f7eb2Smrg { 535627f7eb2Smrg size_t __m = std::min(__n, _M_size); 536627f7eb2Smrg _M_seq.erase(_M_seq.begin(), _M_seq.begin() + __m); 537627f7eb2Smrg _M_size -= __m; 538627f7eb2Smrg } 539627f7eb2Smrg 540627f7eb2Smrg private: 541627f7eb2Smrg _Sequence& _M_seq; 542627f7eb2Smrg size_t _M_size; 543627f7eb2Smrg const size_t _M_max_size; 544627f7eb2Smrg }; 545627f7eb2Smrg 546627f7eb2Smrg template<typename _Tp, typename _Allocator> 547627f7eb2Smrg class dynamic_vector_buffer 548627f7eb2Smrg : public __dynamic_buffer_base<vector<_Tp, _Allocator>> 549627f7eb2Smrg { 550627f7eb2Smrg public: 551627f7eb2Smrg using __dynamic_buffer_base<vector<_Tp, _Allocator>>::__dynamic_buffer_base; 552627f7eb2Smrg }; 553627f7eb2Smrg 554627f7eb2Smrg template<typename _CharT, typename _Traits, typename _Allocator> 555627f7eb2Smrg class dynamic_string_buffer 556627f7eb2Smrg : public __dynamic_buffer_base<basic_string<_CharT, _Traits, _Allocator>> 557627f7eb2Smrg { 558627f7eb2Smrg public: 559627f7eb2Smrg using __dynamic_buffer_base<basic_string<_CharT, _Traits, _Allocator>>:: 560627f7eb2Smrg __dynamic_buffer_base; 561627f7eb2Smrg }; 562627f7eb2Smrg 563627f7eb2Smrg // dynamic buffer creation: 564627f7eb2Smrg 565627f7eb2Smrg template<typename _Tp, typename _Allocator> 566627f7eb2Smrg inline dynamic_vector_buffer<_Tp, _Allocator> 567627f7eb2Smrg dynamic_buffer(vector<_Tp, _Allocator>& __vec) noexcept 568627f7eb2Smrg { return dynamic_vector_buffer<_Tp, _Allocator>{__vec}; } 569627f7eb2Smrg 570627f7eb2Smrg template<typename _Tp, typename _Allocator> 571627f7eb2Smrg inline dynamic_vector_buffer<_Tp, _Allocator> 572627f7eb2Smrg dynamic_buffer(vector<_Tp, _Allocator>& __vec, size_t __n) noexcept 573627f7eb2Smrg { return {__vec, __n}; } 574627f7eb2Smrg 575627f7eb2Smrg template<typename _CharT, typename _Traits, typename _Allocator> 576627f7eb2Smrg inline dynamic_string_buffer<_CharT, _Traits, _Allocator> 577627f7eb2Smrg dynamic_buffer(basic_string<_CharT, _Traits, _Allocator>& __str) noexcept 578627f7eb2Smrg { return dynamic_string_buffer<_CharT, _Traits, _Allocator>{__str}; } 579627f7eb2Smrg 580627f7eb2Smrg template<typename _CharT, typename _Traits, typename _Allocator> 581627f7eb2Smrg inline dynamic_string_buffer<_CharT, _Traits, _Allocator> 582627f7eb2Smrg dynamic_buffer(basic_string<_CharT, _Traits, _Allocator>& __str, 583627f7eb2Smrg size_t __n) noexcept 584627f7eb2Smrg { return {__str, __n}; } 585627f7eb2Smrg 586627f7eb2Smrg class transfer_all 587627f7eb2Smrg { 588627f7eb2Smrg public: 589627f7eb2Smrg size_t operator()(const error_code& __ec, size_t) const 590627f7eb2Smrg { return !__ec ? 1500 : 0; } 591627f7eb2Smrg }; 592627f7eb2Smrg 593627f7eb2Smrg class transfer_at_least 594627f7eb2Smrg { 595627f7eb2Smrg public: 596627f7eb2Smrg explicit transfer_at_least(size_t __m) : _M_minimum(__m) { } 597627f7eb2Smrg 598627f7eb2Smrg size_t operator()(const error_code& __ec, size_t __n) const 599627f7eb2Smrg { return !__ec && __n < _M_minimum ? _M_minimum - __n : 0; } 600627f7eb2Smrg 601627f7eb2Smrg private: 602627f7eb2Smrg size_t _M_minimum; 603627f7eb2Smrg }; 604627f7eb2Smrg 605627f7eb2Smrg class transfer_exactly 606627f7eb2Smrg { 607627f7eb2Smrg public: 608627f7eb2Smrg explicit transfer_exactly(size_t __e) : _M_exact(__e) { } 609627f7eb2Smrg 610627f7eb2Smrg size_t operator()(const error_code& __ec, size_t __n) const 611627f7eb2Smrg { 612627f7eb2Smrg size_t _Nm = -1; 613627f7eb2Smrg return !__ec && __n < _M_exact ? std::min(_M_exact - __n, _Nm) : 0; 614627f7eb2Smrg } 615627f7eb2Smrg 616627f7eb2Smrg private: 617627f7eb2Smrg size_t _M_exact; 618627f7eb2Smrg }; 619627f7eb2Smrg 620627f7eb2Smrg /** @brief synchronous read operations 621627f7eb2Smrg * @{ 622627f7eb2Smrg */ 623627f7eb2Smrg 624627f7eb2Smrg template<typename _SyncReadStream, typename _MutableBufferSequence, 625627f7eb2Smrg typename _CompletionCondition> 626627f7eb2Smrg enable_if_t<is_mutable_buffer_sequence<_MutableBufferSequence>::value, 627627f7eb2Smrg size_t> 628627f7eb2Smrg read(_SyncReadStream& __stream, const _MutableBufferSequence& __buffers, 629627f7eb2Smrg _CompletionCondition __completion_condition, error_code& __ec) 630627f7eb2Smrg { 631627f7eb2Smrg __ec.clear(); 632627f7eb2Smrg auto __i = net::buffer_sequence_begin(__buffers); 633627f7eb2Smrg auto __end = net::buffer_sequence_end(__buffers); 634627f7eb2Smrg mutable_buffer __to; 635627f7eb2Smrg size_t __total = 0; 636627f7eb2Smrg size_t __n; 637627f7eb2Smrg while ((__n = __completion_condition(__ec, __total)) 638627f7eb2Smrg && (__i != __end || __to.size())) 639627f7eb2Smrg { 640627f7eb2Smrg if (__to.size() == 0) 641627f7eb2Smrg __to = mutable_buffer(*__i++); 642627f7eb2Smrg __n = __stream.read_some(buffer(__to, __n), __ec); 643627f7eb2Smrg __to = __to + __n; 644627f7eb2Smrg __total += __n; 645627f7eb2Smrg } 646627f7eb2Smrg return __total; 647627f7eb2Smrg } 648627f7eb2Smrg 649627f7eb2Smrg template<typename _SyncReadStream, typename _MutableBufferSequence> 650627f7eb2Smrg inline 651627f7eb2Smrg enable_if_t<is_mutable_buffer_sequence<_MutableBufferSequence>::value, 652627f7eb2Smrg size_t> 653627f7eb2Smrg read(_SyncReadStream& __stream, const _MutableBufferSequence& __buffers) 654627f7eb2Smrg { 655627f7eb2Smrg error_code __ec; 656627f7eb2Smrg return net::read(__stream, __buffers, transfer_all{}, __ec); 657627f7eb2Smrg } 658627f7eb2Smrg 659627f7eb2Smrg template<typename _SyncReadStream, typename _MutableBufferSequence> 660627f7eb2Smrg inline 661627f7eb2Smrg enable_if_t<is_mutable_buffer_sequence<_MutableBufferSequence>::value, 662627f7eb2Smrg size_t> 663627f7eb2Smrg read(_SyncReadStream& __stream, const _MutableBufferSequence& __buffers, 664627f7eb2Smrg error_code& __ec) 665627f7eb2Smrg { return net::read(__stream, __buffers, transfer_all{}, __ec); } 666627f7eb2Smrg 667627f7eb2Smrg template<typename _SyncReadStream, typename _MutableBufferSequence, 668627f7eb2Smrg typename _CompletionCondition> 669627f7eb2Smrg inline 670627f7eb2Smrg enable_if_t<is_mutable_buffer_sequence<_MutableBufferSequence>::value, 671627f7eb2Smrg size_t> 672627f7eb2Smrg read(_SyncReadStream& __stream, const _MutableBufferSequence& __buffers, 673627f7eb2Smrg _CompletionCondition __completion_condition) 674627f7eb2Smrg { 675627f7eb2Smrg error_code __ec; 676627f7eb2Smrg return net::read(__stream, __buffers, __completion_condition, __ec); 677627f7eb2Smrg } 678627f7eb2Smrg 679627f7eb2Smrg 680627f7eb2Smrg template<typename _SyncReadStream, typename _DynamicBuffer, 681627f7eb2Smrg typename _CompletionCondition> 682627f7eb2Smrg enable_if_t<is_dynamic_buffer<decay_t<_DynamicBuffer>>::value, size_t> 683627f7eb2Smrg read(_SyncReadStream& __stream, _DynamicBuffer&& __b, 684627f7eb2Smrg _CompletionCondition __completion_condition, error_code& __ec) 685627f7eb2Smrg { 686627f7eb2Smrg const size_t __limit = 64; 687627f7eb2Smrg __ec.clear(); 688627f7eb2Smrg size_t __cap = std::max(__b.capacity() - __b.size(), __limit); 689627f7eb2Smrg size_t __total = 0; 690627f7eb2Smrg size_t __n; 691627f7eb2Smrg while ((__n = __completion_condition(__ec, __total)) 692627f7eb2Smrg && __b.size() != __b.max_size()) 693627f7eb2Smrg { 694627f7eb2Smrg __n = std::min(__n, __b.max_size() - __b.size()); 695627f7eb2Smrg size_t __cap = std::max(__b.capacity() - __b.size(), __limit); 696627f7eb2Smrg mutable_buffer __to = __b.prepare(std::min(__cap, __n)); 697627f7eb2Smrg __n = __stream.read_some(__to, __ec); 698627f7eb2Smrg __to = __to + __n; 699627f7eb2Smrg __total += __n; 700627f7eb2Smrg __b.commit(__n); 701627f7eb2Smrg } 702627f7eb2Smrg return __total; 703627f7eb2Smrg } 704627f7eb2Smrg 705627f7eb2Smrg template<typename _SyncReadStream, typename _DynamicBuffer> 706627f7eb2Smrg inline enable_if_t<is_dynamic_buffer<_DynamicBuffer>::value, size_t> 707627f7eb2Smrg read(_SyncReadStream& __stream, _DynamicBuffer&& __b) 708627f7eb2Smrg { 709627f7eb2Smrg error_code __ec; 710627f7eb2Smrg return net::read(__stream, __b, transfer_all{}, __ec); 711627f7eb2Smrg } 712627f7eb2Smrg 713627f7eb2Smrg template<typename _SyncReadStream, typename _DynamicBuffer> 714627f7eb2Smrg inline enable_if_t<is_dynamic_buffer<_DynamicBuffer>::value, size_t> 715627f7eb2Smrg read(_SyncReadStream& __stream, _DynamicBuffer&& __b, error_code& __ec) 716627f7eb2Smrg { 717627f7eb2Smrg return net::read(__stream, __b, transfer_all{}, __ec); 718627f7eb2Smrg } 719627f7eb2Smrg 720627f7eb2Smrg template<typename _SyncReadStream, typename _DynamicBuffer, 721627f7eb2Smrg typename _CompletionCondition> 722627f7eb2Smrg inline enable_if_t<is_dynamic_buffer<_DynamicBuffer>::value, size_t> 723627f7eb2Smrg read(_SyncReadStream& __stream, _DynamicBuffer&& __b, 724627f7eb2Smrg _CompletionCondition __completion_condition) 725627f7eb2Smrg { 726627f7eb2Smrg error_code __ec; 727627f7eb2Smrg return net::read(__stream, __b, __completion_condition, __ec); 728627f7eb2Smrg } 729627f7eb2Smrg 730*4c3eb207Smrg /// @} 731627f7eb2Smrg 732627f7eb2Smrg /** @brief asynchronous read operations 733627f7eb2Smrg * @{ 734627f7eb2Smrg */ 735627f7eb2Smrg 736627f7eb2Smrg template<typename _AsyncReadStream, typename _MutableBufferSequence, 737627f7eb2Smrg typename _CompletionCondition, typename _CompletionToken> 738627f7eb2Smrg __deduced_t<_CompletionToken, void(error_code, size_t)> 739627f7eb2Smrg async_read(_AsyncReadStream& __stream, 740627f7eb2Smrg const _MutableBufferSequence& __buffers, 741627f7eb2Smrg _CompletionCondition __completion_condition, 742627f7eb2Smrg _CompletionToken&& __token) 743627f7eb2Smrg { 744627f7eb2Smrg error_code __ec; 745627f7eb2Smrg } 746627f7eb2Smrg 747627f7eb2Smrg template<typename _AsyncReadStream, typename _MutableBufferSequence, 748627f7eb2Smrg typename _CompletionToken> 749627f7eb2Smrg inline __deduced_t<_CompletionToken, void(error_code, size_t)> 750627f7eb2Smrg async_read(_AsyncReadStream& __stream, 751627f7eb2Smrg const _MutableBufferSequence& __buffers, 752627f7eb2Smrg _CompletionToken&& __token) 753627f7eb2Smrg { 754627f7eb2Smrg return net::async_read(__stream, __buffers, transfer_all{}, 755627f7eb2Smrg std::forward<_CompletionToken>(__token)); 756627f7eb2Smrg } 757627f7eb2Smrg 758627f7eb2Smrg template<typename _AsyncReadStream, typename _DynamicBuffer, 759627f7eb2Smrg typename _CompletionCondition, typename _CompletionToken> 760627f7eb2Smrg __deduced_t<_CompletionToken, void(error_code, size_t)> 761627f7eb2Smrg async_read(_AsyncReadStream& __stream, _DynamicBuffer&& __b, 762627f7eb2Smrg _CompletionCondition __completion_condition, 763627f7eb2Smrg _CompletionToken&& __token) 764627f7eb2Smrg { 765627f7eb2Smrg error_code __ec; 766627f7eb2Smrg } 767627f7eb2Smrg 768627f7eb2Smrg template<typename _AsyncReadStream, typename _DynamicBuffer, 769627f7eb2Smrg typename _CompletionToken> 770627f7eb2Smrg inline __deduced_t<_CompletionToken, void(error_code, size_t)> 771627f7eb2Smrg async_read(_AsyncReadStream& __stream, _DynamicBuffer&& __b, 772627f7eb2Smrg _CompletionToken&& __token) 773627f7eb2Smrg { 774627f7eb2Smrg return net::async_read(__stream, __b, transfer_all{}, 775627f7eb2Smrg std::forward<_CompletionToken>(__token)); 776627f7eb2Smrg } 777627f7eb2Smrg 778*4c3eb207Smrg /// @} 779627f7eb2Smrg 780627f7eb2Smrg#if 0 781627f7eb2Smrg /** @brief synchronous write operations: 782627f7eb2Smrg * @{ 783627f7eb2Smrg */ 784627f7eb2Smrg 785627f7eb2Smrg template<typename _SyncWriteStream, typename _ConstBufferSequence> 786627f7eb2Smrg size_t write(_SyncWriteStream& __stream, 787627f7eb2Smrg const _ConstBufferSequence& __buffers); 788627f7eb2Smrg template<typename _SyncWriteStream, typename _ConstBufferSequence> 789627f7eb2Smrg size_t write(_SyncWriteStream& __stream, 790627f7eb2Smrg const _ConstBufferSequence& __buffers, error_code& __ec); 791627f7eb2Smrg template<typename _SyncWriteStream, typename _ConstBufferSequence, 792627f7eb2Smrg typename _CompletionCondition> 793627f7eb2Smrg size_t write(_SyncWriteStream& __stream, 794627f7eb2Smrg const _ConstBufferSequence& __buffers, 795627f7eb2Smrg _CompletionCondition __completion_condition); 796627f7eb2Smrg template<typename _SyncWriteStream, typename _ConstBufferSequence, 797627f7eb2Smrg typename _CompletionCondition> 798627f7eb2Smrg size_t write(_SyncWriteStream& __stream, 799627f7eb2Smrg const _ConstBufferSequence& __buffers, 800627f7eb2Smrg _CompletionCondition __completion_condition, 801627f7eb2Smrg error_code& __ec); 802627f7eb2Smrg 803627f7eb2Smrg template<typename _SyncWriteStream, typename _DynamicBuffer> 804627f7eb2Smrg size_t write(_SyncWriteStream& __stream, _DynamicBuffer&& __b); 805627f7eb2Smrg template<typename _SyncWriteStream, typename _DynamicBuffer> 806627f7eb2Smrg size_t write(_SyncWriteStream& __stream, _DynamicBuffer&& __b, error_code& __ec); 807627f7eb2Smrg template<typename _SyncWriteStream, typename _DynamicBuffer, typename _CompletionCondition> 808627f7eb2Smrg size_t write(_SyncWriteStream& __stream, _DynamicBuffer&& __b, 809627f7eb2Smrg _CompletionCondition __completion_condition); 810627f7eb2Smrg template<typename _SyncWriteStream, typename _DynamicBuffer, typename _CompletionCondition> 811627f7eb2Smrg size_t write(_SyncWriteStream& __stream, _DynamicBuffer&& __b, 812627f7eb2Smrg _CompletionCondition __completion_condition, error_code& __ec); 813627f7eb2Smrg 814*4c3eb207Smrg /// @} 815627f7eb2Smrg 816627f7eb2Smrg /** @brief asynchronous write operations 817627f7eb2Smrg * @{ 818627f7eb2Smrg */ 819627f7eb2Smrg 820627f7eb2Smrg template<typename _AsyncWriteStream, typename _ConstBufferSequence, 821627f7eb2Smrg typename _CompletionToken> 822627f7eb2Smrg DEDUCED async_write(_AsyncWriteStream& __stream, 823627f7eb2Smrg const _ConstBufferSequence& __buffers, 824627f7eb2Smrg _CompletionToken&& __token); 825627f7eb2Smrg template<typename _AsyncWriteStream, typename _ConstBufferSequence, 826627f7eb2Smrg typename _CompletionCondition, typename _CompletionToken> 827627f7eb2Smrg DEDUCED async_write(_AsyncWriteStream& __stream, 828627f7eb2Smrg const _ConstBufferSequence& __buffers, 829627f7eb2Smrg _CompletionCondition __completion_condition, 830627f7eb2Smrg _CompletionToken&& __token); 831627f7eb2Smrg 832627f7eb2Smrg template<typename _AsyncWriteStream, typename _DynamicBuffer, typename _CompletionToken> 833627f7eb2Smrg DEDUCED async_write(_AsyncWriteStream& __stream, 834627f7eb2Smrg _DynamicBuffer&& __b, _CompletionToken&& __token); 835627f7eb2Smrg template<typename _AsyncWriteStream, typename _DynamicBuffer, 836627f7eb2Smrg typename _CompletionCondition, typename _CompletionToken> 837627f7eb2Smrg DEDUCED async_write(_AsyncWriteStream& __stream, 838627f7eb2Smrg _DynamicBuffer&& __b, 839627f7eb2Smrg _CompletionCondition __completion_condition, 840627f7eb2Smrg _CompletionToken&& __token); 841627f7eb2Smrg 842*4c3eb207Smrg /// @} 843627f7eb2Smrg 844627f7eb2Smrg /** @brief synchronous delimited read operations 845627f7eb2Smrg * @{ 846627f7eb2Smrg */ 847627f7eb2Smrg 848627f7eb2Smrg template<typename _SyncReadStream, typename _DynamicBuffer> 849627f7eb2Smrg size_t read_until(_SyncReadStream& __s, _DynamicBuffer&& __b, char __delim); 850627f7eb2Smrg template<typename _SyncReadStream, typename _DynamicBuffer> 851627f7eb2Smrg size_t read_until(_SyncReadStream& __s, _DynamicBuffer&& __b, 852627f7eb2Smrg char __delim, error_code& __ec); 853627f7eb2Smrg template<typename _SyncReadStream, typename _DynamicBuffer> 854627f7eb2Smrg size_t read_until(_SyncReadStream& __s, _DynamicBuffer&& __b, string_view __delim); 855627f7eb2Smrg template<typename _SyncReadStream, typename _DynamicBuffer> 856627f7eb2Smrg size_t read_until(_SyncReadStream& __s, _DynamicBuffer&& __b, 857627f7eb2Smrg string_view __delim, error_code& __ec); 858627f7eb2Smrg 859*4c3eb207Smrg /// @} 860627f7eb2Smrg 861627f7eb2Smrg /** @brief asynchronous delimited read operations 862627f7eb2Smrg * @{ 863627f7eb2Smrg */ 864627f7eb2Smrg 865627f7eb2Smrg template<typename _AsyncReadStream, typename _DynamicBuffer, typename _CompletionToken> 866627f7eb2Smrg DEDUCED async_read_until(_AsyncReadStream& __s, 867627f7eb2Smrg _DynamicBuffer&& __b, char __delim, 868627f7eb2Smrg _CompletionToken&& __token); 869627f7eb2Smrg template<typename _AsyncReadStream, typename _DynamicBuffer, typename _CompletionToken> 870627f7eb2Smrg DEDUCED async_read_until(_AsyncReadStream& __s, 871627f7eb2Smrg _DynamicBuffer&& __b, string_view __delim, 872627f7eb2Smrg _CompletionToken&& __token); 873627f7eb2Smrg 874*4c3eb207Smrg /// @} 875627f7eb2Smrg 876627f7eb2Smrg#endif 877627f7eb2Smrg /// @} 878627f7eb2Smrg 879627f7eb2Smrg} // namespace v1 880627f7eb2Smrg} // namespace net 881627f7eb2Smrg} // namespace experimental 882627f7eb2Smrg 883627f7eb2Smrg template<> 884627f7eb2Smrg struct is_error_code_enum<experimental::net::v1::stream_errc> 885627f7eb2Smrg : public true_type {}; 886627f7eb2Smrg 887627f7eb2Smrg_GLIBCXX_END_NAMESPACE_VERSION 888627f7eb2Smrg} // namespace std 889627f7eb2Smrg 890627f7eb2Smrg#endif // C++14 891627f7eb2Smrg 892627f7eb2Smrg#endif // _GLIBCXX_EXPERIMENTAL_BUFFER 893