Boost logo

Boost :

From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2024-08-10 20:42:25


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();`?


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk