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
34 class AbstractFunctionDeclaration
;
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
50 class KDEVPLATFORMLANGUAGE_EXPORT DUChainPointerData
: public KShared
{
53 * Will return zero once the pointed-to object was deleted
58 * Will return zero once the pointed-to object was deleted
60 DUChainBase
* base() const;
62 ///Default-initialization of an invalid reference
65 ~DUChainPointerData();
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
;
73 Q_DISABLE_COPY(DUChainPointerData
)
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.
88 class DUChainPointer
{
89 template<class OtherType
>
90 friend class DUChainPointer
;
93 DUChainPointer() : d(KSharedPtr
<DUChainPointerData
>(0)) {
96 DUChainPointer(const DUChainPointer
& rhs
)
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()) )
114 explicit DUChainPointer( KSharedPtr
<DUChainPointerData
> rhs
) {
115 if( dynamic_cast<Type
*>(rhs
->base()) )
119 explicit DUChainPointer( Type
* 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 {
139 return *static_cast<Type
*>(d
->base());
142 Type
* operator->() const {
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()) );
156 return DUChainPointer
<NewType
>();
162 return static_cast<Type
*>(d
->base());
165 DUChainPointer
<Type
>& operator= ( Type
* rhs
) {
167 d
= rhs
->weakPointer();
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
)