LCOV - code coverage report
Current view: top level - solver/unxlngi6.pro/inc/rtl - instance.hxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 34 34 100.0 %
Date: 2012-08-25 Functions: 1315 2525 52.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 398 1027 38.8 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : #ifndef INCLUDED_RTL_INSTANCE_HXX
      30                 :            : #define INCLUDED_RTL_INSTANCE_HXX
      31                 :            : 
      32                 :            : #include "osl/doublecheckedlocking.h"
      33                 :            : #include "osl/getglobalmutex.hxx"
      34                 :            : 
      35                 :            : namespace {
      36                 :            : 
      37                 :            : /** A non-broken version of the double-checked locking pattern.
      38                 :            : 
      39                 :            :     See
      40                 :            :     <http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html>
      41                 :            :     for a description of double-checked locking, why it is broken, and how it
      42                 :            :     can be fixed.  Always use this template instead of spelling out the
      43                 :            :     double-checked locking pattern explicitly, and only in those rare cases
      44                 :            :     where that is not possible and you have to spell it out explicitly, at
      45                 :            :     least call OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER() at the right
      46                 :            :     places.  That way, all platform-dependent code to make double-checked
      47                 :            :     locking work can be kept in one place.
      48                 :            : 
      49                 :            :     Usage scenarios:
      50                 :            : 
      51                 :            :     1  Static instance (most common case)
      52                 :            : 
      53                 :            :     Pattern:
      54                 :            : 
      55                 :            :       T * getInstance()
      56                 :            :       {
      57                 :            :           static T * pInstance = 0;
      58                 :            :           if (!pInstance)
      59                 :            :           {
      60                 :            :               ::osl::MutexGuard aGuard(::osl::Mutex::getGlobalMutex());
      61                 :            :               if (!pInstance)
      62                 :            :               {
      63                 :            :                   static T aInstance;
      64                 :            :                   pInstance = &aInstance;
      65                 :            :               }
      66                 :            :           }
      67                 :            :           return pInstance;
      68                 :            :       }
      69                 :            : 
      70                 :            :     Code:
      71                 :            : 
      72                 :            :       #include "rtl/instance.hxx"
      73                 :            :       #include "osl/getglobalmutex.hxx"
      74                 :            : 
      75                 :            :       namespace {
      76                 :            :           struct Init
      77                 :            :           {
      78                 :            :               T * operator()()
      79                 :            :               {
      80                 :            :                   static T aInstance;
      81                 :            :                   return &aInstance;
      82                 :            :               }
      83                 :            :           };
      84                 :            :       }
      85                 :            : 
      86                 :            :       T * getInstance()
      87                 :            :       {
      88                 :            :           return rtl_Instance< T, Init, ::osl::MutexGuard,
      89                 :            :                                ::osl::GetGlobalMutex >::create(
      90                 :            :               Init(), ::osl::GetGlobalMutex());
      91                 :            :       }
      92                 :            : 
      93                 :            :     2  Dynamic instance
      94                 :            : 
      95                 :            :     Pattern:
      96                 :            : 
      97                 :            :       T * getInstance()
      98                 :            :       {
      99                 :            :           static T * pInstance = 0;
     100                 :            :           if (!pInstance)
     101                 :            :           {
     102                 :            :               ::osl::MutexGuard aGuard(::osl::Mutex::getGlobalMutex());
     103                 :            :               if (!pInstance)
     104                 :            :                   pInstance = new T;
     105                 :            :           }
     106                 :            :           return pInstance;
     107                 :            :       }
     108                 :            : 
     109                 :            :     Code:
     110                 :            : 
     111                 :            :       #include "rtl/instance.hxx"
     112                 :            :       #include "osl/getglobalmutex.hxx"
     113                 :            : 
     114                 :            :       namespace {
     115                 :            :           struct Init
     116                 :            :           {
     117                 :            :               T * operator()()
     118                 :            :               {
     119                 :            :                   return new T;
     120                 :            :               }
     121                 :            :           };
     122                 :            :       }
     123                 :            : 
     124                 :            :       T * getInstance()
     125                 :            :       {
     126                 :            :           return rtl_Instance< T, Init, ::osl::MutexGuard,
     127                 :            :                                ::osl::GetGlobalMutex >::create(
     128                 :            :               Init(), ::osl::GetGlobalMutex());
     129                 :            :       }
     130                 :            : 
     131                 :            :     3  Other guard/mutex
     132                 :            : 
     133                 :            :     Pattern:
     134                 :            : 
     135                 :            :       T * getInstance()
     136                 :            :       {
     137                 :            :           static T * pInstance = 0;
     138                 :            :           if (!pInstance)
     139                 :            :           {
     140                 :            :               SomeGuard aGuard(pSomeMutex);
     141                 :            :               if (!pInstance)
     142                 :            :               {
     143                 :            :                   static T aInstance;
     144                 :            :                   pInstance = &aInstance;
     145                 :            :               }
     146                 :            :           }
     147                 :            :           return pInstance;
     148                 :            :       }
     149                 :            : 
     150                 :            :     Code:
     151                 :            : 
     152                 :            :       #include "rtl/instance.hxx"
     153                 :            : 
     154                 :            :       namespace {
     155                 :            :           struct InitInstance
     156                 :            :           {
     157                 :            :               T * operator()()
     158                 :            :               {
     159                 :            :                   static T aInstance;
     160                 :            :                   return &aInstance;
     161                 :            :               }
     162                 :            :           };
     163                 :            : 
     164                 :            :           struct InitGuard
     165                 :            :           {
     166                 :            :               SomeMutex * operator()()
     167                 :            :               {
     168                 :            :                   return pSomeMutex;
     169                 :            :               }
     170                 :            :           };
     171                 :            :       }
     172                 :            : 
     173                 :            :       T * getInstance()
     174                 :            :       {
     175                 :            :           return rtl_Instance< T, InitInstance,
     176                 :            :                                SomeGuard, InitGuard >::create(
     177                 :            :               InitInstance(), InitMutex());
     178                 :            :       }
     179                 :            : 
     180                 :            :     4  Calculate extra data
     181                 :            : 
     182                 :            :     Pattern:
     183                 :            : 
     184                 :            :       T * getInstance()
     185                 :            :       {
     186                 :            :           static T * pInstance = 0;
     187                 :            :           if (!pInstance)
     188                 :            :           {
     189                 :            :               Data aData(...);
     190                 :            :               ::osl::MutexGuard aGuard(::osl::Mutex::getGlobalMutex());
     191                 :            :               if (!pInstance)
     192                 :            :               {
     193                 :            :                   static T aInstance(aData);
     194                 :            :                   pInstance = &aInstance;
     195                 :            :               }
     196                 :            :           }
     197                 :            :           return pInstance;
     198                 :            :       }
     199                 :            : 
     200                 :            :     Code:
     201                 :            : 
     202                 :            :       #include "rtl/instance.hxx"
     203                 :            :       #include "osl/getglobalmutex.hxx"
     204                 :            : 
     205                 :            :       namespace {
     206                 :            :           struct InitInstance
     207                 :            :           {
     208                 :            :               T * operator()()
     209                 :            :               {
     210                 :            :                   static T aInstance;
     211                 :            :                   return &aInstance;
     212                 :            :               }
     213                 :            :           }
     214                 :            : 
     215                 :            :           struct InitData
     216                 :            :           {
     217                 :            :               Data const & operator()()
     218                 :            :               {
     219                 :            :                   return ...;
     220                 :            :               }
     221                 :            :           }
     222                 :            :       }
     223                 :            : 
     224                 :            :       T * getInstance()
     225                 :            :       {
     226                 :            :           return rtl_Instance< T, InitInstance,
     227                 :            :                                ::osl::Mutex, ::osl::GetGlobalMutex,
     228                 :            :                                Data, InitData >::create(
     229                 :            :               InitInstance(), ::osl::GetGlobalMutex(), InitData());
     230                 :            :       }
     231                 :            : 
     232                 :            :     Some comments:
     233                 :            : 
     234                 :            :     For any instantiation of rtl_Instance, at most one call to a create method
     235                 :            :     may occur in the program code:  Each occurrence of a create method within
     236                 :            :     the program code is supposed to return a fresh object instance on the
     237                 :            :     first call, and that same object instance on subsequent calls; but
     238                 :            :     independent occurrences of create methods are supposed to return
     239                 :            :     independent object instances.  Since there is a one-to-one correspondence
     240                 :            :     between object instances and instantiations of rtl_Instance, the
     241                 :            :     requirement should be clear.  One measure to enforce the requirement is
     242                 :            :     that rtl_Instance lives in an unnamed namespace, so that instantiations of
     243                 :            :     rtl_Instance in different translation units will definitely be different
     244                 :            :     instantiations.  A drawback of that measure is that the name of the class
     245                 :            :     needs a funny "hand coded" prefix "rtl_" instead of a proper namespace
     246                 :            :     prefix like "::rtl::".
     247                 :            : 
     248                 :            :     A known problem with this template is when two occurrences of calls to
     249                 :            :     create methods with identical template arguments appear in one translation
     250                 :            :     unit.  Those two places will share a single object instance.  This can be
     251                 :            :     avoided by using different Init structs (see the above code samples) in
     252                 :            :     the two places.
     253                 :            : 
     254                 :            :     There is no need to make m_pInstance volatile, in order to avoid usage of
     255                 :            :     stale copies of m_pInstance:  At the first check, a thread will see that
     256                 :            :     m_pInstance contains either 0 or a valid pointer.  If it contains a valid
     257                 :            :     pointer, it cannot be stale, and that pointer is used.  If it contains 0,
     258                 :            :     acquiring the mutex will ensure that the second check sees a non-stale
     259                 :            :     value in all cases.
     260                 :            : 
     261                 :            :     On some compilers, the create methods would not be inlined if they
     262                 :            :     contained any static variables, so m_pInstance is made a class member
     263                 :            :     instead (and the create methods are inlined).  But on MSC, the definition
     264                 :            :     of the class member m_pInstance would cause compilation to fail with an
     265                 :            :     internal compiler error.  Since MSC is able to inline methods containing
     266                 :            :     static variables, m_pInstance is moved into the methods there.  Note that
     267                 :            :     this only works well because for any instantiation of rtl_Instance at most
     268                 :            :     one call to a create method should be present, anyway.
     269                 :            :  */
     270                 :            : template< typename Inst, typename InstCtor,
     271                 :            :           typename Guard, typename GuardCtor,
     272                 :            :           typename Data = int, typename DataCtor = int >
     273                 :            : class rtl_Instance
     274                 :            : {
     275                 :            : public:
     276                 :     438165 :     static inline Inst * create(InstCtor aInstCtor, GuardCtor aGuardCtor)
     277                 :            :     {
     278                 :            : #if defined _MSC_VER
     279                 :            :         static Inst * m_pInstance = 0;
     280                 :            : #endif // _MSC_VER
     281                 :     438165 :         Inst * p = m_pInstance;
     282         [ +  + ]:     438165 :         if (!p)
     283                 :            :         {
     284 [ +  - ][ +  - ]:        882 :             Guard aGuard(aGuardCtor());
     285                 :        882 :             p = m_pInstance;
     286         [ +  - ]:        882 :             if (!p)
     287                 :            :             {
     288         [ +  - ]:        882 :                 p = aInstCtor();
     289                 :            :                 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
     290         [ +  - ]:        882 :                 m_pInstance = p;
     291                 :            :             }
     292                 :            :         }
     293                 :            :         else
     294                 :            :         {
     295                 :            :             OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
     296                 :            :         }
     297                 :     438165 :         return p;
     298                 :            :     }
     299                 :            : 
     300                 :          6 :     static inline Inst * create(InstCtor aInstCtor, GuardCtor aGuardCtor,
     301                 :            :                                 DataCtor aDataCtor)
     302                 :            :     {
     303                 :            : #if defined _MSC_VER
     304                 :            :         static Inst * m_pInstance = 0;
     305                 :            : #endif // _MSC_VER
     306                 :          6 :         Inst * p = m_pInstance;
     307         [ +  - ]:          6 :         if (!p)
     308                 :            :         {
     309         [ +  - ]:          6 :             Data aData(aDataCtor());
     310 [ +  - ][ +  - ]:          6 :             Guard aGuard(aGuardCtor());
     311                 :          6 :             p = m_pInstance;
     312         [ +  - ]:          6 :             if (!p)
     313                 :            :             {
     314                 :          6 :                 p = aInstCtor(aData);
     315                 :            :                 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
     316         [ +  - ]:          6 :                 m_pInstance = p;
     317                 :            :             }
     318                 :            :         }
     319                 :            :         else
     320                 :            :         {
     321                 :            :             OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
     322                 :            :         }
     323                 :          6 :         return p;
     324                 :            :     }
     325                 :            : 
     326                 :            :     static inline Inst * create(InstCtor aInstCtor, GuardCtor aGuardCtor,
     327                 :            :                                 const Data &rData)
     328                 :            :     {
     329                 :            : #if defined _MSC_VER
     330                 :            :         static Inst * m_pInstance = 0;
     331                 :            : #endif // _MSC_VER
     332                 :            :         Inst * p = m_pInstance;
     333                 :            :         if (!p)
     334                 :            :         {
     335                 :            :             Guard aGuard(aGuardCtor());
     336                 :            :             p = m_pInstance;
     337                 :            :             if (!p)
     338                 :            :             {
     339                 :            :                 p = aInstCtor(rData);
     340                 :            :                 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
     341                 :            :                 m_pInstance = p;
     342                 :            :             }
     343                 :            :         }
     344                 :            :         else
     345                 :            :         {
     346                 :            :             OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
     347                 :            :         }
     348                 :            :         return p;
     349                 :            :     }
     350                 :            : 
     351                 :            : private:
     352                 :            : #if !defined _MSC_VER
     353                 :            :     static Inst * m_pInstance;
     354                 :            : #endif // _MSC_VER
     355                 :            : };
     356                 :            : 
     357                 :            : #if !defined _MSC_VER
     358                 :            : template< typename Inst, typename InstCtor,
     359                 :            :           typename Guard, typename GuardCtor,
     360                 :            :           typename Data, typename DataCtor >
     361                 :            : Inst *
     362                 :            : rtl_Instance< Inst, InstCtor, Guard, GuardCtor, Data, DataCtor >::m_pInstance
     363                 :            : = 0;
     364                 :            : #endif // _MSC_VER
     365                 :            : 
     366                 :            : }
     367                 :            : 
     368                 :            : namespace rtl {
     369                 :            : 
     370                 :            : /** Helper base class for a late-initialized (default-constructed)
     371                 :            :     static variable, implementing the double-checked locking pattern correctly.
     372                 :            : 
     373                 :            :     @derive
     374                 :            :     Derive from this class (common practice), e.g.
     375                 :            :     <pre>
     376                 :            :     struct MyStatic : public rtl::Static<MyType, MyStatic> {};
     377                 :            :     ...
     378                 :            :     MyType & rStatic = MyStatic::get();
     379                 :            :     ...
     380                 :            :     </pre>
     381                 :            : 
     382                 :            :     @tparam T
     383                 :            :               variable's type
     384                 :            :     @tparam Unique
     385                 :            :               Implementation trick to make the inner static holder unique,
     386                 :            :               using the outer class
     387                 :            :               (the one that derives from this base class)
     388                 :            : */
     389                 :            : #if defined HAVE_THREADSAFE_STATICS
     390                 :            : template<typename T, typename Unique>
     391                 :            : class Static {
     392                 :            : public:
     393                 :            :     /** Gets the static.  Mutual exclusion is implied by a functional
     394                 :            :         -fthreadsafe-statics
     395                 :            : 
     396                 :            :         @return
     397                 :            :                 static variable
     398                 :            :     */
     399                 :   47760669 :     static T & get() {
     400 [ +  + ][ +  - ]:   47760669 :         static T instance;
         [ +  +  - ][ #  
             #  #  #  #  
              # ][ #  # ]
                 [ #  # ]
           [ #  #  #  # ]
           [ +  +  #  # ]
         [ +  - ][ +  - ]
           [ +  +  +  +  
                   #  # ]
           [ +  -  +  - ]
           [ +  +  -  +  
           - ][ #  #  #  
                #  #  # ]
           [ +  +  #  # ]
                 [ +  - ]
           [ +  -  #  # ]
           [ +  +  #  #  
           #  # ][ +  - ]
           [ +  -  #  # ]
           [ #  #  #  # ]
                 [ +  + ]
           [ +  -  #  # ]
           [ +  -  #  # ]
           [ +  +  #  # ]
         [ +  - ][ +  - ]
         [ #  # ][ +  + ]
         [ +  - ][ +  - ]
         [ #  # ][ +  + ]
         [ +  - ][ +  - ]
           [ #  #  #  # ]
         [ #  # ][ #  # ]
           [ +  +  #  # ]
                 [ +  - ]
           [ +  -  #  # ]
           [ #  #  #  # ]
         [ #  # ][ #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
     401                 :   47760624 :         return instance;
     402                 :            :     }
     403                 :            : };
     404                 :            : #else
     405                 :            : template<typename T, typename Unique>
     406                 :            : class Static {
     407                 :            : public:
     408                 :            :     /** Gets the static.  Mutual exclusion is performed using the
     409                 :            :         osl global mutex.
     410                 :            : 
     411                 :            :         @return
     412                 :            :                 static variable
     413                 :            :     */
     414                 :            :     static T & get() {
     415                 :            :         return *rtl_Instance<
     416                 :            :             T, StaticInstance,
     417                 :            :             ::osl::MutexGuard, ::osl::GetGlobalMutex >::create(
     418                 :            :                 StaticInstance(), ::osl::GetGlobalMutex() );
     419                 :            :     }
     420                 :            : private:
     421                 :            :     struct StaticInstance {
     422                 :            :         T * operator () () {
     423                 :            :             static T instance;
     424                 :            :             return &instance;
     425                 :            :         }
     426                 :            :     };
     427                 :            : };
     428                 :            : #endif
     429                 :            : 
     430                 :            : /** Helper base class for a late-initialized (default-constructed)
     431                 :            :     static variable, implementing the double-checked locking pattern correctly.
     432                 :            : 
     433                 :            :     @derive
     434                 :            :     Derive from this class (common practice), e.g.
     435                 :            :     <pre>
     436                 :            :     struct MyStatic : public rtl::Static<MyType, MyStatic> {};
     437                 :            :     ...
     438                 :            :     MyType & rStatic = MyStatic::get();
     439                 :            :     ...
     440                 :            :     </pre>
     441                 :            : 
     442                 :            :     @tparam T
     443                 :            :               variable's type
     444                 :            :     @tparam Unique
     445                 :            :               Implementation trick to make the inner static holder unique,
     446                 :            :               using the outer class
     447                 :            :               (the one that derives from this base class)
     448                 :            : */
     449                 :            : #if defined HAVE_THREADSAFE_STATICS
     450                 :            : template<typename T, typename Data, typename Unique>
     451                 :            : class StaticWithArg {
     452                 :            : public:
     453                 :            :     /** Gets the static.  Mutual exclusion is implied by a functional
     454                 :            :         -fthreadsafe-statics
     455                 :            : 
     456                 :            :         @return
     457                 :            :                 static variable
     458                 :            :     */
     459                 :     134655 :     static T & get(const Data& rData) {
     460 [ +  + ][ +  - ]:     134655 :         static T instance(rData);
         [ +  - ][ #  # ]
     461                 :     134655 :         return instance;
     462                 :            :     }
     463                 :            : 
     464                 :            :     /** Gets the static.  Mutual exclusion is implied by a functional
     465                 :            :         -fthreadsafe-statics
     466                 :            : 
     467                 :            :         @return
     468                 :            :                 static variable
     469                 :            :     */
     470                 :      12794 :     static T & get(Data& rData) {
     471 [ +  + ][ +  - ]:      12794 :         static T instance(rData);
         [ +  - ][ #  # ]
     472                 :      12794 :         return instance;
     473                 :            :     }
     474                 :            : };
     475                 :            : #else
     476                 :            : template<typename T, typename Data, typename Unique>
     477                 :            : class StaticWithArg {
     478                 :            : public:
     479                 :            :     /** Gets the static.  Mutual exclusion is performed using the
     480                 :            :         osl global mutex.
     481                 :            : 
     482                 :            :         @return
     483                 :            :                 static variable
     484                 :            :     */
     485                 :            :     static T & get(const Data& rData) {
     486                 :            :         return *rtl_Instance<
     487                 :            :             T, StaticInstanceWithArg,
     488                 :            :             ::osl::MutexGuard, ::osl::GetGlobalMutex,
     489                 :            :             Data >::create( StaticInstanceWithArg(),
     490                 :            :                                       ::osl::GetGlobalMutex(),
     491                 :            :                                       rData );
     492                 :            :     }
     493                 :            : 
     494                 :            :     /** Gets the static.  Mutual exclusion is performed using the
     495                 :            :         osl global mutex.
     496                 :            : 
     497                 :            :         @return
     498                 :            :                 static variable
     499                 :            :     */
     500                 :            :     static T & get(Data& rData) {
     501                 :            :         return *rtl_Instance<
     502                 :            :             T, StaticInstanceWithArg,
     503                 :            :             ::osl::MutexGuard, ::osl::GetGlobalMutex,
     504                 :            :             Data >::create( StaticInstanceWithArg(),
     505                 :            :                                       ::osl::GetGlobalMutex(),
     506                 :            :                                       rData );
     507                 :            :     }
     508                 :            : private:
     509                 :            :     struct StaticInstanceWithArg {
     510                 :            :         T * operator () (const Data& rData) {
     511                 :            :             static T instance(rData);
     512                 :            :             return &instance;
     513                 :            :         }
     514                 :            : 
     515                 :            :         T * operator () (Data& rData) {
     516                 :            :             static T instance(rData);
     517                 :            :             return &instance;
     518                 :            :          }
     519                 :            :     };
     520                 :            : };
     521                 :            : #endif
     522                 :            : 
     523                 :            : /** Helper class for a late-initialized static aggregate, e.g. an array,
     524                 :            :     implementing the double-checked locking pattern correctly.
     525                 :            : 
     526                 :            :     @tparam T
     527                 :            :               aggregate's element type
     528                 :            :     @tparam InitAggregate
     529                 :            :               initializer functor class
     530                 :            : */
     531                 :            : #if defined HAVE_THREADSAFE_STATICS
     532                 :            : template<typename T, typename InitAggregate>
     533                 :            : class StaticAggregate {
     534                 :            : public:
     535                 :            :     /** Gets the static aggregate, late-initializing.
     536                 :            :         Mutual exclusion is implied by a functional
     537                 :            :         -fthreadsafe-statics
     538                 :            : 
     539                 :            :         @return
     540                 :            :                 aggregate
     541                 :            :     */
     542                 :   19070872 :     static T * get() {
     543 [ +  + ][ +  - ]:   19070872 :         static T *instance = InitAggregate()();
                 [ +  - ]
           [ +  +  #  # ]
         [ +  - ][ +  - ]
           [ +  +  #  # ]
                 [ +  - ]
           [ +  +  +  - ]
           [ +  -  +  +  
                   #  # ]
           [ +  -  +  - ]
           [ +  +  #  # ]
           [ +  -  +  + ]
           [ +  -  +  - ]
           [ +  +  #  # ]
           [ +  -  +  + ]
           [ +  +  +  -  
                   +  - ]
           [ +  -  #  # ]
           [ +  -  +  + ]
           [ +  +  #  #  
           +  - ][ +  - ]
           [ +  -  +  + ]
           [ #  #  +  - ]
         [ +  + ][ +  - ]
           [ #  #  +  + ]
           [ #  #  +  - ]
                 [ #  # ]
           [ #  #  +  + ]
         [ +  - ][ +  + ]
         [ +  - ][ +  + ]
         [ +  - ][ +  + ]
                 [ +  - ]
     544                 :   19070872 :         return instance;
     545                 :            :     }
     546                 :            : };
     547                 :            : #else
     548                 :            : template<typename T, typename InitAggregate>
     549                 :            : class StaticAggregate {
     550                 :            : public:
     551                 :            :     /** Gets the static aggregate, late-initializing.
     552                 :            :         Mutual exclusion is performed using the osl global mutex.
     553                 :            : 
     554                 :            :         @return
     555                 :            :                 aggregate
     556                 :            :     */
     557                 :            :     static T * get() {
     558                 :            :         return rtl_Instance<
     559                 :            :             T, InitAggregate,
     560                 :            :             ::osl::MutexGuard, ::osl::GetGlobalMutex >::create(
     561                 :            :                 InitAggregate(), ::osl::GetGlobalMutex() );
     562                 :            :     }
     563                 :            : };
     564                 :            : #endif
     565                 :            : /** Helper base class for a late-initialized static variable,
     566                 :            :     implementing the double-checked locking pattern correctly.
     567                 :            : 
     568                 :            :     @derive
     569                 :            :     Derive from this class (common practice),
     570                 :            :     providing an initializer functor class, e.g.
     571                 :            :     <pre>
     572                 :            :     struct MyStatic : public rtl::StaticWithInit<MyType, MyStatic> {
     573                 :            :         MyType operator () () {
     574                 :            :             ...
     575                 :            :             return MyType( ... );
     576                 :            :         }
     577                 :            :     };
     578                 :            :     ...
     579                 :            :     MyType & rStatic = MyStatic::get();
     580                 :            :     ...
     581                 :            :     </pre>
     582                 :            : 
     583                 :            :     @tparam T
     584                 :            :               variable's type
     585                 :            :     @tparam InitData
     586                 :            :               initializer functor class
     587                 :            :     @tparam Unique
     588                 :            :               Implementation trick to make the inner static holder unique,
     589                 :            :               using the outer class
     590                 :            :               (the one that derives from this base class).
     591                 :            :               Default is InitData (common practice).
     592                 :            :     @tparam Data
     593                 :            :               Initializer functor's return type.
     594                 :            :               Default is T (common practice).
     595                 :            : */
     596                 :            : #if defined HAVE_THREADSAFE_STATICS
     597                 :            : template<typename T, typename InitData,
     598                 :            :          typename Unique = InitData, typename Data = T>
     599                 :            : class StaticWithInit {
     600                 :            : public:
     601                 :            :     /** Gets the static.  Mutual exclusion is implied by a functional
     602                 :            :         -fthreadsafe-statics
     603                 :            : 
     604                 :            :         @return
     605                 :            :                 static variable
     606                 :            :     */
     607                 :   43949130 :     static T & get() {
     608 [ +  + ][ +  - ]:   43949130 :         static T instance = InitData()();
                 [ +  - ]
              [ #  #  # ]
              [ +  +  + ]
              [ +  +  - ]
              [ +  +  - ]
           [ #  #  #  # ]
           [ +  +  +  + ]
           [ +  -  +  - ]
           [ +  -  +  - ]
           [ #  #  #  #  
                      # ]
           [ +  +  +  - ]
           [ +  +  +  - ]
           [ +  +  +  - ]
           [ #  #  #  # ]
           [ +  +  +  + ]
           [ +  +  +  - ]
           [ +  +  +  - ]
           [ #  #  #  # ]
           [ +  +  +  + ]
           [ +  -  +  - ]
           [ +  -  +  - ]
           [ #  #  #  # ]
           [ +  +  +  + ]
           [ +  -  +  - ]
           [ +  -  +  - ]
           [ #  #  #  # ]
           [ +  +  +  - ]
           [ +  +  +  - ]
           [ +  +  +  - ]
           [ #  #  #  # ]
           [ +  +  +  # ]
           [ +  +  -  # ]
           [ +  +  -  # ]
           [ #  #  #  # ]
           [ +  +  -  # ]
           [ +  +  -  # ]
           [ +  +  -  # ]
           [ #  #  #  # ]
           [ +  +  #  # ]
           [ +  -  #  # ]
           [ +  -  #  # ]
           [ #  #  #  # ]
           [ +  +  #  # ]
           [ +  -  #  # ]
           [ +  -  #  # ]
           [ #  #  #  # ]
           [ +  +  +  - ]
           [ +  -  +  - ]
           [ +  -  +  - ]
           [ #  #  #  # ]
           [ +  +  #  # ]
           [ +  -  #  # ]
           [ +  -  #  # ]
           [ #  #  #  # ]
           [ +  +  +  + ]
           [ +  -  +  - ]
           [ +  -  +  - ]
           [ #  #  #  # ]
           [ +  +  #  # ]
           [ +  -  #  # ]
           [ +  -  #  # ]
           [ #  #  #  # ]
           [ +  +  #  # ]
           [ +  -  #  # ]
           [ +  -  #  # ]
           [ #  #  #  # ]
           [ +  +  #  # ]
           [ +  -  #  # ]
           [ +  -  #  # ]
           [ #  #  #  # ]
           [ +  +  +  + ]
           [ +  -  +  - ]
           [ +  -  +  - ]
           [ #  #  #  # ]
           [ +  +  +  + ]
           [ +  -  +  - ]
           [ +  -  +  - ]
           [ #  #  #  # ]
           [ +  +  #  # ]
           [ +  -  #  # ]
           [ +  -  #  # ]
           [ #  #  #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
         [ +  - ][ +  - ]
         [ +  - ][ #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
         [ +  - ][ +  - ]
         [ +  - ][ #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
         [ +  - ][ +  - ]
         [ +  - ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
         [ +  - ][ +  - ]
         [ +  - ][ #  # ]
         [ +  - ][ +  - ]
         [ +  - ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     609                 :   43949130 :         return instance;
     610                 :            :     }
     611                 :            : };
     612                 :            : #else
     613                 :            : template<typename T, typename InitData,
     614                 :            :          typename Unique = InitData, typename Data = T>
     615                 :            : class StaticWithInit {
     616                 :            : public:
     617                 :            :     /** Gets the static.  Mutual exclusion is performed using the
     618                 :            :         osl global mutex.
     619                 :            : 
     620                 :            :         @return
     621                 :            :                 static variable
     622                 :            :     */
     623                 :            :     static T & get() {
     624                 :            :         return *rtl_Instance<
     625                 :            :             T, StaticInstanceWithInit,
     626                 :            :             ::osl::MutexGuard, ::osl::GetGlobalMutex,
     627                 :            :             Data, InitData >::create( StaticInstanceWithInit(),
     628                 :            :                                       ::osl::GetGlobalMutex(),
     629                 :            :                                       InitData() );
     630                 :            :     }
     631                 :            : private:
     632                 :            :     struct StaticInstanceWithInit {
     633                 :            :         T * operator () ( Data d ) {
     634                 :            :             static T instance(d);
     635                 :            :             return &instance;
     636                 :            :         }
     637                 :            :     };
     638                 :            : };
     639                 :            : #endif
     640                 :            : } // namespace rtl
     641                 :            : 
     642                 :            : #endif // INCLUDED_RTL_INSTANCE_HXX
     643                 :            : 
     644                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10