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.
Modify 16.2.2 [networking.ts::buffer.reqmts.constbuffersequence] Table 13 "ConstBufferSequence
requirements" as indicated:
Table 13 — ConstBufferSequence
requirementsexpression 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; })