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

// Copyright (C) 2015-2019 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.
 */

#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
{

  /**
   * @ingroup networking
   * @{
   */

  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
