File indexing completed on 2024-06-16 04:23:17

0001 /*
0002     SPDX-FileCopyrightText: 2005 Frerich Raabe <raabe@kde.org>
0003     SPDX-FileCopyrightText: 2007-2008 David Nolden <david.nolden.kdevelop@art-master.de>
0004     SPDX-FileCopyrightText: 2014 Kevin Funk <kfunk@kde.org>
0005 
0006     SPDX-License-Identifier: BSD-2-Clause
0007 */
0008 
0009 #ifndef KDEVPLATFORM_TYPEPOINTER_H
0010 #define KDEVPLATFORM_TYPEPOINTER_H
0011 
0012 #include <QExplicitlySharedDataPointer>
0013 
0014 namespace KDevelop {
0015 /**
0016  * @brief QExplicitlySharedDataPointer wrapper with convenience functions attached
0017  */
0018 template <class T>
0019 class TypePtr
0020     : public QExplicitlySharedDataPointer<T>
0021 {
0022     using Base = QExplicitlySharedDataPointer<T>;
0023 
0024 public:
0025     TypePtr() = default;
0026     explicit TypePtr(T* data) noexcept
0027         : Base(data)
0028     {
0029     }
0030     TypePtr& operator=(T* data) noexcept
0031     {
0032         Base::operator=(data);
0033         return *this;
0034     }
0035     TypePtr(const TypePtr&) = default;
0036     TypePtr& operator=(const TypePtr&) = default;
0037     TypePtr(TypePtr&&) = default;
0038     TypePtr& operator=(TypePtr&&) = default;
0039 
0040     template<class X>
0041     TypePtr(const TypePtr<X>& o) noexcept
0042         : Base(o)
0043     {
0044     }
0045 
0046     template<class X>
0047     TypePtr(TypePtr<X>&& o) noexcept
0048         : Base(std::move(o))
0049     {
0050     }
0051 
0052     /**
0053      * Convert TypePtr<T> to TypePtr<U>, using a @c dynamic_cast.
0054      * This will compile whenever T* and U* are compatible, i.e.
0055      * T is a subclass of U or vice-versa.
0056      * Example syntax:
0057      * @code
0058      *   TypePtr<T> tPtr;
0059      *   TypePtr<U> uPtr = tPtr.dynamicCast<U>();
0060      * @endcode
0061      * Since a dynamic_cast is used, if U derives from T, and tPtr isn't an instance of U, uPtr will be 0.
0062      */
0063     template<class U>
0064     TypePtr<U> dynamicCast() const
0065     {
0066         return TypePtr<U>(dynamic_cast<U*>(Base::data()));
0067     }
0068 
0069     /**
0070      * Convert TypePtr<T> to TypePtr<U>, using a @c static_cast.
0071      * This will compile whenever T* and U* are compatible, i.e.
0072      * T is a subclass of U or vice-versa.
0073      * Example syntax:
0074      * @code
0075      *   TypePtr<T> tPtr;
0076      *   TypePtr<U> uPtr = tPtr.staticCast<U>();
0077      * @endcode
0078      */
0079     template<class U>
0080     TypePtr<U> staticCast() const
0081     {
0082         Q_ASSERT(!Base::data() || dynamic_cast<U*>(Base::data()));
0083         return TypePtr<U>(static_cast<U*>(Base::data()));
0084     }
0085 };
0086 }
0087 
0088 #endif