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