1*b1cdbd2cSJim Jagielski /************************************************************** 2*b1cdbd2cSJim Jagielski * 3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one 4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file 5*b1cdbd2cSJim Jagielski * distributed with this work for additional information 6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file 7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the 8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance 9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at 10*b1cdbd2cSJim Jagielski * 11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0 12*b1cdbd2cSJim Jagielski * 13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing, 14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an 15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the 17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations 18*b1cdbd2cSJim Jagielski * under the License. 19*b1cdbd2cSJim Jagielski * 20*b1cdbd2cSJim Jagielski *************************************************************/ 21*b1cdbd2cSJim Jagielski 22*b1cdbd2cSJim Jagielski 23*b1cdbd2cSJim Jagielski 24*b1cdbd2cSJim Jagielski #ifndef _RTL_REF_HXX_ 25*b1cdbd2cSJim Jagielski #define _RTL_REF_HXX_ 26*b1cdbd2cSJim Jagielski 27*b1cdbd2cSJim Jagielski #include <sal/types.h> 28*b1cdbd2cSJim Jagielski #include <osl/diagnose.h> 29*b1cdbd2cSJim Jagielski #include <osl/interlck.h> 30*b1cdbd2cSJim Jagielski 31*b1cdbd2cSJim Jagielski namespace rtl 32*b1cdbd2cSJim Jagielski { 33*b1cdbd2cSJim Jagielski 34*b1cdbd2cSJim Jagielski /** Interface for a reference type. 35*b1cdbd2cSJim Jagielski */ 36*b1cdbd2cSJim Jagielski class IReference 37*b1cdbd2cSJim Jagielski { 38*b1cdbd2cSJim Jagielski public: 39*b1cdbd2cSJim Jagielski /** @see osl_incrementInterlockedCount. 40*b1cdbd2cSJim Jagielski */ 41*b1cdbd2cSJim Jagielski virtual oslInterlockedCount SAL_CALL acquire() = 0; 42*b1cdbd2cSJim Jagielski 43*b1cdbd2cSJim Jagielski /** @see osl_decrementInterlockedCount. 44*b1cdbd2cSJim Jagielski */ 45*b1cdbd2cSJim Jagielski virtual oslInterlockedCount SAL_CALL release() = 0; 46*b1cdbd2cSJim Jagielski }; 47*b1cdbd2cSJim Jagielski 48*b1cdbd2cSJim Jagielski 49*b1cdbd2cSJim Jagielski /** Template reference class for reference type derived from IReference. 50*b1cdbd2cSJim Jagielski */ 51*b1cdbd2cSJim Jagielski template <class reference_type> 52*b1cdbd2cSJim Jagielski class Reference 53*b1cdbd2cSJim Jagielski { 54*b1cdbd2cSJim Jagielski /** The <b>reference_type</b> body pointer. 55*b1cdbd2cSJim Jagielski */ 56*b1cdbd2cSJim Jagielski reference_type * m_pBody; 57*b1cdbd2cSJim Jagielski 58*b1cdbd2cSJim Jagielski 59*b1cdbd2cSJim Jagielski public: 60*b1cdbd2cSJim Jagielski /** Constructor... 61*b1cdbd2cSJim Jagielski */ Reference()62*b1cdbd2cSJim Jagielski inline Reference() 63*b1cdbd2cSJim Jagielski : m_pBody (0) 64*b1cdbd2cSJim Jagielski {} 65*b1cdbd2cSJim Jagielski 66*b1cdbd2cSJim Jagielski 67*b1cdbd2cSJim Jagielski /** Constructor... 68*b1cdbd2cSJim Jagielski */ Reference(reference_type * pBody)69*b1cdbd2cSJim Jagielski inline Reference (reference_type * pBody) 70*b1cdbd2cSJim Jagielski : m_pBody (pBody) 71*b1cdbd2cSJim Jagielski { 72*b1cdbd2cSJim Jagielski if (m_pBody) 73*b1cdbd2cSJim Jagielski m_pBody->acquire(); 74*b1cdbd2cSJim Jagielski } 75*b1cdbd2cSJim Jagielski 76*b1cdbd2cSJim Jagielski 77*b1cdbd2cSJim Jagielski /** Copy constructor... 78*b1cdbd2cSJim Jagielski */ Reference(const Reference<reference_type> & handle)79*b1cdbd2cSJim Jagielski inline Reference (const Reference<reference_type> & handle) 80*b1cdbd2cSJim Jagielski : m_pBody (handle.m_pBody) 81*b1cdbd2cSJim Jagielski { 82*b1cdbd2cSJim Jagielski if (m_pBody) 83*b1cdbd2cSJim Jagielski m_pBody->acquire(); 84*b1cdbd2cSJim Jagielski } 85*b1cdbd2cSJim Jagielski 86*b1cdbd2cSJim Jagielski 87*b1cdbd2cSJim Jagielski /** Destructor... 88*b1cdbd2cSJim Jagielski */ ~Reference()89*b1cdbd2cSJim Jagielski inline ~Reference() 90*b1cdbd2cSJim Jagielski { 91*b1cdbd2cSJim Jagielski if (m_pBody) 92*b1cdbd2cSJim Jagielski m_pBody->release(); 93*b1cdbd2cSJim Jagielski } 94*b1cdbd2cSJim Jagielski 95*b1cdbd2cSJim Jagielski /** Set... 96*b1cdbd2cSJim Jagielski Similar to assignment. 97*b1cdbd2cSJim Jagielski */ 98*b1cdbd2cSJim Jagielski inline Reference<reference_type> & set(reference_type * pBody)99*b1cdbd2cSJim Jagielski SAL_CALL set (reference_type * pBody) 100*b1cdbd2cSJim Jagielski { 101*b1cdbd2cSJim Jagielski if (pBody) 102*b1cdbd2cSJim Jagielski pBody->acquire(); 103*b1cdbd2cSJim Jagielski reference_type * const pOld = m_pBody; 104*b1cdbd2cSJim Jagielski m_pBody = pBody; 105*b1cdbd2cSJim Jagielski if (pOld) 106*b1cdbd2cSJim Jagielski pOld->release(); 107*b1cdbd2cSJim Jagielski return *this; 108*b1cdbd2cSJim Jagielski } 109*b1cdbd2cSJim Jagielski 110*b1cdbd2cSJim Jagielski /** Assignment. 111*b1cdbd2cSJim Jagielski Unbinds this instance from its body (if bound) and 112*b1cdbd2cSJim Jagielski bind it to the body represented by the handle. 113*b1cdbd2cSJim Jagielski */ 114*b1cdbd2cSJim Jagielski inline Reference<reference_type> & operator =(const Reference<reference_type> & handle)115*b1cdbd2cSJim Jagielski SAL_CALL operator= (const Reference<reference_type> & handle) 116*b1cdbd2cSJim Jagielski { 117*b1cdbd2cSJim Jagielski return set( handle.m_pBody ); 118*b1cdbd2cSJim Jagielski } 119*b1cdbd2cSJim Jagielski 120*b1cdbd2cSJim Jagielski /** Assignment... 121*b1cdbd2cSJim Jagielski */ 122*b1cdbd2cSJim Jagielski inline Reference<reference_type> & operator =(reference_type * pBody)123*b1cdbd2cSJim Jagielski SAL_CALL operator= (reference_type * pBody) 124*b1cdbd2cSJim Jagielski { 125*b1cdbd2cSJim Jagielski return set( pBody ); 126*b1cdbd2cSJim Jagielski } 127*b1cdbd2cSJim Jagielski 128*b1cdbd2cSJim Jagielski /** Unbind the body from this handle. 129*b1cdbd2cSJim Jagielski Note that for a handle representing a large body, 130*b1cdbd2cSJim Jagielski "handle.clear().set(new body());" _might_ 131*b1cdbd2cSJim Jagielski perform a little bit better than "handle.set(new body());", 132*b1cdbd2cSJim Jagielski since in the second case two large objects exist in memory 133*b1cdbd2cSJim Jagielski (the old body and the new body). 134*b1cdbd2cSJim Jagielski */ clear()135*b1cdbd2cSJim Jagielski inline Reference<reference_type> & SAL_CALL clear() 136*b1cdbd2cSJim Jagielski { 137*b1cdbd2cSJim Jagielski if (m_pBody) 138*b1cdbd2cSJim Jagielski { 139*b1cdbd2cSJim Jagielski reference_type * const pOld = m_pBody; 140*b1cdbd2cSJim Jagielski m_pBody = 0; 141*b1cdbd2cSJim Jagielski pOld->release(); 142*b1cdbd2cSJim Jagielski } 143*b1cdbd2cSJim Jagielski return *this; 144*b1cdbd2cSJim Jagielski } 145*b1cdbd2cSJim Jagielski 146*b1cdbd2cSJim Jagielski 147*b1cdbd2cSJim Jagielski /** Get the body. Can be used instead of operator->(). 148*b1cdbd2cSJim Jagielski I.e. handle->someBodyOp() and handle.get()->someBodyOp() 149*b1cdbd2cSJim Jagielski are the same. 150*b1cdbd2cSJim Jagielski */ get() const151*b1cdbd2cSJim Jagielski inline reference_type * SAL_CALL get() const 152*b1cdbd2cSJim Jagielski { 153*b1cdbd2cSJim Jagielski return m_pBody; 154*b1cdbd2cSJim Jagielski } 155*b1cdbd2cSJim Jagielski 156*b1cdbd2cSJim Jagielski 157*b1cdbd2cSJim Jagielski /** Probably most common used: handle->someBodyOp(). 158*b1cdbd2cSJim Jagielski */ operator ->() const159*b1cdbd2cSJim Jagielski inline reference_type * SAL_CALL operator->() const 160*b1cdbd2cSJim Jagielski { 161*b1cdbd2cSJim Jagielski OSL_PRECOND(m_pBody, "Reference::operator->() : null body"); 162*b1cdbd2cSJim Jagielski return m_pBody; 163*b1cdbd2cSJim Jagielski } 164*b1cdbd2cSJim Jagielski 165*b1cdbd2cSJim Jagielski 166*b1cdbd2cSJim Jagielski /** Allows (*handle).someBodyOp(). 167*b1cdbd2cSJim Jagielski */ operator *() const168*b1cdbd2cSJim Jagielski inline reference_type & SAL_CALL operator*() const 169*b1cdbd2cSJim Jagielski { 170*b1cdbd2cSJim Jagielski OSL_PRECOND(m_pBody, "Reference::operator*() : null body"); 171*b1cdbd2cSJim Jagielski return *m_pBody; 172*b1cdbd2cSJim Jagielski } 173*b1cdbd2cSJim Jagielski 174*b1cdbd2cSJim Jagielski 175*b1cdbd2cSJim Jagielski /** Returns True if the handle does point to a valid body. 176*b1cdbd2cSJim Jagielski */ is() const177*b1cdbd2cSJim Jagielski inline sal_Bool SAL_CALL is() const 178*b1cdbd2cSJim Jagielski { 179*b1cdbd2cSJim Jagielski return (m_pBody != 0); 180*b1cdbd2cSJim Jagielski } 181*b1cdbd2cSJim Jagielski 182*b1cdbd2cSJim Jagielski 183*b1cdbd2cSJim Jagielski /** Returns True if this points to pBody. 184*b1cdbd2cSJim Jagielski */ operator ==(const reference_type * pBody) const185*b1cdbd2cSJim Jagielski inline sal_Bool SAL_CALL operator== (const reference_type * pBody) const 186*b1cdbd2cSJim Jagielski { 187*b1cdbd2cSJim Jagielski return (m_pBody == pBody); 188*b1cdbd2cSJim Jagielski } 189*b1cdbd2cSJim Jagielski 190*b1cdbd2cSJim Jagielski 191*b1cdbd2cSJim Jagielski /** Returns True if handle points to the same body. 192*b1cdbd2cSJim Jagielski */ 193*b1cdbd2cSJim Jagielski inline sal_Bool operator ==(const Reference<reference_type> & handle) const194*b1cdbd2cSJim Jagielski SAL_CALL operator== (const Reference<reference_type> & handle) const 195*b1cdbd2cSJim Jagielski { 196*b1cdbd2cSJim Jagielski return (m_pBody == handle.m_pBody); 197*b1cdbd2cSJim Jagielski } 198*b1cdbd2cSJim Jagielski 199*b1cdbd2cSJim Jagielski 200*b1cdbd2cSJim Jagielski /** Needed to place References into STL collection. 201*b1cdbd2cSJim Jagielski */ 202*b1cdbd2cSJim Jagielski inline sal_Bool operator !=(const Reference<reference_type> & handle) const203*b1cdbd2cSJim Jagielski SAL_CALL operator!= (const Reference<reference_type> & handle) const 204*b1cdbd2cSJim Jagielski { 205*b1cdbd2cSJim Jagielski return (m_pBody != handle.m_pBody); 206*b1cdbd2cSJim Jagielski } 207*b1cdbd2cSJim Jagielski 208*b1cdbd2cSJim Jagielski 209*b1cdbd2cSJim Jagielski /** Needed to place References into STL collection. 210*b1cdbd2cSJim Jagielski */ 211*b1cdbd2cSJim Jagielski inline sal_Bool operator <(const Reference<reference_type> & handle) const212*b1cdbd2cSJim Jagielski SAL_CALL operator< (const Reference<reference_type> & handle) const 213*b1cdbd2cSJim Jagielski { 214*b1cdbd2cSJim Jagielski return (m_pBody < handle.m_pBody); 215*b1cdbd2cSJim Jagielski } 216*b1cdbd2cSJim Jagielski 217*b1cdbd2cSJim Jagielski 218*b1cdbd2cSJim Jagielski /** Needed to place References into STL collection. 219*b1cdbd2cSJim Jagielski */ 220*b1cdbd2cSJim Jagielski inline sal_Bool operator >(const Reference<reference_type> & handle) const221*b1cdbd2cSJim Jagielski SAL_CALL operator> (const Reference<reference_type> & handle) const 222*b1cdbd2cSJim Jagielski { 223*b1cdbd2cSJim Jagielski return (m_pBody > handle.m_pBody); 224*b1cdbd2cSJim Jagielski } 225*b1cdbd2cSJim Jagielski }; 226*b1cdbd2cSJim Jagielski 227*b1cdbd2cSJim Jagielski /** @internal 228*b1cdbd2cSJim Jagielski Enables boost::mem_fn and boost::bind to recognize Reference. 229*b1cdbd2cSJim Jagielski */ 230*b1cdbd2cSJim Jagielski template <typename T> get_pointer(Reference<T> const & r)231*b1cdbd2cSJim Jagielskiinline T * get_pointer( Reference<T> const& r ) 232*b1cdbd2cSJim Jagielski { 233*b1cdbd2cSJim Jagielski return r.get(); 234*b1cdbd2cSJim Jagielski } 235*b1cdbd2cSJim Jagielski 236*b1cdbd2cSJim Jagielski } // namespace rtl 237*b1cdbd2cSJim Jagielski 238*b1cdbd2cSJim Jagielski #endif /* !_RTL_REF_HXX_ */ 239