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.
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.
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; })