xo-alloc: + ArenaAllocT for use with std::map() etc.
This commit is contained in:
parent
2febec3c8c
commit
50b0f7698c
3 changed files with 140 additions and 0 deletions
74
include/xo/alloc/ArenaAllocT.hpp
Normal file
74
include/xo/alloc/ArenaAllocT.hpp
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/** @file Allocator.hpp
|
||||
*
|
||||
* @author Roland Conybeare, Nov 2025
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xo/alloc/ArenaAlloc.hpp"
|
||||
|
||||
namespace xo {
|
||||
namespace gc {
|
||||
/** @class allocator
|
||||
* @brief c++ allocator with allocator traits
|
||||
*
|
||||
* Can use ArenaAllocT with std::map etc.
|
||||
**/
|
||||
template <typename T>
|
||||
class ArenaAllocT {
|
||||
public:
|
||||
using value_type = T;
|
||||
/** copy assignment: leave lhs allocator in place **/
|
||||
using propagate_on_container_copy_assignment = std::false_type;
|
||||
/** move assignment: adopt rhs allocator
|
||||
* (Forced: cannot mix allocations from different allocators
|
||||
* within a container)
|
||||
**/
|
||||
using propagate_on_container_move_assignment = std::true_type;
|
||||
/** swap: also swap allocators
|
||||
* (Forced: cannot mix allocations from different allocators
|
||||
* within a containers)
|
||||
**/
|
||||
using propagate_on_container_swap = std::true_type;
|
||||
/** An ArenaAlloc instance is unique owner of its own memory:
|
||||
* no other instance can dealloc
|
||||
**/
|
||||
using is_always_equal = std::false_type;
|
||||
|
||||
public:
|
||||
explicit ArenaAllocT(ArenaAlloc * mm) : mm_{mm} {}
|
||||
ArenaAllocT(const ArenaAllocT & other) = default;
|
||||
|
||||
/** rebind ctor. Allows container to use supplied allocator
|
||||
* for multiple types
|
||||
**/
|
||||
template <typename U>
|
||||
ArenaAllocT(const ArenaAllocT<U> & other) noexcept : mm_{other.mm_} {}
|
||||
|
||||
T * allocate(size_t n) {
|
||||
void * mem = mm_->alloc(n * sizeof(T));
|
||||
|
||||
return reinterpret_cast<T *>(mem);
|
||||
}
|
||||
|
||||
void deallocate(T * p, size_t n) noexcept {
|
||||
assert(mm_->contains(p));
|
||||
assert(n == 0 || mm_->contains(p + n - 1));
|
||||
|
||||
//arena_->deallocate(p, n * sizeof(T));
|
||||
}
|
||||
|
||||
bool operator==(const ArenaAllocT & other) const {
|
||||
return mm_ == other.mm_;
|
||||
}
|
||||
|
||||
bool operator!=(const ArenaAllocT & other) const {
|
||||
return mm_ != other.mm_;
|
||||
}
|
||||
|
||||
ArenaAlloc * mm_ = nullptr;
|
||||
};
|
||||
} /*namespace gc*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end Allocator.hpp */
|
||||
65
utest/ArenaAllocT.test.cpp
Normal file
65
utest/ArenaAllocT.test.cpp
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/** @file ArenaAllocT.test.cpp
|
||||
*
|
||||
* @author Roland Conybeare, Nov 2025
|
||||
**/
|
||||
|
||||
#include "xo/alloc/ArenaAllocT.hpp"
|
||||
#include <catch2/catch.hpp>
|
||||
#include <map>
|
||||
|
||||
namespace xo {
|
||||
using xo::gc::ArenaAllocT;
|
||||
using xo::gc::ArenaAlloc;
|
||||
|
||||
namespace ut {
|
||||
|
||||
namespace {
|
||||
struct testcase_ArenaAllocT {
|
||||
testcase_ArenaAllocT(std::size_t z) : arena_z_{z} {}
|
||||
|
||||
std::size_t arena_z_;
|
||||
std::vector<std::pair<std::string, std::string>> kv_pairs_;
|
||||
};
|
||||
|
||||
std::vector<testcase_ArenaAllocT>
|
||||
s_testcase_v = {
|
||||
testcase_ArenaAllocT(4096)
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("ArenaAllocT", "[alloc][traits]")
|
||||
{
|
||||
for (std::size_t i_tc = 0, n_tc = s_testcase_v.size(); i_tc < n_tc; ++i_tc) {
|
||||
const testcase_ArenaAllocT & tc = s_testcase_v[i_tc];
|
||||
|
||||
constexpr bool c_debug_flag = true;
|
||||
|
||||
auto arena = ArenaAlloc::make("arena", tc.arena_z_, c_debug_flag);
|
||||
auto alloc = ArenaAllocT<std::pair<const std::string, std::string>>(arena.get());
|
||||
|
||||
using TestMapType = std::map<std::string,
|
||||
std::string,
|
||||
std::less<std::string>,
|
||||
ArenaAllocT<std::pair<const std::string, std::string>>>;
|
||||
|
||||
TestMapType test_map(alloc);
|
||||
|
||||
size_t n = 0;
|
||||
for (const auto & kv_ix : tc.kv_pairs_) {
|
||||
test_map[kv_ix.first] = kv_ix.second;
|
||||
++n;
|
||||
|
||||
REQUIRE(test_map.size() == n);
|
||||
|
||||
for (const auto & map_ix : test_map) {
|
||||
map_ix.first;
|
||||
map_ix.second;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end ArenaAllocT.test.cpp */
|
||||
|
|
@ -7,6 +7,7 @@ set(UTEST_SRCS
|
|||
alloc_utest_main.cpp
|
||||
IAlloc.test.cpp
|
||||
ArenaAlloc.test.cpp
|
||||
ArenaAllocT.test.cpp
|
||||
ListAlloc.test.cpp
|
||||
GC.test.cpp
|
||||
GcStatistics.test.cpp
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue