This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

### 3021. [networking.ts] Relax pointer equivalence requirement for `ConstBufferSequence`

Section: 16.2.2 [networking.ts::buffer.reqmts.constbuffersequence] Status: New Submitter: Vinnie Falco Opened: 2017-09-20 Last modified: 2020-09-06

Priority: 3

View all issues with New status.

Discussion:

Addresses: networking.ts

The post-condition buffer sequence requirements mandate pointer equivalence. This means that a copies of buffer sequences must point to the same pieces of underlying memory. While this is appropriate for `MutableBufferSequence`, it is unnecessary for `ConstBufferSequence` and can actually prevent useful implementation strategies such as the following constant buffer sequence which avoids dynamic allocations:

>     /// A buffer sequence containing a chunk-encoding header
>     class chunk_size
>     {
>     public:
>         // Storage for the longest hex string we might need
>         class value_type
>         {
>             friend class chunk_size;

>             // First byte holds the length
>             char buf_[1 + 2 * sizeof(std::size_t)];

>             template<class = void>
>             void prepare(std::size_t n);

>             template<class OutIter>
>             static OutIter to_hex(OutIter last, std::size_t n)
>             {
>                 if (n == 0)
>                 {
>                     *--last = '0';
>                     return last;
>                 }
>                 while (n)
>                 {
>                     *--last = "0123456789abcdef"[n & 0xf];
>                     n >>= 4;
>                 }
>                 return last;
>             }
>         public:
>             operator boost::asio::const_buffer() const
>             {
>                 return {
>                     buf_ + sizeof(buf_) - buf_[0],
>                     static_cast(buf_[0])
>                 };
>             }
>         };

>         using const_iterator = value_type const*;

>         chunk_size(chunk_size const& other) = default;

>         /** Construct a chunk header

>             @param n The number of octets in this chunk.
>         */
>         chunk_size(std::size_t n)
>         {
>             value_.prepare(n);
>         }

>         const_iterator begin() const
>         {
>             return &value_;
>         }

>         const_iterator end() const
>         {
>             return begin() + 1;
>         }

>     private:
>         value_type value_;
>     };

Proposed resolution:

This wording is relative to N4588.

1. Modify 16.2.2 [networking.ts::buffer.reqmts.constbuffersequence] Table 13 "`ConstBufferSequence` requirements" as indicated:

   > Table 13 — `ConstBufferSequence` requirements
   > expression | return type | assertion/note pre/post-condition
   > --- | --- | ---
   > `[…]`
   > `X u(x);` |  | post:
   >     equal(
   >       net::buffer_sequence_begin(x),
   >       net::buffer_sequence_end(x),
   >       net::buffer_sequence_begin(u),
   >       net::buffer_sequence_end(u),
   >       [](const typename X::value_type& v1,
   >          const typename X::value_type& v2)
   >         {
   >           const_buffer b1(v1);
   >           const_buffer b2(v2);
   >           return b1.data() == b2.data()
   >               && b1.size() == b2.size()
   >           return b1.size() == b2.size()
   >               && memcmp(b1.data(), b2.data(), b1.size()) == 0;
   >         })