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

Generated by: LCOV version 1.14