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