#ifndef PYTHONIC_UTILS_SHARED_REF_HPP #define PYTHONIC_UTILS_SHARED_REF_HPP #include "pythonic/include/utils/shared_ref.hpp" #include #include #include #ifdef _OPENMP #include #endif PYTHONIC_NS_BEGIN namespace utils { /** Light-weight shared_ptr like-class * * Unlike std::shared_ptr, it allocates the memory itself using new. */ template template shared_ref::memory::memory(Types &&... args) : ptr(std::forward(args)...), count(1), foreign(nullptr) { } template shared_ref::shared_ref(no_memory const &) noexcept : mem(nullptr) { } template shared_ref::shared_ref(no_memory &&) noexcept : mem(nullptr) { } template template shared_ref::shared_ref(Types &&... args) : mem(new (std::nothrow) memory(std::forward(args)...)) { } template shared_ref::shared_ref(shared_ref &&p) noexcept : mem(p.mem) { p.mem = nullptr; } template shared_ref::shared_ref(shared_ref const &p) noexcept : mem(p.mem) { if (mem) acquire(); } template shared_ref::shared_ref(shared_ref &p) noexcept : mem(p.mem) { if (mem) acquire(); } template shared_ref::~shared_ref() noexcept { dispose(); } template void shared_ref::swap(shared_ref &rhs) noexcept { using std::swap; swap(mem, rhs.mem); } template shared_ref &shared_ref::operator=(shared_ref p) noexcept { swap(p); return *this; } template T &shared_ref::operator*() const noexcept { assert(mem); return mem->ptr; } template T *shared_ref::operator->() const noexcept { assert(mem); return &mem->ptr; } template bool shared_ref::operator!=(shared_ref const &other) const noexcept { return mem != other.mem; } template bool shared_ref::operator==(shared_ref const &other) const noexcept { return mem == other.mem; } template void shared_ref::external(extern_type obj_ptr) { assert(mem); mem->foreign = obj_ptr; } template inline extern_type shared_ref::get_foreign() { assert(mem); return mem->foreign; } template void shared_ref::dispose() { if (mem && --mem->count == 0) { #ifdef ENABLE_PYTHON_MODULE if (mem->foreign) { Py_DECREF(mem->foreign); } #endif delete mem; mem = nullptr; } } template void shared_ref::acquire() { assert(mem); ++mem->count; } } PYTHONIC_NS_END #endif