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: 2024-11-21 22:18:42 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 _Float16
      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<float>
     169             : {
     170             :     static constexpr GDALDataType gdal_type = GDT_Float32;
     171             :     static constexpr size_t size = sizeof(float);
     172             :     static constexpr OGRFieldType ogr_type = OFTReal;
     173             :     static constexpr OGRFieldSubType ogr_subtype = OFSTFloat32;
     174             : 
     175           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     176             :     {
     177           1 :         return GDALExtendedDataType::Create(GDT_Float32);
     178             :     }
     179             : };
     180             : 
     181             : template <> struct CXXTypeTraits<double>
     182             : {
     183             :     static constexpr GDALDataType gdal_type = GDT_Float64;
     184             :     static constexpr size_t size = sizeof(double);
     185             :     static constexpr OGRFieldType ogr_type = OFTReal;
     186             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     187             : 
     188           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     189             :     {
     190           1 :         return GDALExtendedDataType::Create(GDT_Float64);
     191             :     }
     192             : };
     193             : 
     194             : template <> struct CXXTypeTraits<std::complex<float>>
     195             : {
     196             :     static constexpr GDALDataType gdal_type = GDT_CFloat32;
     197             :     static constexpr size_t size = sizeof(float) * 2;
     198             :     static constexpr OGRFieldType ogr_type = OFTMaxType;
     199             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     200             : 
     201           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     202             :     {
     203           1 :         return GDALExtendedDataType::Create(GDT_CFloat32);
     204             :     }
     205             : };
     206             : 
     207             : template <> struct CXXTypeTraits<std::complex<double>>
     208             : {
     209             :     static constexpr GDALDataType gdal_type = GDT_CFloat64;
     210             :     static constexpr size_t size = sizeof(double) * 2;
     211             :     static constexpr OGRFieldType ogr_type = OFTMaxType;
     212             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     213             : 
     214           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     215             :     {
     216           1 :         return GDALExtendedDataType::Create(GDT_CFloat64);
     217             :     }
     218             : };
     219             : 
     220             : #if defined(GDAL_ENABLE_FLOAT16) && defined(FLT16_MAX) && defined(FLT16_MIN)
     221             : template <> struct CXXTypeTraits<_Float16>
     222             : {
     223             :     static constexpr GDALDataType gdal_type = GDT_Float16;
     224             :     static constexpr size_t size = sizeof(_Float16);
     225             :     static constexpr OGRFieldType ogr_type = OFTReal;
     226             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     227             : 
     228             :     static inline GDALExtendedDataType GetExtendedDataType()
     229             :     {
     230             :         return GDALExtendedDataType::Create(GDT_Float16);
     231             :     }
     232             : };
     233             : #endif
     234             : 
     235             : template <> struct CXXTypeTraits<std::string>
     236             : {
     237             :     static constexpr GDALDataType gdal_type = GDT_Unknown;
     238             :     static constexpr size_t size = 0;
     239             :     static constexpr OGRFieldType ogr_type = OFTString;
     240             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     241             : 
     242           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     243             :     {
     244           1 :         return GDALExtendedDataType::CreateString();
     245             :     }
     246             : };
     247             : 
     248             : //! @endcond
     249             : 
     250             : /** Trait accepting a GDALDataType and mapping it to corresponding C++ type and
     251             :  * OGRFieldType
     252             :  *
     253             :  * Each specialization has the following members:
     254             :  * typedef T type; (except for GDT_CInt16 and GDT_CInt32)
     255             :  * static constexpr size_t size;
     256             :  * static constexpr OGRFieldType ogr_type;
     257             :  * static constexpr OGRFieldSubType ogr_subtype;
     258             :  * static inline GDALExtendedDataType GetExtendedDataType();
     259             :  *
     260             :  * @since 3.11
     261             :  */
     262             : template <GDALDataType T> struct GDALDataTypeTraits
     263             : {
     264             : };
     265             : 
     266             : //! @cond Doxygen_Suppress
     267             : template <> struct GDALDataTypeTraits<GDT_Int8>
     268             : {
     269             :     typedef int8_t type;
     270             :     static constexpr size_t size = sizeof(int8_t);
     271             :     static constexpr OGRFieldType ogr_type = OFTInteger;
     272             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     273             : 
     274           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     275             :     {
     276           1 :         return GDALExtendedDataType::Create(GDT_Int8);
     277             :     }
     278             : };
     279             : 
     280             : template <> struct GDALDataTypeTraits<GDT_Byte>
     281             : {
     282             :     typedef uint8_t type;
     283             :     static constexpr size_t size = sizeof(uint8_t);
     284             :     static constexpr OGRFieldType ogr_type = OFTInteger;
     285             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     286             : 
     287           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     288             :     {
     289           1 :         return GDALExtendedDataType::Create(GDT_Byte);
     290             :     }
     291             : };
     292             : 
     293             : template <> struct GDALDataTypeTraits<GDT_Int16>
     294             : {
     295             :     typedef int16_t type;
     296             :     static constexpr size_t size = sizeof(int16_t);
     297             :     static constexpr OGRFieldType ogr_type = OFTInteger;
     298             :     static constexpr OGRFieldSubType ogr_subtype = OFSTInt16;
     299             : 
     300           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     301             :     {
     302           1 :         return GDALExtendedDataType::Create(GDT_Int16);
     303             :     }
     304             : };
     305             : 
     306             : template <> struct GDALDataTypeTraits<GDT_UInt16>
     307             : {
     308             :     typedef uint16_t type;
     309             :     static constexpr size_t size = sizeof(uint16_t);
     310             :     static constexpr OGRFieldType ogr_type = OFTInteger;
     311             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     312             : 
     313           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     314             :     {
     315           1 :         return GDALExtendedDataType::Create(GDT_UInt16);
     316             :     }
     317             : };
     318             : 
     319             : template <> struct GDALDataTypeTraits<GDT_Int32>
     320             : {
     321             :     typedef int32_t type;
     322             :     static constexpr size_t size = sizeof(int32_t);
     323             :     static constexpr OGRFieldType ogr_type = OFTInteger;
     324             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     325             : 
     326           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     327             :     {
     328           1 :         return GDALExtendedDataType::Create(GDT_Int32);
     329             :     }
     330             : };
     331             : 
     332             : template <> struct GDALDataTypeTraits<GDT_UInt32>
     333             : {
     334             :     typedef uint32_t type;
     335             :     static constexpr size_t size = sizeof(uint32_t);
     336             :     static constexpr OGRFieldType ogr_type = OFTInteger64;
     337             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     338             : 
     339           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     340             :     {
     341           1 :         return GDALExtendedDataType::Create(GDT_UInt32);
     342             :     }
     343             : };
     344             : 
     345             : template <> struct GDALDataTypeTraits<GDT_Int64>
     346             : {
     347             :     typedef int64_t type;
     348             :     static constexpr size_t size = sizeof(int64_t);
     349             :     static constexpr OGRFieldType ogr_type = OFTInteger64;
     350             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     351             : 
     352           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     353             :     {
     354           1 :         return GDALExtendedDataType::Create(GDT_Int64);
     355             :     }
     356             : };
     357             : 
     358             : template <> struct GDALDataTypeTraits<GDT_UInt64>
     359             : {
     360             :     typedef uint64_t type;
     361             :     static constexpr size_t size = sizeof(uint64_t);
     362             :     // Mapping to Real is questionable...
     363             :     static constexpr OGRFieldType ogr_type = OFTReal;
     364             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     365             : 
     366           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     367             :     {
     368           1 :         return GDALExtendedDataType::Create(GDT_UInt64);
     369             :     }
     370             : };
     371             : 
     372             : template <> struct GDALDataTypeTraits<GDT_Float32>
     373             : {
     374             :     typedef float type;
     375             :     static constexpr size_t size = sizeof(float);
     376             :     static constexpr OGRFieldType ogr_type = OFTReal;
     377             :     static constexpr OGRFieldSubType ogr_subtype = OFSTFloat32;
     378             : 
     379           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     380             :     {
     381           1 :         return GDALExtendedDataType::Create(GDT_Float32);
     382             :     }
     383             : };
     384             : 
     385             : template <> struct GDALDataTypeTraits<GDT_Float64>
     386             : {
     387             :     typedef double type;
     388             :     static constexpr size_t size = sizeof(double);
     389             :     static constexpr OGRFieldType ogr_type = OFTReal;
     390             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     391             : 
     392           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     393             :     {
     394           1 :         return GDALExtendedDataType::Create(GDT_Float64);
     395             :     }
     396             : };
     397             : 
     398             : template <> struct GDALDataTypeTraits<GDT_CInt16>
     399             : {
     400             :     // typedef type not available !
     401             :     static constexpr size_t size = sizeof(int16_t) * 2;
     402             :     static constexpr OGRFieldType ogr_type = OFTMaxType;
     403             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     404             : 
     405           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     406             :     {
     407           1 :         return GDALExtendedDataType::Create(GDT_CInt16);
     408             :     }
     409             : };
     410             : 
     411             : template <> struct GDALDataTypeTraits<GDT_CInt32>
     412             : {
     413             :     // typedef type not available !
     414             :     static constexpr size_t size = sizeof(int32_t) * 2;
     415             :     static constexpr OGRFieldType ogr_type = OFTMaxType;
     416             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     417             : 
     418           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     419             :     {
     420           1 :         return GDALExtendedDataType::Create(GDT_CInt32);
     421             :     }
     422             : };
     423             : 
     424             : template <> struct GDALDataTypeTraits<GDT_CFloat32>
     425             : {
     426             :     typedef std::complex<float> type;
     427             :     static constexpr size_t size = sizeof(float) * 2;
     428             :     static constexpr OGRFieldType ogr_type = OFTMaxType;
     429             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     430             : 
     431           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     432             :     {
     433           1 :         return GDALExtendedDataType::Create(GDT_CFloat32);
     434             :     }
     435             : };
     436             : 
     437             : template <> struct GDALDataTypeTraits<GDT_CFloat64>
     438             : {
     439             :     typedef std::complex<double> type;
     440             :     static constexpr size_t size = sizeof(double) * 2;
     441             :     static constexpr OGRFieldType ogr_type = OFTMaxType;
     442             :     static constexpr OGRFieldSubType ogr_subtype = OFSTNone;
     443             : 
     444           1 :     static inline GDALExtendedDataType GetExtendedDataType()
     445             :     {
     446           1 :         return GDALExtendedDataType::Create(GDT_CFloat64);
     447             :     }
     448             : };
     449             : 
     450             : //! @endcond
     451             : 
     452             : /** Map a GDALDataType to the most suitable OGRFieldType.
     453             :  *
     454             :  * Note that GDT_UInt32 is mapped to OFTInteger64 to avoid data losses.
     455             :  * GDT_UInt64 is mapped to OFTReal, which can be lossy. If values are
     456             :  * guaranteed to be in [0, INT64_MAX] range, callers might want to use
     457             :  * OFTInteger64 instead.
     458             :  * There is no mapping for complex data types.
     459             :  *
     460             :  * @since 3.11
     461             :  */
     462          18 : inline OGRFieldType GetOGRFieldType(const GDALDataType gdal_type)
     463             : {
     464          18 :     switch (gdal_type)
     465             :     {
     466           6 :         case GDT_Byte:
     467             :         case GDT_Int8:
     468             :         case GDT_Int16:
     469             :         case GDT_Int32:
     470             :         case GDT_UInt16:
     471           6 :             return OFTInteger;
     472           2 :         case GDT_UInt32:
     473             :         case GDT_Int64:
     474           2 :             return OFTInteger64;
     475           3 :         case GDT_UInt64:  // Questionable
     476             :         case GDT_Float32:
     477             :         case GDT_Float64:
     478           3 :             return OFTReal;
     479           7 :         case GDT_CInt16:
     480             :         case GDT_CInt32:
     481             :         case GDT_CFloat32:
     482             :         case GDT_CFloat64:
     483             :         case GDT_Unknown:
     484             :         case GDT_TypeCount:
     485           7 :             break;
     486             :     }
     487           7 :     return OFTMaxType;
     488             : }
     489             : 
     490             : /** Map a GDALExtendedDataType to the most suitable OGRFieldType.
     491             :  *
     492             :  * Note that GDT_UInt32 is mapped to OFTInteger64 to avoid data losses.
     493             :  * GDT_UInt64 is mapped to OFTReal, which can be lossy. If values are
     494             :  * guaranteed to be in [0, INT64_MAX] range, callers might want to use
     495             :  * OFTInteger64 instead.
     496             :  *
     497             :  * @since 3.11
     498             :  */
     499           3 : inline OGRFieldType GetOGRFieldType(const GDALExtendedDataType &oEDT)
     500             : {
     501           3 :     if (oEDT.GetClass() == GEDTC_NUMERIC)
     502           2 :         return GetOGRFieldType(oEDT.GetNumericDataType());
     503           1 :     else if (oEDT.GetClass() == GEDTC_STRING)
     504           1 :         return OFTString;
     505           0 :     return OFTMaxType;
     506             : }
     507             : 
     508             : }  // namespace gdal
     509             : 
     510             : #endif  // GDAL_TYPETRAITS_H_INCLUDED

Generated by: LCOV version 1.14