xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/experimental/buffer (revision 4c3eb207d36f67d31994830c0a694161fc1ca39b)
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