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 24 #ifndef _RTL_REF_HXX_ 25 #define _RTL_REF_HXX_ 26 27 #include <sal/types.h> 28 #include <osl/diagnose.h> 29 #include <osl/interlck.h> 30 31 namespace rtl 32 { 33 34 /** Interface for a reference type. 35 */ 36 class IReference 37 { 38 public: 39 /** @see osl_incrementInterlockedCount. 40 */ 41 virtual oslInterlockedCount SAL_CALL acquire() = 0; 42 43 /** @see osl_decrementInterlockedCount. 44 */ 45 virtual oslInterlockedCount SAL_CALL release() = 0; 46 }; 47 48 49 /** Template reference class for reference type derived from IReference. 50 */ 51 template <class reference_type> 52 class Reference 53 { 54 /** The <b>reference_type</b> body pointer. 55 */ 56 reference_type * m_pBody; 57 58 59 public: 60 /** Constructor... 61 */ Reference()62 inline Reference() 63 : m_pBody (0) 64 {} 65 66 67 /** Constructor... 68 */ Reference(reference_type * pBody)69 inline Reference (reference_type * pBody) 70 : m_pBody (pBody) 71 { 72 if (m_pBody) 73 m_pBody->acquire(); 74 } 75 76 77 /** Copy constructor... 78 */ Reference(const Reference<reference_type> & handle)79 inline Reference (const Reference<reference_type> & handle) 80 : m_pBody (handle.m_pBody) 81 { 82 if (m_pBody) 83 m_pBody->acquire(); 84 } 85 86 87 /** Destructor... 88 */ ~Reference()89 inline ~Reference() 90 { 91 if (m_pBody) 92 m_pBody->release(); 93 } 94 95 /** Set... 96 Similar to assignment. 97 */ 98 inline Reference<reference_type> & set(reference_type * pBody)99 SAL_CALL set (reference_type * pBody) 100 { 101 if (pBody) 102 pBody->acquire(); 103 reference_type * const pOld = m_pBody; 104 m_pBody = pBody; 105 if (pOld) 106 pOld->release(); 107 return *this; 108 } 109 110 /** Assignment. 111 Unbinds this instance from its body (if bound) and 112 bind it to the body represented by the handle. 113 */ 114 inline Reference<reference_type> & operator =(const Reference<reference_type> & handle)115 SAL_CALL operator= (const Reference<reference_type> & handle) 116 { 117 return set( handle.m_pBody ); 118 } 119 120 /** Assignment... 121 */ 122 inline Reference<reference_type> & operator =(reference_type * pBody)123 SAL_CALL operator= (reference_type * pBody) 124 { 125 return set( pBody ); 126 } 127 128 /** Unbind the body from this handle. 129 Note that for a handle representing a large body, 130 "handle.clear().set(new body());" _might_ 131 perform a little bit better than "handle.set(new body());", 132 since in the second case two large objects exist in memory 133 (the old body and the new body). 134 */ clear()135 inline Reference<reference_type> & SAL_CALL clear() 136 { 137 if (m_pBody) 138 { 139 reference_type * const pOld = m_pBody; 140 m_pBody = 0; 141 pOld->release(); 142 } 143 return *this; 144 } 145 146 147 /** Get the body. Can be used instead of operator->(). 148 I.e. handle->someBodyOp() and handle.get()->someBodyOp() 149 are the same. 150 */ get() const151 inline reference_type * SAL_CALL get() const 152 { 153 return m_pBody; 154 } 155 156 157 /** Probably most common used: handle->someBodyOp(). 158 */ operator ->() const159 inline reference_type * SAL_CALL operator->() const 160 { 161 OSL_PRECOND(m_pBody, "Reference::operator->() : null body"); 162 return m_pBody; 163 } 164 165 166 /** Allows (*handle).someBodyOp(). 167 */ operator *() const168 inline reference_type & SAL_CALL operator*() const 169 { 170 OSL_PRECOND(m_pBody, "Reference::operator*() : null body"); 171 return *m_pBody; 172 } 173 174 175 /** Returns True if the handle does point to a valid body. 176 */ is() const177 inline sal_Bool SAL_CALL is() const 178 { 179 return (m_pBody != 0); 180 } 181 182 183 /** Returns True if this points to pBody. 184 */ operator ==(const reference_type * pBody) const185 inline sal_Bool SAL_CALL operator== (const reference_type * pBody) const 186 { 187 return (m_pBody == pBody); 188 } 189 190 191 /** Returns True if handle points to the same body. 192 */ 193 inline sal_Bool operator ==(const Reference<reference_type> & handle) const194 SAL_CALL operator== (const Reference<reference_type> & handle) const 195 { 196 return (m_pBody == handle.m_pBody); 197 } 198 199 200 /** Needed to place References into STL collection. 201 */ 202 inline sal_Bool operator !=(const Reference<reference_type> & handle) const203 SAL_CALL operator!= (const Reference<reference_type> & handle) const 204 { 205 return (m_pBody != handle.m_pBody); 206 } 207 208 209 /** Needed to place References into STL collection. 210 */ 211 inline sal_Bool operator <(const Reference<reference_type> & handle) const212 SAL_CALL operator< (const Reference<reference_type> & handle) const 213 { 214 return (m_pBody < handle.m_pBody); 215 } 216 217 218 /** Needed to place References into STL collection. 219 */ 220 inline sal_Bool operator >(const Reference<reference_type> & handle) const221 SAL_CALL operator> (const Reference<reference_type> & handle) const 222 { 223 return (m_pBody > handle.m_pBody); 224 } 225 }; 226 227 /** @internal 228 Enables boost::mem_fn and boost::bind to recognize Reference. 229 */ 230 template <typename T> get_pointer(Reference<T> const & r)231inline T * get_pointer( Reference<T> const& r ) 232 { 233 return r.get(); 234 } 235 236 } // namespace rtl 237 238 #endif /* !_RTL_REF_HXX_ */ 239