#ifndef XRPL_BASICS_SHAREDWEAKCACHEPOINTER_H_INCLUDED #define XRPL_BASICS_SHAREDWEAKCACHEPOINTER_H_INCLUDED #include #include namespace ripple { /** A combination of a std::shared_ptr and a std::weak_pointer. This class is a wrapper to a `std::variant` This class is useful for storing intrusive pointers in tagged caches using less memory than storing both pointers directly. */ template class SharedWeakCachePointer { public: SharedWeakCachePointer() = default; SharedWeakCachePointer(SharedWeakCachePointer const& rhs); template requires std::convertible_to SharedWeakCachePointer(std::shared_ptr const& rhs); SharedWeakCachePointer(SharedWeakCachePointer&& rhs); template requires std::convertible_to SharedWeakCachePointer(std::shared_ptr&& rhs); SharedWeakCachePointer& operator=(SharedWeakCachePointer const& rhs); template requires std::convertible_to SharedWeakCachePointer& operator=(std::shared_ptr const& rhs); template requires std::convertible_to SharedWeakCachePointer& operator=(std::shared_ptr&& rhs); ~SharedWeakCachePointer(); /** Return a strong pointer if this is already a strong pointer (i.e. don't lock the weak pointer. Use the `lock` method if that's what's needed) */ std::shared_ptr const& getStrong() const; /** Return true if this is a strong pointer and the strong pointer is seated. */ explicit operator bool() const noexcept; /** Set the pointer to null, decrement the appropriate ref count, and run the appropriate release action. */ void reset(); /** If this is a strong pointer, return the raw pointer. Otherwise return null. */ T* get() const; /** If this is a strong pointer, return the strong count. Otherwise return 0 */ std::size_t use_count() const; /** Return true if there is a non-zero strong count. */ bool expired() const; /** If this is a strong pointer, return the strong pointer. Otherwise attempt to lock the weak pointer. */ std::shared_ptr lock() const; /** Return true is this represents a strong pointer. */ bool isStrong() const; /** Return true is this represents a weak pointer. */ bool isWeak() const; /** If this is a weak pointer, attempt to convert it to a strong pointer. @return true if successfully converted to a strong pointer (or was already a strong pointer). Otherwise false. */ bool convertToStrong(); /** If this is a strong pointer, attempt to convert it to a weak pointer. @return false if the pointer is null. Otherwise return true. */ bool convertToWeak(); private: std::variant, std::weak_ptr> combo_; }; } // namespace ripple #endif