LCOV - code coverage report
Current view: top level - include/vcl - vclptr.hxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 86 95 90.5 %
Date: 2015-06-13 12:38:46 Functions: 1908 13383 14.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : #ifndef INCLUDED_VCL_PTR_HXX
      21             : #define INCLUDED_VCL_PTR_HXX
      22             : 
      23             : #include <rtl/ref.hxx>
      24             : #include <utility>
      25             : #include <type_traits>
      26             : 
      27             : /// @cond INTERNAL
      28             : namespace vcl { namespace detail {
      29             : 
      30             : // A mechanism to enable up-casts, used by the VclReference conversion constructor,
      31             : // heavily borrowed from boost::is_base_and_derived
      32             : // (which manages to avoid compilation problems with ambiguous bases and cites
      33             : // comp.lang.c++.moderated mail <http://groups.google.com/groups?
      34             : // selm=df893da6.0301280859.522081f7%40posting.google.com> "SuperSubclass
      35             : // (is_base_and_derived) complete implementation!" by Rani Sharoni and cites
      36             : // Aleksey Gurtovoy for the workaround for MSVC), to avoid including Boost
      37             : // headers in URE headers (could ultimately be based on C++11 std::is_base_of):
      38             : 
      39             : template< typename T1, typename T2 > struct UpCast {
      40             : private:
      41             :     template< bool, typename U1, typename > struct C
      42             :     { typedef U1 t; };
      43             : 
      44             :     template< typename U1, typename U2 > struct C< false, U1, U2 >
      45             :     { typedef U2 t; };
      46             : 
      47             :     struct S { char c[2]; };
      48             : 
      49             : #if defined _MSC_VER
      50             :     static char f(T2 *, long);
      51             :     static S f(T1 * const &, int);
      52             : #else
      53             :     template< typename U > static char f(T2 *, U);
      54             :     static S f(T1 *, int);
      55             : #endif
      56             : 
      57             :     struct H {
      58             :         H(); // avoid C2514 "class has no constructors" from MSVC 2008
      59             : #if defined _MSC_VER
      60             :         operator T1 * const & () const;
      61             : #else
      62             :         operator T1 * () const;
      63             : #endif
      64             :         operator T2 * ();
      65             :     };
      66             : 
      67             : public:
      68             :     typedef typename C< sizeof (f(H(), 0)) == 1, void *, void >::t t;
      69             : };
      70             : 
      71             : }; }; // namespace detail, namespace vcl
      72             : 
      73             : /**
      74             :  * A thin wrapper around rtl::Reference to implement the acquire and dispose semantics we want for references to vcl::Window subclasses.
      75             :  *
      76             :  * For more details on the design please see vcl/README.lifecycle
      77             :  *
      78             :  * @param reference_type must be a subclass of vcl::Window
      79             :  */
      80             : template <class reference_type>
      81   207161408 : class VclPtr
      82             : {
      83             :     ::rtl::Reference<reference_type> m_rInnerRef;
      84             : 
      85             : public:
      86             :     /** Constructor...
      87             :      */
      88    12914181 :     inline VclPtr()
      89    12914181 :         : m_rInnerRef()
      90    12914181 :     {}
      91             : 
      92             :     /** Constructor...
      93             :      */
      94   101925896 :     inline VclPtr (reference_type * pBody)
      95   101925896 :         : m_rInnerRef(pBody)
      96   101925896 :     {}
      97             : 
      98             :     /** Constructor... that doesn't take a ref.
      99             :      */
     100      421960 :     inline VclPtr (reference_type * pBody, __sal_NoAcquire)
     101      421960 :         : m_rInnerRef(pBody, SAL_NO_ACQUIRE)
     102      421960 :     {}
     103             : 
     104             :     /** Copy constructor...
     105             :      */
     106     4430998 :     inline VclPtr (const VclPtr<reference_type> & handle)
     107     4430998 :         : m_rInnerRef (handle.m_rInnerRef)
     108     4430998 :     {}
     109             : 
     110             :     /** Up-casting conversion constructor: Copies interface reference.
     111             : 
     112             :         Does not work for up-casts to ambiguous bases.  For the special case of
     113             :         up-casting to Reference< XInterface >, see the corresponding conversion
     114             :         operator.
     115             : 
     116             :         @param rRef another reference
     117             :     */
     118             :     template< class derived_type >
     119      339032 :     inline VclPtr(
     120             :         const VclPtr< derived_type > & rRef,
     121             :         typename ::vcl::detail::UpCast< reference_type, derived_type >::t = 0 )
     122      339032 :         : m_rInnerRef( static_cast<reference_type*>(rRef) )
     123             :     {
     124      339032 :     }
     125             : 
     126             :     /**
     127             :      * A construction helper for VclPtr. Since VclPtr types are created
     128             :      * with a reference-count of one - to help fit into the existing
     129             :      * code-flow; this helps us to construct them easily.
     130             :      *
     131             :      * For more details on the design please see vcl/README.lifecycle
     132             :      *
     133             :      * @param reference_type must be a subclass of vcl::Window
     134             :      */
     135      346324 :     template<typename... Arg> static VclPtr< reference_type > Create(Arg &&... arg)
     136             :     {
     137      346324 :         return VclPtr< reference_type >( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE );
     138             :     }
     139             : 
     140             :     /** Probably most common used: handle->someBodyOp().
     141             :      */
     142    27825837 :     inline reference_type * operator->() const
     143             :     {
     144    27825837 :         return m_rInnerRef.get();
     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             :       */
     151    59252712 :     inline reference_type * get() const
     152             :     {
     153    59252712 :         return m_rInnerRef.get();
     154             :     }
     155             : 
     156       10371 :     inline void set(reference_type *pBody)
     157             :     {
     158       10371 :         m_rInnerRef.set(pBody);
     159       10371 :     }
     160             : 
     161       15380 :     inline void reset(reference_type *pBody)
     162             :     {
     163       15380 :         m_rInnerRef.set(pBody);
     164       15380 :     }
     165             : 
     166             :     /** Up-casting conversion constructor: Copies interface reference.
     167             : 
     168             :         Does not work for up-casts to ambiguous bases.  For the special case of
     169             :         up-casting to Reference< XInterface >, see the corresponding conversion
     170             :         operator.
     171             : 
     172             :         @param rRef another reference
     173             :     */
     174             :     template< class derived_type, class = typename std::enable_if< ::vcl::detail::UpCast< reference_type, derived_type >::t >::type >
     175             :     inline VclPtr<reference_type>& operator= (derived_type * pBody)
     176             :     {
     177             :         m_rInnerRef.set(pBody);
     178             :         return *this;
     179             :     }
     180             : 
     181   102535362 :     inline operator reference_type * () const
     182             :     {
     183   102535362 :         return m_rInnerRef.get();
     184             :     }
     185             : 
     186    93444931 :     inline explicit operator bool () const
     187             :     {
     188    93444931 :         return m_rInnerRef.get() != NULL;
     189             :     }
     190             : 
     191      544037 :     inline void clear()
     192             :     {
     193      544037 :         m_rInnerRef.clear();
     194      544037 :     }
     195             : 
     196         201 :     inline void reset()
     197             :     {
     198         201 :         m_rInnerRef.clear();
     199         201 :     }
     200             : 
     201     1669544 :     inline void disposeAndClear()
     202             :     {
     203             :         // hold it alive for the lifetime of this method
     204     1669544 :         ::rtl::Reference<reference_type> aTmp(m_rInnerRef);
     205     1669544 :         m_rInnerRef.clear(); // we should use some 'swap' method ideally ;-)
     206     1669544 :         if (aTmp.get()) {
     207      430005 :             aTmp->disposeOnce();
     208     1669544 :         }
     209     1669544 :     }
     210             : 
     211             :     /** Needed to place VclPtr's into STL collection.
     212             :      */
     213      171478 :     inline bool operator< (const VclPtr<reference_type> & handle) const
     214             :     {
     215      171478 :         return (m_rInnerRef < handle.m_rInnerRef);
     216             :     }
     217             : 
     218             :     /** Needed to place VclPtr's into STL collection.
     219             :      */
     220             :     inline bool operator> (const VclPtr<reference_type> & handle) const
     221             :     {
     222             :         return (m_rInnerRef > handle.m_rInnerRef);
     223             :     }
     224             : }; // class VclPtr
     225             : 
     226             : template<typename T1, typename T2>
     227      335703 : inline bool operator ==(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
     228      335703 :     return p1.get() == p2.get();
     229             : }
     230             : 
     231    11068086 : template<typename T> inline bool operator ==(VclPtr<T> const & p1, T const * p2)
     232             : {
     233    11068086 :     return p1.get() == p2;
     234             : }
     235             : 
     236     3729050 : template<typename T> inline bool operator ==(VclPtr<T> const & p1, T * p2) {
     237     3729050 :     return p1.get() == p2;
     238             : }
     239             : 
     240      209878 : template<typename T> inline bool operator ==(T const * p1, VclPtr<T> const & p2)
     241             : {
     242      209878 :     return p1 == p2.get();
     243             : }
     244             : 
     245       89003 : template<typename T> inline bool operator ==(T * p1, VclPtr<T> const & p2) {
     246       89003 :     return p1 == p2.get();
     247             : }
     248             : 
     249             : template<typename T1, typename T2>
     250      147535 : inline bool operator !=(VclPtr<T1> const & p1, VclPtr<T2> const & p2) {
     251      147535 :     return !(p1 == p2);
     252             : }
     253             : 
     254        2022 : template<typename T> inline bool operator !=(VclPtr<T> const & p1, T const * p2)
     255             : {
     256        2022 :     return !(p1 == p2);
     257             : }
     258             : 
     259             : template<typename T> inline bool operator !=(VclPtr<T> const & p1, T * p2) {
     260             :     return !(p1 == p2);
     261             : }
     262             : 
     263           0 : template<typename T> inline bool operator !=(T const * p1, VclPtr<T> const & p2)
     264             : {
     265           0 :     return !(p1 == p2);
     266             : }
     267             : 
     268       74391 : template<typename T> inline bool operator !=(T * p1, VclPtr<T> const & p2) {
     269       74391 :     return !(p1 == p2);
     270             : }
     271             : 
     272             : /**
     273             :  * A construction helper for a temporary VclPtr. Since VclPtr types
     274             :  * are created with a reference-count of one - to help fit into
     275             :  * the existing code-flow; this helps us to construct them easily.
     276             :  * see also VclPtr::Create and ScopedVclPtr
     277             :  *
     278             :  * For more details on the design please see vcl/README.lifecycle
     279             :  *
     280             :  * @param reference_type must be a subclass of vcl::Window
     281             :  */
     282             : template <class reference_type>
     283       37496 : class VclPtrInstance : public VclPtr<reference_type>
     284             : {
     285             : public:
     286       37496 :     template<typename... Arg> VclPtrInstance(Arg &&... arg)
     287       37496 :         : VclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
     288             :     {
     289       37496 :     }
     290             : };
     291             : 
     292             : template <class reference_type>
     293             : class ScopedVclPtr : public VclPtr<reference_type>
     294             : {
     295             : public:
     296             :     /** Constructor...
     297             :      */
     298        7061 :     inline ScopedVclPtr()
     299        7061 :         : VclPtr<reference_type>()
     300        7061 :     {}
     301             : 
     302             :     /** Constructor
     303             :      */
     304           0 :     inline ScopedVclPtr (reference_type * pBody)
     305           0 :         : VclPtr<reference_type>(pBody)
     306           0 :     {}
     307             : 
     308             :     /** Copy constructor...
     309             :      */
     310       11390 :     inline ScopedVclPtr (const VclPtr<reference_type> & handle)
     311       11390 :         : VclPtr<reference_type>(handle)
     312       11390 :     {}
     313             : 
     314             :     /**
     315             :        Assignment that releases the last reference.
     316             :      */
     317           0 :     inline ScopedVclPtr<reference_type>& operator= (reference_type * pBody)
     318             :     {
     319           0 :         VclPtr<reference_type>::disposeAndClear();
     320           0 :         VclPtr<reference_type>::set(pBody);
     321           0 :         return *this;
     322             :     }
     323             : 
     324             :     /** Up-casting conversion constructor: Copies interface reference.
     325             : 
     326             :         Does not work for up-casts to ambiguous bases.  For the special case of
     327             :         up-casting to Reference< XInterface >, see the corresponding conversion
     328             :         operator.
     329             : 
     330             :         @param rRef another reference
     331             :     */
     332             :     template< class derived_type >
     333         130 :     inline ScopedVclPtr(
     334             :         const VclPtr< derived_type > & rRef,
     335             :         typename ::vcl::detail::UpCast< reference_type, derived_type >::t = 0 )
     336         130 :         : VclPtr<reference_type>( rRef )
     337             :     {
     338         130 :     }
     339             : 
     340       56766 :     ~ScopedVclPtr()
     341             :     {
     342       56766 :         VclPtr<reference_type>::disposeAndClear();
     343             :         assert(VclPtr<reference_type>::get() == nullptr); // make sure there are no lingering references
     344       56766 :     }
     345             : 
     346             : private:
     347             :     // Most likely we don't want this default copy-construtor.
     348             :     ScopedVclPtr (const ScopedVclPtr<reference_type> &) SAL_DELETED_FUNCTION;
     349             :     // And certainly we don't want a default assignment operator.
     350             :     ScopedVclPtr<reference_type>& operator= (const ScopedVclPtr<reference_type> &) SAL_DELETED_FUNCTION;
     351             : 
     352             : protected:
     353       38260 :     inline ScopedVclPtr (reference_type * pBody, __sal_NoAcquire)
     354       38260 :         : VclPtr<reference_type>(pBody, SAL_NO_ACQUIRE)
     355       38260 :     {}
     356             : };
     357             : 
     358             : /**
     359             :  * A construction helper for ScopedVclPtr. Since VclPtr types are created
     360             :  * with a reference-count of one - to help fit into the existing
     361             :  * code-flow; this helps us to construct them easily.
     362             :  *
     363             :  * For more details on the design please see vcl/README.lifecycle
     364             :  *
     365             :  * @param reference_type must be a subclass of vcl::Window
     366             :  */
     367             : template <class reference_type>
     368       38260 : class ScopedVclPtrInstance : public ScopedVclPtr<reference_type>
     369             : {
     370             : public:
     371       38263 :     template<typename... Arg> ScopedVclPtrInstance(Arg &&... arg)
     372       38266 :         : ScopedVclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE )
     373             :     {
     374       38260 :     }
     375             : };
     376             : 
     377             : #endif // INCLUDED_VCL_PTR_HXX
     378             : 
     379             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11