
On 9/9/19 9:43 AM, Hans Dembinski wrote:
It looks like circular span can adapt any suitable STL container into a circular one. In fact, circular array and vector are implemented by inheriting privately from std::array and circular::span, which is nice. However, wouldn't it be more general to provide a circular_adaptor, which works with any vector or array, and perhaps even any STL container? Perhaps someone wants a circular set?
Circular span operates with any container that has contiguous storage. The circular array and circular vector are there for convenience. An adapter that works on arbitrary containers is an interesting idea. Perhaps it should be conceptualized as a circular range instead.
The rationale is short, I would like to know why I should use this instead of boost.circular_buffer.
I am preparing an appendix for the documentation to address this question (together with the question of why I redesigned P0059R4 ring_span.) The main reason is that boost::circular_buffer allocates the storage for you, whereas you pass your storage to circular::span. The span gives you greater flexibility; for instance you can use the span on DMA buffers or static memory. The span also gives you better performance. circular::array keeps its storage and its internal state in the same memory block, which gives better cache performance. We can also constexpr all the things. Finally, my preliminary investigations show that the compiler is better at auto-vectorization on circular::array than on boost::circular_buffer. The boost::circular_buffer::array_range type that is used as the return type for contiguous sub-ranges is a std::pair<pointer, size_type> so it cannot be passed directly to standard algorithms or ranges. boost:circular_buffer has no functions to return the unused contiguous sub-ranges, which is useful in setups where if you have hardware (e.g. DMA) that blits into the unused memory, and you only want to update the circular span when the blit is completed.