RefCountable¶
RefCountable is a low-overhead, intrusive reference counting base class. It enables manual control of object lifetime without dynamic memory management and is used as the foundation for pooled, shared objects in FLOX.
class RefCountable {
public:
void retain() noexcept;
bool release() noexcept;
void resetRefCount(uint32_t value = 0) noexcept;
uint32_t refCount() const noexcept;
};
Purpose¶
- Provide deterministic, allocation-free lifetime tracking for objects managed in pools or event buses.
Responsibilities¶
| Method | Description |
|---|---|
retain() |
Atomic fetch_add(1, relaxed) on the reference count. |
release() |
Atomic fetch_sub(1, acq_rel); returns true if this was the last ref. |
resetRefCount() |
Resets ref count to 0 or specified value. |
refCount() |
Returns current ref count for debug/inspection. |
Behavior¶
- When
release()returnstrue, the object is no longer in use and may be recycled. - Incorrect calls (e.g.
release()on0) are fatal in debug builds and abort in release.
Design Notes¶
- The counter is
std::atomic<uint32_t>. Orderings differ per operation:retain(),resetRefCount()andrefCount()userelaxed;release()usesacq_relso the decrement that reaches zero synchronizes with the prior releases. - Every method is
noexcept. - Thread-safe under the assumption that retain/release are called from valid ownership contexts.
- Not designed for multi-owner concurrent access — intended for single-threaded or externally synchronized lifecycles.
Concept¶
The concept lives in flox::concepts, not at namespace scope, so it does not collide with the
flox::RefCountable class. Spell it flox::concepts::RefCountable.
namespace concepts
{
template <typename T>
concept RefCountable = requires(T obj) {
{ obj.retain() } -> std::same_as<void>;
{ obj.release() } -> std::same_as<bool>;
{ obj.resetRefCount() } -> std::same_as<void>;
};
} // namespace concepts
This concept ensures compile-time validation for use in pooled or handle-managed objects.