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

Generated by: LCOV version 1.14