Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : : #ifndef _REF_HXX
20 : : #define _REF_HXX
21 : :
22 : : #include "tools/toolsdllapi.h"
23 : : #include <vector>
24 : :
25 : : #define PRV_SV_IMPL_REF_COUNTERS( ClassName, Ref, AddRef, AddNextRef, ReleaseRef, Init, pRefbase ) \
26 : : inline ClassName##Ref::ClassName##Ref( const ClassName##Ref & rObj ) \
27 : : { pObj = rObj.pObj; if( pObj ) { Init pRefbase->AddNextRef; } } \
28 : : inline ClassName##Ref::ClassName##Ref( ClassName * pObjP ) \
29 : : { pObj = pObjP; if( pObj ) { Init pRefbase->AddRef; } } \
30 : : inline void ClassName##Ref::Clear() \
31 : : { \
32 : : if( pObj ) \
33 : : { \
34 : : ClassName* const pRefObj = pRefbase; \
35 : : pObj = 0; \
36 : : pRefObj->ReleaseRef; \
37 : : } \
38 : : } \
39 : : inline ClassName##Ref::~ClassName##Ref() \
40 : : { if( pObj ) { pRefbase->ReleaseRef; } } \
41 : : inline ClassName##Ref & ClassName##Ref:: \
42 : : operator = ( const ClassName##Ref & rObj ) \
43 : : { \
44 : : if( rObj.pObj ) rObj.pRefbase->AddNextRef; \
45 : : ClassName* const pRefObj = pRefbase; \
46 : : pObj = rObj.pObj; \
47 : : Init if( pRefObj ) { pRefObj->ReleaseRef; } \
48 : : return *this; \
49 : : } \
50 : : inline ClassName##Ref & ClassName##Ref::operator = ( ClassName * pObjP ) \
51 : : { return *this = ClassName##Ref( pObjP ); }
52 : :
53 : : #define PRV_SV_DECL_REF_LOCK(ClassName, Ref) \
54 : : protected: \
55 : : ClassName * pObj; \
56 : : public: \
57 : : inline ClassName##Ref() { pObj = 0; } \
58 : : inline ClassName##Ref( const ClassName##Ref & rObj ); \
59 : : inline ClassName##Ref( ClassName * pObjP ); \
60 : : inline void Clear(); \
61 : : inline ~ClassName##Ref(); \
62 : : inline ClassName##Ref & operator = ( const ClassName##Ref & rObj ); \
63 : : inline ClassName##Ref & operator = ( ClassName * pObj ); \
64 : : inline sal_Bool Is() const { return pObj != NULL; } \
65 : : inline ClassName * operator & () const { return pObj; } \
66 : : inline ClassName * operator -> () const { return pObj; } \
67 : : inline ClassName & operator * () const { return *pObj; } \
68 : : inline operator ClassName * () const { return pObj; }
69 : :
70 : : #define PRV_SV_DECL_REF( ClassName ) \
71 : : PRV_SV_DECL_REF_LOCK( ClassName, Ref )
72 : :
73 : : #define SV_DECL_REF( ClassName ) \
74 : : class ClassName; \
75 : : class ClassName##Ref \
76 : : { \
77 : : PRV_SV_DECL_REF( ClassName ) \
78 : : };
79 : :
80 : : #define SV_DECL_LOCK( ClassName ) \
81 : : class ClassName; \
82 : : class ClassName##Lock \
83 : : { \
84 : : PRV_SV_DECL_REF_LOCK( ClassName, Lock ) \
85 : : };
86 : :
87 : : #define SV_IMPL_REF( ClassName ) \
88 : : PRV_SV_IMPL_REF_COUNTERS( ClassName, Ref, AddRef(), AddNextRef(),\
89 : : ReleaseReference(), EMPTYARG, pObj )
90 : :
91 : : #define SV_IMPL_LOCK( ClassName ) \
92 : : PRV_SV_IMPL_REF_COUNTERS( ClassName, Lock, OwnerLock( sal_True ), \
93 : : OwnerLock( sal_True ), OwnerLock( sal_False ), \
94 : : EMPTYARG, pObj )
95 : :
96 : : #define SV_DECL_IMPL_REF(ClassName) \
97 : : SV_DECL_REF(ClassName) \
98 : : SV_IMPL_REF(ClassName)
99 : :
100 : : template<typename T>
101 : : class SvRefMemberList : private std::vector<T>
102 : : {
103 : : private:
104 : : typedef typename std::vector<T> base_t;
105 : :
106 : : public:
107 : : using base_t::size;
108 : : using base_t::front;
109 : : using base_t::back;
110 : : using base_t::operator[];
111 : : using base_t::begin;
112 : : using base_t::end;
113 : : using typename base_t::iterator;
114 : : using typename base_t::const_iterator;
115 : : using base_t::rbegin;
116 : : using base_t::rend;
117 : : using typename base_t::reverse_iterator;
118 : : using base_t::empty;
119 : :
120 : : inline ~SvRefMemberList() { clear(); }
121 : : inline void clear()
122 : : {
123 : : for( typename base_t::const_iterator it = base_t::begin(); it != base_t::end(); ++it )
124 : : {
125 : : T p = *it;
126 : : if( p )
127 : : p->ReleaseReference();
128 : : }
129 : : base_t::clear();
130 : : }
131 : :
132 : : inline void push_back( T p )
133 : : {
134 : : base_t::push_back( p );
135 : : p->AddRef();
136 : : }
137 : :
138 : : inline void insert(const SvRefMemberList& rOther)
139 : : {
140 : : for( typename base_t::const_iterator it = rOther.begin(); it != rOther.end(); ++it )
141 : : {
142 : : push_back(*it);
143 : : }
144 : : }
145 : :
146 : : inline T pop_back()
147 : : {
148 : : T p = base_t::back();
149 : : base_t::pop_back();
150 : : if( p )
151 : : p->ReleaseReference();
152 : : return p;
153 : : }
154 : : };
155 : :
156 : : #define SV_NO_DELETE_REFCOUNT 0x80000000
157 : :
158 : : class TOOLS_DLLPUBLIC SvRefBase
159 : : {
160 : : sal_uIntPtr nRefCount;
161 : :
162 : : protected:
163 : : virtual ~SvRefBase();
164 : : virtual void QueryDelete();
165 : :
166 : : public:
167 : 0 : SvRefBase() { nRefCount = SV_NO_DELETE_REFCOUNT; }
168 : : SvRefBase( const SvRefBase & /* rObj */ )
169 : : { nRefCount = SV_NO_DELETE_REFCOUNT; }
170 : : SvRefBase & operator = ( const SvRefBase & ) { return *this; }
171 : :
172 : 0 : void RestoreNoDelete()
173 : : {
174 [ # # ]: 0 : if( nRefCount < SV_NO_DELETE_REFCOUNT )
175 : 0 : nRefCount += SV_NO_DELETE_REFCOUNT;
176 : 0 : }
177 : : sal_uIntPtr AddMulRef( sal_uIntPtr n ) { return nRefCount += n; }
178 : 22369 : sal_uIntPtr AddNextRef() { return ++nRefCount; }
179 : 22369 : sal_uIntPtr AddRef()
180 : : {
181 [ + + ]: 22369 : if( nRefCount >= SV_NO_DELETE_REFCOUNT )
182 : 2 : nRefCount -= SV_NO_DELETE_REFCOUNT;
183 : 22369 : return ++nRefCount;
184 : : }
185 : 44533 : void ReleaseReference()
186 : : {
187 [ + + ]: 44533 : if( !--nRefCount )
188 : 22164 : QueryDelete();
189 : 44533 : }
190 : 0 : sal_uIntPtr ReleaseRef()
191 : : {
192 : 0 : sal_uIntPtr n = --nRefCount;
193 [ # # ]: 0 : if( !n )
194 : 0 : QueryDelete();
195 : 0 : return n;
196 : : }
197 : : sal_uIntPtr GetRefCount() const { return nRefCount; }
198 : : };
199 : :
200 : : #ifndef EMPTYARG
201 : : #define EMPTYARG
202 : : #endif
203 : :
204 : : SV_DECL_IMPL_REF(SvRefBase)
205 : :
206 [ # # ]: 0 : class SvCompatWeakHdl : public SvRefBase
207 : : {
208 : : friend class SvCompatWeakBase;
209 : : void* _pObj;
210 : : SvCompatWeakHdl( void* pObj ) : _pObj( pObj ) {}
211 : :
212 : : public:
213 : : void ResetWeakBase( ) { _pObj = 0; }
214 : : void* GetObj() { return _pObj; }
215 : : };
216 : :
217 : : SV_DECL_IMPL_REF( SvCompatWeakHdl )
218 : :
219 : : class SvCompatWeakBase
220 : : {
221 : : SvCompatWeakHdlRef _xHdl;
222 : :
223 : : public:
224 : : SvCompatWeakHdl* GetHdl() { return _xHdl; }
225 : :
226 : : // does not use Initalizer due to compiler warnings
227 : : SvCompatWeakBase( void* pObj ) { _xHdl = new SvCompatWeakHdl( pObj ); }
228 : : ~SvCompatWeakBase() { _xHdl->ResetWeakBase(); }
229 : : };
230 : :
231 : : #define SV_DECL_COMPAT_WEAK( ClassName ) \
232 : : class ClassName##Weak \
233 : : { \
234 : : SvCompatWeakHdlRef _xHdl; \
235 : : public: \
236 : : inline ClassName##Weak( ) {} \
237 : : inline ClassName##Weak( ClassName* pObj ) { \
238 : : if( pObj ) _xHdl = pObj->GetHdl(); } \
239 : : inline void Clear() { _xHdl.Clear(); } \
240 : : inline ClassName##Weak& operator = ( ClassName * pObj ) { \
241 : : _xHdl = pObj ? pObj->GetHdl() : 0; return *this; } \
242 : : inline sal_Bool Is() const { \
243 : : return _xHdl.Is() && _xHdl->GetObj(); } \
244 : : inline ClassName * operator & () const { \
245 : : return (ClassName*) ( _xHdl.Is() ? _xHdl->GetObj() : 0 ); } \
246 : : inline ClassName * operator -> () const { \
247 : : return (ClassName*) ( _xHdl.Is() ? _xHdl->GetObj() : 0 ); } \
248 : : inline ClassName & operator * () const { \
249 : : return *(ClassName*) _xHdl->GetObj(); } \
250 : : inline operator ClassName * () const { \
251 : : return (ClassName*) (_xHdl.Is() ? _xHdl->GetObj() : 0 ); } \
252 : : };
253 : :
254 : : #endif
255 : :
256 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|