Coverage Report

Created: 2025-06-13 06:18

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