LCOV - code coverage report
Current view: top level - ogr - ogr_feature.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 343 345 99.4 %
Date: 2024-11-21 22:18:42 Functions: 148 149 99.3 %

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

Generated by: LCOV version 1.14