#pragma once #include "weak-borrowed-ptr.hpp" #ifdef __GNUG__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-function" #endif namespace floormat { template detail_bptr::control_block* weak_bptr::_copy(detail_bptr::control_block* ptr) { if (ptr && ptr->_ptr) { ++ptr->_soft_count; return ptr; } else return nullptr; } template weak_bptr& weak_bptr::_copy_assign(detail_bptr::control_block* other) noexcept { if (blk != other) { detail_bptr::control_block::weak_decrement(blk); if (other && other->_ptr) { ++other->_soft_count; blk = other; } else blk = nullptr; } return *this; } template weak_bptr& weak_bptr::_move_assign(detail_bptr::control_block*& other) noexcept { detail_bptr::control_block::weak_decrement(blk); blk = other; other = nullptr; return *this; } template weak_bptr::weak_bptr(std::nullptr_t) noexcept: blk{nullptr} {} template weak_bptr& weak_bptr::operator=(std::nullptr_t) noexcept { detail_bptr::control_block::weak_decrement(blk); return *this; } template weak_bptr::weak_bptr() noexcept: weak_bptr{nullptr} {} template weak_bptr::~weak_bptr() noexcept { detail_bptr::control_block::weak_decrement(blk); } template template Y> weak_bptr::weak_bptr(const bptr& ptr) noexcept: blk{_copy(ptr.blk)} {} template template Y> weak_bptr::weak_bptr(const weak_bptr& ptr) noexcept: blk{_copy(ptr.blk)} {} template weak_bptr::weak_bptr(const weak_bptr& ptr) noexcept: blk{_copy(ptr.blk)} {} template template Y> weak_bptr& weak_bptr::operator=(const bptr& ptr) noexcept { return _copy_assign(ptr.blk); } template template Y> weak_bptr& weak_bptr::operator=(const weak_bptr& ptr) noexcept { return _copy_assign(ptr.blk); } template weak_bptr& weak_bptr::operator=(const weak_bptr& ptr) noexcept { return _copy_assign(ptr.blk); } template template Y> weak_bptr::weak_bptr(weak_bptr&& ptr) noexcept: blk{ptr.blk} { ptr.blk = nullptr; } template weak_bptr::weak_bptr(weak_bptr&& ptr) noexcept: blk{ptr.blk} { ptr.blk = nullptr; } template template Y> weak_bptr& weak_bptr::operator=(weak_bptr&& ptr) noexcept { return _move_assign(ptr.blk); } template weak_bptr& weak_bptr::operator=(weak_bptr&& ptr) noexcept { return _move_assign(ptr.blk); } template void weak_bptr::reset() noexcept { if (blk) detail_bptr::control_block::weak_decrement(blk); } template void weak_bptr::swap(weak_bptr& other) noexcept { floormat::swap(blk, other.blk); } template uint32_t weak_bptr::use_count() const noexcept { if (blk && blk->_ptr) return blk->_hard_count; else return 0; } template bool weak_bptr::expired() const noexcept { return use_count() == 0; } template bptr weak_bptr::lock() const noexcept { if (blk && blk->_ptr) { fm_bptr_assert(blk->_hard_count > 0); ++blk->_soft_count; ++blk->_hard_count; bptr ret{nullptr}; ret.blk = blk; return ret; } else return bptr{nullptr}; } template bool weak_bptr::operator==(const weak_bptr& other) const noexcept { return lock().get() == other.lock().get(); } } // namespace floormat #ifdef __GNUG__ #pragma GCC diagnostic pop #endif