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 INCLUDED_TOOLS_REF_HXX
20 : #define INCLUDED_TOOLS_REF_HXX
21 :
22 : #include <tools/toolsdllapi.h>
23 : #include <vector>
24 :
25 : namespace tools {
26 :
27 : template<typename T> class SvRef {
28 : public:
29 0 : SvRef(): pObj(0) {}
30 :
31 0 : SvRef(SvRef const & rObj): pObj(rObj.pObj)
32 0 : { if (pObj != 0) pObj->AddNextRef(); }
33 :
34 2 : SvRef(T * pObjP): pObj(pObjP) { if (pObj != 0) pObj->AddRef(); }
35 :
36 2 : ~SvRef() { if (pObj != 0) pObj->ReleaseReference(); }
37 :
38 0 : void Clear() {
39 0 : if (pObj != 0) {
40 0 : T * pRefObj = pObj;
41 0 : pObj = 0;
42 0 : pRefObj->ReleaseReference();
43 : }
44 0 : }
45 :
46 0 : SvRef & operator =(SvRef const & rObj) {
47 0 : if (rObj.pObj != 0) {
48 0 : rObj.pObj->AddNextRef();
49 : }
50 0 : T * pRefObj = pObj;
51 0 : pObj = rObj.pObj;
52 0 : if (pRefObj != 0) {
53 0 : pRefObj->ReleaseReference();
54 : }
55 0 : return *this;
56 : }
57 :
58 0 : bool Is() const { return pObj != 0; }
59 :
60 0 : T * operator &() const { return pObj; }
61 :
62 0 : T * operator ->() const { return pObj; }
63 :
64 0 : T & operator *() const { return *pObj; }
65 :
66 0 : operator T *() const { return pObj; }
67 :
68 : protected:
69 : T * pObj;
70 : };
71 :
72 : }
73 :
74 : template<typename T>
75 0 : class SvRefMemberList : private std::vector<T>
76 : {
77 : private:
78 : typedef typename std::vector<T> base_t;
79 :
80 : public:
81 : using base_t::size;
82 : using base_t::front;
83 : using base_t::back;
84 : using base_t::operator[];
85 : using base_t::begin;
86 : using base_t::end;
87 : using typename base_t::iterator;
88 : using typename base_t::const_iterator;
89 : using base_t::rbegin;
90 : using base_t::rend;
91 : using typename base_t::reverse_iterator;
92 : using base_t::empty;
93 :
94 0 : inline ~SvRefMemberList() { clear(); }
95 0 : inline void clear()
96 : {
97 0 : for( typename base_t::const_iterator it = base_t::begin(); it != base_t::end(); ++it )
98 : {
99 0 : T p = *it;
100 0 : if( p )
101 0 : p->ReleaseReference();
102 : }
103 0 : base_t::clear();
104 0 : }
105 :
106 0 : inline void push_back( T p )
107 : {
108 0 : base_t::push_back( p );
109 0 : p->AddRef();
110 0 : }
111 :
112 0 : inline void insert(const SvRefMemberList& rOther)
113 : {
114 0 : for( typename base_t::const_iterator it = rOther.begin(); it != rOther.end(); ++it )
115 : {
116 0 : push_back(*it);
117 : }
118 0 : }
119 :
120 0 : inline T pop_back()
121 : {
122 0 : T p = base_t::back();
123 0 : base_t::pop_back();
124 0 : if( p )
125 0 : p->ReleaseReference();
126 0 : return p;
127 : }
128 : };
129 :
130 : #define SV_NO_DELETE_REFCOUNT 0x80000000
131 :
132 : class TOOLS_DLLPUBLIC SvRefBase
133 : {
134 : sal_uIntPtr nRefCount;
135 :
136 : protected:
137 : virtual ~SvRefBase();
138 : virtual void QueryDelete();
139 :
140 : public:
141 0 : SvRefBase() { nRefCount = SV_NO_DELETE_REFCOUNT; }
142 0 : SvRefBase( const SvRefBase & /* rObj */ )
143 0 : { nRefCount = SV_NO_DELETE_REFCOUNT; }
144 0 : SvRefBase & operator = ( const SvRefBase & ) { return *this; }
145 :
146 0 : void RestoreNoDelete()
147 : {
148 0 : if( nRefCount < SV_NO_DELETE_REFCOUNT )
149 0 : nRefCount += SV_NO_DELETE_REFCOUNT;
150 0 : }
151 0 : sal_uIntPtr AddNextRef() { return ++nRefCount; }
152 0 : sal_uIntPtr AddRef()
153 : {
154 0 : if( nRefCount >= SV_NO_DELETE_REFCOUNT )
155 0 : nRefCount -= SV_NO_DELETE_REFCOUNT;
156 0 : return ++nRefCount;
157 : }
158 0 : void ReleaseReference()
159 : {
160 0 : if( !--nRefCount )
161 0 : QueryDelete();
162 0 : }
163 0 : sal_uIntPtr ReleaseRef()
164 : {
165 0 : sal_uIntPtr n = --nRefCount;
166 0 : if( !n )
167 0 : QueryDelete();
168 0 : return n;
169 : }
170 0 : sal_uIntPtr GetRefCount() const { return nRefCount; }
171 : };
172 :
173 : typedef tools::SvRef<SvRefBase> SvRefBaseRef;
174 :
175 0 : class SvCompatWeakHdl : public SvRefBase
176 : {
177 : friend class SvCompatWeakBase;
178 : void* _pObj;
179 0 : SvCompatWeakHdl( void* pObj ) : _pObj( pObj ) {}
180 :
181 : public:
182 0 : void ResetWeakBase( ) { _pObj = 0; }
183 0 : void* GetObj() { return _pObj; }
184 : };
185 :
186 : typedef tools::SvRef<SvCompatWeakHdl> SvCompatWeakHdlRef;
187 :
188 : class SvCompatWeakBase
189 : {
190 : SvCompatWeakHdlRef _xHdl;
191 :
192 : public:
193 0 : SvCompatWeakHdl* GetHdl() { return _xHdl; }
194 :
195 : // does not use Initalizer due to compiler warnings
196 0 : SvCompatWeakBase( void* pObj ) { _xHdl = new SvCompatWeakHdl( pObj ); }
197 0 : ~SvCompatWeakBase() { _xHdl->ResetWeakBase(); }
198 : };
199 :
200 : #define SV_DECL_COMPAT_WEAK( ClassName ) \
201 : class ClassName##Weak \
202 : { \
203 : SvCompatWeakHdlRef _xHdl; \
204 : public: \
205 : inline ClassName##Weak( ) {} \
206 : inline ClassName##Weak( ClassName* pObj ) { \
207 : if( pObj ) _xHdl = pObj->GetHdl(); } \
208 : inline void Clear() { _xHdl.Clear(); } \
209 : inline ClassName##Weak& operator = ( ClassName * pObj ) { \
210 : _xHdl = pObj ? pObj->GetHdl() : 0; return *this; } \
211 : inline bool Is() const { \
212 : return _xHdl.Is() && _xHdl->GetObj(); } \
213 : inline ClassName * operator & () const { \
214 : return (ClassName*) ( _xHdl.Is() ? _xHdl->GetObj() : 0 ); } \
215 : inline ClassName * operator -> () const { \
216 : return (ClassName*) ( _xHdl.Is() ? _xHdl->GetObj() : 0 ); } \
217 : inline ClassName & operator * () const { \
218 : return *(ClassName*) _xHdl->GetObj(); } \
219 : inline operator ClassName * () const { \
220 : return (ClassName*) (_xHdl.Is() ? _xHdl->GetObj() : 0 ); } \
221 : };
222 :
223 : #endif
224 :
225 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|