xo-gc/include/xo/gc/DX1CollectorIterator.hpp

95 lines
3.5 KiB
C++

/** @file DX1CollectorIterator.hpp
*
* @author Roland Conybeare, Dec 2025
**/
#pragma once
#include "AllocInfo.hpp"
#include "generation.hpp"
#include <xo/arena/DArenaIterator.hpp>
#include <xo/arena/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(); }
Generation gen_ix() const { return gen_ix_; }
Generation gen_hi() const { return gen_hi_; }
DArenaIterator arena_ix() const { return arena_ix_; }
DArenaIterator arena_hi() const { return arena_hi_; }
/** 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 */