// This file is part of Desktop App Toolkit, // a set of libraries for developing nice desktop applications. // // For license and copyright information please follow this link: // https://github.com/desktop-app/legal/blob/master/LEGAL // #pragma once #include "base/basic_types.h" #include #include #include #include template class object_ptr; namespace base { template class weak_qptr { public: weak_qptr() = default; weak_qptr(std::nullptr_t) noexcept { } template < typename Other, typename = std::enable_if_t>> weak_qptr(Other *value) noexcept : _object(static_cast(value)) { } template < typename Other, typename = std::enable_if_t>> weak_qptr(const QPointer &value) noexcept : weak_qptr(value.data()) { } template < typename Other, typename = std::enable_if_t>> weak_qptr(gsl::not_null value) noexcept : weak_qptr(value.get()) { } template < typename Other, typename = std::enable_if_t>> weak_qptr(const std::unique_ptr &value) noexcept : weak_qptr(value.get()) { } template < typename Other, typename = std::enable_if_t>> weak_qptr(const std::shared_ptr &value) noexcept : weak_qptr(value.get()) { } template < typename Other, typename = std::enable_if_t>> weak_qptr(const std::weak_ptr &value) noexcept : weak_qptr(value.lock().get()) { } template < typename Other, typename = std::enable_if_t>> weak_qptr(const weak_qptr &other) noexcept : _object(other._object) { } template < typename Other, typename = std::enable_if_t>> weak_qptr(weak_qptr &&other) noexcept : _object(std::move(other._object)) { } template < typename Other, typename = std::enable_if_t>> weak_qptr &operator=(Other *value) noexcept { reset(value); return *this; } template < typename Other, typename = std::enable_if_t>> weak_qptr &operator=(const QPointer &value) noexcept { reset(value.data()); return *this; } template < typename Other, typename = std::enable_if_t>> weak_qptr &operator=(gsl::not_null value) noexcept { reset(value.get()); return *this; } template < typename Other, typename = std::enable_if_t>> weak_qptr &operator=(const std::unique_ptr &value) noexcept { reset(value.get()); return *this; } template < typename Other, typename = std::enable_if_t>> weak_qptr &operator=(const std::shared_ptr &value) noexcept { reset(value.get()); return *this; } template < typename Other, typename = std::enable_if_t>> weak_qptr &operator=(const std::weak_ptr &value) noexcept { reset(value.lock().get()); return *this; } template < typename Other, typename = std::enable_if_t>> weak_qptr &operator=(const weak_qptr &other) noexcept { _object = other._object; return *this; } template < typename Other, typename = std::enable_if_t>> weak_qptr &operator=(weak_qptr &&other) noexcept { _object = std::move(other._object); return *this; } [[nodiscard]] bool null() const noexcept { return _object.isNull(); } [[nodiscard]] bool empty() const noexcept { return !_object; } [[nodiscard]] T *get() const noexcept { const auto strong = _object.data(); if constexpr (std::is_const_v) { return static_cast(strong); } else { return const_cast(static_cast(strong)); } } [[nodiscard]] explicit operator bool() const noexcept { return !empty(); } [[nodiscard]] T &operator*() const noexcept { return *get(); } [[nodiscard]] T *operator->() const noexcept { return get(); } friend inline auto operator<=>( weak_qptr, weak_qptr) noexcept = default; void reset(T *value = nullptr) noexcept { _object = static_cast(value); } private: template friend class weak_qptr; QPointer _object; }; template inline bool operator==(const weak_qptr &pointer, std::nullptr_t) noexcept { return (pointer.get() == nullptr); } template inline bool operator==(std::nullptr_t, const weak_qptr &pointer) noexcept { return (pointer == nullptr); } template inline bool operator!=(const weak_qptr &pointer, std::nullptr_t) noexcept { return !(pointer == nullptr); } template inline bool operator!=(std::nullptr_t, const weak_qptr &pointer) noexcept { return !(pointer == nullptr); } template < typename T, typename = std::enable_if_t>> weak_qptr make_weak(T *value) { return value; } template < typename T, typename = std::enable_if_t>> weak_qptr make_weak(gsl::not_null value) { return value; } template < typename T, typename = std::enable_if_t>> weak_qptr make_weak(const std::unique_ptr &value) { return value; } template < typename T, typename = std::enable_if_t>> weak_qptr make_weak(const std::shared_ptr &value) { return value; } template < typename T, typename = std::enable_if_t>> weak_qptr make_weak(const std::weak_ptr &value) { return value; } template weak_qptr make_weak(const object_ptr &value) { return value.data(); } } // namespace base namespace crl { template struct guard_traits; template struct guard_traits, void> { static base::weak_qptr create(const base::weak_qptr &value) { return value; } static base::weak_qptr create(base::weak_qptr &&value) { return std::move(value); } static bool check(const base::weak_qptr &guard) { return guard.get() != nullptr; } }; } // namespace crl