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: 2025-01-18 12:42:00 Functions: 150 151 99.3 %

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

Generated by: LCOV version 1.14