| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| #ifndef _RTL_REF_HXX_ |
| #define _RTL_REF_HXX_ |
| |
| #include <sal/types.h> |
| #include <osl/diagnose.h> |
| #include <osl/interlck.h> |
| |
| namespace rtl |
| { |
| |
| /** Interface for a reference type. |
| */ |
| class IReference |
| { |
| public: |
| /** @see osl_incrementInterlockedCount. |
| */ |
| virtual oslInterlockedCount SAL_CALL acquire() = 0; |
| |
| /** @see osl_decrementInterlockedCount. |
| */ |
| virtual oslInterlockedCount SAL_CALL release() = 0; |
| }; |
| |
| |
| /** Template reference class for reference type derived from IReference. |
| */ |
| template <class reference_type> |
| class Reference |
| { |
| /** The <b>reference_type</b> body pointer. |
| */ |
| reference_type * m_pBody; |
| |
| |
| public: |
| /** Constructor... |
| */ |
| inline Reference() |
| : m_pBody (0) |
| {} |
| |
| |
| /** Constructor... |
| */ |
| inline Reference (reference_type * pBody) |
| : m_pBody (pBody) |
| { |
| if (m_pBody) |
| m_pBody->acquire(); |
| } |
| |
| |
| /** Copy constructor... |
| */ |
| inline Reference (const Reference<reference_type> & handle) |
| : m_pBody (handle.m_pBody) |
| { |
| if (m_pBody) |
| m_pBody->acquire(); |
| } |
| |
| |
| /** Destructor... |
| */ |
| inline ~Reference() |
| { |
| if (m_pBody) |
| m_pBody->release(); |
| } |
| |
| /** Set... |
| Similar to assignment. |
| */ |
| inline Reference<reference_type> & |
| SAL_CALL set (reference_type * pBody) |
| { |
| if (pBody) |
| pBody->acquire(); |
| reference_type * const pOld = m_pBody; |
| m_pBody = pBody; |
| if (pOld) |
| pOld->release(); |
| return *this; |
| } |
| |
| /** Assignment. |
| Unbinds this instance from its body (if bound) and |
| bind it to the body represented by the handle. |
| */ |
| inline Reference<reference_type> & |
| SAL_CALL operator= (const Reference<reference_type> & handle) |
| { |
| return set( handle.m_pBody ); |
| } |
| |
| /** Assignment... |
| */ |
| inline Reference<reference_type> & |
| SAL_CALL operator= (reference_type * pBody) |
| { |
| return set( pBody ); |
| } |
| |
| /** Unbind the body from this handle. |
| Note that for a handle representing a large body, |
| "handle.clear().set(new body());" _might_ |
| perform a little bit better than "handle.set(new body());", |
| since in the second case two large objects exist in memory |
| (the old body and the new body). |
| */ |
| inline Reference<reference_type> & SAL_CALL clear() |
| { |
| if (m_pBody) |
| { |
| reference_type * const pOld = m_pBody; |
| m_pBody = 0; |
| pOld->release(); |
| } |
| return *this; |
| } |
| |
| |
| /** Get the body. Can be used instead of operator->(). |
| I.e. handle->someBodyOp() and handle.get()->someBodyOp() |
| are the same. |
| */ |
| inline reference_type * SAL_CALL get() const |
| { |
| return m_pBody; |
| } |
| |
| |
| /** Probably most common used: handle->someBodyOp(). |
| */ |
| inline reference_type * SAL_CALL operator->() const |
| { |
| OSL_PRECOND(m_pBody, "Reference::operator->() : null body"); |
| return m_pBody; |
| } |
| |
| |
| /** Allows (*handle).someBodyOp(). |
| */ |
| inline reference_type & SAL_CALL operator*() const |
| { |
| OSL_PRECOND(m_pBody, "Reference::operator*() : null body"); |
| return *m_pBody; |
| } |
| |
| |
| /** Returns True if the handle does point to a valid body. |
| */ |
| inline sal_Bool SAL_CALL is() const |
| { |
| return (m_pBody != 0); |
| } |
| |
| |
| /** Returns True if this points to pBody. |
| */ |
| inline sal_Bool SAL_CALL operator== (const reference_type * pBody) const |
| { |
| return (m_pBody == pBody); |
| } |
| |
| |
| /** Returns True if handle points to the same body. |
| */ |
| inline sal_Bool |
| SAL_CALL operator== (const Reference<reference_type> & handle) const |
| { |
| return (m_pBody == handle.m_pBody); |
| } |
| |
| |
| /** Needed to place References into STL collection. |
| */ |
| inline sal_Bool |
| SAL_CALL operator!= (const Reference<reference_type> & handle) const |
| { |
| return (m_pBody != handle.m_pBody); |
| } |
| |
| |
| /** Needed to place References into STL collection. |
| */ |
| inline sal_Bool |
| SAL_CALL operator< (const Reference<reference_type> & handle) const |
| { |
| return (m_pBody < handle.m_pBody); |
| } |
| |
| |
| /** Needed to place References into STL collection. |
| */ |
| inline sal_Bool |
| SAL_CALL operator> (const Reference<reference_type> & handle) const |
| { |
| return (m_pBody > handle.m_pBody); |
| } |
| }; |
| |
| /** @internal |
| Enables boost::mem_fn and boost::bind to recognize Reference. |
| */ |
| template <typename T> |
| inline T * get_pointer( Reference<T> const& r ) |
| { |
| return r.get(); |
| } |
| |
| } // namespace rtl |
| |
| #endif /* !_RTL_REF_HXX_ */ |