/* * Copyright (c) 2022, Tim Schumacher * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include namespace AK { template class MaybeOwned { AK_MAKE_NONCOPYABLE(MaybeOwned); public: template U> MaybeOwned(NonnullOwnPtr handle) : m_handle(static_cast&&>(move(handle))) { } // This is made `explicit` to not accidentally create a non-owning MaybeOwned, // which may not always be intended. explicit MaybeOwned(T& handle) : m_handle(&handle) { } MaybeOwned(MaybeOwned&&) = default; MaybeOwned& operator=(MaybeOwned&&) = default; template U> MaybeOwned(MaybeOwned&& other) : m_handle(downcast(move(other.m_handle))) { } T* ptr() { if (m_handle.template has()) return m_handle.template get(); else return m_handle.template get>(); } T const* ptr() const { if (m_handle.template has()) return m_handle.template get(); else return m_handle.template get>(); } T* operator->() { return ptr(); } T const* operator->() const { return ptr(); } T& operator*() { return *ptr(); } T const& operator*() const { return *ptr(); } bool is_owned() const { return m_handle.template has>(); } private: template friend class MaybeOwned; template using Handle = Variant, HT*>; template Handle downcast(Handle&& variant) { if (variant.template has()) return variant.template get(); else return static_cast&&>(move(variant.template get>())); } Handle m_handle; }; } #if USING_AK_GLOBALLY using AK::MaybeOwned; #endif