Add AbstractDeclarationNavigationContext, and move the html-method from
[kdevelopdvcssupport.git] / language / duchain / duchainpointer.h
blob1b3a2877aac6b460ca9c7d2f2cc09164bea15bae
1 /*
2 Copyright 2007 David Nolden <david.nolden.kdevelop@art-master.de>
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 Boston, MA 02110-1301, USA.
19 #ifndef DUCHAINPOINTER_H
20 #define DUCHAINPOINTER_H
22 #include <QtCore/QMetaType>
23 #include <ksharedptr.h>
24 #include "../languageexport.h"
26 //krazy:excludeall=dpointer
28 namespace KDevelop {
30 class DUContext;
31 class TopDUContext;
32 class DUChainBase;
33 class Declaration;
34 class AbstractFunctionDeclaration;
36 /**
37 * Whenever the du-chain is unlocked and locked again, any du-chain item may have been deleted in between.
38 * For that reason, the following class should be used to make sure that no deleted objects are accessed. It contains a pointer
39 * that will be reset to zero once the pointed object is deleted.
41 * Access to the data must still be serialized through duchain-locking. Using this comes with no additional cost.
43 * In practice this means:
44 * Store an instance of DUChainPointer instead of a pointer to the du-chain object.
45 * Then, access the eventually still existing object by calling pointer->base().
47 * To make it even more convenient see DUChainPointer
48 * */
50 class KDEVPLATFORMLANGUAGE_EXPORT DUChainPointerData : public KShared {
51 public:
52 /**
53 * Will return zero once the pointed-to object was deleted
54 * */
55 DUChainBase* base();
57 /**
58 * Will return zero once the pointed-to object was deleted
59 * */
60 DUChainBase* base() const;
62 ///Default-initialization of an invalid reference
63 DUChainPointerData();
65 ~DUChainPointerData();
67 private:
68 ///Should not be used from outside, but is needed sometimes to construct an invalid dummy-pointer
69 DUChainPointerData( DUChainBase* base );
71 friend class DUChainBase;
72 DUChainBase * m_base;
73 Q_DISABLE_COPY(DUChainPointerData)
76 /**
77 * A smart-pointer similar class that conveniently wraps around DUChainPointerData without
78 * too many dynamic casts.
80 * It can be used like a normal pointer. In order to cast between pointer types, you should
81 * use the staticCast() and dynamicCast() functions as appropriate.
83 * Access must be serialized by holding the KDevelop::DUChain::lock() as appropriate for the
84 * function(s) being called.
85 **/
87 template<class Type>
88 class DUChainPointer {
89 template<class OtherType>
90 friend class DUChainPointer;
92 public:
93 DUChainPointer() : d(KSharedPtr<DUChainPointerData>(0)) {
96 DUChainPointer(const DUChainPointer& rhs)
97 : d(rhs.d)
101 ///This constructor includes dynamic casting. If the object cannot be casted to the type, the constructed DUChainPointer will have value zero.
102 template<class OtherType>
103 explicit DUChainPointer( OtherType* rhs ) {
104 if( dynamic_cast<Type*>(rhs) )
105 d = rhs->weakPointer();
108 template<class OtherType>
109 explicit DUChainPointer( DUChainPointer<OtherType> rhs ) {
110 if( dynamic_cast<Type*>(rhs.data()) )
111 d = rhs.d;
114 explicit DUChainPointer( KSharedPtr<DUChainPointerData> rhs ) {
115 if( dynamic_cast<Type*>(rhs->base()) )
116 d = rhs;
119 explicit DUChainPointer( Type* rhs ) {
120 if( rhs )
121 d = rhs->weakPointer();
124 bool operator ==( const DUChainPointer<Type>& rhs ) const {
125 return d.data() == rhs.d.data();
128 bool operator !=( const DUChainPointer<Type>& rhs ) const {
129 return d.data() != rhs.d.data();
132 ///Returns whether the pointed object is still existing
133 operator bool() const {
134 return d && d->base();
137 Type& operator* () const {
138 Q_ASSERT(d);
139 return *static_cast<Type*>(d->base());
142 Type* operator->() const {
143 Q_ASSERT(d);
144 return static_cast<Type*>(d->base());
147 bool operator<(const DUChainPointer<Type>& rhs) const {
148 return d.data() < rhs.d.data();
151 template<class NewType>
152 DUChainPointer<NewType> dynamicCast() const {
153 if( dynamic_cast<NewType*>( const_cast<DUChainPointerData*>(d->base()) ) ) //When the reference to the pointer is constant that doesn't mean that the pointed object needs to be constant
154 return DUChainPointer<NewType>( static_cast<NewType*>(d->base()) );
155 else
156 return DUChainPointer<NewType>();
159 Type* data() const {
160 if( !d )
161 return 0;
162 return static_cast<Type*>(d->base());
165 DUChainPointer<Type>& operator= ( Type* rhs ) {
166 if( rhs )
167 d = rhs->weakPointer();
168 else
169 d = 0;
171 return *this;
174 private:
175 KSharedPtr<DUChainPointerData> d;
178 typedef DUChainPointer<DUChainBase> DUChainBasePointer;
179 typedef DUChainPointer<DUContext> DUContextPointer;
180 typedef DUChainPointer<TopDUContext> TopDUContextPointer;
181 typedef DUChainPointer<Declaration> DeclarationPointer;
182 typedef DUChainPointer<AbstractFunctionDeclaration> FunctionDeclarationPointer;
185 Q_DECLARE_METATYPE( KDevelop::DUChainBasePointer )
187 #endif