LCOV - code coverage report
Current view: top level - ogr - ogr_refcountedptr.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 42 42 100.0 %
Date: 2026-05-17 16:12:46 Functions: 24 24 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  OGR
       4             :  * Purpose:  Smart pointer around a class that has built-in reference counting.
       5             :  * Author:   Even Rouault <even dot rouault at spatialys.com>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2026, Even Rouault <even dot rouault at spatialys.com>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #ifndef OGR_REFCOUNTEDPTR_INCLUDED
      14             : #define OGR_REFCOUNTEDPTR_INCLUDED
      15             : 
      16             : /*! @cond Doxygen_Suppress */
      17             : 
      18             : #include <cstddef>
      19             : #include <utility>
      20             : 
      21             : /** Base (non-instantiable) class for OGRRefCountedPtr.
      22             :  *
      23             :  * Only intended to be used as the base class for OGRRefCountedPtr.
      24             :  * Done that way so its constructor is protected and force specializations
      25             :  * of redefining a public one (calling it)
      26             :  */
      27             : template <class T> struct OGRRefCountedPtrBase
      28             : {
      29             :   public:
      30             :     /** Destructor.
      31             :      *
      32             :      * Release the raw pointer, that is decrease its reference count and delete
      33             :      * the object when it reaches zero.
      34             :      */
      35      359651 :     inline ~OGRRefCountedPtrBase()
      36             :     {
      37      359651 :         reset(nullptr);
      38      359651 :     }
      39             : 
      40             :     /** Copy constructor.
      41             :      *
      42             :      * Increases the reference count
      43             :      */
      44       20469 :     inline OGRRefCountedPtrBase(const OGRRefCountedPtrBase &other)
      45       20469 :         : OGRRefCountedPtrBase(other.m_poRawPtr, true)
      46             :     {
      47       20469 :     }
      48             : 
      49             :     /** Copy constructor
      50             :      *
      51             :      * Set the raw pointer to the one used by other, and increase the reference
      52             :      * count.
      53             :      */
      54             :     // cppcheck-suppress operatorEqVarError
      55         202 :     inline OGRRefCountedPtrBase &operator=(const OGRRefCountedPtrBase &other)
      56             :     {
      57         202 :         if (this != &other)
      58             :         {
      59         202 :             reset(other.m_poRawPtr);
      60             :         }
      61         202 :         return *this;
      62             :     }
      63             : 
      64             :     /** Move constructor
      65             :      *
      66             :      * Borrows the raw pointer managed by other, without changing its reference
      67             :      * count, and set the managed raw pointer of other to null.
      68             :      */
      69        9441 :     inline OGRRefCountedPtrBase(OGRRefCountedPtrBase &&other)
      70        9441 :     {
      71        9441 :         std::swap(m_poRawPtr, other.m_poRawPtr);
      72        9441 :     }
      73             : 
      74             :     /** Move assignment operator.
      75             :      *
      76             :      * Release the current managed raw pointer and borrow the
      77             :      * one from other.
      78             :      * Does not change the reference count of the borrowed raw pointer.
      79             :      */
      80       23748 :     inline OGRRefCountedPtrBase &operator=(OGRRefCountedPtrBase &&other)
      81             :     {
      82       23748 :         reset(nullptr);
      83       23748 :         std::swap(m_poRawPtr, other.m_poRawPtr);
      84       23748 :         return *this;
      85             :     }
      86             : 
      87             :     /** Reset the managed raw pointer.
      88             :      *
      89             :      * Release the current managed raw pointer and manages a new one.
      90             :      * By default, increases the reference count of the new raw pointer (when
      91             :      * not null).
      92             :      */
      93      423889 :     inline void reset(T *poRawPtr = nullptr, bool add_ref = true)
      94             :     {
      95             : #ifdef __GNUC__
      96             : #pragma GCC diagnostic push
      97             : #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
      98             : #endif
      99      423889 :         if (m_poRawPtr)
     100       58684 :             m_poRawPtr->Release();
     101      423889 :         m_poRawPtr = poRawPtr;
     102      423889 :         if (m_poRawPtr && add_ref)
     103       23191 :             m_poRawPtr->Reference();
     104             : #ifdef __GNUC__
     105             : #pragma GCC diagnostic pop
     106             : #endif
     107      423889 :     }
     108             : 
     109             :     /** Returns the raw pointer without changing its reference count */
     110     3878278 :     inline T *get() const
     111             :     {
     112     3878278 :         return m_poRawPtr;
     113             :     }
     114             : 
     115             :     /** Returns a reference to the raw pointer without changing its reference
     116             :      * count.
     117             :      *
     118             :      * Must be only called when get() != nullptr.
     119             :      */
     120        2351 :     inline T &operator*() const
     121             :     {
     122        2351 :         return *m_poRawPtr;
     123             :     }
     124             : 
     125             :     /** Forwards the access to a member or a call to a method of the raw
     126             :      * pointer.
     127             :      */
     128     1628046 :     inline T *operator->() const
     129             :     {
     130     1628046 :         return m_poRawPtr;
     131             :     }
     132             : 
     133             :     /** Returns whether the raw pointer is null. */
     134       29674 :     inline explicit operator bool() const
     135             :     {
     136       29674 :         return m_poRawPtr != nullptr;
     137             :     }
     138             : 
     139             :   protected:
     140      350242 :     inline explicit OGRRefCountedPtrBase(T *poRawPtr = nullptr,
     141             :                                          bool add_ref = true)
     142      350242 :         : m_poRawPtr(poRawPtr)
     143             :     {
     144             : #ifdef __GNUC__
     145             : #pragma GCC diagnostic push
     146             : #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
     147             : #endif
     148      350242 :         if (m_poRawPtr && add_ref)
     149       22340 :             m_poRawPtr->Reference();
     150             : #ifdef __GNUC__
     151             : #pragma GCC diagnostic pop
     152             : #endif
     153      350242 :     }
     154             : 
     155             :   private:
     156             :     T *m_poRawPtr{};
     157             : };
     158             : 
     159             : /** Smart pointer around a class that has built-in reference counting.
     160             :  *
     161             :  * It uses the Reference() and Release() methods of the wrapped class for
     162             :  * reference counting. The reference count is increased when assigning a raw
     163             :  * pointer to the smart pointer, and decreased when releasing it.
     164             :  * Somewhat similar to https://www.boost.org/doc/libs/latest/libs/smart_ptr/doc/html/smart_ptr.html#intrusive_ptr
     165             :  *
     166             :  * Only meant for T = OGRFeatureDefn and OGRSpatialReference
     167             :  */
     168             : template <class T> struct OGRRefCountedPtr : public OGRRefCountedPtrBase<T>
     169             : {
     170             : };
     171             : 
     172             : template <class T>
     173        7721 : inline bool operator==(const OGRRefCountedPtr<T> &lhs, std::nullptr_t)
     174             : {
     175        7721 :     return lhs.get() == nullptr;
     176             : }
     177             : 
     178             : template <class T>
     179             : inline bool operator==(std::nullptr_t, const OGRRefCountedPtr<T> &rhs)
     180             : {
     181             :     return rhs.get() == nullptr;
     182             : }
     183             : 
     184             : template <class T>
     185        8733 : inline bool operator!=(const OGRRefCountedPtr<T> &lhs, std::nullptr_t)
     186             : {
     187        8733 :     return lhs.get() != nullptr;
     188             : }
     189             : 
     190             : template <class T>
     191             : inline bool operator!=(std::nullptr_t, const OGRRefCountedPtr<T> &rhs)
     192             : {
     193             :     return rhs.get() != nullptr;
     194             : }
     195             : 
     196             : /*! @endcond */
     197             : 
     198             : #endif /* OGR_REFCOUNTEDPTR_INCLUDED */

Generated by: LCOV version 1.14