[networking.ts] Relax pointer equivalence requirement for ConstBufferSequence

Submitter: Vinnie Falco

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 N4695.

  1. Modify 16.2.2 [buffer.reqmts.constbuffersequence], table 13 as indicated:

    return b1.data() == b2.data() && b1.size() == b2.size();

    return b1.size() == b2.size() && memcmp(b1.data(), b2.data(), b1.size()) == 0;