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

Generated by: LCOV version 1.14