|
- // <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
|