Home | History | Annotate | Line # | Download | only in experimental
      1      1.1  mrg // <experimental/buffer> -*- C++ -*-
      2      1.1  mrg 
      3  1.1.1.3  mrg // Copyright (C) 2015-2022 Free Software Foundation, Inc.
      4      1.1  mrg //
      5      1.1  mrg // This file is part of the GNU ISO C++ Library.  This library is free
      6      1.1  mrg // software; you can redistribute it and/or modify it under the
      7      1.1  mrg // terms of the GNU General Public License as published by the
      8      1.1  mrg // Free Software Foundation; either version 3, or (at your option)
      9      1.1  mrg // any later version.
     10      1.1  mrg 
     11      1.1  mrg // This library is distributed in the hope that it will be useful,
     12      1.1  mrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
     13      1.1  mrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14      1.1  mrg // GNU General Public License for more details.
     15      1.1  mrg 
     16      1.1  mrg // Under Section 7 of GPL version 3, you are granted additional
     17      1.1  mrg // permissions described in the GCC Runtime Library Exception, version
     18      1.1  mrg // 3.1, as published by the Free Software Foundation.
     19      1.1  mrg 
     20      1.1  mrg // You should have received a copy of the GNU General Public License and
     21      1.1  mrg // a copy of the GCC Runtime Library Exception along with this program;
     22      1.1  mrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     23      1.1  mrg // <http://www.gnu.org/licenses/>.
     24      1.1  mrg 
     25      1.1  mrg /** @file experimental/buffer
     26      1.1  mrg  *  This is a TS C++ Library header.
     27  1.1.1.2  mrg  *  @ingroup networking-ts
     28      1.1  mrg  */
     29      1.1  mrg 
     30      1.1  mrg #ifndef _GLIBCXX_EXPERIMENTAL_BUFFER
     31      1.1  mrg #define _GLIBCXX_EXPERIMENTAL_BUFFER 1
     32      1.1  mrg 
     33      1.1  mrg #pragma GCC system_header
     34      1.1  mrg 
     35      1.1  mrg #if __cplusplus >= 201402L
     36      1.1  mrg 
     37      1.1  mrg #include <array>
     38      1.1  mrg #include <string>
     39      1.1  mrg #include <system_error>
     40      1.1  mrg #include <vector>
     41      1.1  mrg #include <cstring>
     42      1.1  mrg #include <experimental/string_view>
     43      1.1  mrg #include <experimental/bits/net.h>
     44      1.1  mrg 
     45      1.1  mrg namespace std _GLIBCXX_VISIBILITY(default)
     46      1.1  mrg {
     47      1.1  mrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
     48      1.1  mrg namespace experimental
     49      1.1  mrg {
     50      1.1  mrg namespace net
     51      1.1  mrg {
     52      1.1  mrg inline namespace v1
     53      1.1  mrg {
     54      1.1  mrg 
     55  1.1.1.2  mrg   /** @addtogroup networking-ts
     56  1.1.1.2  mrg    *  @{
     57      1.1  mrg    */
     58      1.1  mrg 
     59      1.1  mrg   enum class stream_errc {    // TODO decide values
     60      1.1  mrg     eof = 1,
     61      1.1  mrg     not_found = 2
     62      1.1  mrg   };
     63      1.1  mrg 
     64      1.1  mrg   const error_category& stream_category() noexcept // TODO not inline
     65      1.1  mrg   {
     66      1.1  mrg     struct __cat : error_category
     67      1.1  mrg     {
     68      1.1  mrg       const char* name() const noexcept { return "stream"; }
     69      1.1  mrg 
     70      1.1  mrg       std::string message(int __e) const
     71      1.1  mrg       {
     72      1.1  mrg 	if (__e == (int)stream_errc::eof)
     73      1.1  mrg 	  return "EOF";
     74      1.1  mrg 	else if (__e == (int)stream_errc::not_found)
     75      1.1  mrg 	  return "not found";
     76      1.1  mrg 	return "stream";
     77      1.1  mrg       }
     78      1.1  mrg 
     79      1.1  mrg       virtual void __message(int) { } // TODO dual ABI XXX
     80      1.1  mrg     };
     81      1.1  mrg     static __cat __c;
     82      1.1  mrg     return __c;
     83      1.1  mrg   }
     84      1.1  mrg 
     85      1.1  mrg   inline error_code
     86      1.1  mrg   make_error_code(stream_errc __e) noexcept
     87      1.1  mrg   { return error_code(static_cast<int>(__e), stream_category()); }
     88      1.1  mrg 
     89      1.1  mrg   inline error_condition
     90      1.1  mrg   make_error_condition(stream_errc __e) noexcept
     91      1.1  mrg   { return error_condition(static_cast<int>(__e), stream_category()); }
     92      1.1  mrg 
     93      1.1  mrg   class mutable_buffer
     94      1.1  mrg   {
     95      1.1  mrg   public:
     96      1.1  mrg     // constructors:
     97      1.1  mrg     mutable_buffer() noexcept : _M_data(), _M_size() { }
     98      1.1  mrg 
     99      1.1  mrg     mutable_buffer(void* __p, size_t __n) noexcept
    100      1.1  mrg     : _M_data(__p), _M_size(__n) { }
    101      1.1  mrg 
    102      1.1  mrg     // members:
    103      1.1  mrg     void* data() const noexcept { return _M_data; }
    104      1.1  mrg     size_t size() const noexcept { return _M_size; }
    105      1.1  mrg 
    106      1.1  mrg   private:
    107      1.1  mrg     void*	_M_data;
    108      1.1  mrg     size_t	_M_size;
    109      1.1  mrg   };
    110      1.1  mrg 
    111      1.1  mrg   class const_buffer
    112      1.1  mrg   {
    113      1.1  mrg   public:
    114      1.1  mrg     // constructors:
    115      1.1  mrg     const_buffer() noexcept : _M_data(), _M_size() { }
    116      1.1  mrg 
    117      1.1  mrg     const_buffer(const void* __p, size_t __n) noexcept
    118      1.1  mrg     : _M_data(__p), _M_size(__n) { }
    119      1.1  mrg 
    120      1.1  mrg     const_buffer(const mutable_buffer& __b) noexcept
    121      1.1  mrg     : _M_data(__b.data()), _M_size(__b.size()) { }
    122      1.1  mrg 
    123      1.1  mrg     // members:
    124      1.1  mrg     const void* data() const noexcept { return _M_data; }
    125      1.1  mrg     size_t size() const noexcept { return _M_size; }
    126      1.1  mrg 
    127      1.1  mrg   private:
    128      1.1  mrg     const void*	_M_data;
    129      1.1  mrg     size_t	_M_size;
    130      1.1  mrg   };
    131      1.1  mrg 
    132      1.1  mrg 
    133      1.1  mrg   /** @brief buffer sequence access
    134      1.1  mrg    *
    135      1.1  mrg    * Uniform access to types that meet the BufferSequence requirements.
    136      1.1  mrg    * @{
    137      1.1  mrg    */
    138      1.1  mrg 
    139      1.1  mrg   inline const mutable_buffer*
    140      1.1  mrg   buffer_sequence_begin(const mutable_buffer& __b)
    141      1.1  mrg   { return std::addressof(__b); }
    142      1.1  mrg 
    143      1.1  mrg   inline const const_buffer*
    144      1.1  mrg   buffer_sequence_begin(const const_buffer& __b)
    145      1.1  mrg   { return std::addressof(__b); }
    146      1.1  mrg 
    147      1.1  mrg   inline const mutable_buffer*
    148      1.1  mrg   buffer_sequence_end(const mutable_buffer& __b)
    149      1.1  mrg   { return std::addressof(__b) + 1; }
    150      1.1  mrg 
    151      1.1  mrg   inline const const_buffer*
    152      1.1  mrg   buffer_sequence_end(const const_buffer& __b)
    153      1.1  mrg   { return std::addressof(__b) + 1; }
    154      1.1  mrg 
    155      1.1  mrg   template<typename _Cont>
    156      1.1  mrg     auto
    157      1.1  mrg     buffer_sequence_begin(_Cont& __c) -> decltype(__c.begin())
    158      1.1  mrg     { return __c.begin(); }
    159      1.1  mrg 
    160      1.1  mrg   template<typename _Cont>
    161      1.1  mrg     auto
    162      1.1  mrg     buffer_sequence_begin(const _Cont& __c) -> decltype(__c.begin())
    163      1.1  mrg     { return __c.begin(); }
    164      1.1  mrg 
    165      1.1  mrg   template<typename _Cont>
    166      1.1  mrg     auto
    167      1.1  mrg     buffer_sequence_end(_Cont& __c) -> decltype(__c.end())
    168      1.1  mrg     { return __c.end(); }
    169      1.1  mrg 
    170      1.1  mrg   template<typename _Cont>
    171      1.1  mrg     auto
    172      1.1  mrg     buffer_sequence_end(const _Cont& __c) -> decltype(__c.end())
    173      1.1  mrg     { return __c.end(); }
    174      1.1  mrg 
    175  1.1.1.2  mrg   /// @}
    176      1.1  mrg 
    177      1.1  mrg 
    178      1.1  mrg   /** @brief buffer type traits
    179      1.1  mrg    *
    180      1.1  mrg    * @{
    181      1.1  mrg    */
    182      1.1  mrg 
    183      1.1  mrg   template<typename _Tp, typename _Buffer,
    184      1.1  mrg 	   typename _Begin
    185      1.1  mrg 	    = decltype(net::buffer_sequence_begin(std::declval<_Tp&>())),
    186      1.1  mrg 	   typename _End
    187      1.1  mrg 	    = decltype(net::buffer_sequence_end(std::declval<_Tp&>()))>
    188      1.1  mrg     using __buffer_sequence = enable_if_t<__and_<
    189      1.1  mrg       __is_value_constructible<_Tp>, is_same<_Begin, _End>,
    190      1.1  mrg       is_convertible<typename iterator_traits<_Begin>::value_type, _Buffer>
    191      1.1  mrg       >::value>;
    192      1.1  mrg 
    193      1.1  mrg   template<typename _Tp, typename _Buffer, typename = void>
    194      1.1  mrg     struct __is_buffer_sequence : false_type
    195      1.1  mrg     { };
    196      1.1  mrg 
    197      1.1  mrg   template<typename _Tp, typename _Buffer>
    198      1.1  mrg     struct __is_buffer_sequence<_Tp, _Buffer, __buffer_sequence<_Tp, _Buffer>>
    199      1.1  mrg     : true_type
    200      1.1  mrg     { };
    201      1.1  mrg 
    202      1.1  mrg   template<typename _Tp>
    203      1.1  mrg     struct is_mutable_buffer_sequence
    204      1.1  mrg     : __is_buffer_sequence<_Tp, mutable_buffer>::type
    205      1.1  mrg     { };
    206      1.1  mrg 
    207      1.1  mrg   template<typename _Tp>
    208      1.1  mrg     struct is_const_buffer_sequence
    209      1.1  mrg     : __is_buffer_sequence<_Tp, const_buffer>::type
    210      1.1  mrg     { };
    211      1.1  mrg 
    212      1.1  mrg   template<typename _Tp>
    213      1.1  mrg     constexpr bool is_mutable_buffer_sequence_v
    214      1.1  mrg       = is_mutable_buffer_sequence<_Tp>::value;
    215      1.1  mrg 
    216      1.1  mrg   template<typename _Tp>
    217      1.1  mrg     constexpr bool is_const_buffer_sequence_v
    218      1.1  mrg       = is_const_buffer_sequence<_Tp>::value;
    219      1.1  mrg 
    220      1.1  mrg   template<typename _Tp, typename = void>
    221      1.1  mrg     struct __is_dynamic_buffer_impl : false_type
    222      1.1  mrg     { };
    223      1.1  mrg 
    224      1.1  mrg   // Check DynamicBuffer requirements.
    225      1.1  mrg   template<typename _Tp, typename _Up = remove_const_t<_Tp>>
    226      1.1  mrg     auto
    227      1.1  mrg     __dynamic_buffer_reqs(_Up* __x = 0, const _Up* __x1 = 0, size_t __n = 0)
    228      1.1  mrg     -> enable_if_t<__and_<
    229      1.1  mrg       is_move_constructible<_Up>,
    230      1.1  mrg       is_const_buffer_sequence<typename _Tp::const_buffers_type>,
    231      1.1  mrg       is_mutable_buffer_sequence<typename _Tp::mutable_buffers_type>,
    232      1.1  mrg       is_same<decltype(__x1->size()), size_t>,
    233      1.1  mrg       is_same<decltype(__x1->max_size()), size_t>,
    234      1.1  mrg       is_same<decltype(__x1->capacity()), size_t>,
    235      1.1  mrg       is_same<decltype(__x1->data()), typename _Tp::const_buffers_type>,
    236      1.1  mrg       is_same<decltype(__x->prepare(__n)), typename _Tp::mutable_buffers_type>,
    237      1.1  mrg       is_void<decltype(__x->commit(__n), __x->consume(__n), void())>
    238      1.1  mrg     >::value>;
    239      1.1  mrg 
    240      1.1  mrg   template<typename _Tp>
    241      1.1  mrg     struct __is_dynamic_buffer_impl<_Tp,
    242      1.1  mrg 				    decltype(__dynamic_buffer_reqs<_Tp>())>
    243      1.1  mrg     : true_type
    244      1.1  mrg     { };
    245      1.1  mrg 
    246      1.1  mrg   template<typename _Tp>
    247      1.1  mrg     struct is_dynamic_buffer : __is_dynamic_buffer_impl<_Tp>::type
    248      1.1  mrg     { };
    249      1.1  mrg 
    250      1.1  mrg   template<typename _Tp>
    251      1.1  mrg     constexpr bool is_dynamic_buffer_v = is_dynamic_buffer<_Tp>::value;
    252      1.1  mrg 
    253  1.1.1.2  mrg   /// @}
    254      1.1  mrg 
    255      1.1  mrg   /// buffer size
    256      1.1  mrg   template<typename _ConstBufferSequence>
    257      1.1  mrg     size_t
    258      1.1  mrg     buffer_size(const _ConstBufferSequence& __buffers) noexcept
    259      1.1  mrg     {
    260      1.1  mrg       size_t __total_size = 0;
    261      1.1  mrg       auto __i = net::buffer_sequence_begin(__buffers);
    262      1.1  mrg       const auto __end = net::buffer_sequence_end(__buffers);
    263      1.1  mrg       for (; __i != __end; ++__i)
    264      1.1  mrg 	__total_size += const_buffer(*__i).size();
    265      1.1  mrg       return __total_size;
    266      1.1  mrg     }
    267      1.1  mrg 
    268      1.1  mrg   template<typename _ConstBufferSequence>
    269      1.1  mrg     bool
    270      1.1  mrg     __buffer_empty(const _ConstBufferSequence& __buffers) noexcept
    271      1.1  mrg     {
    272      1.1  mrg       auto __i = net::buffer_sequence_begin(__buffers);
    273      1.1  mrg       const auto __end = net::buffer_sequence_end(__buffers);
    274      1.1  mrg       for (; __i != __end; ++__i)
    275      1.1  mrg 	if (const_buffer(*__i).size() != 0)
    276      1.1  mrg 	  return false;
    277      1.1  mrg       return true;
    278      1.1  mrg     }
    279      1.1  mrg 
    280      1.1  mrg   // buffer copy:
    281      1.1  mrg 
    282      1.1  mrg   template<typename _MutableBufferSequence, typename _ConstBufferSequence>
    283      1.1  mrg     size_t
    284      1.1  mrg     buffer_copy(const _MutableBufferSequence& __dest,
    285      1.1  mrg 		const _ConstBufferSequence& __source,
    286      1.1  mrg 		size_t __max_size) noexcept
    287      1.1  mrg     {
    288      1.1  mrg       size_t __total_size = 0;
    289      1.1  mrg       auto __to_i = net::buffer_sequence_begin(__dest);
    290      1.1  mrg       const auto __to_end = net::buffer_sequence_end(__dest);
    291      1.1  mrg       auto __from_i = net::buffer_sequence_begin(__source);
    292      1.1  mrg       const auto __from_end = net::buffer_sequence_end(__source);
    293      1.1  mrg       mutable_buffer __to;
    294      1.1  mrg       const_buffer __from;
    295      1.1  mrg       while (((__from_i != __from_end && __to_i != __to_end)
    296      1.1  mrg 	    || (__from.size() && __to.size()))
    297      1.1  mrg 	  && __total_size < __max_size)
    298      1.1  mrg 	{
    299      1.1  mrg 	  if (__from.size() == 0)
    300      1.1  mrg 	    __from = const_buffer{*__from_i++};
    301      1.1  mrg 	  if (__to.size() == 0)
    302      1.1  mrg 	    __to = mutable_buffer{*__to_i++};
    303      1.1  mrg 
    304      1.1  mrg 	  size_t __n = std::min(__from.size(), __to.size());
    305      1.1  mrg 	  __n = std::min(__n, __max_size - __total_size);
    306      1.1  mrg 	  std::memcpy(__to.data(), __from.data(), __n);
    307      1.1  mrg 	  __from = { (const char*)__from.data() + __n, __from.size() - __n };
    308      1.1  mrg 	  __to = { (char*)__to.data() + __n, __to.size() - __n };
    309      1.1  mrg 	  __total_size += __n;
    310      1.1  mrg 	}
    311      1.1  mrg       return __total_size;
    312      1.1  mrg     }
    313      1.1  mrg 
    314      1.1  mrg   template<typename _MutableBufferSequence, typename _ConstBufferSequence>
    315      1.1  mrg     inline size_t
    316      1.1  mrg     buffer_copy(const _MutableBufferSequence& __dest,
    317      1.1  mrg 		const _ConstBufferSequence& __source) noexcept
    318  1.1.1.3  mrg     { return net::buffer_copy(__dest, __source, size_t(-1)); }
    319      1.1  mrg 
    320      1.1  mrg 
    321      1.1  mrg   // buffer arithmetic:
    322      1.1  mrg 
    323      1.1  mrg   inline mutable_buffer
    324      1.1  mrg   operator+(const mutable_buffer& __b, size_t __n) noexcept
    325      1.1  mrg   {
    326      1.1  mrg     if (__n > __b.size())
    327      1.1  mrg       __n = __b.size();
    328      1.1  mrg     return { static_cast<char*>(__b.data()) + __n, __b.size() - __n };
    329      1.1  mrg   }
    330      1.1  mrg 
    331      1.1  mrg   inline mutable_buffer
    332      1.1  mrg   operator+(size_t __n, const mutable_buffer& __b) noexcept
    333      1.1  mrg   { return __b + __n; }
    334      1.1  mrg 
    335      1.1  mrg   inline const_buffer
    336      1.1  mrg   operator+(const const_buffer& __b, size_t __n) noexcept
    337      1.1  mrg   {
    338      1.1  mrg     if (__n > __b.size())
    339      1.1  mrg       __n = __b.size();
    340      1.1  mrg     return { static_cast<const char*>(__b.data()) + __n, __b.size() - __n };
    341      1.1  mrg   }
    342      1.1  mrg 
    343      1.1  mrg   inline const_buffer
    344      1.1  mrg   operator+(size_t __n, const const_buffer& __b) noexcept
    345      1.1  mrg   { return __b + __n; }
    346      1.1  mrg 
    347      1.1  mrg   // buffer creation:
    348      1.1  mrg 
    349      1.1  mrg   inline mutable_buffer
    350      1.1  mrg   buffer(void* __p, size_t __n) noexcept
    351      1.1  mrg   { return { __p, __n }; }
    352      1.1  mrg 
    353      1.1  mrg   inline const_buffer
    354      1.1  mrg   buffer(const void* __p, size_t __n) noexcept
    355      1.1  mrg   { return { __p, __n }; }
    356      1.1  mrg 
    357      1.1  mrg   inline mutable_buffer
    358      1.1  mrg   buffer(const mutable_buffer& __b) noexcept
    359      1.1  mrg   { return __b; }
    360      1.1  mrg 
    361      1.1  mrg   inline mutable_buffer
    362      1.1  mrg   buffer(const mutable_buffer& __b, size_t __n) noexcept
    363      1.1  mrg   { return { __b.data(), std::min(__b.size(), __n) }; }
    364      1.1  mrg 
    365      1.1  mrg   inline const_buffer
    366      1.1  mrg   buffer(const const_buffer& __b) noexcept
    367      1.1  mrg   { return __b; }
    368      1.1  mrg 
    369      1.1  mrg   inline const_buffer
    370      1.1  mrg   buffer(const const_buffer& __b, size_t __n) noexcept
    371      1.1  mrg   { return { __b.data(), std::min(__b.size(), __n) }; }
    372      1.1  mrg 
    373      1.1  mrg   template<typename _Tp>
    374      1.1  mrg     inline mutable_buffer
    375      1.1  mrg     __to_mbuf(_Tp* __data, size_t __n)
    376      1.1  mrg     { return { __n ? __data : nullptr, __n * sizeof(_Tp) }; }
    377      1.1  mrg 
    378      1.1  mrg   template<typename _Tp>
    379      1.1  mrg     inline const_buffer
    380      1.1  mrg     __to_cbuf(const _Tp* __data, size_t __n)
    381      1.1  mrg     { return { __n ? __data : nullptr, __n * sizeof(_Tp) }; }
    382      1.1  mrg 
    383      1.1  mrg   template<typename _Tp, size_t _Nm>
    384      1.1  mrg     inline mutable_buffer
    385      1.1  mrg     buffer(_Tp (&__data)[_Nm]) noexcept
    386      1.1  mrg     { return net::__to_mbuf(__data, _Nm); }
    387      1.1  mrg 
    388      1.1  mrg   template<typename _Tp, size_t _Nm>
    389      1.1  mrg     inline const_buffer
    390      1.1  mrg     buffer(const _Tp (&__data)[_Nm]) noexcept
    391      1.1  mrg     { return net::__to_cbuf(__data, _Nm); }
    392      1.1  mrg 
    393      1.1  mrg   template<typename _Tp, size_t _Nm>
    394      1.1  mrg     inline mutable_buffer
    395      1.1  mrg     buffer(array<_Tp, _Nm>& __data) noexcept
    396      1.1  mrg     { return net::__to_mbuf(__data.data(), _Nm); }
    397      1.1  mrg 
    398      1.1  mrg   template<typename _Tp, size_t _Nm>
    399      1.1  mrg     inline const_buffer
    400      1.1  mrg     buffer(array<const _Tp, _Nm>& __data) noexcept
    401      1.1  mrg     { return net::__to_cbuf(__data.data(), __data.size()); }
    402      1.1  mrg 
    403      1.1  mrg   template<typename _Tp, size_t _Nm>
    404      1.1  mrg     inline const_buffer
    405      1.1  mrg     buffer(const array<_Tp, _Nm>& __data) noexcept
    406      1.1  mrg     { return net::__to_cbuf(__data.data(), __data.size()); }
    407      1.1  mrg 
    408      1.1  mrg   template<typename _Tp, typename _Allocator>
    409      1.1  mrg     inline mutable_buffer
    410      1.1  mrg     buffer(vector<_Tp, _Allocator>& __data) noexcept
    411      1.1  mrg     { return net::__to_mbuf(__data.data(), __data.size()); }
    412      1.1  mrg 
    413      1.1  mrg   template<typename _Tp, typename _Allocator>
    414      1.1  mrg     inline const_buffer
    415      1.1  mrg     buffer(const vector<_Tp, _Allocator>& __data) noexcept
    416      1.1  mrg     { return net::__to_cbuf(__data.data(), __data.size()); }
    417      1.1  mrg 
    418      1.1  mrg   template<typename _CharT, typename _Traits, typename _Allocator>
    419      1.1  mrg     inline mutable_buffer
    420      1.1  mrg     buffer(basic_string<_CharT, _Traits, _Allocator>& __data) noexcept
    421      1.1  mrg     { return net::__to_mbuf(&__data.front(), __data.size()); }
    422      1.1  mrg 
    423      1.1  mrg   template<typename _CharT, typename _Traits, typename _Allocator>
    424      1.1  mrg     inline const_buffer
    425      1.1  mrg     buffer(const basic_string<_CharT, _Traits, _Allocator>& __data) noexcept
    426      1.1  mrg     { return net::__to_cbuf(&__data.front(), __data.size()); }
    427      1.1  mrg 
    428      1.1  mrg   template<typename _CharT, typename _Traits>
    429      1.1  mrg     inline const_buffer
    430      1.1  mrg     buffer(basic_string_view<_CharT, _Traits> __data) noexcept
    431      1.1  mrg     { return net::__to_cbuf(__data.data(), __data.size()); }
    432      1.1  mrg 
    433      1.1  mrg   template<typename _Tp, size_t _Nm>
    434      1.1  mrg     inline mutable_buffer
    435      1.1  mrg     buffer(_Tp (&__data)[_Nm], size_t __n) noexcept
    436      1.1  mrg     { return buffer(net::buffer(__data), __n * sizeof(_Tp)); }
    437      1.1  mrg 
    438      1.1  mrg   template<typename _Tp, size_t _Nm>
    439      1.1  mrg     inline const_buffer
    440      1.1  mrg     buffer(const _Tp (&__data)[_Nm], size_t __n) noexcept
    441      1.1  mrg     { return buffer(net::buffer(__data), __n * sizeof(_Tp)); }
    442      1.1  mrg 
    443      1.1  mrg   template<typename _Tp, size_t _Nm>
    444      1.1  mrg     inline mutable_buffer
    445      1.1  mrg     buffer(array<_Tp, _Nm>& __data, size_t __n) noexcept
    446      1.1  mrg     { return buffer(net::buffer(__data), __n * sizeof(_Tp)); }
    447      1.1  mrg 
    448      1.1  mrg   template<typename _Tp, size_t _Nm>
    449      1.1  mrg     inline const_buffer
    450      1.1  mrg     buffer(array<const _Tp, _Nm>& __data, size_t __n) noexcept
    451      1.1  mrg     { return buffer(net::buffer(__data), __n * sizeof(_Tp)); }
    452      1.1  mrg 
    453      1.1  mrg   template<typename _Tp, size_t _Nm>
    454      1.1  mrg     inline const_buffer
    455      1.1  mrg     buffer(const array<_Tp, _Nm>& __data, size_t __n) noexcept
    456      1.1  mrg     { return buffer(net::buffer(__data), __n * sizeof(_Tp)); }
    457      1.1  mrg 
    458      1.1  mrg   template<typename _Tp, typename _Allocator>
    459      1.1  mrg     inline mutable_buffer
    460      1.1  mrg     buffer(vector<_Tp, _Allocator>& __data, size_t __n) noexcept
    461      1.1  mrg     { return buffer(net::buffer(__data), __n * sizeof(_Tp)); }
    462      1.1  mrg 
    463      1.1  mrg   template<typename _Tp, typename _Allocator>
    464      1.1  mrg     inline const_buffer
    465      1.1  mrg     buffer(const vector<_Tp, _Allocator>& __data, size_t __n) noexcept
    466      1.1  mrg     { return buffer(net::buffer(__data), __n * sizeof(_Tp)); }
    467      1.1  mrg 
    468      1.1  mrg   template<typename _CharT, typename _Traits, typename _Allocator>
    469      1.1  mrg     inline mutable_buffer
    470      1.1  mrg     buffer(basic_string<_CharT, _Traits, _Allocator>& __data,
    471      1.1  mrg 	   size_t __n) noexcept
    472      1.1  mrg     { return buffer(net::buffer(__data), __n * sizeof(_CharT)); }
    473      1.1  mrg 
    474      1.1  mrg   template<typename _CharT, typename _Traits, typename _Allocator>
    475      1.1  mrg     inline const_buffer
    476      1.1  mrg     buffer(const basic_string<_CharT, _Traits, _Allocator>& __data,
    477      1.1  mrg 	   size_t __n) noexcept
    478      1.1  mrg     { return buffer(net::buffer(__data), __n * sizeof(_CharT)); }
    479      1.1  mrg 
    480      1.1  mrg   template<typename _CharT, typename _Traits>
    481      1.1  mrg     inline const_buffer
    482      1.1  mrg     buffer(basic_string_view<_CharT, _Traits> __data, size_t __n) noexcept
    483      1.1  mrg     { return buffer(net::buffer(__data), __n * sizeof(_CharT)); }
    484      1.1  mrg 
    485      1.1  mrg 
    486      1.1  mrg   template<typename _Sequence>
    487      1.1  mrg     class __dynamic_buffer_base
    488      1.1  mrg     {
    489      1.1  mrg     public:
    490      1.1  mrg       // types:
    491  1.1.1.3  mrg       using const_buffers_type = const_buffer;
    492  1.1.1.3  mrg       using mutable_buffers_type = mutable_buffer;
    493      1.1  mrg 
    494      1.1  mrg       // constructors:
    495      1.1  mrg       explicit
    496      1.1  mrg       __dynamic_buffer_base(_Sequence& __seq) noexcept
    497      1.1  mrg       : _M_seq(__seq), _M_size(__seq.size()), _M_max_size(__seq.max_size())
    498      1.1  mrg       { }
    499      1.1  mrg 
    500      1.1  mrg       __dynamic_buffer_base(_Sequence& __seq, size_t __maximum_size) noexcept
    501      1.1  mrg       : _M_seq(__seq), _M_size(__seq.size()), _M_max_size(__maximum_size)
    502      1.1  mrg       { __glibcxx_assert(__seq.size() <= __maximum_size); }
    503      1.1  mrg 
    504      1.1  mrg       __dynamic_buffer_base(__dynamic_buffer_base&&) = default;
    505      1.1  mrg 
    506      1.1  mrg       // members:
    507      1.1  mrg       size_t size() const noexcept { return _M_size; }
    508      1.1  mrg       size_t max_size() const noexcept { return _M_max_size; }
    509      1.1  mrg       size_t capacity() const noexcept { return _M_seq.capacity(); }
    510      1.1  mrg 
    511      1.1  mrg       const_buffers_type
    512      1.1  mrg       data() const noexcept
    513      1.1  mrg       { return net::buffer(_M_seq, _M_size); }
    514      1.1  mrg 
    515      1.1  mrg       mutable_buffers_type
    516      1.1  mrg       prepare(size_t __n)
    517      1.1  mrg       {
    518      1.1  mrg 	if ((_M_size + __n) > _M_max_size)
    519      1.1  mrg 	  __throw_length_error("dynamic_vector_buffer::prepare");
    520      1.1  mrg 
    521      1.1  mrg 	_M_seq.resize(_M_size + __n);
    522      1.1  mrg 	return buffer(net::buffer(_M_seq) + _M_size, __n);
    523      1.1  mrg       }
    524      1.1  mrg 
    525      1.1  mrg       void
    526      1.1  mrg       commit(size_t __n)
    527      1.1  mrg       {
    528      1.1  mrg 	_M_size += std::min(__n, _M_seq.size() - _M_size);
    529      1.1  mrg 	_M_seq.resize(_M_size);
    530      1.1  mrg       }
    531      1.1  mrg 
    532      1.1  mrg       void
    533      1.1  mrg       consume(size_t __n)
    534      1.1  mrg       {
    535      1.1  mrg 	size_t __m = std::min(__n, _M_size);
    536      1.1  mrg 	_M_seq.erase(_M_seq.begin(), _M_seq.begin() + __m);
    537      1.1  mrg 	_M_size -= __m;
    538      1.1  mrg       }
    539      1.1  mrg 
    540      1.1  mrg     private:
    541      1.1  mrg       _Sequence&	_M_seq;
    542      1.1  mrg       size_t		_M_size;
    543      1.1  mrg       const size_t	_M_max_size;
    544      1.1  mrg     };
    545      1.1  mrg 
    546      1.1  mrg   template<typename _Tp, typename _Allocator>
    547      1.1  mrg     class dynamic_vector_buffer
    548      1.1  mrg     : public __dynamic_buffer_base<vector<_Tp, _Allocator>>
    549      1.1  mrg     {
    550      1.1  mrg     public:
    551      1.1  mrg       using __dynamic_buffer_base<vector<_Tp, _Allocator>>::__dynamic_buffer_base;
    552      1.1  mrg     };
    553      1.1  mrg 
    554      1.1  mrg   template<typename _CharT, typename _Traits, typename _Allocator>
    555      1.1  mrg     class dynamic_string_buffer
    556      1.1  mrg     : public __dynamic_buffer_base<basic_string<_CharT, _Traits, _Allocator>>
    557      1.1  mrg     {
    558      1.1  mrg     public:
    559      1.1  mrg       using __dynamic_buffer_base<basic_string<_CharT, _Traits, _Allocator>>::
    560      1.1  mrg 	__dynamic_buffer_base;
    561      1.1  mrg     };
    562      1.1  mrg 
    563      1.1  mrg   // dynamic buffer creation:
    564      1.1  mrg 
    565      1.1  mrg   template<typename _Tp, typename _Allocator>
    566      1.1  mrg     inline dynamic_vector_buffer<_Tp, _Allocator>
    567      1.1  mrg     dynamic_buffer(vector<_Tp, _Allocator>& __vec) noexcept
    568      1.1  mrg     { return dynamic_vector_buffer<_Tp, _Allocator>{__vec}; }
    569      1.1  mrg 
    570      1.1  mrg   template<typename _Tp, typename _Allocator>
    571      1.1  mrg     inline dynamic_vector_buffer<_Tp, _Allocator>
    572      1.1  mrg     dynamic_buffer(vector<_Tp, _Allocator>& __vec, size_t __n) noexcept
    573      1.1  mrg     { return {__vec, __n}; }
    574      1.1  mrg 
    575      1.1  mrg   template<typename _CharT, typename _Traits, typename _Allocator>
    576      1.1  mrg     inline dynamic_string_buffer<_CharT, _Traits, _Allocator>
    577      1.1  mrg     dynamic_buffer(basic_string<_CharT, _Traits, _Allocator>& __str) noexcept
    578      1.1  mrg     { return dynamic_string_buffer<_CharT, _Traits, _Allocator>{__str}; }
    579      1.1  mrg 
    580      1.1  mrg   template<typename _CharT, typename _Traits, typename _Allocator>
    581      1.1  mrg     inline dynamic_string_buffer<_CharT, _Traits, _Allocator>
    582      1.1  mrg     dynamic_buffer(basic_string<_CharT, _Traits, _Allocator>& __str,
    583      1.1  mrg 		   size_t __n) noexcept
    584      1.1  mrg     { return {__str, __n}; }
    585      1.1  mrg 
    586      1.1  mrg   class transfer_all
    587      1.1  mrg   {
    588      1.1  mrg   public:
    589      1.1  mrg     size_t operator()(const error_code& __ec, size_t) const
    590      1.1  mrg     { return !__ec ? 1500 : 0; }
    591      1.1  mrg   };
    592      1.1  mrg 
    593      1.1  mrg   class transfer_at_least
    594      1.1  mrg   {
    595      1.1  mrg   public:
    596      1.1  mrg     explicit transfer_at_least(size_t __m) : _M_minimum(__m) { }
    597      1.1  mrg 
    598      1.1  mrg     size_t operator()(const error_code& __ec, size_t __n) const
    599      1.1  mrg     { return !__ec  && __n < _M_minimum ? _M_minimum - __n : 0; }
    600      1.1  mrg 
    601      1.1  mrg   private:
    602      1.1  mrg     size_t _M_minimum;
    603      1.1  mrg   };
    604      1.1  mrg 
    605      1.1  mrg   class transfer_exactly
    606      1.1  mrg   {
    607      1.1  mrg   public:
    608      1.1  mrg     explicit transfer_exactly(size_t __e) : _M_exact(__e) { }
    609      1.1  mrg 
    610      1.1  mrg     size_t operator()(const error_code& __ec, size_t __n) const
    611      1.1  mrg     {
    612      1.1  mrg       size_t _Nm = -1;
    613      1.1  mrg       return !__ec  && __n < _M_exact ? std::min(_M_exact - __n, _Nm) : 0;
    614      1.1  mrg     }
    615      1.1  mrg 
    616      1.1  mrg   private:
    617      1.1  mrg     size_t _M_exact;
    618      1.1  mrg   };
    619      1.1  mrg 
    620      1.1  mrg   /** @brief synchronous read operations
    621      1.1  mrg    * @{
    622      1.1  mrg    */
    623      1.1  mrg 
    624      1.1  mrg   template<typename _SyncReadStream, typename _MutableBufferSequence,
    625      1.1  mrg 	   typename _CompletionCondition>
    626      1.1  mrg     enable_if_t<is_mutable_buffer_sequence<_MutableBufferSequence>::value,
    627      1.1  mrg 		size_t>
    628      1.1  mrg     read(_SyncReadStream& __stream, const _MutableBufferSequence& __buffers,
    629      1.1  mrg 	 _CompletionCondition __completion_condition, error_code& __ec)
    630      1.1  mrg     {
    631      1.1  mrg       __ec.clear();
    632      1.1  mrg       auto __i = net::buffer_sequence_begin(__buffers);
    633      1.1  mrg       auto __end = net::buffer_sequence_end(__buffers);
    634      1.1  mrg       mutable_buffer __to;
    635      1.1  mrg       size_t __total = 0;
    636      1.1  mrg       size_t __n;
    637      1.1  mrg       while ((__n = __completion_condition(__ec, __total))
    638      1.1  mrg 	  && (__i != __end || __to.size()))
    639      1.1  mrg 	{
    640      1.1  mrg 	  if (__to.size() == 0)
    641      1.1  mrg 	    __to = mutable_buffer(*__i++);
    642      1.1  mrg 	  __n = __stream.read_some(buffer(__to, __n), __ec);
    643      1.1  mrg 	  __to = __to + __n;
    644      1.1  mrg 	  __total += __n;
    645      1.1  mrg 	}
    646      1.1  mrg       return __total;
    647      1.1  mrg     }
    648      1.1  mrg 
    649      1.1  mrg   template<typename _SyncReadStream, typename _MutableBufferSequence>
    650      1.1  mrg     inline
    651      1.1  mrg     enable_if_t<is_mutable_buffer_sequence<_MutableBufferSequence>::value,
    652      1.1  mrg 		size_t>
    653      1.1  mrg     read(_SyncReadStream& __stream, const _MutableBufferSequence& __buffers)
    654      1.1  mrg     {
    655      1.1  mrg       error_code __ec;
    656      1.1  mrg       return net::read(__stream, __buffers, transfer_all{}, __ec);
    657      1.1  mrg     }
    658      1.1  mrg 
    659      1.1  mrg   template<typename _SyncReadStream, typename _MutableBufferSequence>
    660      1.1  mrg     inline
    661      1.1  mrg     enable_if_t<is_mutable_buffer_sequence<_MutableBufferSequence>::value,
    662      1.1  mrg 		size_t>
    663      1.1  mrg     read(_SyncReadStream& __stream, const _MutableBufferSequence& __buffers,
    664      1.1  mrg 	 error_code& __ec)
    665      1.1  mrg     { return net::read(__stream, __buffers, transfer_all{}, __ec); }
    666      1.1  mrg 
    667      1.1  mrg   template<typename _SyncReadStream, typename _MutableBufferSequence,
    668      1.1  mrg 	   typename _CompletionCondition>
    669      1.1  mrg     inline
    670      1.1  mrg     enable_if_t<is_mutable_buffer_sequence<_MutableBufferSequence>::value,
    671      1.1  mrg 		size_t>
    672      1.1  mrg     read(_SyncReadStream& __stream, const _MutableBufferSequence& __buffers,
    673      1.1  mrg 	 _CompletionCondition __completion_condition)
    674      1.1  mrg     {
    675      1.1  mrg       error_code __ec;
    676      1.1  mrg       return net::read(__stream, __buffers, __completion_condition, __ec);
    677      1.1  mrg     }
    678      1.1  mrg 
    679      1.1  mrg 
    680      1.1  mrg   template<typename _SyncReadStream, typename _DynamicBuffer,
    681      1.1  mrg 	   typename _CompletionCondition>
    682      1.1  mrg     enable_if_t<is_dynamic_buffer<decay_t<_DynamicBuffer>>::value, size_t>
    683      1.1  mrg     read(_SyncReadStream& __stream, _DynamicBuffer&& __b,
    684      1.1  mrg 	 _CompletionCondition __completion_condition, error_code& __ec)
    685      1.1  mrg     {
    686      1.1  mrg       const size_t __limit = 64;
    687      1.1  mrg       __ec.clear();
    688      1.1  mrg       size_t __cap = std::max(__b.capacity() - __b.size(), __limit);
    689      1.1  mrg       size_t __total = 0;
    690      1.1  mrg       size_t __n;
    691      1.1  mrg       while ((__n = __completion_condition(__ec, __total))
    692      1.1  mrg 	  && __b.size() != __b.max_size())
    693      1.1  mrg 	{
    694      1.1  mrg 	  __n =  std::min(__n, __b.max_size() - __b.size());
    695      1.1  mrg 	  size_t __cap = std::max(__b.capacity() - __b.size(), __limit);
    696      1.1  mrg 	  mutable_buffer __to = __b.prepare(std::min(__cap, __n));
    697      1.1  mrg 	  __n = __stream.read_some(__to, __ec);
    698      1.1  mrg 	  __to = __to + __n;
    699      1.1  mrg 	  __total += __n;
    700      1.1  mrg 	  __b.commit(__n);
    701      1.1  mrg 	}
    702      1.1  mrg       return __total;
    703      1.1  mrg     }
    704      1.1  mrg 
    705      1.1  mrg   template<typename _SyncReadStream, typename _DynamicBuffer>
    706      1.1  mrg     inline enable_if_t<is_dynamic_buffer<_DynamicBuffer>::value, size_t>
    707      1.1  mrg     read(_SyncReadStream& __stream, _DynamicBuffer&& __b)
    708      1.1  mrg     {
    709      1.1  mrg       error_code __ec;
    710      1.1  mrg       return net::read(__stream, __b, transfer_all{}, __ec);
    711      1.1  mrg     }
    712      1.1  mrg 
    713      1.1  mrg   template<typename _SyncReadStream, typename _DynamicBuffer>
    714      1.1  mrg     inline enable_if_t<is_dynamic_buffer<_DynamicBuffer>::value, size_t>
    715      1.1  mrg     read(_SyncReadStream& __stream, _DynamicBuffer&& __b, error_code& __ec)
    716      1.1  mrg     {
    717      1.1  mrg       return net::read(__stream, __b, transfer_all{}, __ec);
    718      1.1  mrg     }
    719      1.1  mrg 
    720      1.1  mrg   template<typename _SyncReadStream, typename _DynamicBuffer,
    721      1.1  mrg 	   typename _CompletionCondition>
    722      1.1  mrg     inline enable_if_t<is_dynamic_buffer<_DynamicBuffer>::value, size_t>
    723      1.1  mrg     read(_SyncReadStream& __stream, _DynamicBuffer&& __b,
    724      1.1  mrg 	 _CompletionCondition __completion_condition)
    725      1.1  mrg     {
    726      1.1  mrg       error_code __ec;
    727      1.1  mrg       return net::read(__stream, __b, __completion_condition, __ec);
    728      1.1  mrg     }
    729      1.1  mrg 
    730  1.1.1.2  mrg   /// @}
    731      1.1  mrg 
    732      1.1  mrg   /** @brief asynchronous read operations
    733      1.1  mrg    * @{
    734      1.1  mrg    */
    735      1.1  mrg 
    736      1.1  mrg   template<typename _AsyncReadStream, typename _MutableBufferSequence,
    737      1.1  mrg 	   typename _CompletionCondition, typename _CompletionToken>
    738      1.1  mrg     __deduced_t<_CompletionToken, void(error_code, size_t)>
    739      1.1  mrg     async_read(_AsyncReadStream& __stream,
    740      1.1  mrg 	       const _MutableBufferSequence& __buffers,
    741      1.1  mrg 	       _CompletionCondition __completion_condition,
    742      1.1  mrg 	       _CompletionToken&& __token)
    743      1.1  mrg     {
    744      1.1  mrg       error_code __ec;
    745      1.1  mrg     }
    746      1.1  mrg 
    747      1.1  mrg   template<typename _AsyncReadStream, typename _MutableBufferSequence,
    748      1.1  mrg 	   typename _CompletionToken>
    749      1.1  mrg     inline __deduced_t<_CompletionToken, void(error_code, size_t)>
    750      1.1  mrg     async_read(_AsyncReadStream& __stream,
    751      1.1  mrg 	       const _MutableBufferSequence& __buffers,
    752      1.1  mrg 	       _CompletionToken&& __token)
    753      1.1  mrg     {
    754      1.1  mrg       return net::async_read(__stream, __buffers, transfer_all{},
    755      1.1  mrg 			     std::forward<_CompletionToken>(__token));
    756      1.1  mrg     }
    757      1.1  mrg 
    758      1.1  mrg   template<typename _AsyncReadStream, typename _DynamicBuffer,
    759      1.1  mrg 	   typename _CompletionCondition, typename _CompletionToken>
    760      1.1  mrg     __deduced_t<_CompletionToken, void(error_code, size_t)>
    761      1.1  mrg     async_read(_AsyncReadStream& __stream, _DynamicBuffer&& __b,
    762      1.1  mrg 	       _CompletionCondition __completion_condition,
    763      1.1  mrg 	       _CompletionToken&& __token)
    764      1.1  mrg     {
    765      1.1  mrg       error_code __ec;
    766      1.1  mrg     }
    767      1.1  mrg 
    768      1.1  mrg   template<typename _AsyncReadStream, typename _DynamicBuffer,
    769      1.1  mrg 	   typename _CompletionToken>
    770      1.1  mrg     inline __deduced_t<_CompletionToken, void(error_code, size_t)>
    771      1.1  mrg     async_read(_AsyncReadStream& __stream, _DynamicBuffer&& __b,
    772      1.1  mrg 	       _CompletionToken&& __token)
    773      1.1  mrg     {
    774      1.1  mrg       return net::async_read(__stream, __b, transfer_all{},
    775      1.1  mrg 			     std::forward<_CompletionToken>(__token));
    776      1.1  mrg     }
    777      1.1  mrg 
    778  1.1.1.2  mrg   /// @}
    779      1.1  mrg 
    780      1.1  mrg #if 0
    781      1.1  mrg   /** @brief synchronous write operations:
    782      1.1  mrg    * @{
    783      1.1  mrg    */
    784      1.1  mrg 
    785      1.1  mrg   template<typename _SyncWriteStream, typename _ConstBufferSequence>
    786      1.1  mrg     size_t write(_SyncWriteStream& __stream,
    787      1.1  mrg                  const _ConstBufferSequence& __buffers);
    788      1.1  mrg   template<typename _SyncWriteStream, typename _ConstBufferSequence>
    789      1.1  mrg     size_t write(_SyncWriteStream& __stream,
    790      1.1  mrg                  const _ConstBufferSequence& __buffers, error_code& __ec);
    791      1.1  mrg   template<typename _SyncWriteStream, typename _ConstBufferSequence,
    792      1.1  mrg     typename _CompletionCondition>
    793      1.1  mrg       size_t write(_SyncWriteStream& __stream,
    794      1.1  mrg                    const _ConstBufferSequence& __buffers,
    795      1.1  mrg                    _CompletionCondition __completion_condition);
    796      1.1  mrg   template<typename _SyncWriteStream, typename _ConstBufferSequence,
    797      1.1  mrg     typename _CompletionCondition>
    798      1.1  mrg       size_t write(_SyncWriteStream& __stream,
    799      1.1  mrg                    const _ConstBufferSequence& __buffers,
    800      1.1  mrg                    _CompletionCondition __completion_condition,
    801      1.1  mrg                    error_code& __ec);
    802      1.1  mrg 
    803      1.1  mrg   template<typename _SyncWriteStream, typename _DynamicBuffer>
    804      1.1  mrg     size_t write(_SyncWriteStream& __stream, _DynamicBuffer&& __b);
    805      1.1  mrg   template<typename _SyncWriteStream, typename _DynamicBuffer>
    806      1.1  mrg     size_t write(_SyncWriteStream& __stream, _DynamicBuffer&& __b, error_code& __ec);
    807      1.1  mrg   template<typename _SyncWriteStream, typename _DynamicBuffer, typename _CompletionCondition>
    808      1.1  mrg     size_t write(_SyncWriteStream& __stream, _DynamicBuffer&& __b,
    809      1.1  mrg                  _CompletionCondition __completion_condition);
    810      1.1  mrg   template<typename _SyncWriteStream, typename _DynamicBuffer, typename _CompletionCondition>
    811      1.1  mrg     size_t write(_SyncWriteStream& __stream, _DynamicBuffer&& __b,
    812      1.1  mrg                  _CompletionCondition __completion_condition, error_code& __ec);
    813      1.1  mrg 
    814  1.1.1.2  mrg   /// @}
    815      1.1  mrg 
    816      1.1  mrg   /** @brief asynchronous write operations
    817      1.1  mrg    * @{
    818      1.1  mrg    */
    819      1.1  mrg 
    820      1.1  mrg   template<typename _AsyncWriteStream, typename _ConstBufferSequence,
    821      1.1  mrg     typename _CompletionToken>
    822      1.1  mrg       DEDUCED async_write(_AsyncWriteStream& __stream,
    823      1.1  mrg                        const _ConstBufferSequence& __buffers,
    824      1.1  mrg                        _CompletionToken&& __token);
    825      1.1  mrg   template<typename _AsyncWriteStream, typename _ConstBufferSequence,
    826      1.1  mrg     typename _CompletionCondition, typename _CompletionToken>
    827      1.1  mrg       DEDUCED async_write(_AsyncWriteStream& __stream,
    828      1.1  mrg                        const _ConstBufferSequence& __buffers,
    829      1.1  mrg                        _CompletionCondition __completion_condition,
    830      1.1  mrg                        _CompletionToken&& __token);
    831      1.1  mrg 
    832      1.1  mrg   template<typename _AsyncWriteStream, typename _DynamicBuffer, typename _CompletionToken>
    833      1.1  mrg     DEDUCED async_write(_AsyncWriteStream& __stream,
    834      1.1  mrg                      _DynamicBuffer&& __b, _CompletionToken&& __token);
    835      1.1  mrg   template<typename _AsyncWriteStream, typename _DynamicBuffer,
    836      1.1  mrg     typename _CompletionCondition, typename _CompletionToken>
    837      1.1  mrg       DEDUCED async_write(_AsyncWriteStream& __stream,
    838      1.1  mrg                        _DynamicBuffer&& __b,
    839      1.1  mrg                        _CompletionCondition __completion_condition,
    840      1.1  mrg                        _CompletionToken&& __token);
    841      1.1  mrg 
    842  1.1.1.2  mrg   /// @}
    843      1.1  mrg 
    844      1.1  mrg   /** @brief synchronous delimited read operations
    845      1.1  mrg    * @{
    846      1.1  mrg    */
    847      1.1  mrg 
    848      1.1  mrg   template<typename _SyncReadStream, typename _DynamicBuffer>
    849      1.1  mrg     size_t read_until(_SyncReadStream& __s, _DynamicBuffer&& __b, char __delim);
    850      1.1  mrg   template<typename _SyncReadStream, typename _DynamicBuffer>
    851      1.1  mrg     size_t read_until(_SyncReadStream& __s, _DynamicBuffer&& __b,
    852      1.1  mrg                       char __delim, error_code& __ec);
    853      1.1  mrg   template<typename _SyncReadStream, typename _DynamicBuffer>
    854      1.1  mrg     size_t read_until(_SyncReadStream& __s, _DynamicBuffer&& __b, string_view __delim);
    855      1.1  mrg   template<typename _SyncReadStream, typename _DynamicBuffer>
    856      1.1  mrg     size_t read_until(_SyncReadStream& __s, _DynamicBuffer&& __b,
    857      1.1  mrg                       string_view __delim, error_code& __ec);
    858      1.1  mrg 
    859  1.1.1.2  mrg   /// @}
    860      1.1  mrg 
    861      1.1  mrg   /** @brief asynchronous delimited read operations
    862      1.1  mrg    * @{
    863      1.1  mrg    */
    864      1.1  mrg 
    865      1.1  mrg   template<typename _AsyncReadStream, typename _DynamicBuffer, typename _CompletionToken>
    866      1.1  mrg     DEDUCED async_read_until(_AsyncReadStream& __s,
    867      1.1  mrg                           _DynamicBuffer&& __b, char __delim,
    868      1.1  mrg                           _CompletionToken&& __token);
    869      1.1  mrg   template<typename _AsyncReadStream, typename _DynamicBuffer, typename _CompletionToken>
    870      1.1  mrg     DEDUCED async_read_until(_AsyncReadStream& __s,
    871      1.1  mrg                           _DynamicBuffer&& __b, string_view __delim,
    872      1.1  mrg                           _CompletionToken&& __token);
    873      1.1  mrg 
    874  1.1.1.2  mrg   /// @}
    875      1.1  mrg 
    876      1.1  mrg #endif
    877      1.1  mrg   /// @}
    878      1.1  mrg 
    879      1.1  mrg } // namespace v1
    880      1.1  mrg } // namespace net
    881      1.1  mrg } // namespace experimental
    882      1.1  mrg 
    883      1.1  mrg   template<>
    884      1.1  mrg     struct is_error_code_enum<experimental::net::v1::stream_errc>
    885      1.1  mrg     : public true_type {};
    886      1.1  mrg 
    887      1.1  mrg _GLIBCXX_END_NAMESPACE_VERSION
    888      1.1  mrg } // namespace std
    889      1.1  mrg 
    890      1.1  mrg #endif // C++14
    891      1.1  mrg 
    892      1.1  mrg #endif // _GLIBCXX_EXPERIMENTAL_BUFFER
    893