LCOV - code coverage report
Current view: top level - ogr - ogr_feature.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 358 362 98.9 %
Date: 2026-05-17 16:12:46 Functions: 170 171 99.4 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  OpenGIS Simple Features Reference Implementation
       4             :  * Purpose:  Class for representing a whole feature, and layer schemas.
       5             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 1999,  Les Technologies SoftMap Inc.
       9             :  * Copyright (c) 2008-2013, Even Rouault <even dot rouault at spatialys.com>
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  ****************************************************************************/
      13             : 
      14             : #ifndef OGR_FEATURE_H_INCLUDED
      15             : #define OGR_FEATURE_H_INCLUDED
      16             : 
      17             : #include "cpl_atomic_ops.h"
      18             : #include "gdal_fwd.h"
      19             : #include "ogr_featurestyle.h"
      20             : #include "ogr_geometry.h"
      21             : #include "ogr_geomcoordinateprecision.h"
      22             : 
      23             : #include <cstddef>
      24             : 
      25             : #include <exception>
      26             : #include <memory>
      27             : #include <string>
      28             : #if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
      29             : #include <string_view>
      30             : #endif
      31             : #include <vector>
      32             : 
      33             : /**
      34             :  * \file ogr_feature.h
      35             :  *
      36             :  * Simple feature classes.
      37             :  */
      38             : 
      39             : class OGRStyleTable;
      40             : 
      41             : /************************************************************************/
      42             : /*                             OGRFieldDefn                             */
      43             : /************************************************************************/
      44             : 
      45             : /**
      46             :  * Definition of an attribute of an OGRFeatureDefn. A field is described by :
      47             :  * <ul>
      48             :  * <li>a name. See SetName() / GetNameRef()</li>
      49             :  * <li>an alternative name (optional): alternative descriptive name for the
      50             :  * field (sometimes referred to as an "alias"). See SetAlternativeName() /
      51             :  * GetAlternativeNameRef()</li> <li>a type: OFTString, OFTInteger, OFTReal, ...
      52             :  * See SetType() / GetType()</li> <li>a subtype (optional): OFSTBoolean, ... See
      53             :  * SetSubType() / GetSubType()</li> <li>a width (optional): maximal number of
      54             :  * characters. See SetWidth() / GetWidth()</li> <li>a precision (optional):
      55             :  * number of digits after decimal point. See SetPrecision() /
      56             :  * GetPrecision()</li> <li>a NOT NULL constraint (optional). See SetNullable() /
      57             :  * IsNullable()</li> <li>a UNIQUE constraint (optional). See SetUnique() /
      58             :  * IsUnique()</li> <li>a default value (optional).  See SetDefault() /
      59             :  * GetDefault()</li> <li>a boolean to indicate whether it should be ignored when
      60             :  * retrieving features.  See SetIgnored() / IsIgnored()</li> <li>a field domain
      61             :  * name (optional). See SetDomainName() / Get DomainName()</li>
      62             :  * </ul>
      63             :  *
      64             :  * Note that once a OGRFieldDefn has been added to a layer definition with
      65             :  * OGRLayer::AddFieldDefn(), its setter methods should not be called on the
      66             :  * object returned with OGRLayer::GetLayerDefn()->GetFieldDefn(). Instead,
      67             :  * OGRLayer::AlterFieldDefn() should be called on a new instance of
      68             :  * OGRFieldDefn, for drivers that support AlterFieldDefn().
      69             :  */
      70             : 
      71             : class CPL_DLL OGRFieldDefn
      72             : {
      73             :   private:
      74             :     char *pszName;
      75             :     char *pszAlternativeName;
      76             :     OGRFieldType eType;
      77             :     OGRJustification eJustify;
      78             :     int nWidth;  // Zero is variable.
      79             :     int nPrecision;
      80             :     char *pszDefault;
      81             : 
      82             :     int bIgnore;
      83             :     OGRFieldSubType eSubType;
      84             : 
      85             :     int bNullable;
      86             :     int bUnique;
      87             : 
      88             :     // Used by drivers (GPKG) to track generated fields
      89             :     bool m_bGenerated = false;
      90             : 
      91             :     std::string m_osDomainName{};  // field domain name. Might be empty
      92             : 
      93             :     std::string m_osComment{};  // field comment. Might be empty
      94             : 
      95             :     int m_nTZFlag = OGR_TZFLAG_UNKNOWN;
      96             :     bool m_bSealed = false;
      97             : 
      98             :   public:
      99             :     OGRFieldDefn(const char *, OGRFieldType);
     100             :     explicit OGRFieldDefn(const OGRFieldDefn *);
     101             :     ~OGRFieldDefn();
     102             : 
     103             :     // Copy constructor
     104             :     OGRFieldDefn(const OGRFieldDefn &oOther);
     105             : 
     106             :     // Copy assignment operator
     107             :     OGRFieldDefn &operator=(const OGRFieldDefn &oOther);
     108             : 
     109             :     void SetName(const char *);
     110             : 
     111    22634955 :     const char *GetNameRef() const
     112             :     {
     113    22634955 :         return pszName;
     114             :     }
     115             : 
     116             :     void SetAlternativeName(const char *);
     117             : 
     118      933734 :     const char *GetAlternativeNameRef() const
     119             :     {
     120      933734 :         return pszAlternativeName;
     121             :     }
     122             : 
     123    37709418 :     OGRFieldType GetType() const
     124             :     {
     125    37709418 :         return eType;
     126             :     }
     127             : 
     128             :     void SetType(OGRFieldType eTypeIn);
     129             :     static const char *GetFieldTypeName(OGRFieldType);
     130             :     static OGRFieldType GetFieldTypeByName(const char *);
     131             : 
     132     5351538 :     OGRFieldSubType GetSubType() const
     133             :     {
     134     5351538 :         return eSubType;
     135             :     }
     136             : 
     137             :     void SetSubType(OGRFieldSubType eSubTypeIn);
     138             :     static const char *GetFieldSubTypeName(OGRFieldSubType);
     139             :     static OGRFieldSubType GetFieldSubTypeByName(const char *);
     140             : 
     141      773219 :     OGRJustification GetJustify() const
     142             :     {
     143      773219 :         return eJustify;
     144             :     }
     145             : 
     146       87051 :     void SetJustify(OGRJustification eJustifyIn)
     147             :     {
     148       87051 :         eJustify = eJustifyIn;
     149       87051 :     }
     150             : 
     151     5604317 :     int GetWidth() const
     152             :     {
     153     5604317 :         return nWidth;
     154             :     }
     155             : 
     156             :     void SetWidth(int nWidthIn);
     157             : 
     158      929063 :     int GetPrecision() const
     159             :     {
     160      929063 :         return nPrecision;
     161             :     }
     162             : 
     163             :     void SetPrecision(int nPrecisionIn);
     164             : 
     165      786881 :     int GetTZFlag() const
     166             :     {
     167      786881 :         return m_nTZFlag;
     168             :     }
     169             : 
     170             :     void SetTZFlag(int nTZFlag);
     171             : 
     172             :     void Set(const char *, OGRFieldType, int = 0, int = 0,
     173             :              OGRJustification = OJUndefined);
     174             : 
     175             :     void SetDefault(const char *);
     176             :     const char *GetDefault() const;
     177             :     int IsDefaultDriverSpecific() const;
     178             : 
     179      977705 :     int IsIgnored() const
     180             :     {
     181      977705 :         return bIgnore;
     182             :     }
     183             : 
     184       59667 :     void SetIgnored(int bIgnoreIn)
     185             :     {
     186       59667 :         bIgnore = bIgnoreIn;
     187       59667 :     }
     188             : 
     189      975286 :     int IsNullable() const
     190             :     {
     191      975286 :         return bNullable;
     192             :     }
     193             : 
     194             :     void SetNullable(int bNullableIn);
     195             : 
     196      932581 :     int IsUnique() const
     197             :     {
     198      932581 :         return bUnique;
     199             :     }
     200             : 
     201             :     /**
     202             :      * @brief Return whether the field is a generated field.
     203             :      *
     204             :      * At time of writing, only the GeoPackage and PG drivers fill that information. Consequently,
     205             :      * only a returned value equal to TRUE can be fully trusted.
     206             :      * @return TRUE if the field is a generated field, FALSE otherwise.
     207             :      * @since GDAL 3.11
     208             :      */
     209     5254071 :     bool IsGenerated() const
     210             :     {
     211     5254071 :         return m_bGenerated;
     212             :     }
     213             : 
     214             :     /**
     215             :      * @brief SetGenerated set the field generated status.
     216             :      * @param bGeneratedIn TRUE if the field is a generated field, FALSE otherwise.
     217             :      * @since GDAL 3.11
     218             :      */
     219        2553 :     void SetGenerated(bool bGeneratedIn)
     220             :     {
     221        2553 :         m_bGenerated = bGeneratedIn;
     222        2553 :     }
     223             : 
     224             :     void SetUnique(int bUniqueIn);
     225             : 
     226       68455 :     const std::string &GetDomainName() const
     227             :     {
     228       68455 :         return m_osDomainName;
     229             :     }
     230             : 
     231             :     void SetDomainName(const std::string &osDomainName);
     232             : 
     233      932679 :     const std::string &GetComment() const
     234             :     {
     235      932679 :         return m_osComment;
     236             :     }
     237             : 
     238             :     void SetComment(const std::string &osComment);
     239             : 
     240             :     int IsSame(const OGRFieldDefn *) const;
     241             : 
     242             :     /** Convert a OGRFieldDefn* to a OGRFieldDefnH.
     243             :      */
     244      484808 :     static inline OGRFieldDefnH ToHandle(OGRFieldDefn *poFieldDefn)
     245             :     {
     246      484808 :         return reinterpret_cast<OGRFieldDefnH>(poFieldDefn);
     247             :     }
     248             : 
     249             :     /** Convert a OGRFieldDefnH to a OGRFieldDefn*.
     250             :      */
     251      568094 :     static inline OGRFieldDefn *FromHandle(OGRFieldDefnH hFieldDefn)
     252             :     {
     253      568094 :         return reinterpret_cast<OGRFieldDefn *>(hFieldDefn);
     254             :     }
     255             : 
     256             :     void Seal();
     257             : 
     258             :     void Unseal();
     259             : 
     260             :     /*! @cond Doxygen_Suppress */
     261             :     struct CPL_DLL TemporaryUnsealer
     262             :     {
     263             :       private:
     264             :         OGRFieldDefn *m_poFieldDefn = nullptr;
     265             :         CPL_DISALLOW_COPY_ASSIGN(TemporaryUnsealer)
     266             :       public:
     267         235 :         explicit TemporaryUnsealer(OGRFieldDefn *poFieldDefn)
     268         235 :             : m_poFieldDefn(poFieldDefn)
     269             :         {
     270         235 :             m_poFieldDefn->Unseal();
     271         235 :         }
     272             : 
     273             :         TemporaryUnsealer(TemporaryUnsealer &&) = default;
     274             :         TemporaryUnsealer &operator=(TemporaryUnsealer &&) = default;
     275             : 
     276         235 :         ~TemporaryUnsealer()
     277         235 :         {
     278         235 :             m_poFieldDefn->Seal();
     279         235 :         }
     280             : 
     281          84 :         OGRFieldDefn *operator->()
     282             :         {
     283          84 :             return m_poFieldDefn;
     284             :         }
     285             :     };
     286             : 
     287             :     /*! @endcond */
     288             : 
     289             :     TemporaryUnsealer GetTemporaryUnsealer();
     290             : };
     291             : 
     292             : #ifdef GDAL_COMPILATION
     293             : /** Return an object that temporary unseals the OGRFieldDefn.
     294             :  *
     295             :  * The returned object calls Unseal() initially, and when it is destroyed
     296             :  * it calls Seal().
     297             :  *
     298             :  * This method should only be called by driver implementations.
     299             :  *
     300             :  * Usage: whileUnsealing(poFieldDefn)->some_method();
     301             :  *
     302             :  * @since GDAL 3.9
     303             :  */
     304          84 : inline OGRFieldDefn::TemporaryUnsealer whileUnsealing(OGRFieldDefn *object)
     305             : {
     306          84 :     return object->GetTemporaryUnsealer();
     307             : }
     308             : #endif
     309             : 
     310             : /************************************************************************/
     311             : /*                           OGRGeomFieldDefn                           */
     312             : /************************************************************************/
     313             : 
     314             : /**
     315             :  * Definition of a geometry field of an OGRFeatureDefn. A geometry field is
     316             :  * described by :
     317             :  * <ul>
     318             :  * <li>a name. See SetName() / GetNameRef()</li>
     319             :  * <li>a type: wkbPoint, wkbLineString, ... See SetType() / GetType()</li>
     320             :  * <li>a spatial reference system (optional). See SetSpatialRef() /
     321             :  * GetSpatialRef()</li> <li>a NOT NULL constraint (optional). See SetNullable()
     322             :  * / IsNullable()</li> <li>a boolean to indicate whether it should be ignored
     323             :  * when retrieving features.  See SetIgnored() / IsIgnored()</li>
     324             :  * </ul>
     325             :  *
     326             :  * Note that once a OGRGeomFieldDefn has been added to a layer definition with
     327             :  * OGRLayer::AddGeomFieldDefn(), its setter methods should not be called on the
     328             :  * object returned with OGRLayer::GetLayerDefn()->GetGeomFieldDefn(). Instead,
     329             :  * OGRLayer::AlterGeomFieldDefn() should be called on a new instance of
     330             :  * OGRFieldDefn, for drivers that support AlterFieldDefn().
     331             :  *
     332             :  */
     333             : 
     334             : class CPL_DLL OGRGeomFieldDefn
     335             : {
     336             :   protected:
     337             :     //! @cond Doxygen_Suppress
     338             :     char *pszName = nullptr;
     339             :     OGRwkbGeometryType eGeomType =
     340             :         wkbUnknown; /* all values possible except wkbNone */
     341             :     mutable OGRSpatialReferenceRefCountedPtr poSRS = nullptr;
     342             : 
     343             :     int bIgnore = false;
     344             :     mutable int bNullable = true;
     345             :     bool m_bSealed = false;
     346             :     OGRGeomCoordinatePrecision m_oCoordPrecision{};
     347             : 
     348             :     void Initialize(const char *, OGRwkbGeometryType);
     349             :     //! @endcond
     350             : 
     351             :   public:
     352             :     OGRGeomFieldDefn(const char *pszNameIn, OGRwkbGeometryType eGeomTypeIn);
     353             :     explicit OGRGeomFieldDefn(const OGRGeomFieldDefn *);
     354             :     virtual ~OGRGeomFieldDefn();
     355             : 
     356             :     // Copy constructor
     357             :     OGRGeomFieldDefn(const OGRGeomFieldDefn &oOther);
     358             : 
     359             :     // Move constructor
     360             :     OGRGeomFieldDefn(OGRGeomFieldDefn &&oOther);
     361             : 
     362             :     // Copy assignment operator
     363             :     OGRGeomFieldDefn &operator=(const OGRGeomFieldDefn &oOther);
     364             : 
     365             :     // Move assignment operator
     366             :     OGRGeomFieldDefn &operator=(OGRGeomFieldDefn &&oOther);
     367             : 
     368             :     void SetName(const char *);
     369             : 
     370      169242 :     const char *GetNameRef() const
     371             :     {
     372      169242 :         return pszName;
     373             :     }
     374             : 
     375      763161 :     OGRwkbGeometryType GetType() const
     376             :     {
     377      763161 :         return eGeomType;
     378             :     }
     379             : 
     380             :     void SetType(OGRwkbGeometryType eTypeIn);
     381             : 
     382             :     virtual const OGRSpatialReference *GetSpatialRef() const;
     383             :     void SetSpatialRef(const OGRSpatialReference *poSRSIn);
     384             :     void SetSpatialRef(OGRSpatialReferenceRefCountedPtr poSRSIn);
     385             : 
     386      197883 :     int IsIgnored() const
     387             :     {
     388      197883 :         return bIgnore;
     389             :     }
     390             : 
     391       11444 :     void SetIgnored(int bIgnoreIn)
     392             :     {
     393       11444 :         bIgnore = bIgnoreIn;
     394       11444 :     }
     395             : 
     396       14329 :     int IsNullable() const
     397             :     {
     398       14329 :         return bNullable;
     399             :     }
     400             : 
     401             :     void SetNullable(int bNullableIn);
     402             : 
     403        3805 :     const OGRGeomCoordinatePrecision &GetCoordinatePrecision() const
     404             :     {
     405        3805 :         return m_oCoordPrecision;
     406             :     }
     407             : 
     408             :     void SetCoordinatePrecision(const OGRGeomCoordinatePrecision &prec);
     409             : 
     410             :     int IsSame(const OGRGeomFieldDefn *) const;
     411             : 
     412             :     /** Convert a OGRGeomFieldDefn* to a OGRGeomFieldDefnH.
     413             :      */
     414         860 :     static inline OGRGeomFieldDefnH ToHandle(OGRGeomFieldDefn *poGeomFieldDefn)
     415             :     {
     416         860 :         return reinterpret_cast<OGRGeomFieldDefnH>(poGeomFieldDefn);
     417             :     }
     418             : 
     419             :     /** Convert a OGRGeomFieldDefnH to a OGRGeomFieldDefn*.
     420             :      */
     421        1210 :     static inline OGRGeomFieldDefn *FromHandle(OGRGeomFieldDefnH hGeomFieldDefn)
     422             :     {
     423        1210 :         return reinterpret_cast<OGRGeomFieldDefn *>(hGeomFieldDefn);
     424             :     }
     425             : 
     426             :     void Seal();
     427             : 
     428             :     void Unseal();
     429             : 
     430             :     /*! @cond Doxygen_Suppress */
     431             :     struct CPL_DLL TemporaryUnsealer
     432             :     {
     433             :       private:
     434             :         OGRGeomFieldDefn *m_poFieldDefn = nullptr;
     435             :         CPL_DISALLOW_COPY_ASSIGN(TemporaryUnsealer)
     436             :       public:
     437         751 :         explicit TemporaryUnsealer(OGRGeomFieldDefn *poFieldDefn)
     438         751 :             : m_poFieldDefn(poFieldDefn)
     439             :         {
     440         751 :             m_poFieldDefn->Unseal();
     441         751 :         }
     442             : 
     443             :         TemporaryUnsealer(TemporaryUnsealer &&) = default;
     444             :         TemporaryUnsealer &operator=(TemporaryUnsealer &&) = default;
     445             : 
     446         751 :         ~TemporaryUnsealer()
     447         751 :         {
     448         751 :             m_poFieldDefn->Seal();
     449         751 :         }
     450             : 
     451         719 :         OGRGeomFieldDefn *operator->()
     452             :         {
     453         719 :             return m_poFieldDefn;
     454             :         }
     455             :     };
     456             : 
     457             :     /*! @endcond */
     458             : 
     459             :     TemporaryUnsealer GetTemporaryUnsealer();
     460             : 
     461             :   private:
     462       18758 :     OGRSpatialReferenceRefCountedPtr &GetRefCountedSRS() const
     463             :     {
     464       18758 :         GetSpatialRef();
     465       18758 :         return poSRS;
     466             :     }
     467             : };
     468             : 
     469             : #ifdef GDAL_COMPILATION
     470             : /** Return an object that temporary unseals the OGRGeomFieldDefn.
     471             :  *
     472             :  * The returned object calls Unseal() initially, and when it is destroyed
     473             :  * it calls Seal().
     474             :  *
     475             :  * This method should only be called by driver implementations.
     476             :  *
     477             :  * Usage: whileUnsealing(poGeomFieldDefn)->some_method();
     478             :  *
     479             :  * @since GDAL 3.9
     480             :  */
     481             : inline OGRGeomFieldDefn::TemporaryUnsealer
     482         719 : whileUnsealing(OGRGeomFieldDefn *object)
     483             : {
     484         719 :     return object->GetTemporaryUnsealer();
     485             : }
     486             : #endif
     487             : 
     488             : /************************************************************************/
     489             : /*                            OGRFeatureDefn                            */
     490             : /************************************************************************/
     491             : 
     492             : /**
     493             :  * Definition of a feature class or feature layer.
     494             :  *
     495             :  * This object contains schema information for a set of OGRFeatures.  In
     496             :  * table based systems, an OGRFeatureDefn is essentially a layer.  In more
     497             :  * object oriented approaches (such as SF CORBA) this can represent a class
     498             :  * of features but doesn't necessarily relate to all of a layer, or just one
     499             :  * layer.
     500             :  *
     501             :  * This object also can contain some other information such as a name and
     502             :  * potentially other metadata.
     503             :  *
     504             :  * It is essentially a collection of field descriptions (OGRFieldDefn class).
     505             :  * In addition to attribute fields, it can also
     506             :  * contain multiple geometry fields (OGRGeomFieldDefn class).
     507             :  *
     508             :  * It is reasonable for different translators to derive classes from
     509             :  * OGRFeatureDefn with additional translator specific information.
     510             :  *
     511             :  * Note that adding, modifying, removing, reordering a OGRFieldDefn (or a
     512             :  * OGRGeomFieldDefn) from/to a OGRFeatureDefn that belongs to a OGRLayer should
     513             :  * not be done through the OGRFeatureDefn::AddFieldDefn(),
     514             :  * OGRFeatureDefn::DeleteFieldDefn() or OGRFeatureDefn::ReorderFieldDefns()
     515             :  * methods, but rather through OGRLayer::CreateField(),
     516             :  * OGRLayer::AlterFieldDefn() or OGRLayer::ReorderFields(), for drivers that
     517             :  * support those operations.
     518             :  */
     519             : 
     520             : class CPL_DLL OGRFeatureDefn
     521             : {
     522             :   protected:
     523             :     //! @cond Doxygen_Suppress
     524             :     volatile int nRefCount = 0;
     525             : 
     526             :     mutable std::vector<std::unique_ptr<OGRFieldDefn>> apoFieldDefn{};
     527             :     mutable std::vector<std::unique_ptr<OGRGeomFieldDefn>> apoGeomFieldDefn{};
     528             : 
     529             :     char *pszFeatureClassName = nullptr;
     530             : 
     531             :     bool bIgnoreStyle = false;
     532             : 
     533             :     friend class TemporaryUnsealer;
     534             :     bool m_bSealed = false;
     535             :     int m_nTemporaryUnsealCount = 0;
     536             :     //! @endcond
     537             : 
     538             :   public:
     539             :     explicit OGRFeatureDefn(const char *pszName = nullptr);
     540             :     virtual ~OGRFeatureDefn();
     541             : 
     542             :     void SetName(const char *pszName);
     543             :     virtual const char *GetName() const;
     544             : 
     545             :     virtual int GetFieldCount() const;
     546             :     virtual OGRFieldDefn *GetFieldDefn(int i);
     547             :     virtual const OGRFieldDefn *GetFieldDefn(int i) const;
     548             :     virtual int GetFieldIndex(const char *) const;
     549             :     int GetFieldIndexCaseSensitive(const char *) const;
     550             : 
     551             :     //! @cond Doxygen_Suppress
     552             :     /** Helper class to iterate over non-geometry fields.
     553             :      *
     554             :      * Note: fields should not be added or removed while iterating over them.
     555             :      */
     556             :     template <class OwnerT, class ChildT> struct CPL_DLL Fields
     557             :     {
     558             :       private:
     559             :         OwnerT m_poFDefn;
     560             : 
     561             :       public:
     562         190 :         inline explicit Fields(OwnerT poFDefn) : m_poFDefn(poFDefn)
     563             :         {
     564         190 :         }
     565             : 
     566             :         struct CPL_DLL Iterator
     567             :         {
     568             :           private:
     569             :             OwnerT m_poFDefn;
     570             :             const int m_nFieldCount;
     571             :             int m_nIdx;
     572             :             ChildT m_curValue{};
     573             : 
     574             :           public:
     575         374 :             inline Iterator(OwnerT poFDefn, int nIdx)
     576             :                 : m_poFDefn(poFDefn), m_nFieldCount(poFDefn->GetFieldCount()),
     577         374 :                   m_nIdx(nIdx)
     578             :             {
     579         374 :                 if (m_nIdx < m_nFieldCount)
     580         176 :                     m_curValue = m_poFDefn->GetFieldDefn(m_nIdx);
     581         374 :             }
     582             : 
     583          10 :             inline const ChildT &operator*() const
     584             :             {
     585          10 :                 return m_curValue;
     586             :             }
     587             : 
     588         737 :             inline ChildT &operator*()
     589             :             {
     590         737 :                 return m_curValue;
     591             :             }
     592             : 
     593         746 :             inline Iterator &operator++()
     594             :             {
     595         746 :                 m_nIdx++;
     596         746 :                 if (m_nIdx < m_nFieldCount)
     597         571 :                     m_curValue = m_poFDefn->GetFieldDefn(m_nIdx);
     598             :                 else
     599         175 :                     m_curValue = nullptr;
     600         746 :                 return *this;
     601             :             }
     602             : 
     603         933 :             inline bool operator!=(const Iterator &it) const
     604             :             {
     605         933 :                 return m_nIdx != it.m_nIdx;
     606             :             }
     607             :         };
     608             : 
     609         187 :         inline Iterator begin() const
     610             :         {
     611         187 :             return Iterator(m_poFDefn, 0);
     612             :         }
     613             : 
     614         187 :         inline Iterator end() const
     615             :         {
     616         187 :             return Iterator(m_poFDefn, m_poFDefn->GetFieldCount());
     617             :         }
     618             : 
     619           1 :         inline size_t size() const
     620             :         {
     621           1 :             return static_cast<std::size_t>(m_poFDefn->GetFieldCount());
     622             :         }
     623             : 
     624           2 :         inline ChildT operator[](size_t i)
     625             :         {
     626           2 :             return m_poFDefn->GetFieldDefn(static_cast<int>(i));
     627             :         }
     628             :     };
     629             : 
     630             :     //! @endcond
     631             : 
     632             :     /** Return type of GetFields() */
     633             :     using NonConstFields = Fields<OGRFeatureDefn *, OGRFieldDefn *>;
     634             : 
     635             :     /** Return an object that can be used to iterate over non-geometry fields.
     636             :         \verbatim
     637             :         for( const auto* poFieldDefn: poFeatureDefn->GetFields() )
     638             :         {
     639             :             // do something
     640             :         }
     641             :         \endverbatim
     642             : 
     643             :         @since GDAL 3.7
     644             :      */
     645          80 :     inline NonConstFields GetFields()
     646             :     {
     647          80 :         return NonConstFields(this);
     648             :     }
     649             : 
     650             :     /** Return type of GetFields() const */
     651             :     using ConstFields = Fields<const OGRFeatureDefn *, const OGRFieldDefn *>;
     652             : 
     653             :     /** Return an object that can be used to iterate over non-geometry fields.
     654             :         \verbatim
     655             :         for( const auto* poFieldDefn: poFeatureDefn->GetFields() )
     656             :         {
     657             :             // do something
     658             :         }
     659             :         \endverbatim
     660             : 
     661             :         @since GDAL 3.12
     662             :      */
     663         110 :     inline ConstFields GetFields() const
     664             :     {
     665         110 :         return ConstFields(this);
     666             :     }
     667             : 
     668             :     //! @cond Doxygen_Suppress
     669             :     // That method should only be called if there's a guarantee that
     670             :     // GetFieldCount() has been called before
     671     4302342 :     int GetFieldCountUnsafe() const
     672             :     {
     673     4302342 :         return static_cast<int>(apoFieldDefn.size());
     674             :     }
     675             : 
     676             :     // Those methods don't check i is n range.
     677     1490292 :     OGRFieldDefn *GetFieldDefnUnsafe(int i)
     678             :     {
     679     1490292 :         if (apoFieldDefn.empty())
     680           0 :             GetFieldDefn(i);
     681     1490292 :         return apoFieldDefn[static_cast<std::size_t>(i)].get();
     682             :     }
     683             : 
     684    15847700 :     const OGRFieldDefn *GetFieldDefnUnsafe(int i) const
     685             :     {
     686    15847700 :         if (apoFieldDefn.empty())
     687           0 :             GetFieldDefn(i);
     688    15847700 :         return apoFieldDefn[static_cast<std::size_t>(i)].get();
     689             :     }
     690             : 
     691             :     //! @endcond
     692             : 
     693             :     virtual void AddFieldDefn(const OGRFieldDefn *);
     694             :     virtual OGRErr DeleteFieldDefn(int iField);
     695             : 
     696             :     /**
     697             :      * @brief StealFieldDefn takes ownership of the field definition at index detaching
     698             :      *        it from the feature definition.
     699             :      * This is an advanced method designed to be only used for driver implementations.
     700             :      * @param iField index of the field definition to detach.
     701             :      * @return a unique pointer to the detached field definition or nullptr if the index is out of range.
     702             :      * @since GDAL 3.11
     703             :      */
     704             :     virtual std::unique_ptr<OGRFieldDefn> StealFieldDefn(int iField);
     705             : 
     706             :     virtual void AddFieldDefn(std::unique_ptr<OGRFieldDefn> &&poFieldDefn);
     707             : 
     708             :     virtual OGRErr ReorderFieldDefns(const int *panMap);
     709             : 
     710             :     /**
     711             :      * @brief StealGeomFieldDefn takes ownership of the the geometry field definition at index
     712             :      *        detaching it from the feature definition.
     713             :      * This is an advanced method designed to be only used for driver implementations.
     714             :      * @param iField index of the geometry field definition to detach.
     715             :      * @return a unique pointer to the detached geometry field definition or nullptr if the index is out of range.
     716             :      * @since GDAL 3.11
     717             :      */
     718             :     virtual std::unique_ptr<OGRGeomFieldDefn> StealGeomFieldDefn(int iField);
     719             : 
     720             :     virtual int GetGeomFieldCount() const;
     721             :     virtual OGRGeomFieldDefn *GetGeomFieldDefn(int i);
     722             :     virtual const OGRGeomFieldDefn *GetGeomFieldDefn(int i) const;
     723             :     virtual int GetGeomFieldIndex(const char *) const;
     724             : 
     725             :     //! @cond Doxygen_Suppress
     726             :     /** Helper class to iterate over geometry fields.
     727             :      *
     728             :      * Note: fields should not be added or removed while iterating over them.
     729             :      */
     730             :     template <class OwnerT, class ChildT> struct CPL_DLL GeomFields
     731             :     {
     732             :       private:
     733             :         OwnerT m_poFDefn;
     734             : 
     735             :       public:
     736       16321 :         inline explicit GeomFields(OwnerT poFDefn) : m_poFDefn(poFDefn)
     737             :         {
     738       16321 :         }
     739             : 
     740             :         struct CPL_DLL Iterator
     741             :         {
     742             :           private:
     743             :             OwnerT m_poFDefn;
     744             :             int m_nIdx;
     745             : 
     746             :           public:
     747       32634 :             inline Iterator(OwnerT poFDefn, int nIdx)
     748       32634 :                 : m_poFDefn(poFDefn), m_nIdx(nIdx)
     749             :             {
     750       32634 :             }
     751             : 
     752       16302 :             inline ChildT operator*() const
     753             :             {
     754       16302 :                 return m_poFDefn->GetGeomFieldDefn(m_nIdx);
     755             :             }
     756             : 
     757       16298 :             inline Iterator &operator++()
     758             :             {
     759       16298 :                 m_nIdx++;
     760       16298 :                 return *this;
     761             :             }
     762             : 
     763       32615 :             inline bool operator!=(const Iterator &it) const
     764             :             {
     765       32615 :                 return m_nIdx != it.m_nIdx;
     766             :             }
     767             :         };
     768             : 
     769       16317 :         inline Iterator begin()
     770             :         {
     771       16317 :             return Iterator(m_poFDefn, 0);
     772             :         }
     773             : 
     774       16317 :         inline Iterator end()
     775             :         {
     776       16317 :             return Iterator(m_poFDefn, m_poFDefn->GetGeomFieldCount());
     777             :         }
     778             : 
     779           1 :         inline size_t size() const
     780             :         {
     781           1 :             return static_cast<std::size_t>(m_poFDefn->GetGeomFieldCount());
     782             :         }
     783             : 
     784           3 :         inline ChildT operator[](size_t i) const
     785             :         {
     786           3 :             return m_poFDefn->GetGeomFieldDefn(static_cast<int>(i));
     787             :         }
     788             :     };
     789             : 
     790             :     //! @endcond
     791             : 
     792             :     /** Return type of GetGeomFields() */
     793             :     using NonConstGeomFields = GeomFields<OGRFeatureDefn *, OGRGeomFieldDefn *>;
     794             : 
     795             :     /** Return an object that can be used to iterate over geometry fields.
     796             :         \verbatim
     797             :         for( const auto* poGeomFieldDefn: poFeatureDefn->GetGeomFields() )
     798             :         {
     799             :             // do something
     800             :         }
     801             :         \endverbatim
     802             : 
     803             :         @since GDAL 3.7
     804             :      */
     805          20 :     inline NonConstGeomFields GetGeomFields()
     806             :     {
     807          20 :         return NonConstGeomFields(this);
     808             :     }
     809             : 
     810             :     /** Return type of GetGeomFields() const */
     811             :     using ConstGeomFields =
     812             :         GeomFields<const OGRFeatureDefn *, const OGRGeomFieldDefn *>;
     813             : 
     814             :     /** Return an object that can be used to iterate over geometry fields.
     815             :         \verbatim
     816             :         for( const auto* poGeomFieldDefn: poFeatureDefn->GetGeomFields() )
     817             :         {
     818             :             // do something
     819             :         }
     820             :         \endverbatim
     821             : 
     822             :         @since GDAL 3.12
     823             :      */
     824       16301 :     inline ConstGeomFields GetGeomFields() const
     825             :     {
     826       16301 :         return ConstGeomFields(this);
     827             :     }
     828             : 
     829             :     virtual void AddGeomFieldDefn(const OGRGeomFieldDefn *);
     830             :     virtual void AddGeomFieldDefn(std::unique_ptr<OGRGeomFieldDefn> &&);
     831             :     virtual OGRErr DeleteGeomFieldDefn(int iGeomField);
     832             : 
     833             :     virtual OGRwkbGeometryType GetGeomType() const;
     834             :     virtual void SetGeomType(OGRwkbGeometryType);
     835             : 
     836             :     virtual OGRFeatureDefn *Clone() const;
     837             : 
     838             : #ifdef DEPRECATE_OGRFEATUREDEFN_REF_COUNTING
     839           0 :     int Reference()
     840             :         CPL_WARN_DEPRECATED("Use OGRFeatureDefnRefCountedPtr instead")
     841             :     {
     842           0 :         return CPLAtomicInc(&nRefCount);
     843             :     }
     844             : 
     845             :     int Dereference()
     846             :         CPL_WARN_DEPRECATED("Use OGRFeatureDefnRefCountedPtr instead")
     847             :     {
     848             :         return CPLAtomicDec(&nRefCount);
     849             :     }
     850             : 
     851             :     int GetReferenceCount() const
     852             :         CPL_WARN_DEPRECATED("Use OGRFeatureDefnRefCountedPtr instead")
     853             :     {
     854             :         return nRefCount;
     855             :     }
     856             : 
     857             :     void Release()
     858             :         CPL_WARN_DEPRECATED("Use OGRFeatureDefnRefCountedPtr instead");
     859             : #else
     860     2354033 :     int Reference()
     861             :     {
     862     2354033 :         return CPLAtomicInc(&nRefCount);
     863             :     }
     864             : 
     865     2353880 :     int Dereference()
     866             : #if defined(GDAL_COMPILATION) && !defined(DOXYGEN_XML)
     867             :         CPL_WARN_DEPRECATED("Use Release() instead")
     868             : #endif
     869             :     {
     870     2353880 :         return CPLAtomicDec(&nRefCount);
     871             :     }
     872             : 
     873          16 :     int GetReferenceCount() const
     874             :     {
     875          16 :         return nRefCount;
     876             :     }
     877             : 
     878             :     void Release();
     879             : #endif
     880             : 
     881             :     virtual int IsGeometryIgnored() const;
     882             :     virtual void SetGeometryIgnored(int bIgnore);
     883             : 
     884          13 :     virtual bool IsStyleIgnored() const
     885             :     {
     886          13 :         return bIgnoreStyle;
     887             :     }
     888             : 
     889        8566 :     virtual void SetStyleIgnored(bool bIgnore)
     890             :     {
     891        8566 :         bIgnoreStyle = bIgnore;
     892        8566 :     }
     893             : 
     894             :     virtual int IsSame(const OGRFeatureDefn *poOtherFeatureDefn) const;
     895             : 
     896             :     //! @cond Doxygen_Suppress
     897             :     void ReserveSpaceForFields(int nFieldCountIn);
     898             :     //! @endcond
     899             : 
     900             :     std::vector<int> ComputeMapForSetFrom(const OGRFeatureDefn *poSrcFDefn,
     901             :                                           bool bForgiving = true) const;
     902             : 
     903             :     static OGRFeatureDefn *CreateFeatureDefn(const char *pszName = nullptr);
     904             :     static void DestroyFeatureDefn(OGRFeatureDefn *);
     905             : 
     906             :     /** Convert a OGRFeatureDefn* to a OGRFeatureDefnH.
     907             :      */
     908      184266 :     static inline OGRFeatureDefnH ToHandle(OGRFeatureDefn *poFeatureDefn)
     909             :     {
     910      184266 :         return reinterpret_cast<OGRFeatureDefnH>(poFeatureDefn);
     911             :     }
     912             : 
     913             :     /** Convert a OGRFeatureDefnH to a OGRFeatureDefn*.
     914             :      */
     915      759234 :     static inline OGRFeatureDefn *FromHandle(OGRFeatureDefnH hFeatureDefn)
     916             :     {
     917      759234 :         return reinterpret_cast<OGRFeatureDefn *>(hFeatureDefn);
     918             :     }
     919             : 
     920             :     void Seal(bool bSealFields);
     921             : 
     922             :     void Unseal(bool bUnsealFields);
     923             : 
     924             :     /*! @cond Doxygen_Suppress */
     925             :     struct CPL_DLL TemporaryUnsealer
     926             :     {
     927             :       private:
     928             :         OGRFeatureDefn *m_poFeatureDefn = nullptr;
     929             :         bool m_bSealFields = false;
     930             :         CPL_DISALLOW_COPY_ASSIGN(TemporaryUnsealer)
     931             :       public:
     932             :         explicit TemporaryUnsealer(OGRFeatureDefn *poFeatureDefn,
     933             :                                    bool bSealFields);
     934             : 
     935             :         TemporaryUnsealer(TemporaryUnsealer &&) = default;
     936             :         TemporaryUnsealer &operator=(TemporaryUnsealer &&) = default;
     937             : 
     938             :         ~TemporaryUnsealer();
     939             : 
     940       28485 :         OGRFeatureDefn *operator->()
     941             :         {
     942       28485 :             return m_poFeatureDefn;
     943             :         }
     944             :     };
     945             : 
     946             :     /*! @endcond */
     947             : 
     948             :     TemporaryUnsealer GetTemporaryUnsealer(bool bSealFields = true);
     949             : 
     950             :   private:
     951             :     CPL_DISALLOW_COPY_ASSIGN(OGRFeatureDefn)
     952             : };
     953             : 
     954             : /*! @cond Doxygen_Suppress */
     955             : 
     956             : #include "ogr_refcountedptr.h"
     957             : 
     958             : template <>
     959             : struct OGRRefCountedPtr<OGRFeatureDefn>
     960             :     : public OGRRefCountedPtrBase<OGRFeatureDefn>
     961             : {
     962             :     /** Constructs from a raw OGRFeatureDefn instance.
     963             :      */
     964       28076 :     inline explicit OGRRefCountedPtr(OGRFeatureDefn *poFDefn = nullptr,
     965             :                                      bool add_ref = true)
     966       28076 :         : OGRRefCountedPtrBase<OGRFeatureDefn>(poFDefn, add_ref)
     967             :     {
     968       28076 :     }
     969             : 
     970             :     /** Constructs with a null OGRFeatureDefn instance.
     971             :      */
     972             :     inline explicit OGRRefCountedPtr(std::nullptr_t)
     973             :     {
     974             :     }
     975             : 
     976             :     /** Constructs with a new OGRFeatureDefn instance with the provided name
     977             :      */
     978       16069 :     inline static OGRRefCountedPtr makeInstance(const char *pszName)
     979             :     {
     980             :         // Initial ref_count of OGRFeatureDefn is 0, so do add a ref
     981       16069 :         return OGRRefCountedPtr(new OGRFeatureDefn(pszName),
     982       16069 :                                 /* add_ref = */ true);
     983             :     }
     984             : };
     985             : 
     986             : /** Smart pointer around OGRFeatureDefn.
     987             :  *
     988             :  * It uses OGRFeatureDefn built-in reference counting, to increase the reference
     989             :  * count when assigning a raw pointer to the smart pointer, and decrease it
     990             :  * when releasing it.
     991             :  * Somewhat similar to https://www.boost.org/doc/libs/latest/libs/smart_ptr/doc/html/smart_ptr.html#intrusive_ptr
     992             :  */
     993             : using OGRFeatureDefnRefCountedPtr = OGRRefCountedPtr<OGRFeatureDefn>;
     994             : 
     995             : /*! @endcond */
     996             : 
     997             : #ifdef GDAL_COMPILATION
     998             : /** Return an object that temporary unseals the OGRFeatureDefn
     999             :  *
    1000             :  * The returned object calls Unseal() initially, and when it is destroyed
    1001             :  * it calls Seal().
    1002             :  * This method should be called on a OGRFeatureDefn that has been sealed
    1003             :  * previously.
    1004             :  * GetTemporaryUnsealer() calls may be nested, in which case only the first
    1005             :  * one has an effect (similarly to a recursive mutex locked in a nested way
    1006             :  * from the same thread).
    1007             :  *
    1008             :  * This method should only be called by driver implementations.
    1009             :  *
    1010             :  * Usage: whileUnsealing(poFeatureDefn)->some_method();
    1011             :  *
    1012             :  * @param bSealFields Whether fields and geometry fields should be unsealed and
    1013             :  *                    resealed.
    1014             :  *                    This is generally desirable, but in case of deferred
    1015             :  *                    resolution of them, this parameter should be set to false.
    1016             :  * @since GDAL 3.9
    1017             :  */
    1018        9143 : inline OGRFeatureDefn::TemporaryUnsealer whileUnsealing(OGRFeatureDefn *object,
    1019             :                                                         bool bSealFields = true)
    1020             : {
    1021        9143 :     return object->GetTemporaryUnsealer(bSealFields);
    1022             : }
    1023             : 
    1024             : inline OGRFeatureDefn::TemporaryUnsealer
    1025       19342 : whileUnsealing(OGRFeatureDefnRefCountedPtr &object, bool bSealFields = true)
    1026             : {
    1027       19342 :     return object->GetTemporaryUnsealer(bSealFields);
    1028             : }
    1029             : 
    1030             : #endif
    1031             : 
    1032             : /************************************************************************/
    1033             : /*                              OGRFeature                              */
    1034             : /************************************************************************/
    1035             : 
    1036             : /**
    1037             :  * A simple feature, including geometry and attributes.
    1038             :  */
    1039             : 
    1040             : class CPL_DLL OGRFeature
    1041             : {
    1042             :   private:
    1043             :     GIntBig nFID;
    1044             :     const OGRFeatureDefn *poDefn;
    1045             :     OGRGeometry **papoGeometries;
    1046             :     OGRField *pauFields;
    1047             :     char *m_pszNativeData;
    1048             :     char *m_pszNativeMediaType;
    1049             : 
    1050             :     bool SetFieldInternal(int i, const OGRField *puValue);
    1051             : 
    1052             :   protected:
    1053             :     //! @cond Doxygen_Suppress
    1054             :     mutable char *m_pszStyleString;
    1055             :     mutable OGRStyleTable *m_poStyleTable;
    1056             :     mutable char *m_pszTmpFieldValue;
    1057             :     //! @endcond
    1058             : 
    1059             :     bool CopySelfTo(OGRFeature *poNew) const;
    1060             : 
    1061             :   public:
    1062             :     explicit OGRFeature(const OGRFeatureDefn *);
    1063             :     virtual ~OGRFeature();
    1064             : 
    1065             :     /** Field value. */
    1066          51 :     class CPL_DLL FieldValue
    1067             :     {
    1068             :         friend class OGRFeature;
    1069             :         struct Private;
    1070             :         std::unique_ptr<Private> m_poPrivate;
    1071             : 
    1072             :         FieldValue(OGRFeature *poFeature, int iFieldIndex);
    1073             :         FieldValue(const OGRFeature *poFeature, int iFieldIndex);
    1074             :         FieldValue(const FieldValue &oOther) = delete;
    1075             :         FieldValue &Assign(const FieldValue &oOther);
    1076             : 
    1077             :       public:
    1078             :         //! @cond Doxygen_Suppress
    1079             :         ~FieldValue();
    1080             : 
    1081             :         FieldValue &operator=(FieldValue &&oOther);
    1082             :         //! @endcond
    1083             : 
    1084             :         /** Set a field value from another one. */
    1085             :         FieldValue &operator=(const FieldValue &oOther);
    1086             :         /** Set an integer value to the field. */
    1087             :         FieldValue &operator=(int nVal);
    1088             :         /** Set an integer value to the field. */
    1089             :         FieldValue &operator=(GIntBig nVal);
    1090             :         /** Set a real value to the field. */
    1091             :         FieldValue &operator=(double dfVal);
    1092             :         /** Set a string value to the field. */
    1093             :         FieldValue &operator=(const char *pszVal);
    1094             :         /** Set a string value to the field. */
    1095             :         FieldValue &operator=(const std::string &osVal);
    1096             :         /** Set an array of integer to the field. */
    1097             :         FieldValue &operator=(const std::vector<int> &oArray);
    1098             :         /** Set an array of big integer to the field. */
    1099             :         FieldValue &operator=(const std::vector<GIntBig> &oArray);
    1100             :         /** Set an array of double to the field. */
    1101             :         FieldValue &operator=(const std::vector<double> &oArray);
    1102             :         /** Set an array of strings to the field. */
    1103             :         FieldValue &operator=(const std::vector<std::string> &oArray);
    1104             :         /** Set an array of strings to the field. */
    1105             :         FieldValue &operator=(CSLConstList papszValues);
    1106             :         /** Set a null value to the field. */
    1107             :         void SetNull();
    1108             :         /** Unset the field. */
    1109             :         void clear();
    1110             : 
    1111             :         /** Unset the field. */
    1112           2 :         void Unset()
    1113             :         {
    1114           2 :             clear();
    1115           2 :         }
    1116             : 
    1117             :         /** Set date time value/ */
    1118             :         void SetDateTime(int nYear, int nMonth, int nDay, int nHour = 0,
    1119             :                          int nMinute = 0, float fSecond = 0.f, int nTZFlag = 0);
    1120             : 
    1121             :         /** Return field index. */
    1122             :         int GetIndex() const;
    1123             :         /** Return field definition. */
    1124             :         const OGRFieldDefn *GetDefn() const;
    1125             : 
    1126             :         /** Return field name. */
    1127          11 :         const char *GetName() const
    1128             :         {
    1129          11 :             return GetDefn()->GetNameRef();
    1130             :         }
    1131             : 
    1132             :         /** Return field type. */
    1133          23 :         OGRFieldType GetType() const
    1134             :         {
    1135          23 :             return GetDefn()->GetType();
    1136             :         }
    1137             : 
    1138             :         /** Return field subtype. */
    1139          11 :         OGRFieldSubType GetSubType() const
    1140             :         {
    1141          11 :             return GetDefn()->GetSubType();
    1142             :         }
    1143             : 
    1144             :         /** Return whether the field value is unset/empty. */
    1145             :         // cppcheck-suppress functionStatic
    1146           1 :         bool empty() const
    1147             :         {
    1148           1 :             return IsUnset();
    1149             :         }
    1150             : 
    1151             :         /** Return whether the field value is unset/empty. */
    1152             :         // cppcheck-suppress functionStatic
    1153             :         bool IsUnset() const;
    1154             : 
    1155             :         /** Return whether the field value is null. */
    1156             :         // cppcheck-suppress functionStatic
    1157             :         bool IsNull() const;
    1158             : 
    1159             :         /** Return the raw field value */
    1160             :         const OGRField *GetRawValue() const;
    1161             : 
    1162             :         /** Return the integer value.
    1163             :          * Only use that method if and only if GetType() == OFTInteger.
    1164             :          */
    1165             :         // cppcheck-suppress functionStatic
    1166           3 :         int GetInteger() const
    1167             :         {
    1168           3 :             return GetRawValue()->Integer;
    1169             :         }
    1170             : 
    1171             :         /** Return the 64-bit integer value.
    1172             :          * Only use that method if and only if GetType() == OFTInteger64.
    1173             :          */
    1174             :         // cppcheck-suppress functionStatic
    1175           3 :         GIntBig GetInteger64() const
    1176             :         {
    1177           3 :             return GetRawValue()->Integer64;
    1178             :         }
    1179             : 
    1180             :         /** Return the double value.
    1181             :          * Only use that method if and only if GetType() == OFTReal.
    1182             :          */
    1183             :         // cppcheck-suppress functionStatic
    1184           2 :         double GetDouble() const
    1185             :         {
    1186           2 :             return GetRawValue()->Real;
    1187             :         }
    1188             : 
    1189             :         /** Return the string value.
    1190             :          * Only use that method if and only if GetType() == OFTString.
    1191             :          */
    1192             :         // cppcheck-suppress functionStatic
    1193           6 :         const char *GetString() const
    1194             :         {
    1195           6 :             return GetRawValue()->String;
    1196             :         }
    1197             : 
    1198             :         /** Return the date/time/datetime value. */
    1199             :         bool GetDateTime(int *pnYear, int *pnMonth, int *pnDay, int *pnHour,
    1200             :                          int *pnMinute, float *pfSecond, int *pnTZFlag) const;
    1201             : 
    1202             :         /** Return the field value as integer, with potential conversion */
    1203           2 :         operator int() const
    1204             :         {
    1205           2 :             return GetAsInteger();
    1206             :         }
    1207             : 
    1208             :         /** Return the field value as 64-bit integer, with potential conversion
    1209             :          */
    1210           1 :         operator GIntBig() const
    1211             :         {
    1212           1 :             return GetAsInteger64();
    1213             :         }
    1214             : 
    1215             :         /** Return the field value as double, with potential conversion */
    1216           1 :         operator double() const
    1217             :         {
    1218           1 :             return GetAsDouble();
    1219             :         }
    1220             : 
    1221             :         /** Return the field value as string, with potential conversion */
    1222           1 :         operator const char *() const
    1223             :         {
    1224           1 :             return GetAsString();
    1225             :         }
    1226             : 
    1227             :         /** Return the field value as integer list, with potential conversion */
    1228           1 :         operator const std::vector<int> &() const
    1229             :         {
    1230           1 :             return GetAsIntegerList();
    1231             :         }
    1232             : 
    1233             :         /** Return the field value as 64-bit integer list, with potential
    1234             :          * conversion */
    1235           1 :         operator const std::vector<GIntBig> &() const
    1236             :         {
    1237           1 :             return GetAsInteger64List();
    1238             :         }
    1239             : 
    1240             :         /** Return the field value as double list, with potential conversion */
    1241           1 :         operator const std::vector<double> &() const
    1242             :         {
    1243           1 :             return GetAsDoubleList();
    1244             :         }
    1245             : 
    1246             :         /** Return the field value as string list, with potential conversion */
    1247           1 :         operator const std::vector<std::string> &() const
    1248             :         {
    1249           1 :             return GetAsStringList();
    1250             :         }
    1251             : 
    1252             :         /** Return the field value as string list, with potential conversion */
    1253             :         operator CSLConstList() const;
    1254             : 
    1255             :         /** Return the field value as integer, with potential conversion */
    1256             :         int GetAsInteger() const;
    1257             :         /** Return the field value as 64-bit integer, with potential conversion
    1258             :          */
    1259             :         GIntBig GetAsInteger64() const;
    1260             :         /** Return the field value as double, with potential conversion */
    1261             :         double GetAsDouble() const;
    1262             :         /** Return the field value as string, with potential conversion */
    1263             :         const char *GetAsString() const;
    1264             :         /** Return the field value as integer list, with potential conversion */
    1265             :         const std::vector<int> &GetAsIntegerList() const;
    1266             :         /** Return the field value as 64-bit integer list, with potential
    1267             :          * conversion */
    1268             :         const std::vector<GIntBig> &GetAsInteger64List() const;
    1269             :         /** Return the field value as double list, with potential conversion */
    1270             :         const std::vector<double> &GetAsDoubleList() const;
    1271             :         /** Return the field value as string list, with potential conversion */
    1272             :         const std::vector<std::string> &GetAsStringList() const;
    1273             :     };
    1274             : 
    1275             :     /** Field value iterator class. */
    1276           4 :     class CPL_DLL ConstFieldIterator
    1277             :     {
    1278             :         friend class OGRFeature;
    1279             :         struct Private;
    1280             :         std::unique_ptr<Private> m_poPrivate;
    1281             : 
    1282             :         ConstFieldIterator(const OGRFeature *poSelf, int nPos);
    1283             : 
    1284             :       public:
    1285             :         //! @cond Doxygen_Suppress
    1286             :         ConstFieldIterator(
    1287             :             ConstFieldIterator &&oOther) noexcept;  // declared but not defined.
    1288             :         // Needed for gcc 5.4 at least
    1289             :         ~ConstFieldIterator();
    1290             :         const FieldValue &operator*() const;
    1291             :         ConstFieldIterator &operator++();
    1292             :         bool operator!=(const ConstFieldIterator &it) const;
    1293             :         //! @endcond
    1294             :     };
    1295             : 
    1296             :     /** Return begin of field value iterator.
    1297             :      *
    1298             :      * Using this iterator for standard range-based loops is safe, but
    1299             :      * due to implementation limitations, you shouldn't try to access
    1300             :      * (dereference) more than one iterator step at a time, since you will get
    1301             :      * a reference to the same object (FieldValue) at each iteration step.
    1302             :      *
    1303             :      * \code{.cpp}
    1304             :      * for( auto&& oField: poFeature )
    1305             :      * {
    1306             :      *      std::cout << oField.GetIndex() << "," << oField.GetName()<< ": " <<
    1307             :      * oField.GetAsString() << std::endl;
    1308             :      * }
    1309             :      * \endcode
    1310             :      *
    1311             :      */
    1312             :     ConstFieldIterator begin() const;
    1313             :     /** Return end of field value iterator. */
    1314             :     ConstFieldIterator end() const;
    1315             : 
    1316             :     const FieldValue operator[](int iField) const;
    1317             :     FieldValue operator[](int iField);
    1318             : 
    1319             : #if defined(__clang__)
    1320             : #pragma clang diagnostic push
    1321             : #pragma clang diagnostic ignored "-Wweak-vtables"
    1322             : #endif
    1323             : 
    1324             :     /** Exception raised by operator[](const char*) when a field is not found.
    1325             :      */
    1326             :     class FieldNotFoundException final : public std::exception
    1327             :     {
    1328             :     };
    1329             : 
    1330             : #if defined(__clang__)
    1331             : #pragma clang diagnostic pop
    1332             : #endif
    1333             : 
    1334             :     const FieldValue operator[](const char *pszFieldName) const;
    1335             :     FieldValue operator[](const char *pszFieldName);
    1336             : 
    1337     1215828 :     const OGRFeatureDefn *GetDefnRef() const
    1338             :     {
    1339     1215828 :         return poDefn;
    1340             :     }
    1341             : 
    1342             :     //! @cond Doxygen_Suppress
    1343             :     void SetFDefnUnsafe(OGRFeatureDefn *poNewFDefn);
    1344             :     //! @endcond
    1345             : 
    1346             :     OGRErr SetGeometryDirectly(OGRGeometry *);
    1347             :     OGRErr SetGeometry(const OGRGeometry *);
    1348             :     OGRErr SetGeometry(std::unique_ptr<OGRGeometry>);
    1349             :     OGRGeometry *GetGeometryRef();
    1350             :     const OGRGeometry *GetGeometryRef() const;
    1351             :     OGRGeometry *StealGeometry() CPL_WARN_UNUSED_RESULT;
    1352             : 
    1353     7774100 :     int GetGeomFieldCount() const
    1354             :     {
    1355     7774100 :         return poDefn->GetGeomFieldCount();
    1356             :     }
    1357             : 
    1358        9625 :     const OGRGeomFieldDefn *GetGeomFieldDefnRef(int iField) const
    1359             :     {
    1360        9625 :         return poDefn->GetGeomFieldDefn(iField);
    1361             :     }
    1362             : 
    1363        9336 :     int GetGeomFieldIndex(const char *pszName) const
    1364             :     {
    1365        9336 :         return poDefn->GetGeomFieldIndex(pszName);
    1366             :     }
    1367             : 
    1368             :     OGRGeometry *GetGeomFieldRef(int iField);
    1369             :     const OGRGeometry *GetGeomFieldRef(int iField) const;
    1370             :     OGRGeometry *StealGeometry(int iField);
    1371             :     OGRGeometry *GetGeomFieldRef(const char *pszFName);
    1372             :     const OGRGeometry *GetGeomFieldRef(const char *pszFName) const;
    1373             :     OGRErr SetGeomFieldDirectly(int iField, OGRGeometry *);
    1374             :     OGRErr SetGeomField(int iField, const OGRGeometry *);
    1375             :     OGRErr SetGeomField(int iField, std::unique_ptr<OGRGeometry>);
    1376             : 
    1377             :     void Reset();
    1378             : 
    1379             :     OGRFeature *Clone() const CPL_WARN_UNUSED_RESULT;
    1380             :     virtual bool Equal(const OGRFeature *poFeature) const;
    1381             : 
    1382      554666 :     int GetFieldCount() const
    1383             :     {
    1384      554666 :         return poDefn->GetFieldCount();
    1385             :     }
    1386             : 
    1387      631719 :     const OGRFieldDefn *GetFieldDefnRef(int iField) const
    1388             :     {
    1389      631719 :         return poDefn->GetFieldDefn(iField);
    1390             :     }
    1391             : 
    1392     2639544 :     int GetFieldIndex(const char *pszName) const
    1393             :     {
    1394     2639544 :         return poDefn->GetFieldIndex(pszName);
    1395             :     }
    1396             : 
    1397             :     int IsFieldSet(int iField) const;
    1398             : 
    1399             :     void UnsetField(int iField);
    1400             : 
    1401             :     bool IsFieldNull(int iField) const;
    1402             : 
    1403             :     void SetFieldNull(int iField);
    1404             : 
    1405             :     bool IsFieldSetAndNotNull(int iField) const;
    1406             : 
    1407      425520 :     OGRField *GetRawFieldRef(int i)
    1408             :     {
    1409      425520 :         return pauFields + i;
    1410             :     }
    1411             : 
    1412         614 :     const OGRField *GetRawFieldRef(int i) const
    1413             :     {
    1414         614 :         return pauFields + i;
    1415             :     }
    1416             : 
    1417             :     int GetFieldAsInteger(int i) const;
    1418             :     GIntBig GetFieldAsInteger64(int i) const;
    1419             :     double GetFieldAsDouble(int i) const;
    1420             :     const char *GetFieldAsString(int i) const;
    1421             :     const char *GetFieldAsISO8601DateTime(int i,
    1422             :                                           CSLConstList papszOptions) const;
    1423             :     const int *GetFieldAsIntegerList(int i, int *pnCount) const;
    1424             :     const GIntBig *GetFieldAsInteger64List(int i, int *pnCount) const;
    1425             :     const double *GetFieldAsDoubleList(int i, int *pnCount) const;
    1426             :     char **GetFieldAsStringList(int i) const;
    1427             :     GByte *GetFieldAsBinary(int i, int *pnCount) const;
    1428             :     int GetFieldAsDateTime(int i, int *pnYear, int *pnMonth, int *pnDay,
    1429             :                            int *pnHour, int *pnMinute, int *pnSecond,
    1430             :                            int *pnTZFlag) const;
    1431             :     int GetFieldAsDateTime(int i, int *pnYear, int *pnMonth, int *pnDay,
    1432             :                            int *pnHour, int *pnMinute, float *pfSecond,
    1433             :                            int *pnTZFlag) const;
    1434             :     char *GetFieldAsSerializedJSon(int i) const;
    1435             : 
    1436             :     //! @cond Doxygen_Suppress
    1437    31299849 :     bool IsFieldSetUnsafe(int i) const
    1438             :     {
    1439    40162567 :         return !(pauFields[i].Set.nMarker1 == OGRUnsetMarker &&
    1440     8862698 :                  pauFields[i].Set.nMarker2 == OGRUnsetMarker &&
    1441    40162567 :                  pauFields[i].Set.nMarker3 == OGRUnsetMarker);
    1442             :     }
    1443             : 
    1444    13491531 :     bool IsFieldNullUnsafe(int i) const
    1445             :     {
    1446    13553347 :         return (pauFields[i].Set.nMarker1 == OGRNullMarker &&
    1447    13553347 :                 pauFields[i].Set.nMarker2 == OGRNullMarker &&
    1448    13553347 :                 pauFields[i].Set.nMarker3 == OGRNullMarker);
    1449             :     }
    1450             : 
    1451    17778049 :     bool IsFieldSetAndNotNullUnsafe(int i) const
    1452             :     {
    1453    17778049 :         return IsFieldSetUnsafe(i) && !IsFieldNullUnsafe(i);
    1454             :     }
    1455             : 
    1456             :     // Those methods should only be called on a field that is of the type
    1457             :     // consistent with the value, and that is set.
    1458       51779 :     int GetFieldAsIntegerUnsafe(int i) const
    1459             :     {
    1460       51779 :         return pauFields[i].Integer;
    1461             :     }
    1462             : 
    1463       16440 :     GIntBig GetFieldAsInteger64Unsafe(int i) const
    1464             :     {
    1465       16440 :         return pauFields[i].Integer64;
    1466             :     }
    1467             : 
    1468       41934 :     double GetFieldAsDoubleUnsafe(int i) const
    1469             :     {
    1470       41934 :         return pauFields[i].Real;
    1471             :     }
    1472             : 
    1473     4468440 :     const char *GetFieldAsStringUnsafe(int i) const
    1474             :     {
    1475     4468440 :         return pauFields[i].String;
    1476             :     }
    1477             : 
    1478             :     //! @endcond
    1479             : 
    1480       30860 :     int GetFieldAsInteger(const char *pszFName) const
    1481             :     {
    1482       30860 :         return GetFieldAsInteger(GetFieldIndex(pszFName));
    1483             :     }
    1484             : 
    1485        6937 :     GIntBig GetFieldAsInteger64(const char *pszFName) const
    1486             :     {
    1487        6937 :         return GetFieldAsInteger64(GetFieldIndex(pszFName));
    1488             :     }
    1489             : 
    1490         358 :     double GetFieldAsDouble(const char *pszFName) const
    1491             :     {
    1492         358 :         return GetFieldAsDouble(GetFieldIndex(pszFName));
    1493             :     }
    1494             : 
    1495       28042 :     const char *GetFieldAsString(const char *pszFName) const
    1496             :     {
    1497       28042 :         return GetFieldAsString(GetFieldIndex(pszFName));
    1498             :     }
    1499             : 
    1500             :     const char *GetFieldAsISO8601DateTime(const char *pszFName,
    1501             :                                           CSLConstList papszOptions) const
    1502             :     {
    1503             :         return GetFieldAsISO8601DateTime(GetFieldIndex(pszFName), papszOptions);
    1504             :     }
    1505             : 
    1506         120 :     const int *GetFieldAsIntegerList(const char *pszFName, int *pnCount) const
    1507             :     {
    1508         120 :         return GetFieldAsIntegerList(GetFieldIndex(pszFName), pnCount);
    1509             :     }
    1510             : 
    1511             :     const GIntBig *GetFieldAsInteger64List(const char *pszFName,
    1512             :                                            int *pnCount) const
    1513             :     {
    1514             :         return GetFieldAsInteger64List(GetFieldIndex(pszFName), pnCount);
    1515             :     }
    1516             : 
    1517          21 :     const double *GetFieldAsDoubleList(const char *pszFName, int *pnCount) const
    1518             :     {
    1519          21 :         return GetFieldAsDoubleList(GetFieldIndex(pszFName), pnCount);
    1520             :     }
    1521             : 
    1522         491 :     char **GetFieldAsStringList(const char *pszFName) const
    1523             :     {
    1524         491 :         return GetFieldAsStringList(GetFieldIndex(pszFName));
    1525             :     }
    1526             : 
    1527             :     void SetField(int i, int nValue);
    1528             :     void SetField(int i, GIntBig nValue);
    1529             :     void SetField(int i, double dfValue);
    1530             :     void SetField(int i, const char *pszValue);
    1531             : #if defined(DOXYGEN_SKIP) || __cplusplus >= 201703L ||                         \
    1532             :     (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
    1533             :     void SetField(int i, std::string_view svValue);
    1534             : 
    1535             :     //! @cond Doxygen_Suppress
    1536        2253 :     inline void SetField(int i, const std::string &osValue)
    1537             :     {
    1538        2253 :         SetField(i, osValue.c_str());
    1539        2253 :     }
    1540             : 
    1541             :     //! @endcond
    1542             : #endif
    1543             :     void SetField(int i, int nCount, const int *panValues);
    1544             :     void SetField(int i, int nCount, const GIntBig *panValues);
    1545             :     void SetField(int i, int nCount, const double *padfValues);
    1546             :     void SetField(int i, const char *const *papszValues);
    1547             :     void SetField(int i, const OGRField *puValue);
    1548             :     void SetField(int i, int nCount, const void *pabyBinary);
    1549             :     void SetField(int i, int nYear, int nMonth, int nDay, int nHour = 0,
    1550             :                   int nMinute = 0, float fSecond = 0.f, int nTZFlag = 0);
    1551             : 
    1552             :     //! @cond Doxygen_Suppress
    1553             :     // Those methods should only be called on a field that is of the type
    1554             :     // consistent with the value, and in a unset state.
    1555       55036 :     void SetFieldSameTypeUnsafe(int i, int nValue)
    1556             :     {
    1557       55036 :         pauFields[i].Integer = nValue;
    1558       55036 :         pauFields[i].Set.nMarker2 = 0;
    1559       55036 :         pauFields[i].Set.nMarker3 = 0;
    1560       55036 :     }
    1561             : 
    1562       13379 :     void SetFieldSameTypeUnsafe(int i, GIntBig nValue)
    1563             :     {
    1564       13379 :         pauFields[i].Integer64 = nValue;
    1565       13379 :     }
    1566             : 
    1567       22603 :     void SetFieldSameTypeUnsafe(int i, double dfValue)
    1568             :     {
    1569       22603 :         pauFields[i].Real = dfValue;
    1570       22603 :     }
    1571             : 
    1572     1431256 :     void SetFieldSameTypeUnsafe(int i, char *pszValueTransferred)
    1573             :     {
    1574     1431256 :         pauFields[i].String = pszValueTransferred;
    1575     1431256 :     }
    1576             : 
    1577             :     //! @endcond
    1578             : 
    1579      955176 :     void SetField(const char *pszFName, int nValue)
    1580             :     {
    1581      955176 :         SetField(GetFieldIndex(pszFName), nValue);
    1582      955176 :     }
    1583             : 
    1584        1288 :     void SetField(const char *pszFName, GIntBig nValue)
    1585             :     {
    1586        1288 :         SetField(GetFieldIndex(pszFName), nValue);
    1587        1288 :     }
    1588             : 
    1589        4728 :     void SetField(const char *pszFName, double dfValue)
    1590             :     {
    1591        4728 :         SetField(GetFieldIndex(pszFName), dfValue);
    1592        4728 :     }
    1593             : 
    1594     1536012 :     void SetField(const char *pszFName, const char *pszValue)
    1595             :     {
    1596     1536012 :         SetField(GetFieldIndex(pszFName), pszValue);
    1597     1536012 :     }
    1598             : 
    1599        1065 :     void SetField(const char *pszFName, int nCount, const int *panValues)
    1600             :     {
    1601        1065 :         SetField(GetFieldIndex(pszFName), nCount, panValues);
    1602        1065 :     }
    1603             : 
    1604           1 :     void SetField(const char *pszFName, int nCount, const GIntBig *panValues)
    1605             :     {
    1606           1 :         SetField(GetFieldIndex(pszFName), nCount, panValues);
    1607           1 :     }
    1608             : 
    1609          45 :     void SetField(const char *pszFName, int nCount, const double *padfValues)
    1610             :     {
    1611          45 :         SetField(GetFieldIndex(pszFName), nCount, padfValues);
    1612          45 :     }
    1613             : 
    1614        1081 :     void SetField(const char *pszFName, const char *const *papszValues)
    1615             :     {
    1616        1081 :         SetField(GetFieldIndex(pszFName), papszValues);
    1617        1081 :     }
    1618             : 
    1619          86 :     void SetField(const char *pszFName, const OGRField *puValue)
    1620             :     {
    1621          86 :         SetField(GetFieldIndex(pszFName), puValue);
    1622          86 :     }
    1623             : 
    1624           3 :     void SetField(const char *pszFName, int nYear, int nMonth, int nDay,
    1625             :                   int nHour = 0, int nMinute = 0, float fSecond = 0.f,
    1626             :                   int nTZFlag = 0)
    1627             :     {
    1628           3 :         SetField(GetFieldIndex(pszFName), nYear, nMonth, nDay, nHour, nMinute,
    1629             :                  fSecond, nTZFlag);
    1630           3 :     }
    1631             : 
    1632     3717087 :     GIntBig GetFID() const
    1633             :     {
    1634     3717087 :         return nFID;
    1635             :     }
    1636             : 
    1637             :     virtual OGRErr SetFID(GIntBig nFIDIn);
    1638             : 
    1639             :     void DumpReadable(FILE *, CSLConstList papszOptions = nullptr) const;
    1640             :     std::string DumpReadableAsString(CSLConstList papszOptions = nullptr) const;
    1641             : 
    1642             :     OGRErr SetFrom(const OGRFeature *, int bForgiving = TRUE);
    1643             :     OGRErr SetFrom(const OGRFeature *, const int *panMap, int bForgiving = TRUE,
    1644             :                    bool bUseISO8601ForDateTimeAsString = false);
    1645             :     OGRErr SetFieldsFrom(const OGRFeature *, const int *panMap,
    1646             :                          int bForgiving = TRUE,
    1647             :                          bool bUseISO8601ForDateTimeAsString = false);
    1648             : 
    1649             :     //! @cond Doxygen_Suppress
    1650             :     OGRErr RemapFields(const OGRFeatureDefn *poNewDefn,
    1651             :                        const int *panRemapSource);
    1652             :     void AppendField();
    1653             :     OGRErr RemapGeomFields(const OGRFeatureDefn *poNewDefn,
    1654             :                            const int *panRemapSource);
    1655             :     //! @endcond
    1656             : 
    1657             :     int Validate(int nValidateFlags, int bEmitError) const;
    1658             :     void FillUnsetWithDefault(int bNotNullableOnly, CSLConstList papszOptions);
    1659             : 
    1660             :     bool SerializeToBinary(std::vector<GByte> &abyBuffer) const;
    1661             :     bool DeserializeFromBinary(const GByte *pabyBuffer, size_t nSize);
    1662             : 
    1663             :     virtual const char *GetStyleString() const;
    1664             :     virtual void SetStyleString(const char *);
    1665             :     virtual void SetStyleStringDirectly(char *);
    1666             : 
    1667             :     /** Return style table.
    1668             :      * @return style table.
    1669             :      */
    1670         199 :     virtual OGRStyleTable *GetStyleTable() const
    1671             :     {
    1672         199 :         return m_poStyleTable;
    1673             :     } /* f.i.x.m.e: add a const qualifier for return type */
    1674             : 
    1675             :     virtual void SetStyleTable(OGRStyleTable *poStyleTable);
    1676             :     virtual void SetStyleTableDirectly(OGRStyleTable *poStyleTable);
    1677             : 
    1678       15740 :     const char *GetNativeData() const
    1679             :     {
    1680       15740 :         return m_pszNativeData;
    1681             :     }
    1682             : 
    1683       18876 :     const char *GetNativeMediaType() const
    1684             :     {
    1685       18876 :         return m_pszNativeMediaType;
    1686             :     }
    1687             : 
    1688             :     void SetNativeData(const char *pszNativeData);
    1689             :     void SetNativeMediaType(const char *pszNativeMediaType);
    1690             : 
    1691             :     static OGRFeature *CreateFeature(const OGRFeatureDefn *);
    1692             :     static void DestroyFeature(OGRFeature *);
    1693             : 
    1694             :     /** Convert a OGRFeature* to a OGRFeatureH.
    1695             :      */
    1696      227971 :     static inline OGRFeatureH ToHandle(OGRFeature *poFeature)
    1697             :     {
    1698      227971 :         return reinterpret_cast<OGRFeatureH>(poFeature);
    1699             :     }
    1700             : 
    1701             :     /** Convert a OGRFeatureH to a OGRFeature*.
    1702             :      */
    1703     1812860 :     static inline OGRFeature *FromHandle(OGRFeatureH hFeature)
    1704             :     {
    1705     1812860 :         return reinterpret_cast<OGRFeature *>(hFeature);
    1706             :     }
    1707             : 
    1708             :   private:
    1709             :     CPL_DISALLOW_COPY_ASSIGN(OGRFeature)
    1710             : };
    1711             : 
    1712             : //! @cond Doxygen_Suppress
    1713             : struct CPL_DLL OGRFeatureUniquePtrDeleter
    1714             : {
    1715             :     void operator()(OGRFeature *) const;
    1716             : };
    1717             : 
    1718             : //! @endcond
    1719             : 
    1720             : /** Unique pointer type for OGRFeature.
    1721             :  */
    1722             : typedef std::unique_ptr<OGRFeature, OGRFeatureUniquePtrDeleter>
    1723             :     OGRFeatureUniquePtr;
    1724             : 
    1725             : //! @cond Doxygen_Suppress
    1726             : /** @see OGRFeature::begin() const */
    1727             : inline OGRFeature::ConstFieldIterator begin(const OGRFeature *poFeature)
    1728             : {
    1729             :     return poFeature->begin();
    1730             : }
    1731             : 
    1732             : /** @see OGRFeature::end() const */
    1733             : inline OGRFeature::ConstFieldIterator end(const OGRFeature *poFeature)
    1734             : {
    1735             :     return poFeature->end();
    1736             : }
    1737             : 
    1738             : /** @see OGRFeature::begin() const */
    1739             : inline OGRFeature::ConstFieldIterator
    1740             : begin(const OGRFeatureUniquePtr &poFeature)
    1741             : {
    1742             :     return poFeature->begin();
    1743             : }
    1744             : 
    1745             : /** @see OGRFeature::end() const */
    1746             : inline OGRFeature::ConstFieldIterator end(const OGRFeatureUniquePtr &poFeature)
    1747             : {
    1748             :     return poFeature->end();
    1749             : }
    1750             : 
    1751             : //! @endcond
    1752             : 
    1753             : /************************************************************************/
    1754             : /*                            OGRFieldDomain                            */
    1755             : /************************************************************************/
    1756             : 
    1757             : /* clang-format off */
    1758             : /**
    1759             :  * Definition of a field domain.
    1760             :  *
    1761             :  * A field domain is a set of constraints that apply to one or several fields.
    1762             :  *
    1763             :  * This is a concept found in
    1764             :  * <a href="https://desktop.arcgis.com/en/arcmap/latest/manage-data/geodatabases/an-overview-of-attribute-domains.htm">File
    1765             :  * Geodatabase</a> or GeoPackage (using the <a href="http://www.geopackage.org/spec/#extension_schema">schema extension</a>)
    1766             :  * for example.
    1767             :  *
    1768             :  * A field domain can be:
    1769             :  * <ul>
    1770             :  * <li>OGRCodedFieldDomain: an enumerated list of (code, value) tuples.</li>
    1771             :  * <li>OGRRangeFieldDomain: a range constraint (min, max).</li>
    1772             :  * <li>OGRGlobFieldDomain: a glob expression.</li>
    1773             :  * </ul>
    1774             :  *
    1775             :  * @since GDAL 3.3
    1776             :  */
    1777             : /* clang-format on */
    1778             : 
    1779        1382 : class CPL_DLL OGRFieldDomain
    1780             : {
    1781             :   protected:
    1782             :     /*! @cond Doxygen_Suppress */
    1783             :     std::string m_osName;
    1784             :     std::string m_osDescription;
    1785             :     OGRFieldDomainType m_eDomainType;
    1786             :     OGRFieldType m_eFieldType;
    1787             :     OGRFieldSubType m_eFieldSubType;
    1788             :     OGRFieldDomainSplitPolicy m_eSplitPolicy = OFDSP_DEFAULT_VALUE;
    1789             :     OGRFieldDomainMergePolicy m_eMergePolicy = OFDMP_DEFAULT_VALUE;
    1790             : 
    1791             :     OGRFieldDomain(const std::string &osName, const std::string &osDescription,
    1792             :                    OGRFieldDomainType eDomainType, OGRFieldType eFieldType,
    1793             :                    OGRFieldSubType eFieldSubType);
    1794             :     /*! @endcond */
    1795             : 
    1796             :   public:
    1797             :     /** Destructor.
    1798             :      *
    1799             :      * This is the same as the C function OGR_FldDomain_Destroy().
    1800             :      */
    1801             :     virtual ~OGRFieldDomain();
    1802             : 
    1803             :     /** Clone.
    1804             :      *
    1805             :      * Return a cloned object, or nullptr in case of error.
    1806             :      */
    1807             :     virtual OGRFieldDomain *Clone() const = 0;
    1808             : 
    1809             :     /** Get the name of the field domain.
    1810             :      *
    1811             :      * This is the same as the C function OGR_FldDomain_GetName().
    1812             :      */
    1813        1353 :     const std::string &GetName() const
    1814             :     {
    1815        1353 :         return m_osName;
    1816             :     }
    1817             : 
    1818             :     /** Get the description of the field domain.
    1819             :      * Empty string if there is none.
    1820             :      *
    1821             :      * This is the same as the C function OGR_FldDomain_GetDescription().
    1822             :      */
    1823         109 :     const std::string &GetDescription() const
    1824             :     {
    1825         109 :         return m_osDescription;
    1826             :     }
    1827             : 
    1828             :     /** Get the type of the field domain.
    1829             :      *
    1830             :      * This is the same as the C function OGR_FldDomain_GetDomainType().
    1831             :      */
    1832         231 :     OGRFieldDomainType GetDomainType() const
    1833             :     {
    1834         231 :         return m_eDomainType;
    1835             :     }
    1836             : 
    1837             :     /** Get the field type.
    1838             :      *
    1839             :      * This is the same as the C function OGR_FldDomain_GetFieldType().
    1840             :      */
    1841         205 :     OGRFieldType GetFieldType() const
    1842             :     {
    1843         205 :         return m_eFieldType;
    1844             :     }
    1845             : 
    1846             :     /** Get the field subtype.
    1847             :      *
    1848             :      * This is the same as the C function OGR_FldDomain_GetFieldSubType().
    1849             :      */
    1850         101 :     OGRFieldSubType GetFieldSubType() const
    1851             :     {
    1852         101 :         return m_eFieldSubType;
    1853             :     }
    1854             : 
    1855             :     /** Convert a OGRFieldDomain* to a OGRFieldDomainH. */
    1856         226 :     static inline OGRFieldDomainH ToHandle(OGRFieldDomain *poFieldDomain)
    1857             :     {
    1858         226 :         return reinterpret_cast<OGRFieldDomainH>(poFieldDomain);
    1859             :     }
    1860             : 
    1861             :     /** Convert a OGRFieldDomainH to a OGRFieldDomain*. */
    1862         554 :     static inline OGRFieldDomain *FromHandle(OGRFieldDomainH hFieldDomain)
    1863             :     {
    1864         554 :         return reinterpret_cast<OGRFieldDomain *>(hFieldDomain);
    1865             :     }
    1866             : 
    1867             :     /** Get the split policy.
    1868             :      *
    1869             :      * This is the same as the C function OGR_FldDomain_GetSplitPolicy().
    1870             :      */
    1871          32 :     OGRFieldDomainSplitPolicy GetSplitPolicy() const
    1872             :     {
    1873          32 :         return m_eSplitPolicy;
    1874             :     }
    1875             : 
    1876             :     /** Set the split policy.
    1877             :      *
    1878             :      * This is the same as the C function OGR_FldDomain_SetSplitPolicy().
    1879             :      */
    1880        1196 :     void SetSplitPolicy(OGRFieldDomainSplitPolicy policy)
    1881             :     {
    1882        1196 :         m_eSplitPolicy = policy;
    1883        1196 :     }
    1884             : 
    1885             :     /** Get the merge policy.
    1886             :      *
    1887             :      * This is the same as the C function OGR_FldDomain_GetMergePolicy().
    1888             :      */
    1889          32 :     OGRFieldDomainMergePolicy GetMergePolicy() const
    1890             :     {
    1891          32 :         return m_eMergePolicy;
    1892             :     }
    1893             : 
    1894             :     /** Set the merge policy.
    1895             :      *
    1896             :      * This is the same as the C function OGR_FldDomain_SetMergePolicy().
    1897             :      */
    1898        1196 :     void SetMergePolicy(OGRFieldDomainMergePolicy policy)
    1899             :     {
    1900        1196 :         m_eMergePolicy = policy;
    1901        1196 :     }
    1902             : };
    1903             : 
    1904             : /** Definition of a coded / enumerated field domain.
    1905             :  *
    1906             :  * A code field domain is a domain for which only a limited set of codes,
    1907             :  * associated with their expanded value, are allowed.
    1908             :  * The type of the code should be the one of the field domain.
    1909             :  */
    1910             : class CPL_DLL OGRCodedFieldDomain final : public OGRFieldDomain
    1911             : {
    1912             :   private:
    1913             :     std::vector<OGRCodedValue> m_asValues{};
    1914             : 
    1915             :     OGRCodedFieldDomain(const OGRCodedFieldDomain &) = delete;
    1916             :     OGRCodedFieldDomain &operator=(const OGRCodedFieldDomain &) = delete;
    1917             : 
    1918             :   public:
    1919             :     /** Constructor.
    1920             :      *
    1921             :      * This is the same as the C function OGR_CodedFldDomain_Create()
    1922             :      * (except that the C function copies the enumeration, whereas the C++
    1923             :      * method moves it)
    1924             :      *
    1925             :      * @param osName         Domain name.
    1926             :      * @param osDescription  Domain description.
    1927             :      * @param eFieldType     Field type. Generally numeric. Potentially
    1928             :      * OFTDateTime
    1929             :      * @param eFieldSubType  Field subtype.
    1930             :      * @param asValues       Enumeration as (code, value) pairs.
    1931             :      *                       Each code should appear only once, but it is the
    1932             :      *                       responsibility of the user to check it.
    1933             :      */
    1934             :     OGRCodedFieldDomain(const std::string &osName,
    1935             :                         const std::string &osDescription,
    1936             :                         OGRFieldType eFieldType, OGRFieldSubType eFieldSubType,
    1937             :                         std::vector<OGRCodedValue> &&asValues);
    1938             : 
    1939             :     ~OGRCodedFieldDomain() override;
    1940             : 
    1941             :     OGRCodedFieldDomain *Clone() const override;
    1942             : 
    1943             :     /** Get the enumeration as (code, value) pairs.
    1944             :      * The end of the enumeration is signaled by code == NULL.
    1945             :      *
    1946             :      * This is the same as the C function OGR_CodedFldDomain_GetEnumeration().
    1947             :      */
    1948         173 :     const OGRCodedValue *GetEnumeration() const
    1949             :     {
    1950         173 :         return m_asValues.data();
    1951             :     }
    1952             : };
    1953             : 
    1954             : /** Definition of a numeric field domain with a range of validity for values.
    1955             :  */
    1956             : class CPL_DLL OGRRangeFieldDomain final : public OGRFieldDomain
    1957             : {
    1958             :   private:
    1959             :     OGRField m_sMin;
    1960             :     OGRField m_sMax;
    1961             :     bool m_bMinIsInclusive;
    1962             :     bool m_bMaxIsInclusive;
    1963             : 
    1964             :     OGRRangeFieldDomain(const OGRRangeFieldDomain &) = delete;
    1965             :     OGRRangeFieldDomain &operator=(const OGRRangeFieldDomain &) = delete;
    1966             : 
    1967             :   public:
    1968             :     /** Constructor.
    1969             :      *
    1970             :      * This is the same as the C function OGR_RangeFldDomain_Create().
    1971             :      *
    1972             :      * @param osName          Domain name.
    1973             :      * @param osDescription   Domain description.
    1974             :      * @param eFieldType      Field type.
    1975             :      *                        One among OFTInteger, OFTInteger64, OFTReal or
    1976             :      * OFTDateTime
    1977             :      * @param eFieldSubType   Field subtype.
    1978             :      * @param sMin            Minimum value.
    1979             :      *                        Which member in the OGRField enum must be read
    1980             :      *                        depends on the field type.
    1981             :      *                        If no minimum is set (might not be supported by
    1982             :      *                        all backends), then initialize the value with
    1983             :      *                        OGR_RawField_SetUnset().
    1984             :      * @param bMinIsInclusive Whether the minimum value is included in the
    1985             :      * range.
    1986             :      * @param sMax            Minimum value.
    1987             :      *                        Which member in the OGRField enum must be read
    1988             :      *                        depends on the field type.
    1989             :      *                        If no maximum is set (might not be supported by
    1990             :      *                        all backends), then initialize the value with
    1991             :      *                        OGR_RawField_SetUnset().
    1992             :      * @param bMaxIsInclusive Whether the minimum value is included in the
    1993             :      * range.
    1994             :      */
    1995             :     OGRRangeFieldDomain(const std::string &osName,
    1996             :                         const std::string &osDescription,
    1997             :                         OGRFieldType eFieldType, OGRFieldSubType eFieldSubType,
    1998             :                         const OGRField &sMin, bool bMinIsInclusive,
    1999             :                         const OGRField &sMax, bool bMaxIsInclusive);
    2000             : 
    2001             :     OGRRangeFieldDomain *Clone() const override;
    2002             : 
    2003             :     /** Get the minimum value.
    2004             :      *
    2005             :      * Which member in the returned OGRField enum must be read depends on the
    2006             :      * field type.
    2007             :      *
    2008             :      * If no minimum value is set, the OGR_RawField_IsUnset() will return true
    2009             :      * when called on the result.
    2010             :      *
    2011             :      * This is the same as the C function OGR_RangeFldDomain_GetMin().
    2012             :      *
    2013             :      * @param bIsInclusiveOut set to true if the minimum is included in the
    2014             :      * range.
    2015             :      */
    2016          52 :     const OGRField &GetMin(bool &bIsInclusiveOut) const
    2017             :     {
    2018          52 :         bIsInclusiveOut = m_bMinIsInclusive;
    2019          52 :         return m_sMin;
    2020             :     }
    2021             : 
    2022             :     /** Get the maximum value.
    2023             :      *
    2024             :      * Which member in the returned OGRField enum must be read depends on the
    2025             :      * field type.
    2026             :      *
    2027             :      * If no maximum value is set, the OGR_RawField_IsUnset() will return true
    2028             :      * when called on the result.
    2029             :      *
    2030             :      * This is the same as the C function OGR_RangeFldDomain_GetMax().
    2031             :      *
    2032             :      * @param bIsInclusiveOut set to true if the maximum is included in the
    2033             :      * range.
    2034             :      */
    2035          52 :     const OGRField &GetMax(bool &bIsInclusiveOut) const
    2036             :     {
    2037          52 :         bIsInclusiveOut = m_bMaxIsInclusive;
    2038          52 :         return m_sMax;
    2039             :     }
    2040             : };
    2041             : 
    2042             : /** Definition of a field domain for field content validated by a glob.
    2043             :  *
    2044             :  * Globs are matching expression like "*[a-z][0-1]?"
    2045             :  */
    2046             : class CPL_DLL OGRGlobFieldDomain final : public OGRFieldDomain
    2047             : {
    2048             :   private:
    2049             :     std::string m_osGlob;
    2050             : 
    2051             :     OGRGlobFieldDomain(const OGRGlobFieldDomain &) = delete;
    2052             :     OGRGlobFieldDomain &operator=(const OGRGlobFieldDomain &) = delete;
    2053             : 
    2054             :   public:
    2055             :     /** Constructor.
    2056             :      *
    2057             :      * This is the same as the C function OGR_GlobFldDomain_Create().
    2058             :      *
    2059             :      * @param osName          Domain name.
    2060             :      * @param osDescription   Domain description.
    2061             :      * @param eFieldType      Field type.
    2062             :      * @param eFieldSubType   Field subtype.
    2063             :      * @param osBlob          Blob expression
    2064             :      */
    2065             :     OGRGlobFieldDomain(const std::string &osName,
    2066             :                        const std::string &osDescription,
    2067             :                        OGRFieldType eFieldType, OGRFieldSubType eFieldSubType,
    2068             :                        const std::string &osBlob);
    2069             : 
    2070             :     OGRGlobFieldDomain *Clone() const override;
    2071             : 
    2072             :     /** Get the glob expression.
    2073             :      *
    2074             :      * This is the same as the C function OGR_GlobFldDomain_GetGlob().
    2075             :      */
    2076          13 :     const std::string &GetGlob() const
    2077             :     {
    2078          13 :         return m_osGlob;
    2079             :     }
    2080             : };
    2081             : 
    2082             : /************************************************************************/
    2083             : /*                           OGRFeatureQuery                            */
    2084             : /************************************************************************/
    2085             : 
    2086             : //! @cond Doxygen_Suppress
    2087             : class OGRLayer;
    2088             : class swq_expr_node;
    2089             : class swq_custom_func_registrar;
    2090             : struct swq_evaluation_context;
    2091             : 
    2092             : class CPL_DLL OGRFeatureQuery
    2093             : {
    2094             :   private:
    2095             :     const OGRFeatureDefn *poTargetDefn;
    2096             :     void *pSWQExpr;
    2097             :     swq_evaluation_context *m_psContext = nullptr;
    2098             : 
    2099             :     char **FieldCollector(void *, char **);
    2100             : 
    2101             :     static GIntBig *EvaluateAgainstIndices(const swq_expr_node *, OGRLayer *,
    2102             :                                            GIntBig &nFIDCount);
    2103             : 
    2104             :     static int CanUseIndex(const swq_expr_node *, OGRLayer *);
    2105             : 
    2106             :     OGRErr Compile(const OGRLayer *, const OGRFeatureDefn *, const char *,
    2107             :                    int bCheck,
    2108             :                    swq_custom_func_registrar *poCustomFuncRegistrar);
    2109             : 
    2110             :     CPL_DISALLOW_COPY_ASSIGN(OGRFeatureQuery)
    2111             : 
    2112             :   public:
    2113             :     OGRFeatureQuery();
    2114             :     ~OGRFeatureQuery();
    2115             : 
    2116             :     OGRErr Compile(const OGRLayer *, const char *, int bCheck = TRUE,
    2117             :                    swq_custom_func_registrar *poCustomFuncRegistrar = nullptr);
    2118             :     OGRErr Compile(const OGRFeatureDefn *, const char *, int bCheck = TRUE,
    2119             :                    swq_custom_func_registrar *poCustomFuncRegistrar = nullptr);
    2120             :     int Evaluate(OGRFeature *);
    2121             : 
    2122             :     GIntBig *EvaluateAgainstIndices(OGRLayer *, OGRErr *);
    2123             : 
    2124             :     int CanUseIndex(OGRLayer *);
    2125             : 
    2126             :     char **GetUsedFields();
    2127             : 
    2128        3433 :     void *GetSWQExpr()
    2129             :     {
    2130        3433 :         return pSWQExpr;
    2131             :     }
    2132             : };
    2133             : 
    2134             : //! @endcond
    2135             : 
    2136             : #endif /* ndef OGR_FEATURE_H_INCLUDED */

Generated by: LCOV version 1.14