Coverage Report

Created: 2026-04-10 07:04

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