// <experimental/buffer> -*- C++ -*-

// Copyright (C) 2015-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file experimental/buffer
 *  This is a TS C++ Library header.
 *  @ingroup networking-ts
 */

#ifndef _GLIBCXX_EXPERIMENTAL_BUFFER
#define _GLIBCXX_EXPERIMENTAL_BUFFER 1

#pragma GCC system_header

#if __cplusplus >= 201402L

#include <array>
#include <string>
#include <system_error>
#include <vector>
#include <cstring>
#include <experimental/string_view>
#include <experimental/bits/net.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace experimental
{
namespace net
{
inline namespace v1
{

  /** @addtogroup networking-ts
   *  @{
   */

  enum class stream_errc {    // TODO decide values
    eof = 1,
    not_found = 2
  };

  const error_category& stream_category() noexcept // TODO not inline
  {
    struct __cat : error_category
    {
      const char* name() const noexcept { return "stream"; }

      std::string message(int __e) const
      {
	if (__e == (int)stream_errc::eof)
	  return "EOF";
	else if (__e == (int)stream_errc::not_found)
	  return "not found";
	return "stream";
      }

      virtual void __message(int) { } // TODO dual ABI XXX
    };
    static __cat __c;
    return __c;
  }

  inline error_code
  make_error_code(stream_errc __e) noexcept
  { return error_code(static_cast<int>(__e), stream_category()); }

  inline error_condition
  make_error_condition(stream_errc __e) noexcept
  { return error_condition(static_cast<int>(__e), stream_category()); }

  class mutable_buffer
  {
  public:
    // constructors:
    mutable_buffer() noexcept : _M_data(), _M_size() { }

    mutable_buffer(void* __p, size_t __n) noexcept
    : _M_data(__p), _M_size(__n) { }

    // members:
    void* data() const noexcept { return _M_data; }
    size_t size() const noexcept { return _M_size; }

  private:
    void*	_M_data;
    size_t	_M_size;
  };

  class const_buffer
  {
  public:
    // constructors:
    const_buffer() noexcept : _M_data(), _M_size() { }

    const_buffer(const void* __p, size_t __n) noexcept
    : _M_data(__p), _M_size(__n) { }

    const_buffer(const mutable_buffer& __b) noexcept
    : _M_data(__b.data()), _M_size(__b.size()) { }

    // members:
    const void* data() const noexcept { return _M_data; }
    size_t size() const noexcept { return _M_size; }

  private:
    const void*	_M_data;
    size_t	_M_size;
  };


  /** @brief buffer sequence access
   *
   * Uniform access to types that meet the BufferSequence requirements.
   * @{
   */

  inline const mutable_buffer*
  buffer_sequence_begin(const mutable_buffer& __b)
  { return std::addressof(__b); }

  inline const const_buffer*
  buffer_sequence_begin(const const_buffer& __b)
  { return std::addressof(__b); }

  inline const mutable_buffer*
  buffer_sequence_end(const mutable_buffer& __b)
  { return std::addressof(__b) + 1; }

  inline const const_buffer*
  buffer_sequence_end(const const_buffer& __b)
  { return std::addressof(__b) + 1; }

  template<typename _Cont>
    auto
    buffer_sequence_begin(_Cont& __c) -> decltype(__c.begin())
    { return __c.begin(); }

  template<typename _Cont>
    auto
    buffer_sequence_begin(const _Cont& __c) -> decltype(__c.begin())
    { return __c.begin(); }

  template<typename _Cont>
    auto
    buffer_sequence_end(_Cont& __c) -> decltype(__c.end())
    { return __c.end(); }

  template<typename _Cont>
    auto
    buffer_sequence_end(const _Cont& __c) -> decltype(__c.end())
    { return __c.end(); }

  // @}


  /** @brief buffer type traits
   *
   * @{
   */

  template<typename _Tp, typename _Buffer,
	   typename _Begin
	    = decltype(net::buffer_sequence_begin(std::declval<_Tp&>())),
	   typename _End
	    = decltype(net::buffer_sequence_end(std::declval<_Tp&>()))>
    using __buffer_sequence = enable_if_t<__and_<
      __is_value_constructible<_Tp>, is_same<_Begin, _End>,
      is_convertible<typename iterator_traits<_Begin>::value_type, _Buffer>
      >::value>;

  template<typename _Tp, typename _Buffer, typename = void>
    struct __is_buffer_sequence : false_type
    { };

  template<typename _Tp, typename _Buffer>
    struct __is_buffer_sequence<_Tp, _Buffer, __buffer_sequence<_Tp, _Buffer>>
    : true_type
    { };

  template<typename _Tp>
    struct is_mutable_buffer_sequence
    : __is_buffer_sequence<_Tp, mutable_buffer>::type
    { };

  template<typename _Tp>
    struct is_const_buffer_sequence
    : __is_buffer_sequence<_Tp, const_buffer>::type
    { };

  template<typename _Tp>
    constexpr bool is_mutable_buffer_sequence_v
      = is_mutable_buffer_sequence<_Tp>::value;

  template<typename _Tp>
    constexpr bool is_const_buffer_sequence_v
      = is_const_buffer_sequence<_Tp>::value;

  template<typename _Tp, typename = void>
    struct __is_dynamic_buffer_impl : false_type
    { };

  // Check DynamicBuffer requirements.
  template<typename _Tp, typename _Up = remove_const_t<_Tp>>
    auto
    __dynamic_buffer_reqs(_Up* __x = 0, const _Up* __x1 = 0, size_t __n = 0)
    -> enable_if_t<__and_<
      is_move_constructible<_Up>,
      is_const_buffer_sequence<typename _Tp::const_buffers_type>,
      is_mutable_buffer_sequence<typename _Tp::mutable_buffers_type>,
      is_same<decltype(__x1->size()), size_t>,
      is_same<decltype(__x1->max_size()), size_t>,
      is_same<decltype(__x1->capacity()), size_t>,
      is_same<decltype(__x1->data()), typename _Tp::const_buffers_type>,
      is_same<decltype(__x->prepare(__n)), typename _Tp::mutable_buffers_type>,
      is_void<decltype(__x->commit(__n), __x->consume(__n), void())>
    >::value>;

  template<typename _Tp>
    struct __is_dynamic_buffer_impl<_Tp,
				    decltype(__dynamic_buffer_reqs<_Tp>())>
    : true_type
    { };

  template<typename _Tp>
    struct is_dynamic_buffer : __is_dynamic_buffer_impl<_Tp>::type
    { };

  template<typename _Tp>
    constexpr bool is_dynamic_buffer_v = is_dynamic_buffer<_Tp>::value;

  // @}

  /// buffer size
  template<typename _ConstBufferSequence>
    size_t
    buffer_size(const _ConstBufferSequence& __buffers) noexcept
    {
      size_t __total_size = 0;
      auto __i = net::buffer_sequence_begin(__buffers);
      const auto __end = net::buffer_sequence_end(__buffers);
      for (; __i != __end; ++__i)
	__total_size += const_buffer(*__i).size();
      return __total_size;
    }

  template<typename _ConstBufferSequence>
    bool
    __buffer_empty(const _ConstBufferSequence& __buffers) noexcept
    {
      auto __i = net::buffer_sequence_begin(__buffers);
      const auto __end = net::buffer_sequence_end(__buffers);
      for (; __i != __end; ++__i)
	if (const_buffer(*__i).size() != 0)
	  return false;
      return true;
    }

  // buffer copy:

  template<typename _MutableBufferSequence, typename _ConstBufferSequence>
    size_t
    buffer_copy(const _MutableBufferSequence& __dest,
		const _ConstBufferSequence& __source,
		size_t __max_size) noexcept
    {
      size_t __total_size = 0;
      auto __to_i = net::buffer_sequence_begin(__dest);
      const auto __to_end = net::buffer_sequence_end(__dest);
      auto __from_i = net::buffer_sequence_begin(__source);
      const auto __from_end = net::buffer_sequence_end(__source);
      mutable_buffer __to;
      const_buffer __from;
      while (((__from_i != __from_end && __to_i != __to_end)
	    || (__from.size() && __to.size()))
	  && __total_size < __max_size)
	{
	  if (__from.size() == 0)
	    __from = const_buffer{*__from_i++};
	  if (__to.size() == 0)
	    __to = mutable_buffer{*__to_i++};

	  size_t __n = std::min(__from.size(), __to.size());
	  __n = std::min(__n, __max_size - __total_size);
	  std::memcpy(__to.data(), __from.data(), __n);
	  __from = { (const char*)__from.data() + __n, __from.size() - __n };
	  __to = { (char*)__to.data() + __n, __to.size() - __n };
	  __total_size += __n;
	}
      return __total_size;
    }

  template<typename _MutableBufferSequence, typename _ConstBufferSequence>
    inline size_t
    buffer_copy(const _MutableBufferSequence& __dest,
		const _ConstBufferSequence& __source) noexcept
    { return net::buffer_copy(__dest, __source, size_t{-1}); }


  // buffer arithmetic:

  inline mutable_buffer
  operator+(const mutable_buffer& __b, size_t __n) noexcept
  {
    if (__n > __b.size())
      __n = __b.size();
    return { static_cast<char*>(__b.data()) + __n, __b.size() - __n };
  }

  inline mutable_buffer
  operator+(size_t __n, const mutable_buffer& __b) noexcept
  { return __b + __n; }

  inline const_buffer
  operator+(const const_buffer& __b, size_t __n) noexcept
  {
    if (__n > __b.size())
      __n = __b.size();
    return { static_cast<const char*>(__b.data()) + __n, __b.size() - __n };
  }

  inline const_buffer
  operator+(size_t __n, const const_buffer& __b) noexcept
  { return __b + __n; }

  // buffer creation:

  inline mutable_buffer
  buffer(void* __p, size_t __n) noexcept
  { return { __p, __n }; }

  inline const_buffer
  buffer(const void* __p, size_t __n) noexcept
  { return { __p, __n }; }

  inline mutable_buffer
  buffer(const mutable_buffer& __b) noexcept
  { return __b; }

  inline mutable_buffer
  buffer(const mutable_buffer& __b, size_t __n) noexcept
  { return { __b.data(), std::min(__b.size(), __n) }; }

  inline const_buffer
  buffer(const const_buffer& __b) noexcept
  { return __b; }

  inline const_buffer
  buffer(const const_buffer& __b, size_t __n) noexcept
  { return { __b.data(), std::min(__b.size(), __n) }; }

  template<typename _Tp>
    inline mutable_buffer
    __to_mbuf(_Tp* __data, size_t __n)
    { return { __n ? __data : nullptr, __n * sizeof(_Tp) }; }

  template<typename _Tp>
    inline const_buffer
    __to_cbuf(const _Tp* __data, size_t __n)
    { return { __n ? __data : nullptr, __n * sizeof(_Tp) }; }

  template<typename _Tp, size_t _Nm>
    inline mutable_buffer
    buffer(_Tp (&__data)[_Nm]) noexcept
    { return net::__to_mbuf(__data, _Nm); }

  template<typename _Tp, size_t _Nm>
    inline const_buffer
    buffer(const _Tp (&__data)[_Nm]) noexcept
    { return net::__to_cbuf(__data, _Nm); }

  template<typename _Tp, size_t _Nm>
    inline mutable_buffer
    buffer(array<_Tp, _Nm>& __data) noexcept
    { return net::__to_mbuf(__data.data(), _Nm); }

  template<typename _Tp, size_t _Nm>
    inline const_buffer
    buffer(array<const _Tp, _Nm>& __data) noexcept
    { return net::__to_cbuf(__data.data(), __data.size()); }

  template<typename _Tp, size_t _Nm>
    inline const_buffer
    buffer(const array<_Tp, _Nm>& __data) noexcept
    { return net::__to_cbuf(__data.data(), __data.size()); }

  template<typename _Tp, typename _Allocator>
    inline mutable_buffer
    buffer(vector<_Tp, _Allocator>& __data) noexcept
    { return net::__to_mbuf(__data.data(), __data.size()); }

  template<typename _Tp, typename _Allocator>
    inline const_buffer
    buffer(const vector<_Tp, _Allocator>& __data) noexcept
    { return net::__to_cbuf(__data.data(), __data.size()); }

  template<typename _CharT, typename _Traits, typename _Allocator>
    inline mutable_buffer
    buffer(basic_string<_CharT, _Traits, _Allocator>& __data) noexcept
    { return net::__to_mbuf(&__data.front(), __data.size()); }

  template<typename _CharT, typename _Traits, typename _Allocator>
    inline const_buffer
    buffer(const basic_string<_CharT, _Traits, _Allocator>& __data) noexcept
    { return net::__to_cbuf(&__data.front(), __data.size()); }

  template<typename _CharT, typename _Traits>
    inline const_buffer
    buffer(basic_string_view<_CharT, _Traits> __data) noexcept
    { return net::__to_cbuf(__data.data(), __data.size()); }

  template<typename _Tp, size_t _Nm>
    inline mutable_buffer
    buffer(_Tp (&__data)[_Nm], size_t __n) noexcept
    { return buffer(net::buffer(__data), __n * sizeof(_Tp)); }

  template<typename _Tp, size_t _Nm>
    inline const_buffer
    buffer(const _Tp (&__data)[_Nm], size_t __n) noexcept
    { return buffer(net::buffer(__data), __n * sizeof(_Tp)); }

  template<typename _Tp, size_t _Nm>
    inline mutable_buffer
    buffer(array<_Tp, _Nm>& __data, size_t __n) noexcept
    { return buffer(net::buffer(__data), __n * sizeof(_Tp)); }

  template<typename _Tp, size_t _Nm>
    inline const_buffer
    buffer(array<const _Tp, _Nm>& __data, size_t __n) noexcept
    { return buffer(net::buffer(__data), __n * sizeof(_Tp)); }

  template<typename _Tp, size_t _Nm>
    inline const_buffer
    buffer(const array<_Tp, _Nm>& __data, size_t __n) noexcept
    { return buffer(net::buffer(__data), __n * sizeof(_Tp)); }

  template<typename _Tp, typename _Allocator>
    inline mutable_buffer
    buffer(vector<_Tp, _Allocator>& __data, size_t __n) noexcept
    { return buffer(net::buffer(__data), __n * sizeof(_Tp)); }

  template<typename _Tp, typename _Allocator>
    inline const_buffer
    buffer(const vector<_Tp, _Allocator>& __data, size_t __n) noexcept
    { return buffer(net::buffer(__data), __n * sizeof(_Tp)); }

  template<typename _CharT, typename _Traits, typename _Allocator>
    inline mutable_buffer
    buffer(basic_string<_CharT, _Traits, _Allocator>& __data,
	   size_t __n) noexcept
    { return buffer(net::buffer(__data), __n * sizeof(_CharT)); }

  template<typename _CharT, typename _Traits, typename _Allocator>
    inline const_buffer
    buffer(const basic_string<_CharT, _Traits, _Allocator>& __data,
	   size_t __n) noexcept
    { return buffer(net::buffer(__data), __n * sizeof(_CharT)); }

  template<typename _CharT, typename _Traits>
    inline const_buffer
    buffer(basic_string_view<_CharT, _Traits> __data, size_t __n) noexcept
    { return buffer(net::buffer(__data), __n * sizeof(_CharT)); }


  template<typename _Sequence>
    class __dynamic_buffer_base
    {
    public:
      // types:
      typedef const_buffer const_buffers_type;
      typedef mutable_buffer mutable_buffers_type;

      // constructors:
      explicit
      __dynamic_buffer_base(_Sequence& __seq) noexcept
      : _M_seq(__seq), _M_size(__seq.size()), _M_max_size(__seq.max_size())
      { }

      __dynamic_buffer_base(_Sequence& __seq, size_t __maximum_size) noexcept
      : _M_seq(__seq), _M_size(__seq.size()), _M_max_size(__maximum_size)
      { __glibcxx_assert(__seq.size() <= __maximum_size); }

      __dynamic_buffer_base(__dynamic_buffer_base&&) = default;

      // members:
      size_t size() const noexcept { return _M_size; }
      size_t max_size() const noexcept { return _M_max_size; }
      size_t capacity() const noexcept { return _M_seq.capacity(); }

      const_buffers_type
      data() const noexcept
      { return net::buffer(_M_seq, _M_size); }

      mutable_buffers_type
      prepare(size_t __n)
      {
	if ((_M_size + __n) > _M_max_size)
	  __throw_length_error("dynamic_vector_buffer::prepare");

	_M_seq.resize(_M_size + __n);
	return buffer(net::buffer(_M_seq) + _M_size, __n);
      }

      void
      commit(size_t __n)
      {
	_M_size += std::min(__n, _M_seq.size() - _M_size);
	_M_seq.resize(_M_size);
      }

      void
      consume(size_t __n)
      {
	size_t __m = std::min(__n, _M_size);
	_M_seq.erase(_M_seq.begin(), _M_seq.begin() + __m);
	_M_size -= __m;
      }

    private:
      _Sequence&	_M_seq;
      size_t		_M_size;
      const size_t	_M_max_size;
    };

  template<typename _Tp, typename _Allocator>
    class dynamic_vector_buffer
    : public __dynamic_buffer_base<vector<_Tp, _Allocator>>
    {
    public:
      using __dynamic_buffer_base<vector<_Tp, _Allocator>>::__dynamic_buffer_base;
    };

  template<typename _CharT, typename _Traits, typename _Allocator>
    class dynamic_string_buffer
    : public __dynamic_buffer_base<basic_string<_CharT, _Traits, _Allocator>>
    {
    public:
      using __dynamic_buffer_base<basic_string<_CharT, _Traits, _Allocator>>::
	__dynamic_buffer_base;
    };

  // dynamic buffer creation:

  template<typename _Tp, typename _Allocator>
    inline dynamic_vector_buffer<_Tp, _Allocator>
    dynamic_buffer(vector<_Tp, _Allocator>& __vec) noexcept
    { return dynamic_vector_buffer<_Tp, _Allocator>{__vec}; }

  template<typename _Tp, typename _Allocator>
    inline dynamic_vector_buffer<_Tp, _Allocator>
    dynamic_buffer(vector<_Tp, _Allocator>& __vec, size_t __n) noexcept
    { return {__vec, __n}; }

  template<typename _CharT, typename _Traits, typename _Allocator>
    inline dynamic_string_buffer<_CharT, _Traits, _Allocator>
    dynamic_buffer(basic_string<_CharT, _Traits, _Allocator>& __str) noexcept
    { return dynamic_string_buffer<_CharT, _Traits, _Allocator>{__str}; }

  template<typename _CharT, typename _Traits, typename _Allocator>
    inline dynamic_string_buffer<_CharT, _Traits, _Allocator>
    dynamic_buffer(basic_string<_CharT, _Traits, _Allocator>& __str,
		   size_t __n) noexcept
    { return {__str, __n}; }

  class transfer_all
  {
  public:
    size_t operator()(const error_code& __ec, size_t) const
    { return !__ec ? 1500 : 0; }
  };

  class transfer_at_least
  {
  public:
    explicit transfer_at_least(size_t __m) : _M_minimum(__m) { }

    size_t operator()(const error_code& __ec, size_t __n) const
    { return !__ec  && __n < _M_minimum ? _M_minimum - __n : 0; }

  private:
    size_t _M_minimum;
  };

  class transfer_exactly
  {
  public:
    explicit transfer_exactly(size_t __e) : _M_exact(__e) { }

    size_t operator()(const error_code& __ec, size_t __n) const
    {
      size_t _Nm = -1;
      return !__ec  && __n < _M_exact ? std::min(_M_exact - __n, _Nm) : 0;
    }

  private:
    size_t _M_exact;
  };

  /** @brief synchronous read operations
   * @{
   */

  template<typename _SyncReadStream, typename _MutableBufferSequence,
	   typename _CompletionCondition>
    enable_if_t<is_mutable_buffer_sequence<_MutableBufferSequence>::value,
		size_t>
    read(_SyncReadStream& __stream, const _MutableBufferSequence& __buffers,
	 _CompletionCondition __completion_condition, error_code& __ec)
    {
      __ec.clear();
      auto __i = net::buffer_sequence_begin(__buffers);
      auto __end = net::buffer_sequence_end(__buffers);
      mutable_buffer __to;
      size_t __total = 0;
      size_t __n;
      while ((__n = __completion_condition(__ec, __total))
	  && (__i != __end || __to.size()))
	{
	  if (__to.size() == 0)
	    __to = mutable_buffer(*__i++);
	  __n = __stream.read_some(buffer(__to, __n), __ec);
	  __to = __to + __n;
	  __total += __n;
	}
      return __total;
    }

  template<typename _SyncReadStream, typename _MutableBufferSequence>
    inline
    enable_if_t<is_mutable_buffer_sequence<_MutableBufferSequence>::value,
		size_t>
    read(_SyncReadStream& __stream, const _MutableBufferSequence& __buffers)
    {
      error_code __ec;
      return net::read(__stream, __buffers, transfer_all{}, __ec);
    }

  template<typename _SyncReadStream, typename _MutableBufferSequence>
    inline
    enable_if_t<is_mutable_buffer_sequence<_MutableBufferSequence>::value,
		size_t>
    read(_SyncReadStream& __stream, const _MutableBufferSequence& __buffers,
	 error_code& __ec)
    { return net::read(__stream, __buffers, transfer_all{}, __ec); }

  template<typename _SyncReadStream, typename _MutableBufferSequence,
	   typename _CompletionCondition>
    inline
    enable_if_t<is_mutable_buffer_sequence<_MutableBufferSequence>::value,
		size_t>
    read(_SyncReadStream& __stream, const _MutableBufferSequence& __buffers,
	 _CompletionCondition __completion_condition)
    {
      error_code __ec;
      return net::read(__stream, __buffers, __completion_condition, __ec);
    }


  template<typename _SyncReadStream, typename _DynamicBuffer,
	   typename _CompletionCondition>
    enable_if_t<is_dynamic_buffer<decay_t<_DynamicBuffer>>::value, size_t>
    read(_SyncReadStream& __stream, _DynamicBuffer&& __b,
	 _CompletionCondition __completion_condition, error_code& __ec)
    {
      const size_t __limit = 64;
      __ec.clear();
      size_t __cap = std::max(__b.capacity() - __b.size(), __limit);
      size_t __total = 0;
      size_t __n;
      while ((__n = __completion_condition(__ec, __total))
	  && __b.size() != __b.max_size())
	{
	  __n =  std::min(__n, __b.max_size() - __b.size());
	  size_t __cap = std::max(__b.capacity() - __b.size(), __limit);
	  mutable_buffer __to = __b.prepare(std::min(__cap, __n));
	  __n = __stream.read_some(__to, __ec);
	  __to = __to + __n;
	  __total += __n;
	  __b.commit(__n);
	}
      return __total;
    }

  template<typename _SyncReadStream, typename _DynamicBuffer>
    inline enable_if_t<is_dynamic_buffer<_DynamicBuffer>::value, size_t>
    read(_SyncReadStream& __stream, _DynamicBuffer&& __b)
    {
      error_code __ec;
      return net::read(__stream, __b, transfer_all{}, __ec);
    }

  template<typename _SyncReadStream, typename _DynamicBuffer>
    inline enable_if_t<is_dynamic_buffer<_DynamicBuffer>::value, size_t>
    read(_SyncReadStream& __stream, _DynamicBuffer&& __b, error_code& __ec)
    {
      return net::read(__stream, __b, transfer_all{}, __ec);
    }

  template<typename _SyncReadStream, typename _DynamicBuffer,
	   typename _CompletionCondition>
    inline enable_if_t<is_dynamic_buffer<_DynamicBuffer>::value, size_t>
    read(_SyncReadStream& __stream, _DynamicBuffer&& __b,
	 _CompletionCondition __completion_condition)
    {
      error_code __ec;
      return net::read(__stream, __b, __completion_condition, __ec);
    }

  // @}

  /** @brief asynchronous read operations
   * @{
   */

  template<typename _AsyncReadStream, typename _MutableBufferSequence,
	   typename _CompletionCondition, typename _CompletionToken>
    __deduced_t<_CompletionToken, void(error_code, size_t)>
    async_read(_AsyncReadStream& __stream,
	       const _MutableBufferSequence& __buffers,
	       _CompletionCondition __completion_condition,
	       _CompletionToken&& __token)
    {
      error_code __ec;
    }

  template<typename _AsyncReadStream, typename _MutableBufferSequence,
	   typename _CompletionToken>
    inline __deduced_t<_CompletionToken, void(error_code, size_t)>
    async_read(_AsyncReadStream& __stream,
	       const _MutableBufferSequence& __buffers,
	       _CompletionToken&& __token)
    {
      return net::async_read(__stream, __buffers, transfer_all{},
			     std::forward<_CompletionToken>(__token));
    }

  template<typename _AsyncReadStream, typename _DynamicBuffer,
	   typename _CompletionCondition, typename _CompletionToken>
    __deduced_t<_CompletionToken, void(error_code, size_t)>
    async_read(_AsyncReadStream& __stream, _DynamicBuffer&& __b,
	       _CompletionCondition __completion_condition,
	       _CompletionToken&& __token)
    {
      error_code __ec;
    }

  template<typename _AsyncReadStream, typename _DynamicBuffer,
	   typename _CompletionToken>
    inline __deduced_t<_CompletionToken, void(error_code, size_t)>
    async_read(_AsyncReadStream& __stream, _DynamicBuffer&& __b,
	       _CompletionToken&& __token)
    {
      return net::async_read(__stream, __b, transfer_all{},
			     std::forward<_CompletionToken>(__token));
    }

  // @}

#if 0
  /** @brief synchronous write operations:
   * @{
   */

  template<typename _SyncWriteStream, typename _ConstBufferSequence>
    size_t write(_SyncWriteStream& __stream,
                 const _ConstBufferSequence& __buffers);
  template<typename _SyncWriteStream, typename _ConstBufferSequence>
    size_t write(_SyncWriteStream& __stream,
                 const _ConstBufferSequence& __buffers, error_code& __ec);
  template<typename _SyncWriteStream, typename _ConstBufferSequence,
    typename _CompletionCondition>
      size_t write(_SyncWriteStream& __stream,
                   const _ConstBufferSequence& __buffers,
                   _CompletionCondition __completion_condition);
  template<typename _SyncWriteStream, typename _ConstBufferSequence,
    typename _CompletionCondition>
      size_t write(_SyncWriteStream& __stream,
                   const _ConstBufferSequence& __buffers,
                   _CompletionCondition __completion_condition,
                   error_code& __ec);

  template<typename _SyncWriteStream, typename _DynamicBuffer>
    size_t write(_SyncWriteStream& __stream, _DynamicBuffer&& __b);
  template<typename _SyncWriteStream, typename _DynamicBuffer>
    size_t write(_SyncWriteStream& __stream, _DynamicBuffer&& __b, error_code& __ec);
  template<typename _SyncWriteStream, typename _DynamicBuffer, typename _CompletionCondition>
    size_t write(_SyncWriteStream& __stream, _DynamicBuffer&& __b,
                 _CompletionCondition __completion_condition);
  template<typename _SyncWriteStream, typename _DynamicBuffer, typename _CompletionCondition>
    size_t write(_SyncWriteStream& __stream, _DynamicBuffer&& __b,
                 _CompletionCondition __completion_condition, error_code& __ec);

  // @}

  /** @brief asynchronous write operations
   * @{
   */

  template<typename _AsyncWriteStream, typename _ConstBufferSequence,
    typename _CompletionToken>
      DEDUCED async_write(_AsyncWriteStream& __stream,
                       const _ConstBufferSequence& __buffers,
                       _CompletionToken&& __token);
  template<typename _AsyncWriteStream, typename _ConstBufferSequence,
    typename _CompletionCondition, typename _CompletionToken>
      DEDUCED async_write(_AsyncWriteStream& __stream,
                       const _ConstBufferSequence& __buffers,
                       _CompletionCondition __completion_condition,
                       _CompletionToken&& __token);

  template<typename _AsyncWriteStream, typename _DynamicBuffer, typename _CompletionToken>
    DEDUCED async_write(_AsyncWriteStream& __stream,
                     _DynamicBuffer&& __b, _CompletionToken&& __token);
  template<typename _AsyncWriteStream, typename _DynamicBuffer,
    typename _CompletionCondition, typename _CompletionToken>
      DEDUCED async_write(_AsyncWriteStream& __stream,
                       _DynamicBuffer&& __b,
                       _CompletionCondition __completion_condition,
                       _CompletionToken&& __token);

  // @}

  /** @brief synchronous delimited read operations
   * @{
   */

  template<typename _SyncReadStream, typename _DynamicBuffer>
    size_t read_until(_SyncReadStream& __s, _DynamicBuffer&& __b, char __delim);
  template<typename _SyncReadStream, typename _DynamicBuffer>
    size_t read_until(_SyncReadStream& __s, _DynamicBuffer&& __b,
                      char __delim, error_code& __ec);
  template<typename _SyncReadStream, typename _DynamicBuffer>
    size_t read_until(_SyncReadStream& __s, _DynamicBuffer&& __b, string_view __delim);
  template<typename _SyncReadStream, typename _DynamicBuffer>
    size_t read_until(_SyncReadStream& __s, _DynamicBuffer&& __b,
                      string_view __delim, error_code& __ec);

  // @}

  /** @brief asynchronous delimited read operations
   * @{
   */

  template<typename _AsyncReadStream, typename _DynamicBuffer, typename _CompletionToken>
    DEDUCED async_read_until(_AsyncReadStream& __s,
                          _DynamicBuffer&& __b, char __delim,
                          _CompletionToken&& __token);
  template<typename _AsyncReadStream, typename _DynamicBuffer, typename _CompletionToken>
    DEDUCED async_read_until(_AsyncReadStream& __s,
                          _DynamicBuffer&& __b, string_view __delim,
                          _CompletionToken&& __token);

  // @}

#endif
  /// @}

} // namespace v1
} // namespace net
} // namespace experimental

  template<>
    struct is_error_code_enum<experimental::net::v1::stream_errc>
    : public true_type {};

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std

#endif // C++14

#endif // _GLIBCXX_EXPERIMENTAL_BUFFER
