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-04-09 00:01:40 Functions: 20 20 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       39013 :     inline ~OGRRefCountedPtrBase()
      36             :     {
      37       39013 :         reset(nullptr);
      38       39013 :     }
      39             : 
      40             :     /** Copy constructor.
      41             :      *
      42             :      * Increases the reference count
      43             :      */
      44        1059 :     inline OGRRefCountedPtrBase(const OGRRefCountedPtrBase &other)
      45        1059 :         : OGRRefCountedPtrBase(other.m_poRawPtr, true)
      46             :     {
      47        1059 :     }
      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         199 :     inline OGRRefCountedPtrBase &operator=(const OGRRefCountedPtrBase &other)
      56             :     {
      57         199 :         if (this != &other)
      58             :         {
      59         199 :             reset(other.m_poRawPtr);
      60             :         }
      61         199 :         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        2293 :     inline OGRRefCountedPtrBase(OGRRefCountedPtrBase &&other)
      70        2293 :     {
      71        2293 :         std::swap(m_poRawPtr, other.m_poRawPtr);
      72        2293 :     }
      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        7898 :     inline OGRRefCountedPtrBase &operator=(OGRRefCountedPtrBase &&other)
      81             :     {
      82        7898 :         reset(nullptr);
      83        7898 :         std::swap(m_poRawPtr, other.m_poRawPtr);
      84        7898 :         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       47445 :     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       47445 :         if (m_poRawPtr)
     100       10213 :             m_poRawPtr->Release();
     101       47445 :         m_poRawPtr = poRawPtr;
     102       47445 :         if (m_poRawPtr && add_ref)
     103         321 :             m_poRawPtr->Reference();
     104             : #ifdef __GNUC__
     105             : #pragma GCC diagnostic pop
     106             : #endif
     107       47445 :     }
     108             : 
     109             :     /** Returns the raw pointer without changing its reference count */
     110       43041 :     inline T *get() const
     111             :     {
     112       43041 :         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         342 :     inline T &operator*() const
     121             :     {
     122         342 :         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       28408 :     inline T *operator->() const
     129             :     {
     130       28408 :         return m_poRawPtr;
     131             :     }
     132             : 
     133             :     /** Returns whether the raw pointer is null. */
     134        5932 :     inline explicit operator bool() const
     135             :     {
     136        5932 :         return m_poRawPtr != nullptr;
     137             :     }
     138             : 
     139             :   protected:
     140       36720 :     inline explicit OGRRefCountedPtrBase(T *poRawPtr = nullptr,
     141             :                                          bool add_ref = true)
     142       36720 :         : m_poRawPtr(poRawPtr)
     143             :     {
     144             : #ifdef __GNUC__
     145             : #pragma GCC diagnostic push
     146             : #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
     147             : #endif
     148       36720 :         if (m_poRawPtr && add_ref)
     149        1285 :             m_poRawPtr->Reference();
     150             : #ifdef __GNUC__
     151             : #pragma GCC diagnostic pop
     152             : #endif
     153       36720 :     }
     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        3056 : inline bool operator==(const OGRRefCountedPtr<T> &lhs, std::nullptr_t)
     174             : {
     175        3056 :     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        3337 : inline bool operator!=(const OGRRefCountedPtr<T> &lhs, std::nullptr_t)
     186             : {
     187        3337 :     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