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 3762 : 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 619 : inline ~SvRefMemberList() { clear(); }
121 635 : inline void clear()
122 : {
123 28560 : for( typename base_t::const_iterator it = base_t::begin(); it != base_t::end(); ++it )
124 : {
125 27925 : T p = *it;
126 27925 : if( p )
127 27925 : p->ReleaseReference();
128 : }
129 635 : base_t::clear();
130 635 : }
131 :
132 33103 : inline void push_back( T p )
133 : {
134 33103 : base_t::push_back( p );
135 33103 : p->AddRef();
136 33103 : }
137 :
138 0 : inline void insert(const SvRefMemberList& rOther)
139 : {
140 0 : for( typename base_t::const_iterator it = rOther.begin(); it != rOther.end(); ++it )
141 : {
142 0 : push_back(*it);
143 : }
144 0 : }
145 :
146 8 : inline T pop_back()
147 : {
148 8 : T p = base_t::back();
149 8 : base_t::pop_back();
150 8 : if( p )
151 8 : p->ReleaseReference();
152 8 : 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 595206 : SvRefBase() { nRefCount = SV_NO_DELETE_REFCOUNT; }
168 12039 : SvRefBase( const SvRefBase & /* rObj */ )
169 12039 : { nRefCount = SV_NO_DELETE_REFCOUNT; }
170 21339 : 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 288291 : sal_uIntPtr AddNextRef() { return ++nRefCount; }
179 650466 : sal_uIntPtr AddRef()
180 : {
181 650466 : if( nRefCount >= SV_NO_DELETE_REFCOUNT )
182 411934 : nRefCount -= SV_NO_DELETE_REFCOUNT;
183 650466 : return ++nRefCount;
184 : }
185 647999 : void ReleaseReference()
186 : {
187 647999 : if( !--nRefCount )
188 137921 : QueryDelete();
189 647999 : }
190 77363 : sal_uIntPtr ReleaseRef()
191 : {
192 77363 : sal_uIntPtr n = --nRefCount;
193 77363 : if( !n )
194 65455 : QueryDelete();
195 77363 : return n;
196 : }
197 11888 : sal_uIntPtr GetRefCount() const { return nRefCount; }
198 : };
199 :
200 : #ifndef EMPTYARG
201 : #define EMPTYARG
202 : #endif
203 :
204 7122 : SV_DECL_IMPL_REF(SvRefBase)
205 :
206 2150 : class SvCompatWeakHdl : public SvRefBase
207 : {
208 : friend class SvCompatWeakBase;
209 : void* _pObj;
210 1082 : SvCompatWeakHdl( void* pObj ) : _pObj( pObj ) {}
211 :
212 : public:
213 1075 : void ResetWeakBase( ) { _pObj = 0; }
214 1071 : void* GetObj() { return _pObj; }
215 : };
216 :
217 32548 : SV_DECL_IMPL_REF( SvCompatWeakHdl )
218 :
219 : class SvCompatWeakBase
220 : {
221 : SvCompatWeakHdlRef _xHdl;
222 :
223 : public:
224 2153 : SvCompatWeakHdl* GetHdl() { return _xHdl; }
225 :
226 : // does not use Initalizer due to compiler warnings
227 1082 : SvCompatWeakBase( void* pObj ) { _xHdl = new SvCompatWeakHdl( pObj ); }
228 1075 : ~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: */
|