Adam Macdonald a8d8b9b9ab
All checks were successful
Build (Arch Linux) / build (push) Successful in 3m10s
initial commit
2025-04-16 01:58:29 +01:00

75 lines
1.5 KiB
C++

#pragma once
#include <atomic>
#include <cstddef>
#include <utility>
namespace kuiper
{
/// Atomically reference counted type
template<typename T>
class arc {
public:
/// Argument-forwarding constructor
template<typename... Args>
explicit arc(Args&&... args)
: m_inner(std::forward<Args>(args)...) {}
/// Default constructor (no args.)
arc()
: m_inner() {}
/// Destructor
~arc() {
if (m_ref_count.load() > 0)
return;
}
/// Copy constructor
arc(const arc& other)
: m_inner(other.m_inner), m_ref_count(other.m_ref_count.load() + 1) {}
/// Copy assignment constructor
arc& operator=(const arc& other) {
m_inner = other.m_inner;
m_ref_count = other.m_ref_count.load() + 1;
return *this;
}
/// Move constructor
arc(arc&& other) noexcept
: m_inner(std::move(other.m_inner)), m_ref_count(other.m_ref_count.load()) {};
/// Move assignment constructor
arc& operator=(arc&& other) noexcept {
*this = std::move(other);
return *this;
};
// Inner type access
/// Reference to the type contained in the `arc`
T& inner() noexcept {
return m_inner;
}
/// Read-only reference to the type contained in the `arc`
const T& const_inner() const noexcept {
return m_inner;
}
// Reference count
std::size_t ref_count() const noexcept {
return m_ref_count.load();
}
private:
T m_inner;
std::atomic_size_t m_ref_count = 0;
};
} // namespace kuiper