xref: /aoo4110/main/tools/inc/tools/ref.hxx (revision b1cdbd2c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 #ifndef _REF_HXX
24 #define _REF_HXX
25 
26 #include "tools/toolsdllapi.h"
27 #include <tools/list.hxx>
28 #include <tools/link.hxx>
29 
30 //=========================================================================
31 
32 #define PRV_SV_DECL_REF_SIGNATURE( ClassName, Ref )						\
33     inline               ClassName##Ref() { pObj = 0; }					\
34     inline               ClassName##Ref( const ClassName##Ref & rObj );	\
35     inline               ClassName##Ref( ClassName * pObjP );			\
36     inline void          Clear();										\
37     inline               ~ClassName##Ref();								\
38     inline ClassName##Ref & operator = ( const ClassName##Ref & rObj );	\
39     inline ClassName##Ref & operator = ( ClassName * pObj );			\
40     inline sal_Bool            Is() const { return pObj != NULL; }			\
41     inline ClassName *     operator &  () const { return pObj; }		\
42     inline ClassName *     operator -> () const { return pObj; }		\
43     inline ClassName &     operator *  () const { return *pObj; }		\
44     inline operator ClassName * () const { return pObj; }
45 
46 #define PRV_SV_IMPL_REF_COUNTERS( ClassName, Ref, AddRef, AddNextRef, ReleaseRef, Init, pRefbase ) \
47 inline ClassName##Ref::ClassName##Ref( const ClassName##Ref & rObj )		\
48 	{ pObj = rObj.pObj; if( pObj ) { Init pRefbase->AddNextRef; } }			\
49 inline ClassName##Ref::ClassName##Ref( ClassName * pObjP )					\
50 { pObj = pObjP; if( pObj ) { Init pRefbase->AddRef; } }						\
51 inline void ClassName##Ref::Clear()											\
52 {																			\
53     if( pObj )																\
54     {																		\
55 		ClassName* const pRefObj = pRefbase;								\
56         pObj = 0;															\
57         pRefObj->ReleaseRef;												\
58     }																		\
59 }																			\
60 inline ClassName##Ref::~ClassName##Ref()									\
61 { if( pObj ) { pRefbase->ReleaseRef; } }									\
62 inline ClassName##Ref & ClassName##Ref::									\
63             operator = ( const ClassName##Ref & rObj )						\
64 {																			\
65     if( rObj.pObj ) rObj.pRefbase->AddNextRef;								\
66 	ClassName* const pRefObj = pRefbase;									\
67 	pObj = rObj.pObj;														\
68 	Init if( pRefObj ) { pRefObj->ReleaseRef; }								\
69     return *this;															\
70 }																			\
71 inline ClassName##Ref & ClassName##Ref::operator = ( ClassName * pObjP )	\
72 { return *this = ClassName##Ref( pObjP ); }
73 
74 #define PRV_SV_DECL_REF_LOCK(ClassName, Ref)	\
75 protected:										\
76     ClassName * pObj;							\
77 public:											\
78 PRV_SV_DECL_REF_SIGNATURE(ClassName, Ref)
79 
80 #define PRV_SV_DECL_REF( ClassName )			\
81 PRV_SV_DECL_REF_LOCK( ClassName, Ref )
82 
83 #define PRV_SV_DECL_LOCK( ClassName )			\
84 PRV_SV_DECL_REF_LOCK( ClassName, Lock )
85 
86 #define SV_DECL_REF( ClassName )				\
87 class ClassName;								\
88 class ClassName##Ref							\
89 {												\
90 	PRV_SV_DECL_REF( ClassName )				\
91 };
92 
93 #define SV_DECL_LOCK( ClassName )				\
94 class ClassName;								\
95 class ClassName##Lock							\
96 {												\
97 	PRV_SV_DECL_LOCK( ClassName )				\
98 };
99 
100 #define SV_IMPL_REF( ClassName )								\
101 PRV_SV_IMPL_REF_COUNTERS( ClassName, Ref, AddRef(), AddNextRef(),\
102 						  ReleaseReference(), EMPTYARG, pObj )
103 
104 #define SV_IMPL_LOCK( ClassName )									\
105 PRV_SV_IMPL_REF_COUNTERS( ClassName, Lock, OwnerLock( sal_True ), 		\
106 						  OwnerLock( sal_True ), OwnerLock( sal_False ), 	\
107 						  EMPTYARG, pObj )
108 
109 #define SV_DECL_IMPL_REF(ClassName)				\
110     SV_DECL_REF(ClassName)						\
111     SV_IMPL_REF(ClassName)
112 
113 #define SV_DECL_IMPL_LOCK( ClassName )			\
114     SV_DECL_LOCK(ClassName)						\
115     SV_IMPL_LOCK(ClassName)
116 
117 
118 /************************** S v R e f L i s t ****************************/
119 #define PRV_SV_DECL_REF_LIST(CN,EN,vis) \
120 DECLARE_LIST(CN##List,EN)\
121 class vis CN##MemberList : public CN##List\
122 {\
123 public:\
124 inline CN##MemberList();\
125 inline CN##MemberList(sal_uInt16 nInitSz, sal_uInt16 nResize );\
126 inline CN##MemberList( const CN##MemberList & rRef );\
127 inline ~CN##MemberList();\
128 inline CN##MemberList & operator =\
129        ( const CN##MemberList & rRef );\
130 inline void Clear();\
131 inline void Insert( EN p )\
132 { CN##List::Insert( p ); p->AddRef();}\
133 inline void Insert( EN p, sal_uIntPtr nIndex )\
134 { CN##List::Insert( p, nIndex ); p->AddRef();}\
135 inline void Insert( EN p, EN pOld )\
136 { CN##List::Insert( p, pOld ); p->AddRef();}\
137 inline void Append( EN p )\
138 { Insert( p, LIST_APPEND );}\
139 inline EN   Remove();\
140 inline EN   Remove( sal_uIntPtr nIndex );\
141 inline EN   Remove( EN p );\
142 inline EN   Replace( EN p );\
143 inline EN   Replace( EN p, sal_uIntPtr nIndex );\
144 inline EN   Replace( EN pNew, EN pOld );\
145 inline void Append( const CN##MemberList & );\
146 };
147 
148 #define SV_DECL_REF_LIST(CN,EN) \
149 PRV_SV_DECL_REF_LIST(CN,EN,/* empty */)
150 #define SV_DECL_REF_LIST_VISIBILITY(CN,EN,vis) \
151 PRV_SV_DECL_REF_LIST(CN,EN,vis)
152 
153 /************************** S v R e f L i s t ****************************/
154 #define SV_IMPL_REF_LIST( CN, EN ) \
155 inline CN##MemberList::CN##MemberList(){}\
156 inline CN##MemberList::CN##MemberList(sal_uInt16 nInitSz, sal_uInt16 nResize )\
157 	: CN##List( nInitSz, nResize ){}\
158 inline CN##MemberList::CN##MemberList( const CN##MemberList & rRef ) \
159       : CN##List( rRef ) \
160 {\
161     sal_uIntPtr nOldCount = Count(); \
162     EN pEntry = First(); \
163     while( pEntry ) \
164     { pEntry->AddRef(); pEntry = Next(); } \
165     Seek( nOldCount ); /* auch Curser gleich */ \
166 }\
167 inline CN##MemberList::~CN##MemberList() { Clear(); } \
168 inline CN##MemberList & CN##MemberList::operator = \
169                     ( const CN##MemberList & rRef ) \
170 {\
171     CN##MemberList & rList = (CN##MemberList &)rRef; \
172     sal_uIntPtr nOldCount = rList.Count(); \
173     /* Count der Objekte erhoehen */ \
174     EN pEntry = rList.First(); \
175     while( pEntry ) \
176     { pEntry->AddRef(); pEntry = rList.Next(); } \
177     rList.Seek( nOldCount ); /* Curser zurueck */ \
178     /* Liste kopieren */ \
179     Clear(); \
180     CN##List::operator = ( rRef ); \
181     return *this; \
182 }\
183 inline void        CN##MemberList::Clear() \
184 {\
185     EN pEntry = Last();\
186     while( NULL != pEntry )\
187         pEntry = Remove();\
188 }\
189 inline EN CN##MemberList::Remove() \
190 {\
191     EN p = CN##List::Remove(); \
192     if( p ) p->ReleaseReference(); return p; \
193 }\
194 inline EN CN##MemberList::Remove( sal_uIntPtr nIndex ) \
195 {\
196     EN p = CN##List::Remove( nIndex ); \
197     if( p ) p->ReleaseReference(); return p; \
198 }\
199 inline EN CN##MemberList::Remove( EN p ) \
200 {\
201     p = CN##List::Remove( p ); \
202     if( p ) p->ReleaseReference(); return p; \
203 }\
204 inline EN CN##MemberList::Replace( EN p ) \
205 {\
206     p->AddRef(); p = CN##List::Replace( p ); \
207     if( p ) p->ReleaseReference(); return p; \
208 }\
209 inline EN CN##MemberList::Replace( EN p, sal_uIntPtr nIndex ) \
210 {\
211     p->AddRef(); p = CN##List::Replace( p, nIndex ); \
212     if( p ) p->ReleaseReference(); return p; \
213 }\
214 inline EN CN##MemberList::Replace( EN pNew, EN pOld ) \
215 {\
216     pNew->AddRef(); CN##List::Replace( pNew, pOld ); \
217     if( pOld ) pOld->ReleaseReference(); return pOld; \
218 }\
219 inline void CN##MemberList::Append( const CN##MemberList & rList )\
220 {\
221     for( sal_uIntPtr i = 0; i < rList.Count(); i++ )\
222         Append( rList.GetObject( i ) );\
223 }
224 
225 /************************** S V _ D E C L _ R E F _ L I S T **************/
226 #define SV_DECL_IMPL_REF_LIST(ClassName,EntryName) \
227     SV_DECL_REF_LIST(ClassName,EntryName) \
228     SV_IMPL_REF_LIST(ClassName,EntryName)
229 
230 /************************** S v M e m b e r L i s t **********************/
231 #define PRV_SV_DECL_MEMBER_LIST(Class,EntryName)        \
232        Class##MemberList() {}                           \
233 inline Class##MemberList(sal_uInt16 nInitSz,sal_uInt16 nResize);\
234 inline void Insert( EntryName p );                      \
235 inline void Insert( EntryName p, sal_uIntPtr nIndex );        \
236 inline void Insert( EntryName p, EntryName pOld );      \
237 inline void Append( EntryName p );                      \
238 inline EntryName   Remove();                            \
239 inline EntryName   Remove( sal_uIntPtr nIndex );              \
240 inline EntryName   Remove( EntryName p );               \
241 inline EntryName   Replace( EntryName p );              \
242 inline EntryName   Replace( EntryName p, sal_uIntPtr nIndex );\
243 inline EntryName   Replace( EntryName pNew, EntryName pOld );\
244 inline EntryName   GetCurObject() const;\
245 inline EntryName   GetObject( sal_uIntPtr nIndex ) const;\
246 inline sal_uIntPtr       GetPos( const EntryName ) const;\
247 inline sal_uIntPtr       GetPos( const EntryName, sal_uIntPtr nStartIndex,\
248                            sal_Bool bForward = sal_True ) const;\
249 inline EntryName Seek( sal_uIntPtr nIndex );\
250 inline EntryName Seek( EntryName p );\
251 inline EntryName First();\
252 inline EntryName Last();\
253 inline EntryName Next();\
254 inline EntryName Prev();\
255 inline void      Append( const Class##MemberList & rList );
256 
257 #define PRV_SV_IMPL_MEMBER_LIST(ClassName,EntryName,BaseList)\
258 inline ClassName##MemberList::ClassName##MemberList\
259 					(sal_uInt16 nInitSz,sal_uInt16 nResize)\
260 			: BaseList( nInitSz, nResize ){}\
261 inline void ClassName##MemberList::Insert( EntryName p )\
262             {BaseList::Insert(p);}\
263 inline void ClassName##MemberList::Insert( EntryName p, sal_uIntPtr nIdx )\
264             {BaseList::Insert(p,nIdx);}\
265 inline void ClassName##MemberList::Insert( EntryName p, EntryName pOld )\
266             {BaseList::Insert(p,pOld);}\
267 inline void ClassName##MemberList::Append( EntryName p )\
268             {BaseList::Append(p);}\
269 inline EntryName ClassName##MemberList::Remove()\
270             {return (EntryName)BaseList::Remove();}\
271 inline EntryName ClassName##MemberList::Remove( sal_uIntPtr nIdx )\
272             {return (EntryName)BaseList::Remove(nIdx);}\
273 inline EntryName ClassName##MemberList::Remove( EntryName p )\
274             {return (EntryName)BaseList::Remove(p);}\
275 inline EntryName ClassName##MemberList::Replace( EntryName p )\
276             {return (EntryName)BaseList::Replace(p);}\
277 inline EntryName ClassName##MemberList::Replace( EntryName p, sal_uIntPtr nIdx )\
278             {return (EntryName)BaseList::Replace(p,nIdx);}\
279 inline EntryName ClassName##MemberList::Replace( EntryName p, EntryName pOld )\
280             {return (EntryName)BaseList::Replace(p,pOld);}\
281 inline EntryName   ClassName##MemberList::GetCurObject() const\
282             {return (EntryName)BaseList::GetCurObject();}\
283 inline EntryName   ClassName##MemberList::GetObject( sal_uIntPtr nIdx ) const\
284             {return (EntryName)BaseList::GetObject( nIdx );}\
285 inline EntryName ClassName##MemberList::Seek( sal_uIntPtr nIdx )\
286             {return (EntryName)BaseList::Seek( nIdx );}\
287 inline EntryName ClassName##MemberList::Seek( EntryName p )\
288             {return (EntryName)BaseList::Seek( p );}\
289 inline EntryName ClassName##MemberList::First()\
290             {return (EntryName)BaseList::First();}\
291 inline EntryName ClassName##MemberList::Last()\
292             {return (EntryName)BaseList::Last();}\
293 inline EntryName ClassName##MemberList::Next()\
294             {return (EntryName)BaseList::Next();}\
295 inline EntryName ClassName##MemberList::Prev()\
296             {return (EntryName)BaseList::Prev();}\
297 inline void      ClassName##MemberList::Append( const ClassName##MemberList & rList )\
298             {BaseList::Append(rList);}\
299 inline sal_uIntPtr	 ClassName##MemberList::GetPos( const EntryName p) const\
300 			{return BaseList::GetPos( p );}\
301 inline sal_uIntPtr	 ClassName##MemberList::GetPos\
302 					( const EntryName p, sal_uIntPtr nStart, sal_Bool bForward ) const\
303 			{return BaseList::GetPos( p, nStart, bForward );}
304 
305 #define SV_DECL_MEMBER_LIST(ClassName,EntryName)\
306 class ClassName##MemberList : public SvRefBaseMemberList\
307 {\
308 public:\
309     PRV_SV_DECL_MEMBER_LIST(ClassName,EntryName)\
310 };
311 
312 #define SV_IMPL_MEMBER_LIST(ClassName,EntryName)\
313     PRV_SV_IMPL_MEMBER_LIST(ClassName,EntryName,SvRefBaseMemberList)
314 
315 #define SV_DECL_IMPL_MEMBER_LIST(ClassName,EntryName)\
316 SV_DECL_MEMBER_LIST(ClassName,EntryName)\
317 SV_IMPL_MEMBER_LIST(ClassName,EntryName)
318 
319 /************************** S v R e f B a s e ****************************/
320 #define SV_NO_DELETE_REFCOUNT  0x80000000
321 class TOOLS_DLLPUBLIC SvRefBase
322 {
323     sal_uIntPtr nRefCount;
324 #if defined (GCC) && (defined (C281) || defined (C290) || defined (C291))
325 public:
326 #else
327 protected:
328 #endif
329     virtual         ~SvRefBase();
330     virtual void    QueryDelete();
331 public:
SvRefBase()332                     SvRefBase() { nRefCount = SV_NO_DELETE_REFCOUNT; }
SvRefBase(const SvRefBase &)333                     SvRefBase( const SvRefBase & /* rObj */ )
334                     { nRefCount = SV_NO_DELETE_REFCOUNT; }
operator =(const SvRefBase &)335     SvRefBase &     operator = ( const SvRefBase & ) { return *this; }
336 
RestoreNoDelete()337     void            RestoreNoDelete()
338                     {
339                         if( nRefCount < SV_NO_DELETE_REFCOUNT )
340                             nRefCount += SV_NO_DELETE_REFCOUNT;
341                     }
AddMulRef(sal_uIntPtr n)342     sal_uIntPtr          AddMulRef( sal_uIntPtr n ) { return nRefCount += n; }
AddNextRef()343     sal_uIntPtr          AddNextRef() { return ++nRefCount; }
AddRef()344     sal_uIntPtr          AddRef()
345                     {
346                         if( nRefCount >= SV_NO_DELETE_REFCOUNT )
347                             nRefCount -= SV_NO_DELETE_REFCOUNT;
348                         return ++nRefCount;
349                     }
ReleaseReference()350     void			ReleaseReference()
351                     {
352                         if( !--nRefCount )
353                             QueryDelete();
354                     }
ReleaseRef()355     sal_uIntPtr          ReleaseRef()
356                     {
357                         sal_uIntPtr n = --nRefCount;
358                         if( !n )
359                             QueryDelete();
360                         return n;
361                     }
GetRefCount() const362     sal_uIntPtr          GetRefCount() const { return nRefCount; }
363 };
364 
365 //#if 0 // _SOLAR__PRIVATE
366 #ifndef EMPTYARG
367 #define EMPTYARG
368 #endif
369 //#endif
370 
371 SV_DECL_IMPL_REF(SvRefBase)
372 
373 SV_DECL_REF_LIST(SvRefBase,SvRefBase*)
374 
375 class SvWeakBase;
376 class SvWeakHdl : public SvRefBase
377 {
378 	friend class SvWeakBase;
379 	SvWeakBase* _pObj;
380 public:
ResetWeakBase()381 	void ResetWeakBase( ) { _pObj = 0; }
382 private:
SvWeakHdl(SvWeakBase * pObj)383 	SvWeakHdl( SvWeakBase* pObj ) : _pObj( pObj ) {}
384 public:
GetObj()385 	SvWeakBase* GetObj() { return _pObj; }
386 };
387 
388 SV_DECL_IMPL_REF( SvWeakHdl )
389 
390 class SvCompatWeakHdl : public SvRefBase
391 {
392 	friend class SvCompatWeakBase;
393 	void* _pObj;
SvCompatWeakHdl(void * pObj)394 	SvCompatWeakHdl( void* pObj ) : _pObj( pObj ) {}
395 public:
ResetWeakBase()396 	void ResetWeakBase( ) { _pObj = 0; }
GetObj()397 	void* GetObj() { return _pObj; }
398 };
399 
400 SV_DECL_IMPL_REF( SvCompatWeakHdl )
401 
402 class SvWeakBase
403 {
404 	SvWeakHdlRef _xHdl;
405 public:
GetHdl()406 	SvWeakHdl* GetHdl() { return _xHdl; }
407 
408 	// Wg CompilerWarnung nicht ueber Initializer
SvWeakBase()409 	SvWeakBase() { _xHdl = new SvWeakHdl( this ); }
~SvWeakBase()410 	~SvWeakBase() { _xHdl->ResetWeakBase(); }
411 };
412 
413 class SvCompatWeakBase
414 {
415 	SvCompatWeakHdlRef _xHdl;
416 public:
GetHdl()417 	SvCompatWeakHdl* GetHdl() { return _xHdl; }
418 
419 	// Wg CompilerWarnung nicht ueber Initializer
SvCompatWeakBase(void * pObj)420 	SvCompatWeakBase( void* pObj ) { _xHdl = new SvCompatWeakHdl( pObj ); }
~SvCompatWeakBase()421 	~SvCompatWeakBase() { _xHdl->ResetWeakBase(); }
422 };
423 
424 #define SV_DECL_WEAK_IMPL( ClassName, HdlName )						\
425 class ClassName##Weak												\
426 {																	\
427 	HdlName _xHdl;												    \
428 public:																\
429     inline               ClassName##Weak( ) {}           			\
430     inline               ClassName##Weak( ClassName* pObj ) {		\
431 		if( pObj ) _xHdl = pObj->GetHdl(); }						\
432     inline void          Clear() { _xHdl.Clear(); }					\
433     inline ClassName##Weak& operator = ( ClassName * pObj ) {		\
434 		_xHdl = pObj ? pObj->GetHdl() : 0; return *this; }			\
435     inline sal_Bool            Is() const {								\
436 		return _xHdl.Is() && _xHdl->GetObj(); }						\
437     inline ClassName *     operator &  () const {					\
438 		return (ClassName*) ( _xHdl.Is() ? _xHdl->GetObj() : 0 ); }	\
439     inline ClassName *     operator -> () const {					\
440 		return (ClassName*) ( _xHdl.Is() ? _xHdl->GetObj() : 0 ); }	\
441     inline ClassName &     operator *  () const {					\
442 		return *(ClassName*) _xHdl->GetObj(); }						\
443     inline operator ClassName * () const {							\
444 		return (ClassName*) (_xHdl.Is() ? _xHdl->GetObj() : 0 ); }	\
445 };
446 
447 #define SV_DECL_WEAK( ClassName ) SV_DECL_WEAK_IMPL( ClassName, SvWeakHdlRef )
448 #define SV_DECL_COMPAT_WEAK( ClassName ) SV_DECL_WEAK_IMPL( ClassName, SvCompatWeakHdlRef )
449 
450 SV_DECL_WEAK( SvWeakBase )
451 
452 #endif // _Weak_HXX
453