Coverage Report

Created: 2026-09-14 06:50

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