Memory 0.4: Polishing, Error handling, Storage, Traits, Documentation and more
It took a really long time - three months minus one day - but I have finally finished version 0.4 of foonathan/memory. The release contains a lot of changes and has more than doubled the number of commits.
Polishing
The interface is completely cleaned and I’ve got rid of the historically grown stuff. This required renaming or moving a lot of stuff, in particular:
raw_allocator_allocator
is nowstd_allocator
and moved to the new headerstd_allocator.hpp
raw_allocator_deallocator
andraw_allocator_deleter
are now simplyallocator_deleter
andallocator_deallocator
in new haderdeleter.hpp
raw_allocate_shared
andraw_allocate_delete
are likewise renamed intoallocate_shared
andallocate_delete
since they can also handle normal Allocators- the jungle of
allocator_type
,impl_allocator
orraw_allocator
typedefs are allallocator_type
, likewise for the getter, they’re allget_allocator()
now pool_allocator.hpp
andstack_allocator.hpp
are now named after their classes:memory_pool.hpp
andmemory_stack.hpp
respectively; the other pool headers have gotten thememory_
-prefix as wellallocator_adapter.hpp
is nowallocator_storage.hpp
for a similar reason as the other headers
I’ve also added some missing features I’ve noticed while writing the documentation.
They are many tiny things like the ability to specify a Mutex
at almost every class or alias or more default template arguments for other classes.
Error handling
Another thing polished are the error handling facilites.
Before they were a mess of various exceptions and calls to assert()
.
Now they use a well-defined interface and exception types.
But those facilites are customizable using handler functions. This allows a user-defined error handling even if exception support is disabled.
Allocator storage and traits improvement
The old allocator adapters are completely changed in the implementation.
A new allocator_storage
class template takes a StoragePolicy
and stores a RawAllocator
using it.
The adapters like allocator_adapter
or allocator_reference
are now simply aliases for the allocator_storage
template with a given policy.
Type-erased storage has been added as well, the tag type any_allocator
can be specified as RawAllocator
everywhere it is stored by an allocator_reference
,
like in std_allocator
, allocator_deleter
or allocator_reference
itself.
It activates a specialization of allocator_reference
that uses type-erasure to store a generic reference to any RawAllocator
.
The default template specialization of allocator_traits
has been overhauled, too.
It is now able to handle a broader range of types including all Allocator
classes!
The minimum required interface for it has been reduced to allocate_node
and deallocate_node
only,
the defaults in case of missing member functions are improved and there are better error messages if a type does not fulfill the criteria.
The addition of supporting the Allocator
concept allows passing an Allocator
anywhere a RawAllocator
is required.
Nodesize Debugger
The problem with pool allocators are that they require a node size.
For example, if you want to use a std::list
with a memory::memory_pool
you write:
memory::memory_pool<> pool(???, 4096);
memory::list<int, decltype(pool)> list(pool);
At the point of ???
belongs the size of each node in the pool.
But what should it be? 16? 32? It depends on the size of each node in the std::list
of int
.
But the internal node size is not accessible, so there is no easy and portable way to get its size.
So I’ve added the nodesize_dbg
.
This tool debugs the node sizes of STL containers by passing them a custom allocator that tracks the size of the type it is rebound too.
It automatically generates constants in the header container.hpp
that contains the appropriate node sizes, allowing us to write:
memory::memory_pool<> pool(memory::list_node_size<int>::value, 4096);
memory::list<int, decltype(pool)> list(pool);
Other things worth mentioning
- new documentation and tutorial hosted here, at http://memory.foonathan.net/
- all functionality except those that is an explicit wrapper around the standard library - like
smart_ptr.hpp
andcontainer.hpp
- can work on a freestanding implementation - the compatibility checks are outsourced to foonathan/compatibility
- bugfixes, bugfixes and bugfixes, most notably regarding alignment issues with activated fence memory
This blog post was written for my old blog design and ported over. If there are any issues, please let me know.