#pragma once #include #include #include namespace kuiper { /// Atomically reference counted type template class arc { public: /// Argument-forwarding constructor template explicit arc(Args&&... args) : m_inner(std::forward(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