update emoji autocorrect entries from po-files
[LibreOffice.git] / include / tools / ref.hxx
blob7ae2535b5bd0a8d63e0e301970c958288336c5bc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
19 #ifndef INCLUDED_TOOLS_REF_HXX
20 #define INCLUDED_TOOLS_REF_HXX
22 #include <sal/config.h>
24 #include <cassert>
26 #include <tools/toolsdllapi.h>
27 #include <vector>
29 /**
30 This implements similar functionality to boost::intrusive_ptr
33 namespace tools {
35 /** T must be a class that extends SvRefBase */
36 template<typename T> class SAL_DLLPUBLIC_RTTI SvRef {
37 public:
38 SvRef(): pObj(0) {}
40 SvRef(SvRef const & rObj): pObj(rObj.pObj)
42 if (pObj != 0) pObj->AddNextRef();
45 SvRef(T * pObjP): pObj(pObjP)
47 if (pObj != 0) pObj->AddFirstRef();
50 ~SvRef()
52 if (pObj != 0) pObj->ReleaseRef();
55 void Clear()
57 if (pObj != 0) {
58 T * pRefObj = pObj;
59 pObj = 0;
60 pRefObj->ReleaseRef();
64 SvRef & operator =(SvRef const & rObj)
66 if (rObj.pObj != 0) {
67 rObj.pObj->AddNextRef();
69 T * pRefObj = pObj;
70 pObj = rObj.pObj;
71 if (pRefObj != 0) {
72 pRefObj->ReleaseRef();
74 return *this;
77 bool Is() const { return pObj != 0; }
79 T * get() const { return pObj; }
81 T * operator &() const { return pObj; }
83 T * operator ->() const { assert(pObj != 0); return pObj; }
85 T & operator *() const { assert(pObj != 0); return *pObj; }
87 operator T *() const { return pObj; }
89 protected:
90 T * pObj;
95 template<typename T>
96 class SvRefMemberList : private std::vector<T>
98 private:
99 typedef typename std::vector<T> base_t;
101 public:
102 using base_t::size;
103 using base_t::front;
104 using base_t::back;
105 using base_t::operator[];
106 using base_t::begin;
107 using base_t::end;
108 using typename base_t::iterator;
109 using typename base_t::const_iterator;
110 using base_t::rbegin;
111 using base_t::rend;
112 using typename base_t::reverse_iterator;
113 using base_t::empty;
115 inline ~SvRefMemberList() { clear(); }
116 inline void clear()
118 for( typename base_t::const_iterator it = base_t::begin(); it != base_t::end(); ++it )
120 T p = *it;
121 if( p )
122 p->ReleaseRef();
124 base_t::clear();
127 inline void push_back( T p )
129 base_t::push_back( p );
130 p->AddFirstRef();
133 inline void insert(const SvRefMemberList& rOther)
135 for( typename base_t::const_iterator it = rOther.begin(); it != rOther.end(); ++it )
137 push_back(*it);
141 inline T pop_back()
143 T p = base_t::back();
144 base_t::pop_back();
145 if( p )
146 p->ReleaseRef();
147 return p;
152 /** Classes that want to be referenced-counted via SvRef<T>, should extend this base class */
153 class TOOLS_DLLPUBLIC SvRefBase
155 // the only reason this is not bool is because MSVC cannot handle mixed type bitfields
156 unsigned int bNoDelete : 1;
157 unsigned int nRefCount : 31;
159 protected:
160 virtual ~SvRefBase();
162 public:
163 SvRefBase() : bNoDelete(1), nRefCount(0) {}
165 SvRefBase( const SvRefBase & /* rObj */ ) : bNoDelete(1), nRefCount(0) {}
167 SvRefBase & operator = ( const SvRefBase & )
168 { return *this; }
170 void RestoreNoDelete()
171 { bNoDelete = 1; }
173 void AddNextRef()
175 assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" );
176 ++nRefCount;
179 void AddFirstRef()
181 assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" );
182 if( bNoDelete )
183 bNoDelete = 0;
184 ++nRefCount;
187 void ReleaseRef()
189 assert( nRefCount >= 1);
190 if( --nRefCount == 0 && !bNoDelete)
192 // I'm not sure about the original purpose of this line, but right now
193 // it serves the purpose that anything that attempts to do an AddRef()
194 // after an object is deleted will trip an assert.
195 nRefCount = 1 << 30;
196 delete this;
200 unsigned int GetRefCount() const
201 { return nRefCount; }
204 template<typename T>
205 class SvCompatWeakBase;
207 /** SvCompatWeakHdl acts as a intermediary between SvCompatWeakRef<T> and T.
209 template<typename T>
210 class SvCompatWeakHdl : public SvRefBase
212 friend class SvCompatWeakBase<T>;
213 T* _pObj;
215 SvCompatWeakHdl( T* pObj ) : _pObj( pObj ) {}
217 public:
218 void ResetWeakBase( ) { _pObj = 0; }
219 T* GetObj() { return _pObj; }
222 /** We only have one place that extends this, in include/sfx2/frame.hxx, class SfxFrame.
223 Its function is to notify the SvCompatWeakHdl when an SfxFrame object is deleted.
225 template<typename T>
226 class SvCompatWeakBase
228 tools::SvRef< SvCompatWeakHdl<T> > _xHdl;
230 public:
231 /** Does not use initializer due to compiler warnings,
232 because the lifetime of the _xHdl object can exceed the lifetime of this class.
234 SvCompatWeakBase( T* pObj ) { _xHdl = new SvCompatWeakHdl<T>( pObj ); }
236 ~SvCompatWeakBase() { _xHdl->ResetWeakBase(); }
238 SvCompatWeakHdl<T>* GetHdl() { return _xHdl; }
241 /** We only have one weak reference in LO, in include/sfx2/frame.hxx, class SfxFrameWeak.
243 template<typename T>
244 class SvCompatWeakRef
246 tools::SvRef< SvCompatWeakHdl<T> > _xHdl;
247 public:
248 inline SvCompatWeakRef( ) {}
249 inline SvCompatWeakRef( T* pObj )
250 { if( pObj ) _xHdl = pObj->GetHdl(); }
251 inline SvCompatWeakRef& operator = ( T * pObj )
252 { _xHdl = pObj ? pObj->GetHdl() : 0; return *this; }
253 inline bool Is() const
254 { return _xHdl.Is() && _xHdl->GetObj(); }
255 inline T* operator -> () const
256 { return _xHdl.Is() ? _xHdl->GetObj() : 0; }
257 inline T* operator & () const
258 { return _xHdl.Is() ? _xHdl->GetObj() : 0; }
259 inline operator T* () const
260 { return _xHdl.Is() ? _xHdl->GetObj() : 0; }
263 #endif
265 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */