xo-alloc: streamlining DArena allocation: + construct_with() helper

This commit is contained in:
Roland Conybeare 2025-12-18 19:41:47 -05:00
commit 20abea5289
5 changed files with 53 additions and 42 deletions

View file

@ -100,6 +100,13 @@ namespace xo {
/** @ret iterator pointing to just after the last allocation in this arena **/
DArenaIterator end() const noexcept;
/** @ret header for first allocation in this arena **/
AllocHeader * begin_header() const noexcept;
/** @ret location of header for next (not yet performed!)
* allocation in this arena
**/
AllocHeader * end_header() const noexcept;
/** get header from allocated object address **/
header_type * obj2hdr(void * obj) noexcept;
@ -208,6 +215,22 @@ namespace xo {
///@}
};
/** construct a @tparam T instance from arguments @p args
* using memory obtained from arena @p ialloc
**/
template <typename T,
typename... Args>
static T *
construct_with(DArena & ialloc, Args&&... args)
{
std::byte * mem = ialloc.alloc(sizeof(T));
if (mem)
return new (mem) T(std::forward<Args>(args)...);
return nullptr;
}
} /*namespace mm*/
} /*namespace xo*/

View file

@ -290,6 +290,30 @@ namespace xo {
return DArenaIterator::end(this);
}
AllocHeader *
DArena::begin_header() const noexcept
{
if (config_.store_header_flag_ == false) {
this->capture_error(error::alloc_iterator_not_supported);
return nullptr;
}
return (AllocHeader *)lo_;
}
AllocHeader *
DArena::end_header() const noexcept
{
if (config_.store_header_flag_ == false) {
this->capture_error(error::alloc_iterator_not_supported);
return nullptr;
}
return (AllocHeader *)free_;
}
std::byte *
DArena::alloc(std::size_t req_z)
{

View file

@ -50,16 +50,7 @@ namespace xo {
{
assert(arena);
if (arena->config_.store_header_flag_ == false) {
arena->capture_error(error::alloc_iterator_not_supported);
return nullptr;
}
byte * begin_byte = arena->lo_;
AllocHeader * begin_hdr = (AllocHeader *)begin_byte;
return begin_hdr;
return arena->begin_header();
}
AllocHeader *
@ -67,16 +58,7 @@ namespace xo {
{
assert(arena);
if (arena->config_.store_header_flag_ == false) {
arena->capture_error(error::alloc_iterator_not_supported);
return nullptr;
}
byte * end_byte = arena->free_;
AllocHeader * end_hdr = (AllocHeader *)end_byte;
return end_hdr;
return arena->end_header();
}
AllocInfo

View file

@ -74,16 +74,8 @@ namespace xo {
IAllocator_DArena::alloc_range(const DArena & s,
DArena & ialloc) noexcept -> range_type
{
byte * begin_mem = IAllocator_DArena::alloc(ialloc,
sizeof(DArenaIterator));
byte * end_mem = IAllocator_DArena::alloc(ialloc,
sizeof(DArenaIterator));
assert(begin_mem);
assert(end_mem);
DArenaIterator * begin_ix = new (begin_mem) DArenaIterator(&s, DArenaIterator::begin_header(&s));
DArenaIterator * end_ix = new ( end_mem) DArenaIterator(&s, DArenaIterator::end_header(&s));
DArenaIterator * begin_ix = construct_with<DArenaIterator>(ialloc, &s, s.begin_header());
DArenaIterator * end_ix = construct_with<DArenaIterator>(ialloc, &s, s.end_header());
obj<AAllocIterator> begin_obj = with_facet<AAllocIterator>::mkobj(begin_ix);
obj<AAllocIterator> end_obj = with_facet<AAllocIterator>::mkobj( end_ix);

View file

@ -70,18 +70,8 @@ namespace xo {
IAllocator_DX1Collector::alloc_range(const DX1Collector & d,
DArena & ialloc) noexcept -> range_type
{
byte * begin_mem = IAllocator_DArena::alloc(ialloc,
sizeof(DX1CollectorIterator));
byte * end_mem = IAllocator_DArena::alloc(ialloc,
sizeof(DX1CollectorIterator));
assert(begin_mem);
assert(end_mem);
DX1CollectorIterator * begin_ix
= new (begin_mem) DX1CollectorIterator(d.begin());
DX1CollectorIterator * end_ix
= new ( end_mem) DX1CollectorIterator(d.end());
DX1CollectorIterator * begin_ix = construct_with<DX1CollectorIterator>(ialloc, d.begin());
DX1CollectorIterator * end_ix = construct_with<DX1CollectorIterator>(ialloc, d.end());
obj<AAllocIterator> begin_obj = with_facet<AAllocIterator>::mkobj(begin_ix);
obj<AAllocIterator> end_obj = with_facet<AAllocIterator>::mkobj( end_ix);