xo-alloc2: ++ plumbing for AAllocator / DArena
This commit is contained in:
parent
5964bcf3d5
commit
e0dd9d2a1c
10 changed files with 223 additions and 91 deletions
|
|
@ -35,90 +35,61 @@ namespace xo {
|
|||
///@{
|
||||
|
||||
/** RTTI: unique id# for actual runtime data representation **/
|
||||
virtual int32_t _typeseq() = 0;
|
||||
virtual int32_t _typeseq() const = 0;
|
||||
/** optional name for allocator @p d
|
||||
* Labeling, for diagnostics.
|
||||
**/
|
||||
virtual const std::string & name(Copaque d) = 0;
|
||||
virtual const std::string & name(Copaque d) const = 0;
|
||||
/** reserved size in bytes for allocator @p d.
|
||||
* Includes committed + uncommitted memory.
|
||||
* Cannot be increased.
|
||||
**/
|
||||
virtual std::size_t reserved(Copaque d) const = 0;
|
||||
/** allocator size in bytes (up to reserved limit)
|
||||
* for allocator @p d.
|
||||
* Includes allocated and uncomitted memory
|
||||
* Includes all committed memory.
|
||||
* Can increase on @ref alloc
|
||||
**/
|
||||
virtual std::size_t size(Copaque d) = 0;
|
||||
virtual std::size_t size(Copaque d) const = 0;
|
||||
/** committed size (physical addresses obtained)
|
||||
* for allocator @p d.
|
||||
**/
|
||||
virtual std::size_t committed(Copaque d) = 0;
|
||||
virtual std::size_t committed(Copaque d) const = 0;
|
||||
/** true iff allocator @p d is responsible for memory at address @p p.
|
||||
**/
|
||||
virtual bool contains(Copaque d, const void * p) = 0;
|
||||
virtual bool contains(Copaque d, const void * p) const = 0;
|
||||
|
||||
/** allocate @p z bytes of memory from allocator @p d. **/
|
||||
virtual std::byte * alloc(Opaque d, std::size_t z) = 0;
|
||||
virtual std::byte * alloc(Opaque d, std::size_t z) const = 0;
|
||||
/** reset allocator @p d to empty state **/
|
||||
virtual void clear(Opaque d) = 0;
|
||||
virtual void clear(Opaque d) const = 0;
|
||||
/** destruct allocator @p d **/
|
||||
virtual void destruct_data(Opaque d) = 0;
|
||||
virtual void destruct_data(Opaque d) const = 0;
|
||||
|
||||
///@}
|
||||
}; /*AAllocator*/
|
||||
|
||||
// implementation IAllocator_DRepr of AAllocator for state DRepr
|
||||
// should provide a specialization:
|
||||
//
|
||||
// template <>
|
||||
// struct xo::facet::FacetImplementation<AAllocator, DRepr> {
|
||||
// using ImplType = IAllocator_DRepr;
|
||||
// };
|
||||
//
|
||||
// then IAllocator_ImplType<DRepr> --> IAllocator_DRepr
|
||||
//
|
||||
template <typename DRepr>
|
||||
struct IAllocator_Impl;
|
||||
using IAllocator_ImplType = xo::facet::FacetImplType<AAllocator, DRepr>;
|
||||
|
||||
template <typename DRepr>
|
||||
using IAllocator_ImplType = IAllocator_Impl<DRepr>::ImplType;
|
||||
// can't we do this with FacetImplementation<AAllocator, DRepr>
|
||||
//
|
||||
// template <typename DRepr>
|
||||
// struct IAllocator_Impl {};
|
||||
|
||||
struct IAllocator_Any : public AAllocator {
|
||||
using Impl = Allocator_ImplType<xo::facet::DVariantPlaceholder>;
|
||||
// template <typename DRepr>
|
||||
// using IAllocator_ImplType = IAllocator_Impl<DRepr>::ImplType;
|
||||
|
||||
// from AAllocator
|
||||
int32_t _typeseq() override { return s_typeseq; }
|
||||
|
||||
const std::string & name(Copaque d) override { assert(false); static std::string x; return x; }
|
||||
std::size_t size(Copaque d) override { assert(false); return 0ul; }
|
||||
std::size_t committed(Copaque d) override { assert(false); reutrn 0ul; }
|
||||
bool contains(Copaque d, const void * p) override { assert(false); return false; }
|
||||
|
||||
std::byte * alloc(Opaque d, std::size_t z) override { assert(false); return nullptr; }
|
||||
void clear(Opaque d) override { assert(false); }
|
||||
void destruct_data(Opaque d) override { assert(false); }
|
||||
|
||||
static int32_t s_typeseq;
|
||||
static bool _valid;
|
||||
}
|
||||
|
||||
/** @class IAllocator_Xfer
|
||||
**/
|
||||
template <typename DRepr>
|
||||
struct IAllocator_Xfer : public AAllocator {
|
||||
// parallel interface to AAllocator, with specific data type
|
||||
using Impl = IAllocator_ImplType<DRepr>;
|
||||
|
||||
static const DRepr & _dcast(Copaque d) { return *(const DRepr *)d; }
|
||||
|
||||
// from AAllocator
|
||||
int32_t _typeseq() override { return s_typeseq; }
|
||||
const std::string & name(Copaque d) override { return Impl::name(_dcast(d)); }
|
||||
std::size_t size(Copaque d) override { return Impl::size(*(DRepr*)d); }
|
||||
std::size_t committed(Copaque d) override { return Impl::committed(*(DRepr*)d); }
|
||||
bool contains(Copaque d, const void * p) override { return Impl::contains(*(DRepr*)d, p); }
|
||||
|
||||
std::byte * alloc(Opaque d, std::size_t z) override { return Impl::alloc(*(DRepr*)d, z); }
|
||||
void clear(Opaque d) override { return Impl::clear(*(DRepr*)d); }
|
||||
void destruct_data(Opaque d) override { return Impl::destruct_data(*(DRepr*)d); }
|
||||
|
||||
static int32_t s_typeseq;
|
||||
static bool _valid;
|
||||
};
|
||||
|
||||
template <typename DRepr>
|
||||
int32_t
|
||||
IAllocator_Xfer<DRepr>::s_typeseq = facet::typeseq::id<DRepr>();
|
||||
|
||||
template <typename DRepr>
|
||||
bool
|
||||
IAllocator_Xfer<DRepr>::_valid = facet::valid_facet_implementation<AAllocator, IAllocator_Xfer>();
|
||||
} /*namespace mm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
|
|
|
|||
47
include/xo/alloc2/IAllocator_Any.hpp
Normal file
47
include/xo/alloc2/IAllocator_Any.hpp
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/** @file IAllocator_Any.hpp
|
||||
*
|
||||
* @author Roland Conybeare, Dec 2025
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AAllocator.hpp"
|
||||
#include <cassert>
|
||||
|
||||
namespace xo {
|
||||
namespace mm {
|
||||
struct IAllocator_Any;
|
||||
}
|
||||
|
||||
namespace facet {
|
||||
template <>
|
||||
struct FacetImplementation<xo::mm::AAllocator, DVariantPlaceholder> {
|
||||
using ImplType = xo::mm::IAllocator_Any;
|
||||
};
|
||||
}
|
||||
|
||||
namespace mm {
|
||||
struct IAllocator_Any : public AAllocator {
|
||||
//using Impl = IAllocator_ImplType<xo::facet::DVariantPlaceholder>;
|
||||
|
||||
// from AAllocator
|
||||
int32_t _typeseq() const override { return s_typeseq; }
|
||||
|
||||
const std::string & name(Copaque) const override { assert(false); static std::string * x; return *x; }
|
||||
std::size_t reserved(Copaque) const override { assert(false); return 0ul; }
|
||||
std::size_t size(Copaque) const override { assert(false); return 0ul; }
|
||||
std::size_t committed(Copaque) const override { assert(false); return 0ul; }
|
||||
bool contains(Copaque, const void *) const override { assert(false); return false; }
|
||||
|
||||
std::byte * alloc(Opaque, std::size_t) const override { assert(false); return nullptr; }
|
||||
void clear(Opaque) const override { assert(false); }
|
||||
void destruct_data(Opaque) const override { assert(false); }
|
||||
|
||||
static int32_t s_typeseq;
|
||||
static bool _valid;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* end IAllocator_Any.hpp */
|
||||
|
|
@ -4,25 +4,38 @@
|
|||
**/
|
||||
|
||||
#include "AAllocator.hpp"
|
||||
#include "IAllocator_Xfer.hpp"
|
||||
#include "DArena.hpp"
|
||||
|
||||
namespace xo {
|
||||
namespace mm {
|
||||
struct IAllocator_DArena;
|
||||
}
|
||||
|
||||
struct IAllocator_DArena {
|
||||
static const std::string & name(const DArena & s);
|
||||
static std::size_t size(const DArena & s);
|
||||
static std::size_t committed(const DArena & s);
|
||||
static bool contains(const DArena & s, const void * p);
|
||||
static std::byte * alloc(const DArena & s, std::size_t z);
|
||||
static void clear(DArena & s);
|
||||
static void destruct_data(DArena & s);
|
||||
};
|
||||
|
||||
namespace facet {
|
||||
template <>
|
||||
struct IAllocator_Impl<DArena> {
|
||||
using ImplType = IAllocator_DArena;
|
||||
struct FacetImplementation<xo::mm::AAllocator, xo::mm::DArena> {
|
||||
using ImplType = xo::mm::IAllocator_Xfer<xo::mm::DArena,
|
||||
xo::mm::IAllocator_DArena>;
|
||||
};
|
||||
}
|
||||
|
||||
namespace mm {
|
||||
struct IAllocator_DArena {
|
||||
static const std::string & name(const DArena &);
|
||||
static std::size_t reserved(const DArena &);
|
||||
static std::size_t size(const DArena &);
|
||||
static std::size_t committed(const DArena &);
|
||||
static bool contains(const DArena &, const void * p);
|
||||
static std::byte * alloc(const DArena &, std::size_t z);
|
||||
static void clear(DArena &);
|
||||
static void destruct_data(DArena &);
|
||||
};
|
||||
|
||||
// template <>
|
||||
// struct IAllocator_Impl<DArena> {
|
||||
// using ImplType = IAllocator_DArena;
|
||||
// };
|
||||
|
||||
} /*namespace mm*/
|
||||
} /*namespace xo*/
|
||||
|
|
|
|||
47
include/xo/alloc2/IAllocator_Xfer.hpp
Normal file
47
include/xo/alloc2/IAllocator_Xfer.hpp
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/** @file IAllocator_Xfer.hpp
|
||||
*
|
||||
* @author Roland Conybeare, Dec 2025
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AAllocator.hpp"
|
||||
|
||||
namespace xo {
|
||||
namespace mm {
|
||||
/** @class IAllocator_Xfer
|
||||
**/
|
||||
template <typename DRepr, typename IAllocator_DRepr>
|
||||
struct IAllocator_Xfer : public AAllocator {
|
||||
// parallel interface to AAllocator, with specific data type
|
||||
using Impl = IAllocator_DRepr;
|
||||
|
||||
static const DRepr & _dcast(Copaque d) { return *(const DRepr *)d; }
|
||||
|
||||
// from AAllocator
|
||||
int32_t _typeseq() const override { return s_typeseq; }
|
||||
const std::string & name(Copaque d) const override { return Impl::name(_dcast(d)); }
|
||||
std::size_t reserved(Copaque d) const override { return Impl::reserved(*(DRepr*)d); }
|
||||
std::size_t size(Copaque d) const override { return Impl::size(*(DRepr*)d); }
|
||||
std::size_t committed(Copaque d) const override { return Impl::committed(*(DRepr*)d); }
|
||||
bool contains(Copaque d, const void * p) const override { return Impl::contains(*(DRepr*)d, p); }
|
||||
|
||||
std::byte * alloc(Opaque d, std::size_t z) const override { return Impl::alloc(*(DRepr*)d, z); }
|
||||
void clear(Opaque d) const override { return Impl::clear(*(DRepr*)d); }
|
||||
void destruct_data(Opaque d) const override { return Impl::destruct_data(*(DRepr*)d); }
|
||||
|
||||
static int32_t s_typeseq;
|
||||
static bool _valid;
|
||||
};
|
||||
|
||||
template <typename DRepr, typename IAllocator_DRepr>
|
||||
int32_t
|
||||
IAllocator_Xfer<DRepr, IAllocator_DRepr>::s_typeseq = facet::typeseq::id<DRepr>();
|
||||
|
||||
template <typename DRepr, typename IAllocator_DRepr>
|
||||
bool
|
||||
IAllocator_Xfer<DRepr, IAllocator_DRepr>::_valid = facet::valid_facet_implementation<AAllocator, IAllocator_Xfer>();
|
||||
} /*namespace mm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end IAllocator_Xfer.hpp */
|
||||
|
|
@ -6,18 +6,29 @@
|
|||
#pragma once
|
||||
|
||||
#include "xo/facet/RRouter.hpp"
|
||||
#include <string>
|
||||
|
||||
namespace xo {
|
||||
namespace mm {
|
||||
/** @class RAllocator **/
|
||||
template <typename Object>
|
||||
struct RAllocator : public Object {
|
||||
private:
|
||||
using O = Object;
|
||||
public:
|
||||
using ObjectType = Object;
|
||||
using size_type = std::size_t;
|
||||
|
||||
RAllocator() {}
|
||||
RAllocator(Object::DataPtr data) : Object{std::move(data)} {}
|
||||
|
||||
int32_t _typeseq() const { return Object::iface()->_typeseq(); }
|
||||
int32_t _typeseq() const { return O::iface()->_typeseq(); }
|
||||
const std::string & name() const { return O::iface()->name(O::data()); }
|
||||
size_type reserved() const { return O::iface()->reserved(O::data()); }
|
||||
size_type size() const { return O::iface()->size(O::data()); }
|
||||
size_type committed() const { return O::iface()->committed(O::data()); }
|
||||
bool contains(const void * p) const { return O::iface()->contains(O::data(), p); }
|
||||
std::byte * alloc(size_type z) { return O::iface()->alloc(O::data(), z); }
|
||||
|
||||
static bool _valid;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue