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

0001 /*
0002     SPDX-FileCopyrightText: 2007-2009 David Nolden <david.nolden.kdevelop@art-master.de>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-only
0005 */
0006 
0007 #ifndef KDEVPLATFORM_INDEXEDTYPE_H
0008 #define KDEVPLATFORM_INDEXEDTYPE_H
0009 
0010 #include "abstracttype.h"
0011 
0012 #include <serialization/referencecounting.h>
0013 
0014 namespace KDevelop {
0015 /**
0016  * \short Indexed type pointer.
0017  *
0018  * IndexedType is a class which references a type by an index.
0019  * This way the type can be stored to disk.
0020  *
0021  * This class does "disk reference counting"
0022  * @warning Do not use this after QCoreApplication::aboutToQuit() has been emitted, items that are not disk-referenced will be invalid at that point
0023  */
0024 class KDEVPLATFORMLANGUAGE_EXPORT IndexedType
0025     : public ReferenceCountManager
0026 {
0027 public:
0028     IndexedType(const IndexedType& rhs);
0029     /**
0030      * Construct an indexed type from the @p type
0031      */
0032     explicit IndexedType(const AbstractType* type);
0033     /**
0034      * Construct an indexed type from the data in the @c TypePtr @p type
0035      *
0036      * NOTE: This is required to ensure we don't call `IndexedType(uint)` with a `TypePtr` casted implicitly to bool.
0037      */
0038     explicit IndexedType(const AbstractType::Ptr& type)
0039         : IndexedType(type.data())
0040     {
0041     }
0042     explicit IndexedType(uint index = 0);
0043 
0044     ~IndexedType();
0045 
0046     IndexedType& operator=(const IndexedType& rhs);
0047 
0048     /**
0049      * Access the type.
0050      *
0051      * \returns the type pointer, or null if this index is invalid.
0052      */
0053     AbstractType::Ptr abstractType() const;
0054 
0055     /**
0056      * Access the type, dynamically casted to the type you provide.
0057      *
0058      * \returns the type pointer, or null if this index is invalid.
0059      */
0060     template<class T>
0061     TypePtr<T> type() const
0062     {
0063         return abstractType().dynamicCast<T>();
0064     }
0065 
0066     /// Determine if the type is valid. \returns true if valid, otherwise false.
0067     bool isValid() const
0068     {
0069         return ( bool )m_index;
0070     }
0071 
0072     /// \copydoc
0073     operator bool() const {
0074         return ( bool )m_index;
0075     }
0076 
0077     /// Equivalence operator. \param rhs indexed type to compare. \returns true if equal (or both invalid), otherwise false.
0078     bool operator==(const IndexedType& rhs) const
0079     {
0080         return m_index == rhs.m_index;
0081     }
0082 
0083     /// Not equal operator. \param rhs indexed type to compare. \returns true if types are not the same, otherwise false.
0084     bool operator!=(const IndexedType& rhs) const
0085     {
0086         return m_index != rhs.m_index;
0087     }
0088 
0089     /// Less than operator, \param rhs indexed type to compare.
0090     /// \returns true if integral index value of this type is lower than the index of \p rhs.
0091     bool operator<(const IndexedType& rhs) const
0092     {
0093         return m_index < rhs.m_index;
0094     }
0095 
0096     /// Access the type's hash value. \returns the hash value.
0097     uint hash() const
0098     {
0099         return m_index >> 1;
0100     }
0101 
0102     /// Access the type's index. \returns the index.
0103     uint index() const
0104     {
0105         return m_index;
0106     }
0107 
0108 private:
0109     ///This class must _never_ hold more than one unsigned integer
0110     uint m_index;
0111 };
0112 
0113 inline uint qHash(const IndexedType& type)
0114 {
0115     return type.hash();
0116 }
0117 }
0118 
0119 Q_DECLARE_TYPEINFO(KDevelop::IndexedType, Q_MOVABLE_TYPE);
0120 
0121 #endif