In the "Must allocate to combine buffer sequences" example, if you already know you have 2 HeaderBuffers and 3 BodyBuffers, then you can avoid allocation by just using std::array or std::inplace_vector instead of std::vector.
To what extent is the "Type-level composition - no runtime allocation" example able to avoid allocation if the lengths are not known at compile time?
If send() ultimately needs to make an array of iovec, then if it doesn't know at compile-time how many it'll need to make, won't it have to do an allocation?
I wonder whether an interface is technically possible that would let a user who happens to have an array<span<byte>, N> where N > boost::corosio::detail::max_iovec_ pass that to send() in a way that avoids allocation.
Hm, that seems suboptimal though. I bet one could write a send() that can look at its argument and see "hey that's a std::array of 33 byte spans. so lemme just make a std::array of 33 iovecs (instead of 64 iovecs with 31 unused ones)".
Thanks. Can you believe the entire paper was AI-generated? Anyway... I've been building the successor to Boost.Asio (https://github.com/cppalliance/corosio) and I struggled for a while because on the one hand I like the compositional power of concepts but on the other hand I have grown to dislike header-only libraries which are template-only. I think I found the right balance now :)
In the "Must allocate to combine buffer sequences" example, if you already know you have 2 HeaderBuffers and 3 BodyBuffers, then you can avoid allocation by just using std::array or std::inplace_vector instead of std::vector.
Right, if the length (number of elements) is known at compile time then they can be combined into a new type without allocation.
To what extent is the "Type-level composition - no runtime allocation" example able to avoid allocation if the lengths are not known at compile time?
If send() ultimately needs to make an array of iovec, then if it doesn't know at compile-time how many it'll need to make, won't it have to do an allocation?
We make a tradeoff, and put an upper limit on the number of elements in the iovec:
https://github.com/cppalliance/corosio/blob/4276bd4039097fd4dd62dda4bb55e53d03351088/include/boost/corosio/detail/config.hpp#L58
Thanks, that makes a lot of sense.
I wonder whether an interface is technically possible that would let a user who happens to have an array<span<byte>, N> where N > boost::corosio::detail::max_iovec_ pass that to send() in a way that avoids allocation.
Yes it is possible. You have N functions. Each function has an iovec array which is a power of two:
iovec iv[32];
iovec iv[64];
iovec iv[128];
...
And then you choose the function based on how many elements you have. If N is large enough you can cover all possibilities.
Hm, that seems suboptimal though. I bet one could write a send() that can look at its argument and see "hey that's a std::array of 33 byte spans. so lemme just make a std::array of 33 iovecs (instead of 64 iovecs with 31 unused ones)".
Nice and clear! Thanks!
Thanks. Can you believe the entire paper was AI-generated? Anyway... I've been building the successor to Boost.Asio (https://github.com/cppalliance/corosio) and I struggled for a while because on the one hand I like the compositional power of concepts but on the other hand I have grown to dislike header-only libraries which are template-only. I think I found the right balance now :)