Skip to content

EntropyEngine::Core::TypeSystem::GenericHandle

EntropyEngine::Core::TypeSystem::GenericHandle

Section titled “EntropyEngine::Core::TypeSystem::GenericHandle”

Base class for type-safe handle implementations with generation-based validation. More…

#include <GenericHandle.h>

Name
structHash
Hash support for use in unordered containers.
Name
booloperator==(const GenericHandle & other) const
Equality comparison.
booloperator<(const GenericHandle & other) const
Less-than comparison for use in sorted containers.
booloperator!=(const GenericHandle & other) const
Inequality comparison.
boolisValid() const
Checks if this handle is potentially valid.
voidinvalidate()
Invalidates this handle.
uint64_tgetRawData() const
Gets the raw packed data.
OwnerType *getOwner() const
Gets the owner of this handle.
uint32_tgetIndex() const
Gets the index component of this handle.
uint64_tgetId() const
Gets the raw data as a 64-bit ID (for non-generation use cases).
uint32_tgetGeneration() const
Gets the generation component of this handle.
constexprGenericHandle()
Default constructor creates an invalid handle.
constexprGenericHandle(OwnerType * owner, uint32_t index, uint32_t generation)
Constructs a handle with the specified owner, index and generation.
constexprGenericHandle(OwnerType * owner, uint64_t id)
Constructs a handle with the specified owner and raw ID (for non-generation use).
Name
uint64_tpack(uint32_t index, uint32_t generation)
Packs index and generation into a single 64-bit value.
Name
OwnerType *_owner
uint64_t_data
uint64_tINVALID_HANDLE
uint64_tINDEX_MASK
uint32_tGENERATION_SHIFT
uint64_tGENERATION_MASK
template <typename OwnerType =void>
class EntropyEngine::Core::TypeSystem::GenericHandle;

Base class for type-safe handle implementations with generation-based validation.

Provides a handle validation system that prevents use-after-free bugs through generation counting. Each handle contains an index and generation packed into a single 64-bit value, plus an optional owner reference.

Focuses solely on handle representation and basic validation - does not dictate storage mechanisms. Storage classes (pools, arrays, maps, etc.) are responsible for implementing their own validation logic using the handle’s index and generation.

Features:

  • Handle validation with owner reference support
  • Generation-based validation to detect stale handles
  • Type safety through templated derived classes
  • Support for up to 4 billion objects with 4 billion generations each
  • Storage-agnostic design for maximum flexibility

The handle is packed as: [32-bit generation][32-bit index]

  • Index 0 with generation 0 is reserved as invalid handle
  • Maximum index: 4,294,967,295 (0xFFFFFFFF)
  • Maximum generation: 4,294,967,295 (0xFFFFFFFF)

Example usage with custom storage:

class MyObjectManager {
struct Slot { MyObject obj; uint32_t generation; bool occupied; };
std::vector<Slot> slots;
bool isHandleValid(const MyObjectHandle& handle) const {
uint32_t index = handle.getIndex();
return index < slots.size() &&
slots[index].occupied &&
slots[index].generation == handle.getGeneration();
}
};
inline bool operator==(
const GenericHandle & other
) const

Equality comparison.

inline bool operator<(
const GenericHandle & other
) const

Less-than comparison for use in sorted containers.

inline bool operator!=(
const GenericHandle & other
) const

Inequality comparison.

inline bool isValid() const

Checks if this handle is potentially valid.

Return: true if the handle is not the invalid handle value and owner validation passes

Note: For handles without owners, this only checks if the handle is non-null

inline void invalidate()

Invalidates this handle.

inline uint64_t getRawData() const

Gets the raw packed data.

Return: The 64-bit packed handle data

inline OwnerType * getOwner() const

Gets the owner of this handle.

Return: Pointer to the owning container

inline uint32_t getIndex() const

Gets the index component of this handle.

Return: The 32-bit index value

inline uint64_t getId() const

Gets the raw data as a 64-bit ID (for non-generation use cases).

Return: The 64-bit ID value

inline uint32_t getGeneration() const

Gets the generation component of this handle.

Return: The 32-bit generation value

inline constexpr GenericHandle()

Default constructor creates an invalid handle.

inline constexpr GenericHandle(
OwnerType * owner,
uint32_t index,
uint32_t generation
)

Constructs a handle with the specified owner, index and generation.

Parameters:

  • owner Pointer to the owning container
  • index Object index in the container
  • generation Generation counter for validation
inline constexpr GenericHandle(
OwnerType * owner,
uint64_t id
)

Constructs a handle with the specified owner and raw ID (for non-generation use).

Parameters:

  • owner Pointer to the owning container
  • id Raw 64-bit identifier
static inline uint64_t pack(
uint32_t index,
uint32_t generation
)

Packs index and generation into a single 64-bit value.

OwnerType * _owner = nullptr;
uint64_t _data;
static uint64_t INVALID_HANDLE = 0;
static uint64_t INDEX_MASK = 0xFFFFFFFF;
static uint32_t GENERATION_SHIFT = 32;
static uint64_t GENERATION_MASK = 0xFFFFFFFF00000000;

Updated on 2026-01-26 at 16:50:32 -0500