[circular_buffer] Is it usable in embedded contexts?
Hi Everyone, This is a couple of questions about Boost.Circular_buffer, but also about Boost in general. A colleague of mine says he needs a ring buffer for usage in the embedded context, and I am investigating why he chooses to write his own rather than using Boost.Circular_Buffer, even though he knows the latter exists. It is a natural expectation for containers like static_vector/inplace_vector, array, circular_buffer to be a natural fit for the embedded contexts, as, at least in principle, they should not require any memory allocation. Question 1: Is Boost a suitable place for libraries targeting systems where exceptions, RTTI and memory allocation are banned? I tried to check what Boost.Circular_Buffer offers, and I was surprised that it requires at least one, initial allocation. Maybe I could get away with a custom allocator, but then why do we have static_vector, rather than the advice to use std::vector with "in-place allocator"? Question 2: Is it a reasonable expectation of a ring buffer to not require allocations? I tried to find more details in the docs, but I found that the entire reference documentation for class template circular_buffer is missing from the docs. Question 3: Is Boost.Circular_Buffer actively maintained? The last commit is from three years ago. One thing, my colleague says, that puts him off from even considering Boost.Circular_Buffer is the amount of headers that circular_buffer.hpp directly and indirectly includes. This dwarfs the number of headers in his entire project. Also the fact that Boost.Circular_Buffer includes the standard headers is problematic, as some standard-mandated headers are not available on some embedded platforms. A lot of these dependencies are for emulating C++11 features, like static_assert, which may not be necessary if we assume some C++11 level of compiler conformance. Question 4: Maybe there would be a value, at least for some Boost libraries, to provide a single-header, header-only variant that works under some assumptions, like C++11 compiler? My colleagues use case is that, because removals from the buffer can occur asynchronously, when doing a pop_back() there is no way to be sure that the buffer is non-empty, so this would require a function that does the check and the pop_back at one go. I am interested to learn what others think about this. Ideally, I would like for Boost to be in a state where developers prefer to use it rather than writing their own popular components. Regards, &rzej;
On 8/10/24 16:03, Andrzej Krzemienski via Boost wrote:
Hi Everyone, This is a couple of questions about Boost.Circular_buffer, but also about Boost in general.
A colleague of mine says he needs a ring buffer for usage in the embedded context, and I am investigating why he chooses to write his own rather than using Boost.Circular_Buffer, even though he knows the latter exists.
It is a natural expectation for containers like static_vector/inplace_vector, array, circular_buffer to be a natural fit for the embedded contexts, as, at least in principle, they should not require any memory allocation.
Not necessarily. These types are useful beyond embedded environments, where exceptions and dynamic memory allocations are allowed and actively used.
Question 1: Is Boost a suitable place for libraries targeting systems where exceptions, RTTI and memory allocation are banned?
I think, if a library provides an option to be usable in such environments, it is definitely welcome. If the library targets such environments *exclusively* then its usefulness in other, more widespread and less restricted domains would be rather limited.
Question 2: Is it a reasonable expectation of a ring buffer to not require allocations?
There doesn't need to be a single type of a ring buffer. Similarly to vector/static_vector/small_vector, there can be multiple ring buffer types that make different tradeoffs wrt. their storage and other properties. Specifically re. Boost.CircularBuffer, I see no problem that it performs dynamic memory allocations given its support for dynamic sizes and capacities. That is, circular_buffer provides a ring buffer with (reasonably) unlimited capacity, and it is good at that purpose. There may be other use cases, where a different set of tradeoffs are more suitable. For example, I've written a ring buffer adapter that operates on an array of fixed capacity (meaning that all elements of the array are constructed upon the ring buffer construction rather than on insertion), which was better suited for a given use case than Boost.CircularBuffer. Again, there's nothing wrong in having different ring buffer types that make different tradeoffs and fit different use cases. If your colleague's use case is sufficiently different from that of Boost.CircularBuffer, there's nothing wrong with implementing his own version. If such a use case is widespread enough, it would make sense to extract (or reimplement) that version as a Boost library, so that it is useful to many.
Question 4: Maybe there would be a value, at least for some Boost libraries, to provide a single-header, header-only variant that works under some assumptions, like C++11 compiler?
If this means duplicating code and potential ODR issues, I would be opposed.
My colleagues use case is that, because removals from the buffer can occur asynchronously, when doing a pop_back() there is no way to be sure that the buffer is non-empty, so this would require a function that does the check and the pop_back at one go.
I'm not sure how this relates to the previous questions, but why the need for a function that does two things at once? Why not `if (!cb.empty()) cb.pop_back();`?
On Sat, Aug 10, 2024 at 1:42 PM Andrey Semashev via Boost
Boost.CircularBuffer
I use an embedded-friendly, non-allocating circular buffer in several of my implementations https://github.com/cppalliance/buffers/blob/aaa070cc9c3141429e264301ed533dfb... Upon reading this discussion I realize, perhaps it should be renamed to circular_span. Thanks
On 8/10/24 6:03 AM, Andrzej Krzemienski via Boost wrote:
I am interested to learn what others think about this. Ideally, I would like for Boost to be in a state where developers prefer to use it rather than writing their own popular components.
FWIW - When I gave a talk on Documentation, I used a ring buffer as an example. I was dissatisfied with boost circular buffer as I wanted one with only static allocation - suitable for embedded applications. Here is the talk: https://www.youtube.com/watch?v=YxmdCxX9dMk Robert Ramey.
Regards, &rzej;
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (4)
-
Andrey Semashev
-
Andrzej Krzemienski
-
Robert Ramey
-
Vinnie Falco