[review] The review of boost::container::hub starts! April 16 - April 26
Dear users and members of Boost, I'm proud to announce that the formal review of Joaquín M López Muñoz's boost::container::hub container, for inclusion in the Boost.Container library, starts today ( in my timezone ;-) ), April 16, and runs through April 26. It may be downloaded from https://github.com/joaquintides/hub and the documentation may be found here: https://github.com/joaquintides/hub/blob/develop/README.md Anyone is welcome to post a review and/or take part in subsequent discussions (see below for review guidelines). Introduction ------------ boost::container::hub is a sequence container with O(1) insertion and erasure and element stability: pointers/iterators to an element remain valid as long as the element is not erased. boost::container::hub is very similar but not entirely equivalent to C++26 std::hive (hence the different naming, consult the section "Comparison with std::hive", for details): https://github.com/joaquintides/hub/blob/develop/README.md#comparison-with-s... boost::container::hub has excellent performance, you can see some benchmarks here: https://github.com/joaquintides/hub/blob/develop/README.md#performance Basic example: #include <boost/container/hub.hpp> #include <cassert> int main() { boost::container::hub<int> h; // Insert some elements and keep an iterator to one of them for(int i = 0; i < 100; ++i) h.insert(i); auto it = h.insert(100); for(int i = 101; i < 200; ++i) h.insert(i); // Erase some of the elements erase_if(h, [](int x) { return x % 2 != 0;}); assert(*it = 100); // iterator still valid // Insert many more elements for(int i = 200; i < 10000; ++i) h.insert(i); assert(*it = 100); // iterator still valid } An important tradeoff when using boost::container::hub is the fact that the user can't control the position where a new element will be inserted: boost::container::hub reuses the memory addresses of previously erased elements to maximize performance and keep the data structure as compact as possible. The primary use case for boost::container::hub is in high-performance scenarios where elements are created and destroyed frequently, insertion order is not relevant and pointer/iterator stability is required: game entity systems, particle simulation, HFT... For more information, see the Tutorial section: https://github.com/joaquintides/hub/blob/develop/README.md#tutorial Review guidelines ----------------- Please provide in your review whatever information you think is valuable to understand your final choice of ACCEPT or REJECT including Fit as a Boost component. Please be explicit about your decision. Some other questions you might want to consider answering: - What is your evaluation of the design? - What is your evaluation of the implementation? - What is your evaluation of the documentation? (Note that, if accepted, final documentation will be included in Boost.Container docs, so please review the content, not the format) - What is your evaluation of its potential usefulness? - Did you try to use the container? With which compiler(s)? Did you have any problems? - How much effort did you put into your evaluation? A glance? A quick reading? In-depth study? - Are you knowledgeable about the problem domain? More information about the Boost Formal Review Process can be found here: http://www.boost.org/community/reviews.html Kind regards, Ion Gaztañaga, Review manager
Hello, I hope everyone is doing well. My review of `hub` will cover: Documentation, Design and the implementation of the hub container. ## DESIGN: - The presence of pre-conditions, a single container, and free functions is a big plus in the design, this lets the developer use the library without too much hurdle on the development side. - Speaking of development the presence of a NATVIS file is also a big plus in terms of debugging for Visual Studio. (IIRC a lot of users of Boost develop on Windows) - There is a clear cause and effect in the design as well, easy to reason about and solve problems upon. - The usage of known requirements like CopyInsertable in the design is also a big plus to avoid technical debt. ## DOCUMENTATION: - The format of the documentation consists of the function signature, preconditons, snyposis, and effects. It is another plus for users wanting to get started using the library. - The addition of equivalent examples is also a plus for the library, knowing what else can be done is as important as the solution. ## IMPLEMENTATION: - It has clean free functions like erase_if and is easy to read, which fits what the library `container` library should do. ```cpp template<typename T, typename Allocator, typename Predicate> typename hub<T, Allocator>::size_type erase_if(hub<T, Allocator>& x, Predicate pred) { using hub_container = hub<T, Allocator>; using size_type = typename hub_container::size_type; using block = typename hub_container::block; auto s = x.size_; for(auto pbb = x.blist.next; pbb != x.blist.header(); ) { auto pb = x.static_cast_block_pointer(pbb); pbb = pb->next; BOOST_CONTAINER_HUB_PREFETCH_BLOCK(pbb, block); auto mask = pb->mask; do { auto n = hub_detail::unchecked_countr_zero(mask); if(pred(pb->data()[n])) x.erase_impl(pb, n); mask &= mask - 1; } while(mask); } return (size_type)(s - x.size_); } ``` Fig 1: erase_if implementation (https://github.com/joaquintides/hub/blob/develop/include/boost/container/hub...) - The design pattern is respected per design guidelines and there is a separation of concerns. - There is a clear consideration for MSVC and other compilers, which is a big plus for adoption. ## EFFORT: I went and looked at the documentation, implementation and overall structure of the repository. ## COMMENTS: - The transparency about `BOOST_CONTAINER_HUB_PREFETCH` is really valuable, it's wroth finding more cases like this in the future and documenting them. ## CHOICE: I vote to ACCEPT `hub` to be merged into `container`. It clearly has a lot of upsides (including HFT, per the author's examples)
El 18/04/2026 a las 13:13, Amlal El Mahrouss via Boost escribió:
Hello, I hope everyone is doing well.
My review of `hub` will cover: Documentation, Design and the implementation of the hub container.
## DESIGN:
- The presence of pre-conditions, a single container, and free functions is a big plus in the design, this lets the developer use the library without too much hurdle on the development side. - Speaking of development the presence of a NATVIS file is also a big plus in terms of debugging for Visual Studio. (IIRC a lot of users of Boost develop on Windows) - There is a clear cause and effect in the design as well, easy to reason about and solve problems upon. - The usage of known requirements like CopyInsertable in the design is also a big plus to avoid technical debt.
## DOCUMENTATION:
- The format of the documentation consists of the function signature, preconditons, snyposis, and effects. It is another plus for users wanting to get started using the library. - The addition of equivalent examples is also a plus for the library, knowing what else can be done is as important as the solution.
## IMPLEMENTATION:
- It has clean free functions like erase_if and is easy to read, which fits what the library `container` library should do.
```cpp template<typename T, typename Allocator, typename Predicate> typename hub<T, Allocator>::size_type erase_if(hub<T, Allocator>& x, Predicate pred) { using hub_container = hub<T, Allocator>; using size_type = typename hub_container::size_type; using block = typename hub_container::block;
auto s = x.size_; for(auto pbb = x.blist.next; pbb != x.blist.header(); ) { auto pb = x.static_cast_block_pointer(pbb); pbb = pb->next; BOOST_CONTAINER_HUB_PREFETCH_BLOCK(pbb, block); auto mask = pb->mask; do { auto n = hub_detail::unchecked_countr_zero(mask); if(pred(pb->data()[n])) x.erase_impl(pb, n); mask &= mask - 1; } while(mask); } return (size_type)(s - x.size_); } ``` Fig 1: erase_if implementation (https://github.com/joaquintides/hub/blob/develop/include/boost/container/hub...)
- The design pattern is respected per design guidelines and there is a separation of concerns. - There is a clear consideration for MSVC and other compilers, which is a big plus for adoption.
## EFFORT:
I went and looked at the documentation, implementation and overall structure of the repository.
## COMMENTS:
- The transparency about `BOOST_CONTAINER_HUB_PREFETCH` is really valuable, it's wroth finding more cases like this in the future and documenting them.
## CHOICE:
I vote to ACCEPT `hub` to be merged into `container`. It clearly has a lot of upsides (including HFT, per the author's examples)
Hi Amlal, Thanks for your review! Best, Joaquín M López Muñoz
On Wed, Apr 15, 2026 at 3:48 PM Ion Gaztañaga via Boost < boost@lists.boost.org> wrote:
Dear users and members of Boost,
I'm proud to announce that the formal review of Joaquín M López Muñoz's boost::container::hub container, for inclusion in the Boost.Container library, starts today ( in my timezone ;-) ), April 16, and runs through April 26.
I'm not sure if we've already had this discussion or not but I'd actually suggest considering putting Hub either in its own library or one that's unconditionally header-only. My concern here is that if we put Hub into Container, people looking for Hub and using CMake will wind up using Boost::container which I fear transitively carries a binary dependency. I would suppose users can instead depend on the header-only meta-target (Boost::headers) but I'd prefer to avoid a situation where users must do that. - Christian
On 19 Apr 2026 22:34, Christian Mazakas via Boost wrote:
On Wed, Apr 15, 2026 at 3:48 PM Ion Gaztañaga via Boost < boost@lists.boost.org> wrote:
Dear users and members of Boost,
I'm proud to announce that the formal review of Joaquín M López Muñoz's boost::container::hub container, for inclusion in the Boost.Container library, starts today ( in my timezone ;-) ), April 16, and runs through April 26.
I'm not sure if we've already had this discussion or not but I'd actually suggest considering putting Hub either in its own library or one that's unconditionally header-only.
My concern here is that if we put Hub into Container, people looking for Hub and using CMake will wind up using Boost::container which I fear transitively carries a binary dependency.
I would suppose users can instead depend on the header-only meta-target (Boost::headers) but I'd prefer to avoid a situation where users must do that. This is solved by adding a new target to Boost.Container CMakeLists.txt, e.g. `Boost::container_header_only` for the header-only bits. I would argue, this would be useful regardless of `hub` being part of Boost.Container. Some other libraries already provide more lightweight targets where a full dependency would be too expensive for users.
On 19 Apr 2026 23:36, Andrey Semashev wrote:
On 19 Apr 2026 22:34, Christian Mazakas via Boost wrote:
On Wed, Apr 15, 2026 at 3:48 PM Ion Gaztañaga via Boost < boost@lists.boost.org> wrote:
Dear users and members of Boost,
I'm proud to announce that the formal review of Joaquín M López Muñoz's boost::container::hub container, for inclusion in the Boost.Container library, starts today ( in my timezone ;-) ), April 16, and runs through April 26.
I'm not sure if we've already had this discussion or not but I'd actually suggest considering putting Hub either in its own library or one that's unconditionally header-only.
My concern here is that if we put Hub into Container, people looking for Hub and using CMake will wind up using Boost::container which I fear transitively carries a binary dependency.
I would suppose users can instead depend on the header-only meta-target (Boost::headers) but I'd prefer to avoid a situation where users must do that. This is solved by adding a new target to Boost.Container CMakeLists.txt, e.g. `Boost::container_header_only` for the header-only bits. I would argue, this would be useful regardless of `hub` being part of Boost.Container. Some other libraries already provide more lightweight targets where a full dependency would be too expensive for users.
BTW, the same would be useful in b2, too.
On Sun, Apr 19, 2026, at 10:36 PM, Andrey Semashev via Boost wrote:
This is solved by adding a new target to Boost.Container CMakeLists.txt, e.g. `Boost::container_header_only` for the header-only bits. I would argue, this would be useful regardless of `hub` being part of Boost.Container. Some other libraries already provide more lightweight targets where a full dependency would be too expensive for users.
I always solve this by just depending on Boost::headers. Is there something I'm missing? Is there some added benefit of having "XXXX_header_only" targets per library as well? Seth
On 20 Apr 2026 00:08, Seth via Boost wrote:
On Sun, Apr 19, 2026, at 10:36 PM, Andrey Semashev via Boost wrote:
This is solved by adding a new target to Boost.Container CMakeLists.txt, e.g. `Boost::container_header_only` for the header-only bits. I would argue, this would be useful regardless of `hub` being part of Boost.Container. Some other libraries already provide more lightweight targets where a full dependency would be too expensive for users.
I always solve this by just depending on Boost::headers. Is there something I'm missing? Is there some added benefit of having "XXXX_header_only" targets per library as well?
The long-term plan is to not have Boost::headers target. Boost libraries already should have dependencies on other libraries' targets like Boost::container, including header-only libraries, in order to be compatible with modular design. I think, users should do the same already, although I'm not sure if this was communicated to the public. Therefore, it is beneficial for libraries to provide targets with reduced dependencies, where it makes sense. Some Boost libraries already do that.
On Sun, Apr 19, 2026 at 1:38 PM Andrey Semashev via Boost < boost@lists.boost.org> wrote:
This is solved by adding a new target to Boost.Container CMakeLists.txt, e.g. `Boost::container_header_only` for the header-only bits. I would argue, this would be useful regardless of `hub` being part of Boost.Container. Some other libraries already provide more lightweight targets where a full dependency would be too expensive for users.
If Ion is okay with this, then I have no problems at all with Hub being in Container. Otherwise, what else is there to really say? Joaquin is a long-time veteran Boost author contributing Yet Another Container. I can safely vote that we strongly Accept this library for inclusion into Container. I think certain things will, by their nature, maybe be surprising to users unfamiliar with the container like insertion order not being preserved as old slots are reused. But I gave the docs a cursory once-over and I couldn't find any glaring issues. Interestingly, this makes me wonder if maybe we could use a proper slotmap implementation as well, i.e. instead of a linked list of fixed blocks, a single contiguous block that uses a freelist internally. Obviously this design would invalidate iterators on resize but if a user simply stored indices into the slotmap, it could be made to work pretty well, I think. - Christian
El 21/04/2026 a las 0:32, Christian Mazakas via Boost escribió:
On Sun, Apr 19, 2026 at 1:38 PM Andrey Semashev via Boost < boost@lists.boost.org> wrote:
This is solved by adding a new target to Boost.Container CMakeLists.txt, e.g. `Boost::container_header_only` for the header-only bits. I would argue, this would be useful regardless of `hub` being part of Boost.Container. Some other libraries already provide more lightweight targets where a full dependency would be too expensive for users.
If Ion is okay with this, then I have no problems at all with Hub being in Container.
Otherwise, what else is there to really say? Joaquin is a long-time veteran Boost author contributing Yet Another Container.
I can safely vote that we strongly Accept this library for inclusion into Container.
I think certain things will, by their nature, maybe be surprising to users unfamiliar with the container like insertion order not being preserved as old slots are reused.
But I gave the docs a cursory once-over and I couldn't find any glaring issues.
Interestingly, this makes me wonder if maybe we could use a proper slotmap implementation as well, i.e. instead of a linked list of fixed blocks, a single contiguous block that uses a freelist internally. Obviously this design would invalidate iterators on resize but if a user simply stored indices into the slotmap, it could be made to work pretty well, I think.
Thanks Christian for your review! It'd be fairly straightforward (I think) to implement a slot map using the same underlying structure as boost::container::hub: https://raw.githubusercontent.com/joaquintides/hub/develop/doc/img/data_stru... except that elements all lie in a contiguous array. Writing down in my todo list to prototype that and benchmark against boost::container::hub; from a purely theoretical analysis, slotmap should lose on insertions (because of reallocation) and win on iteration (because of cache locality). On a related note, some weeks ago an author came on reddit with an interesting design: https://www.reddit.com/r/cpp/comments/1sbro26/a_fast_contiguous_windows_slot... The interesting part is that memory chunks are allocated _contiguously_ by reserving the maximum possible size in memory via Win32 VirtualAlloc --downside, among others, is the user has to specify the maximum possible size in advance. This reserve/commit scheme can't be served by C++ allocator API, but maybe a reserving_allocator concept or something could be designed to abstract the pattern. I'll play with this when I have the time. Joaquín M López Muñoz
No dia 19 de abr. de 2026, às 21:36, Christian Mazakas via Boost <boost@lists.boost.org> escreveu:
On Wed, Apr 15, 2026 at 3:48 PM Ion Gaztañaga via Boost < boost@lists.boost.org> wrote:
[…]
I'm not sure if we've already had this discussion or not but I'd actually suggest considering putting Hub either in its own library or one that's unconditionally header-only.
My concern here is that if we put Hub into Container, people looking for Hub and using CMake will wind up using Boost::container which I fear transitively carries a binary dependency.
There was some discussion on this before the review period. I am happy with whatever decision the review manager takes after the community feedback, standalone or part of Container (if the library is accepted). It makes sense that this be part of Boost.Container as it’s thematically related, but standalone has its pros too. I take the opportunity to invite you to submit a full review. Joaquín M López Muñoz
El 19/04/2026 a las 21:34, Christian Mazakas via Boost escribió:
On Wed, Apr 15, 2026 at 3:48 PM Ion Gaztañaga via Boost < boost@lists.boost.org> wrote:
Dear users and members of Boost,
I'm proud to announce that the formal review of Joaquín M López Muñoz's boost::container::hub container, for inclusion in the Boost.Container library, starts today ( in my timezone ;-) ), April 16, and runs through April 26.
I'm not sure if we've already had this discussion or not but I'd actually suggest considering putting Hub either in its own library or one that's unconditionally header-only.
My concern here is that if we put Hub into Container, people looking for Hub and using CMake will wind up using Boost::container which I fear transitively carries a binary dependency.
I was certainly not an optimal decision to make Boost.Container compiled for some functions. I don't think those functions are very popular, and maybe Boost.Container should contain in the future the code that the user should put in its own DLL (say, globals for PMR, allocators, etc.). In the latest CMakeLists.txt there is a BOOST_CONTAINER_HEADER_ONLY option to avoid the binary dependency: https://github.com/boostorg/container/blob/boost-1.90.0/CMakeLists.txt Best, Ion
Hi Ion, Joaquin, Here is my review of the Container.Hub documentation, with my 2c thrown in on the design. The documentation is certainly usable in the state that it is in, my comments are aimed more at increasing usage of the library should it be included in Boost. The use for the library seems narrow - it addresses the perennial dilemma of a computer language trying to extricate the developer from needing any knowledge of the underlying hardware - fighting against the performance improvements which can be gained by taking advantage of that underlying hardware. The Standard Hive seems to lean towards the former, leaving an opportunity for the other approach which Hub addresses. It is a tougher sell to lead developers away from the Standard, unless necessary. Does seem like strong use cases and example code taken from those use cases are needed. 1. Not crazy about the first sentence (too much punctuation): "boost::container::hub is a sequence container with O(1) insertion and erasure and element stability: pointers/iterators to an element remain valid as long as the element is not erased." Better to read more fluidly (avoid pointers/iterators as it's awkward to read smoothly) and with a more compelling argument than "O(1)" - not sure a storage system would have a much higher complexity than O(1)? Perhaps something like: *Boost.Container.Hub is a sequence container with accelerated insertion and erasure, and solid element stability. Pointers and iterators to an element remain valid and unchanged until the element is explicitly deleted.* 2. Good that use cases are mentioned "game entity systems, particle simulation and HFT come to mind." I assume HFT means "high-frequency transfers" or close. However, "come to mind" is too conversational. This is formal documentation and use cases should be researched more deeply. Game developers are certainly used to coding for hardware efficiency. Agreed particle simulation (molecular modelling) is a second compelling use case - perhaps Conway's Game of Life - Wikipedia <https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life> would make a good tutorial example? 3. Might be an idea to explain why "64" provides the performance - is it word size, simply 8 bytes, or other hardware feature.? I assume it is word size, though the question does arise as to why this cannot be changed - say to 32 or 128 or 1024? I assume the library guarantees word alignment. 4. Good that there are code examples throughout, though I much prefer English comments to pseudo code as comments, for example: h.reserve(1000); // capacity() == 1024 (rounded up to 64) Better to say: // The capacity is rounded up to the next 64 block size, so 1024 in this case 5. On a similar note, using pseudo code like the following - I am not even sure what the comment is trying to say: // won't allocate (500 <= 1024) // ~trim_capacity(0), capacity() == 512 Better to explain in natural language. 6. In the Performance section the sample sizes (16,64,80) do seem to favor a block size of 64, rather than an arbitrary size. The performance improvements do seem significant. 7. Don't use brackets in text unless necessary, they are a known barrier to readability. For example, they are unnecessary in comments such as: (Note: Potentially faster than the sample code due to internal optimizations.) 8. The Reference section could do with code examples, ideally including the errors or exceptions that can be thrown, and best practices in handling them, or perhaps links to example code in the Tutorial section of the doc where the code constructs are used. Thanks for your great efforts again Joaquin - and hope my comments are useful! I am the Technical Writer for the Cpp Alliance. - best Peter Turcan On Mon, Apr 20, 2026 at 2:34 AM Ion Gaztañaga via Boost < boost@lists.boost.org> wrote:
El 19/04/2026 a las 21:34, Christian Mazakas via Boost escribió:
On Wed, Apr 15, 2026 at 3:48 PM Ion Gaztañaga via Boost < boost@lists.boost.org> wrote:
Dear users and members of Boost,
I'm proud to announce that the formal review of Joaquín M López Muñoz's boost::container::hub container, for inclusion in the Boost.Container library, starts today ( in my timezone ;-) ), April 16, and runs through April 26.
I'm not sure if we've already had this discussion or not but I'd actually suggest considering putting Hub either in its own library or one that's unconditionally header-only.
My concern here is that if we put Hub into Container, people looking for Hub and using CMake will wind up using Boost::container which I fear transitively carries a binary dependency.
I was certainly not an optimal decision to make Boost.Container compiled for some functions. I don't think those functions are very popular, and maybe Boost.Container should contain in the future the code that the user should put in its own DLL (say, globals for PMR, allocators, etc.).
In the latest CMakeLists.txt there is a BOOST_CONTAINER_HEADER_ONLY option to avoid the binary dependency:
https://github.com/boostorg/container/blob/boost-1.90.0/CMakeLists.txt
Best,
Ion _______________________________________________ Boost mailing list -- boost@lists.boost.org To unsubscribe send an email to boost-leave@lists.boost.org https://lists.boost.org/mailman3/lists/boost.lists.boost.org/ Archived at: https://lists.boost.org/archives/list/boost@lists.boost.org/message/5SPO2LOE...
El 20/04/2026 a las 23:47, Peter Turcan via Boost escribió:
Hi Ion, Joaquin,
Here is my review of the Container.Hub documentation, with my 2c thrown in on the design. The documentation is certainly usable in the state that it is in, my comments are aimed more at increasing usage of the library should it be included in Boost.
Thanks for your review Peter, Ion
El 20/04/2026 a las 23:47, Peter Turcan via Boost escribió:
Hi Ion, Joaquin,
Here is my review of the Container.Hub documentation, with my 2c thrown in on the design. The documentation is certainly usable in the state that it is in, my comments are aimed more at increasing usage of the library should it be included in Boost.
Hi Peter, thanks for your review!
The use for the library seems narrow - it addresses the perennial dilemma of a computer language trying to extricate the developer from needing any knowledge of the underlying hardware - fighting against the performance improvements which can be gained by taking advantage of that underlying hardware. The Standard Hive seems to lean towards the former, leaving an opportunity for the other approach which Hub addresses. It is a tougher sell to lead developers away from the Standard, unless necessary. Does seem like strong use cases and example code taken from those use cases are needed.
With respect to this, boost::container::hub serves pretty much the same use cases std::hive does, whatever these are. The selling point for the former is that it's generally faster.
1. Not crazy about the first sentence (too much punctuation): "boost::container::hub is a sequence container with O(1) insertion and erasure and element stability: pointers/iterators to an element remain valid as long as the element is not erased."
Better to read more fluidly (avoid pointers/iterators as it's awkward to read smoothly) and with a more compelling argument than "O(1)" - not sure a storage system would have a much higher complexity than O(1)? Perhaps something like:
*Boost.Container.Hub is a sequence container with accelerated insertion and erasure, and solid element stability. Pointers and iterators to an element remain valid and unchanged until the element is explicitly deleted.*
I'll see to change the intro statement along the lines you suggest. As for O(1), this is technical parlance for "executes in constant time regardless of the size of the container". It's quite common terminology in the standard, maybe I should reassess if the average Boost user understands it without problem too.
2. Good that use cases are mentioned "game entity systems, particle simulation and HFT come to mind." I assume HFT means "high-frequency transfers" or close. However, "come to mind" is too conversational. This is formal documentation and use cases should be researched more deeply. Noted. HFT stands for "high-frequency trading". Again, maybe it's an acronym the average reader may not get. Game developers are certainly used to coding for hardware efficiency. Agreed particle simulation (molecular modelling) is a second compelling use case - perhaps Conway's Game of Life - Wikipedia <https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life> would make a good tutorial example? Probably not: Game of Life lends itself to array-like structures for representation. Thinking out loud, something like a deque of deques :-) 3. Might be an idea to explain why "64" provides the performance - is it word size, simply 8 bytes, or other hardware feature.? I assume it is word size, though the question does arise as to why this cannot be changed - say to 32 or 128 or 1024? I assume the library guarantees word alignment. Good point. It's 64 because CPUs have instructions to very quickly identify bits set to one in a 64-bit word: BSF/TXCNT in X86, CTZ in ARM. 128 bits would be even better performance wise, but we don't have yet single CPU instructions for that. I can add a short remark on this. 4. Good that there are code examples throughout, though I much prefer English comments to pseudo code as comments, for example: h.reserve(1000); // capacity() == 1024 (rounded up to 64) Better to say: // The capacity is rounded up to the next 64 block size, so 1024 in this case
5. On a similar note, using pseudo code like the following - I am not even sure what the comment is trying to say: // won't allocate (500 <= 1024) // ~trim_capacity(0), capacity() == 512
Better to explain in natural language. Noted. 6. In the Performance section the sample sizes (16,64,80) do seem to favor a block size of 64, rather than an arbitrary size. The performance improvements do seem significant.
Umm, this is not the block size (which stays constant at 64 element), but the size in bytes of the element itself. In general (though with exceptions), a larger element makes boost::container::hub more performant relative to plf::hive, basically because cache locality matters less.
7. Don't use brackets in text unless necessary, they are a known barrier to readability. For example, they are unnecessary in comments such as: (Note: Potentially faster than the sample code due to internal optimizations.) You mean parentheses? I'm mimicking here the style of the standard, see for instance
https://eel.is/c++draft/container.requirements#pre-3
8. The Reference section could do with code examples, ideally including the errors or exceptions that can be thrown, and best practices in handling them, or perhaps links to example code in the Tutorial section of the doc where the code constructs are used. I'd rather relegate examples to the code cause we have a tradition, in the standard as well as in most of Boost, to keep reference sections factual, precise, and, admittedly, somewhat dry :-) FWIW, the reference for this particular container is quite unsurprising as the API is the same, with minor variations, as that of countless other STL-like containers. Thanks for your great efforts again Joaquin - and hope my comments are useful!
They are! Thanks again for your review. Joaquín M López Muñoz
Hello All, Below is my review of boost::container::hub: - What is your evaluation of the design? It's clearly well thought out. The deviations from std::hive are well rationalized and clearly articulated. The performance delta makes it clear the right changes were found and implemented. - What is your evaluation of the implementation? Generally the implementation is pretty clean and straightforward. I don't have any specific recommendations to offer on this front. No warnings are set in the testing by default. At a minimum I recommend checking -Wall and -Werror, with -Wextra plus a handful of additional being ideal. The one that's most obviously needing a fix after reading the code is -Wold-style-cast. I appreciate that the library ships with pretty printers and information on how to use them. I find it odd that GCC 4.8 and Clang 3.5 are supported but the minimum MSVC version is 14.3. Surely 14.0 can be supported if such ancient versions of other compilers are? - What is your evaluation of the documentation? (Note that, if accepted, final documentation will be included in Boost.Container docs, so please review the content, not the format) In general I think the docs answers the questions as to why use this container, and why he engineered it as such. My biggest complaint is with the performance comparisons; there must be a better way to display the information than densely packed ASCII tables. I think a good starting point is likely to talk to Peter Turcan on a better way to display this information. I expect Peter has some good opinions on the matter. - What is your evaluation of its potential usefulness? Hub has articulated use cases, and std::hive has been accepted into C++26. There's clearly demand and applications for such a container. - Did you try to use the container? With which compiler(s)? Did you have any problems? I ran the tests an ARM Mac using Clang version 22.1.3 and GCC 15.2.0. 4 of the 5 tests failed which have been reported upstream along with PRs. The fix is a one-liner so I am not deeply concerned. I did not try running with enhanced warnings like I have recommended above. - How much effort did you put into your evaluation? A glance? A quick reading? In-depth study? A few hours to go through the implementation and doc page. - Are you knowledgeable about the problem domain? I do not claim to be an expert in the design of containers. In conclusion, I vote to ACCEPT. I think this is a useful, and well engineered container. Joaquín has an extensive history in the Boost ecosystem so I have high degree of confidence that hub will continue to be improved and maintained. I think the quality of the author is nearly as important as the quality of the library. Disclaimer: I am a staff engineer at C++Alliance Matt
El 21/04/2026 a las 17:13, Matt Borland via Boost escribió:
Hello All,
Below is my review of boost::container::hub: Hi Matt, thanks for your review. [...]
- What is your evaluation of the implementation?
Generally the implementation is pretty clean and straightforward. I don't have any specific recommendations to offer on this front.
No warnings are set in the testing by default. At a minimum I recommend checking -Wall and -Werror, with -Wextra plus a handful of additional being ideal. The one that's most obviously needing a fix after reading the code is -Wold-style-cast. Noted, will do. I appreciate that the library ships with pretty printers and information on how to use them.
I find it odd that GCC 4.8 and Clang 3.5 are supported but the minimum MSVC version is 14.3. Surely 14.0 can be supported if such ancient versions of other compilers are? Chances are MSVC 14.0 is supported, but Boost.CI, which I rely on, doesn't seem to exercise that compiler? - What is your evaluation of the documentation? (Note that, if accepted, final documentation will be included in Boost.Container docs, so please review the content, not the format)
In general I think the docs answers the questions as to why use this container, and why he engineered it as such. My biggest complaint is with the performance comparisons; there must be a better way to display the information than densely packed ASCII tables. I think a good starting point is likely to talk to Peter Turcan on a better way to display this information. I expect Peter has some good opinions on the matter. Ideas here most welcome. The main problem I have wrapping my head around this is that the info displayed runs across 5 different dimensions :-) (compiler, sizeof(element), test case, container size, erase rate). - What is your evaluation of its potential usefulness?
Hub has articulated use cases, and std::hive has been accepted into C++26. There's clearly demand and applications for such a container.
- Did you try to use the container? With which compiler(s)? Did you have any problems?
I ran the tests an ARM Mac using Clang version 22.1.3 and GCC 15.2.0. 4 of the 5 tests failed which have been reported upstream along with PRs. The fix is a one-liner so I am not deeply concerned. I did not try running with enhanced warnings like I have recommended above.
Thanks for that, PRs noted, I'm keeping them on hold till the review ends so that the develop branch is not a moving target for reviewers. GCC 15.2 and Clang 22 are not being used by Boost.CI yet, in case Alexander Grund / Sam Darwin are reading this.
- How much effort did you put into your evaluation? A glance? A quick reading? In-depth study?
A few hours to go through the implementation and doc page.
- Are you knowledgeable about the problem domain?
I do not claim to be an expert in the design of containers.
In conclusion, I vote to ACCEPT. I think this is a useful, and well engineered container. Joaquín has an extensive history in the Boost ecosystem so I have high degree of confidence that hub will continue to be improved and maintained. I think the quality of the author is nearly as important as the quality of the library.
Thanks again for your time and excellent feedback, Joaquín M López Muñoz
Am 21.04.26 um 17:52 schrieb Joaquin M López Muñoz via Boost:
Chances are MSVC 14.0 is supported, but Boost.CI, which I rely on, doesn't seem to exercise that compiler? It's not on the GitHub runners as that old version isn't available there anymore. However you can use Appveyor (templates also in Boost.CI) for that.
- What is your evaluation of its potential usefulness?
Hub has articulated use cases, and std::hive has been accepted into C++26. There's clearly demand and applications for such a container.
- Did you try to use the container? With which compiler(s)? Did you have any problems?
I ran the tests an ARM Mac using Clang version 22.1.3 and GCC 15.2.0. 4 of the 5 tests failed which have been reported upstream along with PRs. The fix is a one-liner so I am not deeply concerned. I did not try running with enhanced warnings like I have recommended above.
Thanks for that, PRs noted, I'm keeping them on hold till the review ends so that the develop branch is not a moving target for reviewers.
GCC 15.2 and Clang 22 are not being used by Boost.CI yet, in case Alexander Grund / Sam Darwin are reading this. Good point. There wasn't even Clang 21 there.
Now upcoming with https://github.com/boostorg/boost-ci/pull/327 - Alex
Dear Boost Community, This is my review for boost::container::hub. Thank you, Joaquin, for authoring such a high-quality proposal. Thank you, Ion, for managing the review. I suggest: ACCEPT. The component is clearly delimited, and its equivalences and divergences with std::hive are clearly explained. I am impressed it's C++11 compatible, meaning anyone wanting to use std::hive but stuck with C++ < 26 will be very happy to find it. As usual, Joaquin developed extremely detailed benchmarks. The documentation is very good, although some formatting may need revisiting (unless Markdown is not the final destination format, in that case, please discard my comment. Edit: you will discard my comment :p ). Given history, I trust Joaquin with the long-term management of the code. - What is your evaluation of the design? Clearly reflects the std::hive design and documents any deviations from it. - What is your evaluation of the implementation? Although I scrolled through the code, I am not knowledgeable enough about the domain to formulate relevant criticisms. But the code is clearly written, properly structured, and well-formatted (although the two-line lambdas looked weird to me aha). I saw a pair of comments but I wonder if they will be enough for future maintainers to understand the current implementation design. Although it's relatively short (1,880 lines), it may be easy to jump in if necessary. - What is your evaluation of the documentation? (Note that, if accepted, final documentation will be included in Boost.Container docs, so please review the content, not the format) Oops. I am such a bad student for not reading through the entire exercise before diving in. I will leave my formatting remarks anyway. The documentation is excellent, I mention a few typos later in my review. - What is your evaluation of its potential usefulness? This is obviously very useful. - Did you try to use the container? With which compiler(s)? Did you have any problems? I compiled a fabricated example with Apple Clang. No issue. - How much effort did you put into your evaluation? A glance? A quick reading? In-depth study? I spent ~5 hours on this evaluation. The documentation review was in-depth, but the code review was more of a glance. - Are you knowledgeable about the problem domain? Not really, but having some knowledge of entity simulation, boost::hub may be very useful for my future explorations. Here are some random notes: - I like the example first documentation. It makes it immediately clear what the intent/API is. - Good explanation against std::list and its tradeoffs. - this line sounded weirdly complicated to me, i think it means that adding elements does not reallocate existing elements : > Pointers and iterators to an element remain valid as long as the element is not erased. hub will not reallocate elements as it grows in size. - the trim_capacity example is not as clear as it could be; it deserves more explanation to be crystal clear. - in the Motivation for a novel data structure: it introduces the design of a competitor, then presents the new design. It is not immediately clear what the tradeoffs are or if boost:hub design is better and why. It's like a proper section comparing competitors/current implementation is missing. - when comparing implementations, I tend to prefer comparative tables rather than paragraphs. - ascii tables are probably generated from standard output, so maybe it would not be too hard to automatically format them as markdown tables instead ? They would render in github, but I'm not sure about Boost.Container (edit: forget this formatting remark) - maybe use horizontal lines in the reference to distinguish each function block more clearly? (edit: forget this formatting remark) - the get_iterator section will make little sense for people who did not encounter such situation and wonder "why would we ever want this?". Lowering the bar for new boost users, it could maybe 1. start with a real case usage, e.g. in a legacy physics simulation I need to store T* in a map pointing into the hub. So when it's time to remove a particle, I have only the pointer, not the iterator that is required by erase() 2. at this point the naive user will wonder why not simply have an overload erase(T*) so it may be time to mention that it mimicks std::hive for the reason that STL convention is to not hide non-constant time operation behind constant time looking interfaces (if i understood correctly, otherwise please ignore). 3. Given that iterators are heavier, if you need to store millions of particles it's nice to just have a "ugly" one liner that allows to cut memory usage by 2 4. in terms of encapsulation it may make sense to hide the hub iterator type using T* - typos: // erase the element (couldn't be done *drectly* with p) // transfer non-empty blocks from h2 to h1 (no *rellocation*)
Preconditions: *Tp* is DefaultInsertable into hub. missing new line: If the second overload is called, uses *alloc. Complexity: *Linear in x.size().
Affiliation: C++ Alliance Thanks again to all of you for this very interesting piece of work. Throughout the review I kept picturing my old Windows 95 defragmenter running in the back of my mind, it was quite a refreshing remembrance ;) Best wishes, Arnaud Becheler
El 24/04/2026 a las 15:47, Arnaud Becheler via Boost escribió:
Dear Boost Community,
This is my review for boost::container::hub.
Thank you, Joaquin, for authoring such a high-quality proposal. Thank you, Ion, for managing the review.
Thanks for your review!
I suggest: ACCEPT.
The component is clearly delimited, and its equivalences and divergences with std::hive are clearly explained. I am impressed it's C++11 compatible, meaning anyone wanting to use std::hive but stuck with C++ < 26 will be very happy to find it. As usual, Joaquin developed extremely detailed benchmarks. The documentation is very good, although some formatting may need revisiting (unless Markdown is not the final destination format, in that case, please discard my comment. Edit: you will discard my comment :p ). Yes, the case with documentation was somewhat unusual because the proposal is for integration in Boost.Container, so if the lib is accepted I don't expect the docs to survive in MD form. Given history, I trust Joaquin with the long-term management of the code.
- What is your evaluation of the design?
Clearly reflects the std::hive design and documents any deviations from it.
- What is your evaluation of the implementation?
Although I scrolled through the code, I am not knowledgeable enough about the domain to formulate relevant criticisms. But the code is clearly written, properly structured, and well-formatted (although the two-line lambdas looked weird to me aha). I saw a pair of comments but I wonder if they will be enough for future maintainers to understand the current implementation design. Although it's relatively short (1,880 lines), it may be easy to jump in if necessary.
- What is your evaluation of the documentation? (Note that, if accepted, final documentation will be included in Boost.Container docs, so please review the content, not the format)
Oops. I am such a bad student for not reading through the entire exercise before diving in. I will leave my formatting remarks anyway. The documentation is excellent, I mention a few typos later in my review.
- What is your evaluation of its potential usefulness?
This is obviously very useful.
- Did you try to use the container? With which compiler(s)? Did you have any problems?
I compiled a fabricated example with Apple Clang. No issue.
- How much effort did you put into your evaluation? A glance? A quick reading? In-depth study?
I spent ~5 hours on this evaluation. The documentation review was in-depth, but the code review was more of a glance.
- Are you knowledgeable about the problem domain?
Not really, but having some knowledge of entity simulation, boost::hub may be very useful for my future explorations.
Here are some random notes:
- I like the example first documentation. It makes it immediately clear what the intent/API is. - Good explanation against std::list and its tradeoffs. - this line sounded weirdly complicated to me, i think it means that adding elements does not reallocate existing elements : > Pointers and iterators to an element remain valid as long as the element is not erased. hub will not reallocate elements as it grows in size. Yes, your reading is correct, I'll try to rewrite the statement in a less convoluted way. - the trim_capacity example is not as clear as it could be; it deserves more explanation to be crystal clear. Noted, will try to improve that part. - in the Motivation for a novel data structure: it introduces the design of a competitor, then presents the new design. It is not immediately clear what the tradeoffs are or if boost:hub design is better and why. It's like a proper section comparing competitors/current implementation is missing. This is provided in https://github.com/joaquintides/hub#deviations-from-stdhive . Is this not sufficiently clear? - when comparing implementations, I tend to prefer comparative tables rather than paragraphs. - ascii tables are probably generated from standard output, so maybe it would not be too hard to automatically format them as markdown tables instead ? They would render in github, but I'm not sure about Boost.Container (edit: forget this formatting remark) - maybe use horizontal lines in the reference to distinguish each function block more clearly? (edit: forget this formatting remark) Others have also complained about tables being clumsy in their current format, will try to improve on that. The reason I didn't produce MD tables is they end up being too wide. - the get_iterator section will make little sense for people who did not encounter such situation and wonder "why would we ever want this?". Lowering the bar for new boost users, it could maybe 1. start with a real case usage, e.g. in a legacy physics simulation I need to store T* in a map pointing into the hub. So when it's time to remove a particle, I have only the pointer, not the iterator that is required by erase() 2. at this point the naive user will wonder why not simply have an overload erase(T*) so it may be time to mention that it mimicks std::hive for the reason that STL convention is to not hide non-constant time operation behind constant time looking interfaces (if i understood correctly, otherwise please ignore). 3. Given that iterators are heavier, if you need to store millions of particles it's nice to just have a "ugly" one liner that allows to cut memory usage by 2 4. in terms of encapsulation it may make sense to hide the hub iterator type using T* I have to confess I don't know myself what the potential usefulness of get_iterator is: the function is there because std::hive provides it. The rationale I give in the documentation is my bona fide speculation. - typos: // erase the element (couldn't be done *drectly* with p) // transfer non-empty blocks from h2 to h1 (no *rellocation*) Already fixed: https://github.com/joaquintides/hub/pull/10/changes
Preconditions: *Tp* is DefaultInsertable into hub. missing new line: If the second overload is called, uses *alloc. Complexity: *Linear in x.size(). Good catches, will fix. Affiliation: C++ Alliance
Thanks again to all of you for this very interesting piece of work. Throughout the review I kept picturing my old Windows 95 defragmenter running in the back of my mind, it was quite a refreshing remembrance ;)
Thank you for your time and feedback, Joaquín M López Muñoz
participants (11)
-
Alexander Grund -
Amlal El Mahrouss -
Andrey Semashev -
Arnaud Becheler -
Christian Mazakas -
Ion Gaztañaga -
Joaquin M López Muñoz -
Joaquín M López Muñoz -
Matt Borland -
Peter Turcan -
Seth