1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #ifndef _RTL_REF_HXX_ 29 #define _RTL_REF_HXX_ 30 31 #include <sal/types.h> 32 #include <osl/diagnose.h> 33 #include <osl/interlck.h> 34 35 namespace rtl 36 { 37 38 /** Interface for a reference type. 39 */ 40 class IReference 41 { 42 public: 43 /** @see osl_incrementInterlockedCount. 44 */ 45 virtual oslInterlockedCount SAL_CALL acquire() = 0; 46 47 /** @see osl_decrementInterlockedCount. 48 */ 49 virtual oslInterlockedCount SAL_CALL release() = 0; 50 }; 51 52 53 /** Template reference class for reference type derived from IReference. 54 */ 55 template <class reference_type> 56 class Reference 57 { 58 /** The <b>reference_type</b> body pointer. 59 */ 60 reference_type * m_pBody; 61 62 63 public: 64 /** Constructor... 65 */ 66 inline Reference() 67 : m_pBody (0) 68 {} 69 70 71 /** Constructor... 72 */ 73 inline Reference (reference_type * pBody) 74 : m_pBody (pBody) 75 { 76 if (m_pBody) 77 m_pBody->acquire(); 78 } 79 80 81 /** Copy constructor... 82 */ 83 inline Reference (const Reference<reference_type> & handle) 84 : m_pBody (handle.m_pBody) 85 { 86 if (m_pBody) 87 m_pBody->acquire(); 88 } 89 90 91 /** Destructor... 92 */ 93 inline ~Reference() 94 { 95 if (m_pBody) 96 m_pBody->release(); 97 } 98 99 /** Set... 100 Similar to assignment. 101 */ 102 inline Reference<reference_type> & 103 SAL_CALL set (reference_type * pBody) 104 { 105 if (pBody) 106 pBody->acquire(); 107 reference_type * const pOld = m_pBody; 108 m_pBody = pBody; 109 if (pOld) 110 pOld->release(); 111 return *this; 112 } 113 114 /** Assignment. 115 Unbinds this instance from its body (if bound) and 116 bind it to the body represented by the handle. 117 */ 118 inline Reference<reference_type> & 119 SAL_CALL operator= (const Reference<reference_type> & handle) 120 { 121 return set( handle.m_pBody ); 122 } 123 124 /** Assignment... 125 */ 126 inline Reference<reference_type> & 127 SAL_CALL operator= (reference_type * pBody) 128 { 129 return set( pBody ); 130 } 131 132 /** Unbind the body from this handle. 133 Note that for a handle representing a large body, 134 "handle.clear().set(new body());" _might_ 135 perform a little bit better than "handle.set(new body());", 136 since in the second case two large objects exist in memory 137 (the old body and the new body). 138 */ 139 inline Reference<reference_type> & SAL_CALL clear() 140 { 141 if (m_pBody) 142 { 143 reference_type * const pOld = m_pBody; 144 m_pBody = 0; 145 pOld->release(); 146 } 147 return *this; 148 } 149 150 151 /** Get the body. Can be used instead of operator->(). 152 I.e. handle->someBodyOp() and handle.get()->someBodyOp() 153 are the same. 154 */ 155 inline reference_type * SAL_CALL get() const 156 { 157 return m_pBody; 158 } 159 160 161 /** Probably most common used: handle->someBodyOp(). 162 */ 163 inline reference_type * SAL_CALL operator->() const 164 { 165 OSL_PRECOND(m_pBody, "Reference::operator->() : null body"); 166 return m_pBody; 167 } 168 169 170 /** Allows (*handle).someBodyOp(). 171 */ 172 inline reference_type & SAL_CALL operator*() const 173 { 174 OSL_PRECOND(m_pBody, "Reference::operator*() : null body"); 175 return *m_pBody; 176 } 177 178 179 /** Returns True if the handle does point to a valid body. 180 */ 181 inline sal_Bool SAL_CALL is() const 182 { 183 return (m_pBody != 0); 184 } 185 186 187 /** Returns True if this points to pBody. 188 */ 189 inline sal_Bool SAL_CALL operator== (const reference_type * pBody) const 190 { 191 return (m_pBody == pBody); 192 } 193 194 195 /** Returns True if handle points to the same body. 196 */ 197 inline sal_Bool 198 SAL_CALL operator== (const Reference<reference_type> & handle) const 199 { 200 return (m_pBody == handle.m_pBody); 201 } 202 203 204 /** Needed to place References into STL collection. 205 */ 206 inline sal_Bool 207 SAL_CALL operator!= (const Reference<reference_type> & handle) const 208 { 209 return (m_pBody != handle.m_pBody); 210 } 211 212 213 /** Needed to place References into STL collection. 214 */ 215 inline sal_Bool 216 SAL_CALL operator< (const Reference<reference_type> & handle) const 217 { 218 return (m_pBody < handle.m_pBody); 219 } 220 221 222 /** Needed to place References into STL collection. 223 */ 224 inline sal_Bool 225 SAL_CALL operator> (const Reference<reference_type> & handle) const 226 { 227 return (m_pBody > handle.m_pBody); 228 } 229 }; 230 231 /** @internal 232 Enables boost::mem_fn and boost::bind to recognize Reference. 233 */ 234 template <typename T> 235 inline T * get_pointer( Reference<T> const& r ) 236 { 237 return r.get(); 238 } 239 240 } // namespace rtl 241 242 #endif /* !_RTL_REF_HXX_ */ 243