All checks were successful
Build (Arch Linux) / build (push) Successful in 3m10s
75 lines
1.5 KiB
C++
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
|