LCOV - code coverage report
Current view: top level - gcore - gdal_typetraits.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 70 71 98.6 %
Date: 2025-10-01 17:07:58 Functions: 29 29 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  * Name:     gdal_typetraits.h
       3             :  * Project:  GDAL Core
       4             :  * Purpose:  Type traits for mapping C++ types to and from GDAL/OGR types.
       5             :  * Author:   Robin Princeley, <rprinceley at esri dot com>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Permission is hereby granted, free of charge, to any person obtaining a
       9             :  * copy of this software and associated documentation files (the "Software"),
      10             :  * to deal in the Software without restriction, including without limitation
      11             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      12             :  * and/or sell copies of the Software, and to permit persons to whom the
      13             :  * Software is furnished to do so, subject to the following conditions:
      14             :  *
      15             :  * The above copyright notice and this permission notice shall be included
      16             :  * in all copies or substantial portions of the Software.
      17             :  *
      18             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      19             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      20             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      21             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      22             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      23             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      24             :  * DEALINGS IN THE SOFTWARE.
      25             :  ****************************************************************************/
      26             : #if !defined(GDAL_TYPETRAITS_H_INCLUDED)
      27             : #define GDAL_TYPETRAITS_H_INCLUDED
      28             : 
      29             : #include "gdal_priv.h"
      30             : #include "cpl_float.h"
      31             : 
      32             : #include <cstddef>
      33             : #include <cstdint>
      34             : #include <complex>
      35             : 
      36             : namespace gdal
      37             : {
      38             : 
      39             : /** Trait accepting a C++ type ([u]int[8/16/32/64], float, double,
      40             :  * std::complex<float>, std::complex<double> or std::string)
      41             :  * and mapping it to GDALDataType / OGRFieldType.
      42             :  *
      43             :  * Each specialization has the following members:
      44             :  * static constexpr GDALDataType gdal_type;
      45             :  * static constexpr size_t size;
      46             :  * static constexpr OGRFieldType ogr_type;
      47             :  * static constexpr OGRFieldSubType ogr_subtype;
      48             :  *
      49             :  * @since 3.11
      50             :  */
      51             : template <typename T> struct CXXTypeTraits
      52             : {
      53             : };
      54             : 
      55             : //! @cond Doxygen_Suppress
      56             : template <> struct CXXTypeTraits<int8_t>
      57             : {
      58             :     static constexpr GDALDataType gdal_type = GDT_Int8;
      59             :     static constexpr size_t size = sizeof(int8_t);
      60             :     static constexpr OGRFieldType ogr_type = OFTInteger;
      61             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
      62             : 
      63           1 :     static inline GDALExtendedDataType GetExtendedDataType()
      64             :     {
      65           1 :         return GDALExtendedDataType::Create(GDT_Int8);
      66             :     }
      67             : };
      68             : 
      69             : template <> struct CXXTypeTraits<uint8_t>
      70             : {
      71             :     static constexpr GDALDataType gdal_type = GDT_Byte;
      72             :     static constexpr size_t size = sizeof(uint8_t);
      73             :     static constexpr OGRFieldType ogr_type = OFTInteger;
      74             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
      75             : 
      76           1 :     static inline GDALExtendedDataType GetExtendedDataType()
      77             :     {
      78           1 :         return GDALExtendedDataType::Create(GDT_Byte);
      79             :     }
      80             : };
      81             : 
      82             : template <> struct CXXTypeTraits<int16_t>
      83             : {
      84             :     static constexpr GDALDataType gdal_type = GDT_Int16;
      85             :     static constexpr size_t size = sizeof(int16_t);
      86             :     static constexpr OGRFieldType ogr_type = OFTInteger;
      87             :     static constexpr OGRFieldSubType ogr_subtype = OFSTInt16;
      88             : 
      89           1 :     static inline GDALExtendedDataType GetExtendedDataType()
      90             :     {
      91           1 :         return GDALExtendedDataType::Create(GDT_Int16);
      92             :     }
      93             : };
      94             : 
      95             : template <> struct CXXTypeTraits<uint16_t>
      96             : {
      97             :     static constexpr GDALDataType gdal_type = GDT_UInt16;
      98             :     static constexpr size_t size = sizeof(uint16_t);
      99             :     static constexpr OGRFieldType ogr_type = OFTInteger;
     100             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     101             : 
     102           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     103             :     {
     104           1 :         return GDALExtendedDataType::Create(GDT_UInt16);
     105             :     }
     106             : };
     107             : 
     108             : template <> struct CXXTypeTraits<int32_t>
     109             : {
     110             :     static constexpr GDALDataType gdal_type = GDT_Int32;
     111             :     static constexpr size_t size = sizeof(int32_t);
     112             :     static constexpr OGRFieldType ogr_type = OFTInteger;
     113             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     114             : 
     115           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     116             :     {
     117           1 :         return GDALExtendedDataType::Create(GDT_Int32);
     118             :     }
     119             : };
     120             : 
     121             : template <> struct CXXTypeTraits<uint32_t>
     122             : {
     123             :     static constexpr GDALDataType gdal_type = GDT_UInt32;
     124             :     static constexpr size_t size = sizeof(uint32_t);
     125             :     static constexpr OGRFieldType ogr_type = OFTInteger64;
     126             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     127             : 
     128           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     129             :     {
     130           1 :         return GDALExtendedDataType::Create(GDT_UInt32);
     131             :     }
     132             : };
     133             : 
     134             : template <> struct CXXTypeTraits<int64_t>
     135             : {
     136             :     static constexpr GDALDataType gdal_type = GDT_Int64;
     137             :     static constexpr size_t size = sizeof(int64_t);
     138             :     static constexpr OGRFieldType ogr_type = OFTInteger64;
     139             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     140             : 
     141           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     142             :     {
     143           1 :         return GDALExtendedDataType::Create(GDT_Int64);
     144             :     }
     145             : };
     146             : 
     147             : template <> struct CXXTypeTraits<uint64_t>
     148             : {
     149             :     static constexpr GDALDataType gdal_type = GDT_UInt64;
     150             :     static constexpr size_t size = sizeof(uint64_t);
     151             :     // Mapping to Real is questionable...
     152             :     static constexpr OGRFieldType ogr_type = OFTReal;
     153             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     154             : 
     155           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     156             :     {
     157           1 :         return GDALExtendedDataType::Create(GDT_UInt64);
     158             :     }
     159             : };
     160             : 
     161             : template <> struct CXXTypeTraits<GFloat16>
     162             : {
     163             :     static constexpr GDALDataType gdal_type = GDT_Float16;
     164             :     static constexpr size_t size = sizeof(GFloat16);
     165             :     static constexpr OGRFieldType ogr_type = OFTReal;
     166             :     // We could introduce OFSTFloat16
     167             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     168             : 
     169             :     static inline GDALExtendedDataType GetExtendedDataType()
     170             :     {
     171             :         return GDALExtendedDataType::Create(GDT_Float16);
     172             :     }
     173             : };
     174             : 
     175             : template <> struct CXXTypeTraits<float>
     176             : {
     177             :     static constexpr GDALDataType gdal_type = GDT_Float32;
     178             :     static constexpr size_t size = sizeof(float);
     179             :     static constexpr OGRFieldType ogr_type = OFTReal;
     180             :     static constexpr OGRFieldSubType ogr_subtype = OFSTFloat32;
     181             : 
     182           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     183             :     {
     184           1 :         return GDALExtendedDataType::Create(GDT_Float32);
     185             :     }
     186             : };
     187             : 
     188             : template <> struct CXXTypeTraits<double>
     189             : {
     190             :     static constexpr GDALDataType gdal_type = GDT_Float64;
     191             :     static constexpr size_t size = sizeof(double);
     192             :     static constexpr OGRFieldType ogr_type = OFTReal;
     193             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     194             : 
     195           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     196             :     {
     197           1 :         return GDALExtendedDataType::Create(GDT_Float64);
     198             :     }
     199             : };
     200             : 
     201             : template <> struct CXXTypeTraits<std::complex<GFloat16>>
     202             : {
     203             :     static constexpr GDALDataType gdal_type = GDT_CFloat16;
     204             :     static constexpr size_t size = sizeof(GFloat16) * 2;
     205             :     static constexpr OGRFieldType ogr_type = OFTMaxType;
     206             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     207             : 
     208             :     static inline GDALExtendedDataType GetExtendedDataType()
     209             :     {
     210             :         return GDALExtendedDataType::Create(GDT_CFloat16);
     211             :     }
     212             : };
     213             : 
     214             : template <> struct CXXTypeTraits<std::complex<float>>
     215             : {
     216             :     static constexpr GDALDataType gdal_type = GDT_CFloat32;
     217             :     static constexpr size_t size = sizeof(float) * 2;
     218             :     static constexpr OGRFieldType ogr_type = OFTMaxType;
     219             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     220             : 
     221           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     222             :     {
     223           1 :         return GDALExtendedDataType::Create(GDT_CFloat32);
     224             :     }
     225             : };
     226             : 
     227             : template <> struct CXXTypeTraits<std::complex<double>>
     228             : {
     229             :     static constexpr GDALDataType gdal_type = GDT_CFloat64;
     230             :     static constexpr size_t size = sizeof(double) * 2;
     231             :     static constexpr OGRFieldType ogr_type = OFTMaxType;
     232             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     233             : 
     234           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     235             :     {
     236           1 :         return GDALExtendedDataType::Create(GDT_CFloat64);
     237             :     }
     238             : };
     239             : 
     240             : template <> struct CXXTypeTraits<std::string>
     241             : {
     242             :     static constexpr GDALDataType gdal_type = GDT_Unknown;
     243             :     static constexpr size_t size = 0;
     244             :     static constexpr OGRFieldType ogr_type = OFTString;
     245             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     246             : 
     247           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     248             :     {
     249           1 :         return GDALExtendedDataType::CreateString();
     250             :     }
     251             : };
     252             : 
     253             : //! @endcond
     254             : 
     255             : /** Trait accepting a GDALDataType and mapping it to corresponding C++ type and
     256             :  * OGRFieldType
     257             :  *
     258             :  * Each specialization has the following members:
     259             :  * typedef T type; (except for GDT_CInt16 and GDT_CInt32)
     260             :  * static constexpr size_t size;
     261             :  * static constexpr OGRFieldType ogr_type;
     262             :  * static constexpr OGRFieldSubType ogr_subtype;
     263             :  * static inline GDALExtendedDataType GetExtendedDataType();
     264             :  *
     265             :  * @since 3.11
     266             :  */
     267             : template <GDALDataType T> struct GDALDataTypeTraits
     268             : {
     269             : };
     270             : 
     271             : //! @cond Doxygen_Suppress
     272             : template <> struct GDALDataTypeTraits<GDT_Int8>
     273             : {
     274             :     typedef int8_t type;
     275             :     static constexpr size_t size = sizeof(int8_t);
     276             :     static constexpr OGRFieldType ogr_type = OFTInteger;
     277             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     278             : 
     279           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     280             :     {
     281           1 :         return GDALExtendedDataType::Create(GDT_Int8);
     282             :     }
     283             : };
     284             : 
     285             : template <> struct GDALDataTypeTraits<GDT_Byte>
     286             : {
     287             :     typedef uint8_t type;
     288             :     static constexpr size_t size = sizeof(uint8_t);
     289             :     static constexpr OGRFieldType ogr_type = OFTInteger;
     290             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     291             : 
     292           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     293             :     {
     294           1 :         return GDALExtendedDataType::Create(GDT_Byte);
     295             :     }
     296             : };
     297             : 
     298             : template <> struct GDALDataTypeTraits<GDT_Int16>
     299             : {
     300             :     typedef int16_t type;
     301             :     static constexpr size_t size = sizeof(int16_t);
     302             :     static constexpr OGRFieldType ogr_type = OFTInteger;
     303             :     static constexpr OGRFieldSubType ogr_subtype = OFSTInt16;
     304             : 
     305           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     306             :     {
     307           1 :         return GDALExtendedDataType::Create(GDT_Int16);
     308             :     }
     309             : };
     310             : 
     311             : template <> struct GDALDataTypeTraits<GDT_UInt16>
     312             : {
     313             :     typedef uint16_t type;
     314             :     static constexpr size_t size = sizeof(uint16_t);
     315             :     static constexpr OGRFieldType ogr_type = OFTInteger;
     316             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     317             : 
     318           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     319             :     {
     320           1 :         return GDALExtendedDataType::Create(GDT_UInt16);
     321             :     }
     322             : };
     323             : 
     324             : template <> struct GDALDataTypeTraits<GDT_Int32>
     325             : {
     326             :     typedef int32_t type;
     327             :     static constexpr size_t size = sizeof(int32_t);
     328             :     static constexpr OGRFieldType ogr_type = OFTInteger;
     329             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     330             : 
     331           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     332             :     {
     333           1 :         return GDALExtendedDataType::Create(GDT_Int32);
     334             :     }
     335             : };
     336             : 
     337             : template <> struct GDALDataTypeTraits<GDT_UInt32>
     338             : {
     339             :     typedef uint32_t type;
     340             :     static constexpr size_t size = sizeof(uint32_t);
     341             :     static constexpr OGRFieldType ogr_type = OFTInteger64;
     342             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     343             : 
     344           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     345             :     {
     346           1 :         return GDALExtendedDataType::Create(GDT_UInt32);
     347             :     }
     348             : };
     349             : 
     350             : template <> struct GDALDataTypeTraits<GDT_Int64>
     351             : {
     352             :     typedef int64_t type;
     353             :     static constexpr size_t size = sizeof(int64_t);
     354             :     static constexpr OGRFieldType ogr_type = OFTInteger64;
     355             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     356             : 
     357           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     358             :     {
     359           1 :         return GDALExtendedDataType::Create(GDT_Int64);
     360             :     }
     361             : };
     362             : 
     363             : template <> struct GDALDataTypeTraits<GDT_UInt64>
     364             : {
     365             :     typedef uint64_t type;
     366             :     static constexpr size_t size = sizeof(uint64_t);
     367             :     // Mapping to Real is questionable...
     368             :     static constexpr OGRFieldType ogr_type = OFTReal;
     369             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     370             : 
     371           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     372             :     {
     373           1 :         return GDALExtendedDataType::Create(GDT_UInt64);
     374             :     }
     375             : };
     376             : 
     377             : template <> struct GDALDataTypeTraits<GDT_Float32>
     378             : {
     379             :     typedef float type;
     380             :     static constexpr size_t size = sizeof(float);
     381             :     static constexpr OGRFieldType ogr_type = OFTReal;
     382             :     static constexpr OGRFieldSubType ogr_subtype = OFSTFloat32;
     383             : 
     384           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     385             :     {
     386           1 :         return GDALExtendedDataType::Create(GDT_Float32);
     387             :     }
     388             : };
     389             : 
     390             : template <> struct GDALDataTypeTraits<GDT_Float64>
     391             : {
     392             :     typedef double type;
     393             :     static constexpr size_t size = sizeof(double);
     394             :     static constexpr OGRFieldType ogr_type = OFTReal;
     395             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     396             : 
     397           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     398             :     {
     399           1 :         return GDALExtendedDataType::Create(GDT_Float64);
     400             :     }
     401             : };
     402             : 
     403             : template <> struct GDALDataTypeTraits<GDT_CInt16>
     404             : {
     405             :     // typedef type not available !
     406             :     static constexpr size_t size = sizeof(int16_t) * 2;
     407             :     static constexpr OGRFieldType ogr_type = OFTMaxType;
     408             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     409             : 
     410           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     411             :     {
     412           1 :         return GDALExtendedDataType::Create(GDT_CInt16);
     413             :     }
     414             : };
     415             : 
     416             : template <> struct GDALDataTypeTraits<GDT_CInt32>
     417             : {
     418             :     // typedef type not available !
     419             :     static constexpr size_t size = sizeof(int32_t) * 2;
     420             :     static constexpr OGRFieldType ogr_type = OFTMaxType;
     421             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     422             : 
     423           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     424             :     {
     425           1 :         return GDALExtendedDataType::Create(GDT_CInt32);
     426             :     }
     427             : };
     428             : 
     429             : template <> struct GDALDataTypeTraits<GDT_CFloat32>
     430             : {
     431             :     typedef std::complex<float> type;
     432             :     static constexpr size_t size = sizeof(float) * 2;
     433             :     static constexpr OGRFieldType ogr_type = OFTMaxType;
     434             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     435             : 
     436           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     437             :     {
     438           1 :         return GDALExtendedDataType::Create(GDT_CFloat32);
     439             :     }
     440             : };
     441             : 
     442             : template <> struct GDALDataTypeTraits<GDT_CFloat64>
     443             : {
     444             :     typedef std::complex<double> type;
     445             :     static constexpr size_t size = sizeof(double) * 2;
     446             :     static constexpr OGRFieldType ogr_type = OFTMaxType;
     447             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     448             : 
     449           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     450             :     {
     451           1 :         return GDALExtendedDataType::Create(GDT_CFloat64);
     452             :     }
     453             : };
     454             : 
     455             : //! @endcond
     456             : 
     457             : /** Map a GDALDataType to the most suitable OGRFieldType.
     458             :  *
     459             :  * Note that GDT_UInt32 is mapped to OFTInteger64 to avoid data losses.
     460             :  * GDT_UInt64 is mapped to OFTReal, which can be lossy. If values are
     461             :  * guaranteed to be in [0, INT64_MAX] range, callers might want to use
     462             :  * OFTInteger64 instead.
     463             :  * There is no mapping for complex data types.
     464             :  *
     465             :  * @since 3.11
     466             :  */
     467          18 : inline OGRFieldType GetOGRFieldType(const GDALDataType gdal_type)
     468             : {
     469          18 :     switch (gdal_type)
     470             :     {
     471           6 :         case GDT_Byte:
     472             :         case GDT_Int8:
     473             :         case GDT_Int16:
     474             :         case GDT_Int32:
     475             :         case GDT_UInt16:
     476           6 :             return OFTInteger;
     477           2 :         case GDT_UInt32:
     478             :         case GDT_Int64:
     479           2 :             return OFTInteger64;
     480           3 :         case GDT_UInt64:  // Questionable
     481             :         case GDT_Float16:
     482             :         case GDT_Float32:
     483             :         case GDT_Float64:
     484           3 :             return OFTReal;
     485           7 :         case GDT_CInt16:
     486             :         case GDT_CInt32:
     487             :         case GDT_CFloat16:
     488             :         case GDT_CFloat32:
     489             :         case GDT_CFloat64:
     490             :         case GDT_Unknown:
     491             :         case GDT_TypeCount:
     492           7 :             break;
     493             :     }
     494           7 :     return OFTMaxType;
     495             : }
     496             : 
     497             : /** Map a GDALExtendedDataType to the most suitable OGRFieldType.
     498             :  *
     499             :  * Note that GDT_UInt32 is mapped to OFTInteger64 to avoid data losses.
     500             :  * GDT_UInt64 is mapped to OFTReal, which can be lossy. If values are
     501             :  * guaranteed to be in [0, INT64_MAX] range, callers might want to use
     502             :  * OFTInteger64 instead.
     503             :  *
     504             :  * @since 3.11
     505             :  */
     506           3 : inline OGRFieldType GetOGRFieldType(const GDALExtendedDataType &oEDT)
     507             : {
     508           3 :     if (oEDT.GetClass() == GEDTC_NUMERIC)
     509           2 :         return GetOGRFieldType(oEDT.GetNumericDataType());
     510           1 :     else if (oEDT.GetClass() == GEDTC_STRING)
     511           1 :         return OFTString;
     512           0 :     return OFTMaxType;
     513             : }
     514             : 
     515             : }  // namespace gdal
     516             : 
     517             : #endif  // GDAL_TYPETRAITS_H_INCLUDED

Generated by: LCOV version 1.14