xo-alloc2: DX1CollectorIterator infra [WIP]
This commit is contained in:
parent
59c0311ed7
commit
bf27314688
30 changed files with 1041 additions and 176 deletions
|
|
@ -6,6 +6,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "alloc/AllocInfo.hpp"
|
||||
#include "cmpresult.hpp"
|
||||
#include <xo/facet/obj.hpp>
|
||||
|
||||
namespace xo {
|
||||
|
|
@ -19,7 +20,8 @@ namespace xo {
|
|||
/** @class AAllocIterator
|
||||
* @brief Abstract facet for iterating over allocs
|
||||
*
|
||||
* Iterator refers to an AllocInfo instance.
|
||||
* Iterator refers to an AllocInfo instance
|
||||
* Only supporting forward-allocator.
|
||||
**/
|
||||
struct AAllocIterator {
|
||||
using obj_AAllocIterator = xo::facet::obj<AAllocIterator>;
|
||||
|
|
@ -29,13 +31,11 @@ namespace xo {
|
|||
/** retrieve AllocInfo for current iterator position
|
||||
**/
|
||||
virtual AllocInfo deref(Copaque d) const noexcept = 0;
|
||||
/** compare alloc iterators @p d and @p other for equality **/
|
||||
virtual int compare(Copaque d,
|
||||
const obj_AAllocIterator & other) const noexcept = 0;
|
||||
/** compare alloc iterators @p d and @p other **/
|
||||
virtual cmpresult compare(Copaque d,
|
||||
const obj_AAllocIterator & other) const noexcept = 0;
|
||||
/** advance iterator to next position **/
|
||||
virtual void next(Opaque d) const noexcept = 0;
|
||||
/** retreat iterator to previous position **/
|
||||
virtual void prev(Opaque d) const noexcept = 0;
|
||||
};
|
||||
} /*namespace mm*/
|
||||
} /*namespace xo*/
|
||||
|
|
|
|||
|
|
@ -29,6 +29,14 @@ namespace xo {
|
|||
alloc_info_disabled,
|
||||
/** attempt to call alloc_info for address not owned by allocator **/
|
||||
alloc_info_address,
|
||||
/** for example: alloc iteration not supported in arenas with
|
||||
* AllocConfig.store_header_flag_ = false
|
||||
**/
|
||||
alloc_iterator_not_supported,
|
||||
/** attempt to deref an iterator that does not refer to an alloc **/
|
||||
alloc_iterator_deref,
|
||||
/** attempt to advance an iterator that does not refer to an alloc **/
|
||||
alloc_iterator_next,
|
||||
};
|
||||
|
||||
struct AllocError {
|
||||
|
|
|
|||
|
|
@ -17,20 +17,6 @@ namespace xo {
|
|||
|
||||
explicit AllocHeader(repr_type x) : repr_{x} {}
|
||||
|
||||
#ifdef OBSOLETE
|
||||
std::uint32_t tseq(const AllocHeaderConfig & cfg) const noexcept {
|
||||
return cfg.tseq(repr_);
|
||||
}
|
||||
|
||||
std::uint32_t age(const AllocHeaderConfig & cfg) const noexcept {
|
||||
return cfg.age(repr_);
|
||||
}
|
||||
|
||||
size_type size(const AllocHeaderConfig & cfg) const noexcept {
|
||||
return cfg.size(repr_);
|
||||
}
|
||||
#endif
|
||||
|
||||
repr_type repr_;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,11 @@ namespace xo {
|
|||
p_guard_hi_{p_guard_hi} {}
|
||||
|
||||
/** error when alloc-header not configured **/
|
||||
static AllocInfo error_not_configured(AllocHeaderConfig * p_cfg) {
|
||||
static AllocInfo error_not_configured(const AllocHeaderConfig * p_cfg) {
|
||||
return AllocInfo(p_cfg, nullptr, nullptr, nullptr);
|
||||
}
|
||||
/** error on deref empty iterator **/
|
||||
static AllocInfo error_invalid_iterator(const AllocHeaderConfig * p_cfg) {
|
||||
return AllocInfo(p_cfg, nullptr, nullptr, nullptr);
|
||||
}
|
||||
|
||||
|
|
@ -46,6 +50,8 @@ namespace xo {
|
|||
std::uint32_t age() const noexcept { return p_config_->age (*p_header_); }
|
||||
/** Allocation size (including allocator-supplied padding) **/
|
||||
size_type size() const noexcept { return p_config_->size(*p_header_); }
|
||||
/** Payload for this allocation. This is the memory available to application **/
|
||||
span_type payload() const noexcept;
|
||||
/** Guard bytes immediately following allocation **/
|
||||
span_type guard_hi() const noexcept;
|
||||
/** Number of guard bytes **/
|
||||
|
|
|
|||
|
|
@ -27,12 +27,11 @@ namespace xo {
|
|||
|
||||
// const methods
|
||||
[[noreturn]] AllocInfo deref(Copaque) const noexcept override { _fatal(); }
|
||||
[[noreturn]] int compare(Copaque,
|
||||
const obj_AAllocIterator &) const noexcept override { _fatal(); }
|
||||
[[noreturn]] cmpresult compare(Copaque,
|
||||
const obj_AAllocIterator &) const noexcept override { _fatal(); }
|
||||
|
||||
// non-const methods
|
||||
[[noreturn]] void next(Opaque) const noexcept override { _fatal(); }
|
||||
[[noreturn]] void prev(Opaque) const noexcept override { _fatal(); }
|
||||
|
||||
private:
|
||||
[[noreturn]] static void _fatal();
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
* @author Roland Conybeare, Dec 2025
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AAllocIterator.hpp"
|
||||
|
||||
namespace xo {
|
||||
|
|
@ -27,15 +29,14 @@ namespace xo {
|
|||
int32_t _typeseq() const noexcept override { return s_typeseq; }
|
||||
AllocInfo deref(Copaque d)
|
||||
const noexcept override { return I::deref(_dcast(d)); }
|
||||
int compare(Copaque d,
|
||||
const obj_AAllocIterator & other)
|
||||
cmpresult compare(Copaque d,
|
||||
const obj_AAllocIterator & other)
|
||||
const noexcept override
|
||||
{ return I::compare(_dcast(d), other); }
|
||||
|
||||
// non-const methods
|
||||
|
||||
void next(Opaque d) const noexcept override { I::prev(_dcast(d)); }
|
||||
void prev(Opaque d) const noexcept override { I::next(_dcast(d)); }
|
||||
void next(Opaque d) const noexcept override { I::next(_dcast(d)); }
|
||||
|
||||
private:
|
||||
using I = Impl;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
**/
|
||||
|
||||
#include "AAllocIterator.hpp"
|
||||
#include <xo/facet/RRouter.hpp"
|
||||
#include <xo/facet/RRouter.hpp>
|
||||
//#include <string>
|
||||
|
||||
namespace xo {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "alloc/AllocHeader.hpp"
|
||||
#include "alloc/AllocHeaderConfig.hpp"
|
||||
#include "alloc/AllocError.hpp"
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
|
|
@ -34,11 +34,6 @@ namespace xo {
|
|||
* present in arena
|
||||
**/
|
||||
bool store_header_flag_ = false;
|
||||
#ifdef OBSOLETE
|
||||
/** number of bits to represent allocation size **/
|
||||
std::uint64_t header_size_bits_ = 32;
|
||||
std::uint64_t header_size_mask_ = (1ul << header_size_bits_) - 1;
|
||||
#endif
|
||||
/** configuration for per-alloc header **/
|
||||
AllocHeaderConfig header_;
|
||||
/** true to enable debug logging **/
|
||||
|
|
|
|||
|
|
@ -6,9 +6,11 @@
|
|||
#pragma once
|
||||
|
||||
#include "ArenaConfig.hpp"
|
||||
#include "alloc/AllocInfo.hpp"
|
||||
|
||||
namespace xo {
|
||||
namespace mm {
|
||||
struct DArenaIterator; // see DArenaIterator.hpp
|
||||
|
||||
/** @class DArena
|
||||
*
|
||||
|
|
@ -85,6 +87,11 @@ namespace xo {
|
|||
/** true if arena is mapped i.e. has a reserved address range **/
|
||||
bool is_mapped() const noexcept { return (lo_ != nullptr) && (hi_ != nullptr); }
|
||||
|
||||
/** @ret iterator pointing to the first allocation in this arena **/
|
||||
DArenaIterator begin() const noexcept;
|
||||
/** @ret iterator pointing to just after the last allocation in this arena **/
|
||||
DArenaIterator end() const noexcept;
|
||||
|
||||
/** get header from allocated object address **/
|
||||
header_type * obj2hdr(void * obj) noexcept;
|
||||
|
||||
|
|
@ -98,7 +105,11 @@ namespace xo {
|
|||
*
|
||||
* Note: non-const, may stash error details
|
||||
**/
|
||||
AllocInfo alloc_info(value_type mem) noexcept;
|
||||
AllocInfo alloc_info(value_type mem) const noexcept;
|
||||
|
||||
/** capture error information: advance error count + set last_error **/
|
||||
void capture_error(error err,
|
||||
size_type target_z = 0) const;
|
||||
|
||||
/** discard all allocated memory, return to empty state
|
||||
* Promise:
|
||||
|
|
|
|||
102
include/xo/alloc2/arena/DArenaIterator.hpp
Normal file
102
include/xo/alloc2/arena/DArenaIterator.hpp
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/** @file DArenaIterator.hpp
|
||||
*
|
||||
* @author Roland Conybeare, Dec 2025
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "alloc/AllocInfo.hpp"
|
||||
#include "alloc/AllocHeader.hpp"
|
||||
#include "cmpresult.hpp"
|
||||
|
||||
namespace xo {
|
||||
namespace mm {
|
||||
struct DArena;
|
||||
|
||||
/** @class DArenaIterator
|
||||
* @brief Representation for alloc iterator over arena
|
||||
*
|
||||
* Map showing an arena allocation:
|
||||
*
|
||||
* @pre
|
||||
*
|
||||
* <-------------z1--------------->
|
||||
* < guard >< hz >< req_z >< dz >< guard >
|
||||
*
|
||||
* +++++++++0000zzzz@@@@@@@@@@@@@@@@@ppppppp+++++++++
|
||||
*
|
||||
* ^ ^ ^
|
||||
* header mem header
|
||||
* ^ (next alloc)
|
||||
* DArenaIterator::pos_
|
||||
*
|
||||
* guard [+] guard before+after each allocation, for simple sanitize checks
|
||||
* header [0] alloc header (non-size bits)
|
||||
* [z] alloc header (size bits)
|
||||
* mem [@] app-requested memory, including padding [p]
|
||||
* dz [p] padding (to uintptr_t alignment. req_z+dz recorded in header)
|
||||
* free_ DArena::free_ just after guard bytes for last allocation
|
||||
*
|
||||
* @endpre
|
||||
**/
|
||||
struct DArenaIterator {
|
||||
DArenaIterator() = default;
|
||||
DArenaIterator(const DArena * arena,
|
||||
AllocHeader * pos) : arena_{arena},
|
||||
pos_{pos} {}
|
||||
|
||||
/** Create iterator in invalid state **/
|
||||
static DArenaIterator invalid() { return DArenaIterator(); }
|
||||
|
||||
/** Create iterator pointing to the beginning of @p arena
|
||||
* Iterator cannot modify memory, but can capture
|
||||
* an iterator error in @p *arena
|
||||
**/
|
||||
static DArenaIterator begin(const DArena * arena);
|
||||
/** Create iterator pointing to the end of @p arena
|
||||
* Iterator cannot modify memory, but can capture
|
||||
* an iterator error in @p *arena
|
||||
**/
|
||||
static DArenaIterator end(const DArena * arena);
|
||||
|
||||
/** A valid iterator can be compared, at least with itself
|
||||
* It can be dereferenced if is also non-empty
|
||||
**/
|
||||
bool is_valid() const noexcept { return (arena_ != nullptr) && (pos_ != nullptr); }
|
||||
bool is_invalid() const noexcept { return !is_valid(); }
|
||||
|
||||
/** fetch contents at current iterator position **/
|
||||
AllocInfo deref() const noexcept;
|
||||
/** compare two iterators. To be comparable,
|
||||
* iterators must refer to the same arena
|
||||
**/
|
||||
cmpresult compare(const DArenaIterator & other) const noexcept;
|
||||
/** advance iterator to next allocation **/
|
||||
void next() noexcept;
|
||||
|
||||
std::byte * pos_as_byte() const { return (std::byte *)pos_; }
|
||||
|
||||
/** *ix synonym for ix.deref() **/
|
||||
AllocInfo operator*() const noexcept { return this->deref(); }
|
||||
/** ++ix synonym for ix.next() **/
|
||||
DArenaIterator & operator++() noexcept { this->next(); return *this; }
|
||||
|
||||
/** iterator visits allocations from this arena **/
|
||||
const DArena * arena_ = nullptr;
|
||||
/** current iterator position **/
|
||||
AllocHeader * pos_ = nullptr;
|
||||
};
|
||||
|
||||
inline bool
|
||||
operator==(const DArenaIterator & x, const DArenaIterator & y) {
|
||||
return x.compare(y).is_equal();
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!=(const DArenaIterator & x, const DArenaIterator & y) {
|
||||
return !x.compare(y).is_equal();
|
||||
}
|
||||
} /*namespace mm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end DArenaIterator.hpp */
|
||||
36
include/xo/alloc2/arena/IAllocIterator_DArenaIterator.hpp
Normal file
36
include/xo/alloc2/arena/IAllocIterator_DArenaIterator.hpp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/** @file IAllocIterator_DArenaIterator.hpp
|
||||
*
|
||||
* @author Roland Conybeare, Dec 2025
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "alloc/IAllocIterator_Xfer.hpp"
|
||||
#include "arena/DArenaIterator.hpp"
|
||||
|
||||
namespace xo {
|
||||
namespace mm { struct IAllocIterator_DArenaIterator; }
|
||||
|
||||
namespace facet {
|
||||
template <>
|
||||
struct FacetImplementation<xo::mm::AAllocIterator,
|
||||
xo::mm::DArenaIterator> {
|
||||
using ImplType = xo::mm::IAllocIterator_Xfer<xo::mm::DArenaIterator,
|
||||
xo::mm::IAllocIterator_DArenaIterator>;
|
||||
};
|
||||
}
|
||||
|
||||
namespace mm {
|
||||
/** @class IAllocIterator_DArena
|
||||
* @brief alloc iteration for the DArena allocator
|
||||
**/
|
||||
struct IAllocIterator_DArenaIterator {
|
||||
static AllocInfo deref(const DArenaIterator &) noexcept;
|
||||
static cmpresult compare(const DArenaIterator &,
|
||||
const obj<AAllocIterator> & other) noexcept;
|
||||
static void next(DArenaIterator &) noexcept;
|
||||
};
|
||||
} /*namespace mm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end IAllocIterator_DArenaIterator.cpp */
|
||||
59
include/xo/alloc2/cmpresult.hpp
Normal file
59
include/xo/alloc2/cmpresult.hpp
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/** @file cmpresult.hpp
|
||||
*
|
||||
* @author Roland Conybeare, Dec 2025
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdint>
|
||||
|
||||
namespace xo {
|
||||
namespace mm {
|
||||
enum class comparison : int32_t {
|
||||
invalid = -1,
|
||||
comparable = 0,
|
||||
incomparable = 1,
|
||||
};
|
||||
|
||||
struct cmpresult {
|
||||
cmpresult() : err_{comparison::invalid}, cmp_{0} {}
|
||||
cmpresult(comparison err, std::int16_t cmp) : err_{err}, cmp_{cmp} {}
|
||||
|
||||
static cmpresult incomparable() { return cmpresult(comparison::incomparable, 0); }
|
||||
static cmpresult lesser() { return cmpresult(comparison::comparable, -1); }
|
||||
static cmpresult equal() { return cmpresult(comparison::comparable, 0); }
|
||||
static cmpresult greater() { return cmpresult(comparison::comparable, +1); }
|
||||
|
||||
template<typename T>
|
||||
static cmpresult from_cmp(T && x, T && y) {
|
||||
if (x < y)
|
||||
return cmpresult::lesser();
|
||||
else if (x == y)
|
||||
return cmpresult::equal();
|
||||
else
|
||||
return cmpresult::greater();
|
||||
}
|
||||
|
||||
|
||||
bool is_equal() const { return (err_ == comparison::comparable) && (cmp_ == 0); }
|
||||
|
||||
/* -1 -> invalid (sentinel)
|
||||
* 0 -> comparable
|
||||
* 1 -> incomparable (e.g. iterators from different arenas)
|
||||
*/
|
||||
comparison err_ = comparison::invalid;
|
||||
/* <0 -> lesser; 0 -> equal, >0 -> greater */
|
||||
std::int16_t cmp_ = 0;
|
||||
};
|
||||
|
||||
inline std::ostream & operator<<(std::ostream & os,
|
||||
const cmpresult & x)
|
||||
{
|
||||
os << "<cmpresult " << xtag("err", x.err_) << xtag("cmp", x.cmp_) << ">";
|
||||
}
|
||||
|
||||
} /*namespace mm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end cmpresult.hpp */
|
||||
|
|
@ -145,6 +145,8 @@ namespace xo {
|
|||
generation gc_upto_;
|
||||
};
|
||||
|
||||
struct DX1CollectorIterator;
|
||||
|
||||
// ----- DX1Collector -----
|
||||
|
||||
struct DX1Collector {
|
||||
|
|
@ -212,6 +214,15 @@ namespace xo {
|
|||
/** Retreive bookkeeping info for allocation at @p mem. **/
|
||||
AllocInfo alloc_info(value_type mem) noexcept;
|
||||
|
||||
// ----- iteration -----
|
||||
|
||||
/** alloc iterator at begin position **/
|
||||
DX1CollectorIterator begin() const noexcept;
|
||||
/** alloc iterator at end position
|
||||
* (valid, but cannot be dereferenced)
|
||||
**/
|
||||
DX1CollectorIterator end() const noexcept;
|
||||
|
||||
// ----- book-keeping -----
|
||||
|
||||
/** reverse to-space and from-space roles for generation g **/
|
||||
|
|
|
|||
90
include/xo/alloc2/gc/DX1CollectorIterator.hpp
Normal file
90
include/xo/alloc2/gc/DX1CollectorIterator.hpp
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/** @file DX1CollectorIterator.hpp
|
||||
*
|
||||
* @author Roland Conybeare, Dec 2025
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "alloc/AllocInfo.hpp"
|
||||
#include "gc/generation.hpp"
|
||||
#include "arena/DArenaIterator.hpp"
|
||||
#include "cmpresult.hpp"
|
||||
|
||||
namespace xo {
|
||||
namespace mm {
|
||||
struct DX1Collector;
|
||||
|
||||
/** @class DX1CollectorIterator
|
||||
* @brief Representation for alloc iterator over X1 collector
|
||||
*
|
||||
* Will iterate across all allocs in all generations
|
||||
**/
|
||||
struct DX1CollectorIterator {
|
||||
DX1CollectorIterator() = default;
|
||||
DX1CollectorIterator(const DX1Collector * gc,
|
||||
generation gen_ix,
|
||||
generation gen_hi,
|
||||
DArenaIterator arena_ix,
|
||||
DArenaIterator arena_hi);
|
||||
|
||||
/** Invalid iterator. Does not compare equal to anything, including itself **/
|
||||
static DX1CollectorIterator invalid() { return DX1CollectorIterator(); }
|
||||
/** Create iterator pointing to the beginning of @p gc.
|
||||
* Iterator cannot modify payload memory
|
||||
**/
|
||||
static DX1CollectorIterator begin(DX1Collector * gc);
|
||||
/** Create iterator pointing to the end of @p gc.
|
||||
* Iterator cannot modify payload memory.
|
||||
**/
|
||||
static DX1CollectorIterator end(DX1Collector * gc);
|
||||
|
||||
/** true if iterator is invalid. invalid iterators are not comparable **/
|
||||
bool is_valid() const noexcept { return (gc_ != nullptr); }
|
||||
bool is_invalid() const noexcept { return !is_valid(); }
|
||||
|
||||
/** fetch contents at current iterator position **/
|
||||
AllocInfo deref() const noexcept;
|
||||
/** compare two iterators. To be comparable,
|
||||
* iterators must refer to the same collector
|
||||
**/
|
||||
cmpresult compare(const DX1CollectorIterator & other) const noexcept;
|
||||
/** advance iterator to next allocation **/
|
||||
void next() noexcept;
|
||||
|
||||
/** for *ix synonym for ix.deref() **/
|
||||
AllocInfo operator*() const noexcept { return this->deref(); }
|
||||
|
||||
private:
|
||||
/** if non-empty, normalize to state with arena_ix_ != arena_hi_ **/
|
||||
void normalize() noexcept;
|
||||
|
||||
private:
|
||||
/** Iterator visits allocations from this collector **/
|
||||
const DX1Collector * gc_ = nullptr;
|
||||
/** Iterating over generations in [@p gen_ix_, @p gen_hi_).
|
||||
* Current position is within arena for @p gen_ix_ to-space,
|
||||
* Provided @p gen_ix_ < @p gen_hi_
|
||||
**/
|
||||
generation gen_ix_;
|
||||
generation gen_hi_;
|
||||
/** Iterating over allocs in [@p arena_ix_, @p arena_hi_).
|
||||
* Current position is at @p arena_ix_
|
||||
**/
|
||||
DArenaIterator arena_ix_;
|
||||
DArenaIterator arena_hi_;
|
||||
};
|
||||
|
||||
inline bool
|
||||
operator==(const DX1CollectorIterator & x, const DX1CollectorIterator & y) {
|
||||
return x.compare(y).is_equal();
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!=(const DX1CollectorIterator & x, const DX1CollectorIterator & y) {
|
||||
return !x.compare(y).is_equal();
|
||||
}
|
||||
|
||||
} /*namespace mm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end DX1CollectorIterator.hpp */
|
||||
36
include/xo/alloc2/gc/IAllocIterator_DX1CollectorIterator.hpp
Normal file
36
include/xo/alloc2/gc/IAllocIterator_DX1CollectorIterator.hpp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/** @file IAllocIterator_DX1Collector.hpp
|
||||
*
|
||||
* @author Roland Conybeare, Dec 2025
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "alloc/IAllocIterator_Xfer.hpp"
|
||||
#include "gc/DX1CollectorIterator.hpp"
|
||||
|
||||
namespace xo {
|
||||
namespace mm { struct IAllocIterator_DX1CollectorIterator; }
|
||||
|
||||
namespace facet {
|
||||
template <>
|
||||
struct FacetImplementation<xo::mm::AAllocIterator,
|
||||
xo::mm::DX1CollectorIterator> {
|
||||
using ImplType = xo::mm::IAllocIterator_Xfer<xo::mm::DX1CollectorIterator,
|
||||
xo::mm::IAllocIterator_DX1CollectorIterator>;
|
||||
};
|
||||
}
|
||||
|
||||
namespace mm {
|
||||
/** @class IAllocIterator_DX1Collector
|
||||
* @brief alloc iteration for the DX1Collector allocator
|
||||
**/
|
||||
struct IAllocIterator_DX1CollectorIterator {
|
||||
static AllocInfo deref(const DX1CollectorIterator &) noexcept;
|
||||
static cmpresult compare(const DX1CollectorIterator &,
|
||||
const obj<AAllocIterator> & other) noexcept;
|
||||
static void next(DX1CollectorIterator &) noexcept;
|
||||
};
|
||||
} /*namespace mm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end IAllocIterator_DX1Collector.hpp */
|
||||
|
|
@ -19,6 +19,7 @@ namespace xo {
|
|||
struct generation {
|
||||
using value_type = std::uint32_t;
|
||||
|
||||
constexpr generation() = default;
|
||||
explicit constexpr generation(value_type x) : value_{x} {}
|
||||
|
||||
static generation nursery() { return generation{0}; }
|
||||
|
|
@ -27,7 +28,7 @@ namespace xo {
|
|||
|
||||
generation & operator++() { ++value_; return *this; }
|
||||
|
||||
std::uint32_t value_;
|
||||
std::uint32_t value_ = 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue