Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-08-27 08:47:24

0001 // Licensed to the Apache Software Foundation (ASF) under one
0002 // or more contributor license agreements.  See the NOTICE file
0003 // distributed with this work for additional information
0004 // regarding copyright ownership.  The ASF licenses this file
0005 // to you under the Apache License, Version 2.0 (the
0006 // "License"); you may not use this file except in compliance
0007 // with the License.  You may obtain a copy of the License at
0008 //
0009 //   http://www.apache.org/licenses/LICENSE-2.0
0010 //
0011 // Unless required by applicable law or agreed to in writing,
0012 // software distributed under the License is distributed on an
0013 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
0014 // KIND, either express or implied.  See the License for the
0015 // specific language governing permissions and limitations
0016 // under the License.
0017 
0018 #pragma once
0019 
0020 #include <memory>
0021 #include <string>
0022 #include <type_traits>
0023 #include <vector>
0024 
0025 #include "arrow/type.h"
0026 #include "arrow/util/bit_util.h"
0027 
0028 namespace arrow {
0029 
0030 //
0031 // Per-type id type lookup
0032 //
0033 
0034 template <Type::type id>
0035 struct TypeIdTraits {};
0036 
0037 #define TYPE_ID_TRAIT(_id, _typeclass) \
0038   template <>                          \
0039   struct TypeIdTraits<Type::_id> {     \
0040     using Type = _typeclass;           \
0041   };
0042 
0043 TYPE_ID_TRAIT(NA, NullType)
0044 TYPE_ID_TRAIT(BOOL, BooleanType)
0045 TYPE_ID_TRAIT(INT8, Int8Type)
0046 TYPE_ID_TRAIT(INT16, Int16Type)
0047 TYPE_ID_TRAIT(INT32, Int32Type)
0048 TYPE_ID_TRAIT(INT64, Int64Type)
0049 TYPE_ID_TRAIT(UINT8, UInt8Type)
0050 TYPE_ID_TRAIT(UINT16, UInt16Type)
0051 TYPE_ID_TRAIT(UINT32, UInt32Type)
0052 TYPE_ID_TRAIT(UINT64, UInt64Type)
0053 TYPE_ID_TRAIT(HALF_FLOAT, HalfFloatType)
0054 TYPE_ID_TRAIT(FLOAT, FloatType)
0055 TYPE_ID_TRAIT(DOUBLE, DoubleType)
0056 TYPE_ID_TRAIT(STRING, StringType)
0057 TYPE_ID_TRAIT(BINARY, BinaryType)
0058 TYPE_ID_TRAIT(LARGE_STRING, LargeStringType)
0059 TYPE_ID_TRAIT(LARGE_BINARY, LargeBinaryType)
0060 TYPE_ID_TRAIT(FIXED_SIZE_BINARY, FixedSizeBinaryType)
0061 TYPE_ID_TRAIT(DATE32, Date32Type)
0062 TYPE_ID_TRAIT(DATE64, Date64Type)
0063 TYPE_ID_TRAIT(TIME32, Time32Type)
0064 TYPE_ID_TRAIT(TIME64, Time64Type)
0065 TYPE_ID_TRAIT(TIMESTAMP, TimestampType)
0066 TYPE_ID_TRAIT(INTERVAL_DAY_TIME, DayTimeIntervalType)
0067 TYPE_ID_TRAIT(INTERVAL_MONTH_DAY_NANO, MonthDayNanoIntervalType)
0068 TYPE_ID_TRAIT(INTERVAL_MONTHS, MonthIntervalType)
0069 TYPE_ID_TRAIT(DURATION, DurationType)
0070 TYPE_ID_TRAIT(DECIMAL32, Decimal32Type)
0071 TYPE_ID_TRAIT(DECIMAL64, Decimal64Type)
0072 TYPE_ID_TRAIT(DECIMAL128, Decimal128Type)
0073 TYPE_ID_TRAIT(DECIMAL256, Decimal256Type)
0074 TYPE_ID_TRAIT(STRUCT, StructType)
0075 TYPE_ID_TRAIT(LIST, ListType)
0076 TYPE_ID_TRAIT(LARGE_LIST, LargeListType)
0077 TYPE_ID_TRAIT(FIXED_SIZE_LIST, FixedSizeListType)
0078 TYPE_ID_TRAIT(MAP, MapType)
0079 TYPE_ID_TRAIT(DENSE_UNION, DenseUnionType)
0080 TYPE_ID_TRAIT(SPARSE_UNION, SparseUnionType)
0081 TYPE_ID_TRAIT(DICTIONARY, DictionaryType)
0082 TYPE_ID_TRAIT(EXTENSION, ExtensionType)
0083 
0084 #undef TYPE_ID_TRAIT
0085 
0086 //
0087 // Per-type type traits
0088 //
0089 
0090 /// \addtogroup type-traits
0091 /// \brief Base template for type traits of Arrow data types
0092 /// Type traits provide various information about a type at compile time, such
0093 /// as the associated ArrayType, BuilderType, and ScalarType. Not all types
0094 /// provide all information.
0095 /// \tparam T An Arrow data type
0096 template <typename T>
0097 struct TypeTraits {};
0098 
0099 /// \brief Base template for type traits of C++ types
0100 /// \tparam T A standard C++ type
0101 template <typename T>
0102 struct CTypeTraits {};
0103 
0104 /// \addtogroup type-traits
0105 /// @{
0106 template <>
0107 struct TypeTraits<NullType> {
0108   using ArrayType = NullArray;
0109   using BuilderType = NullBuilder;
0110   using ScalarType = NullScalar;
0111 
0112   static constexpr int64_t bytes_required(int64_t) { return 0; }
0113   constexpr static bool is_parameter_free = true;
0114   static inline std::shared_ptr<DataType> type_singleton() { return null(); }
0115 };
0116 
0117 template <>
0118 struct TypeTraits<BooleanType> {
0119   using ArrayType = BooleanArray;
0120   using BuilderType = BooleanBuilder;
0121   using ScalarType = BooleanScalar;
0122   using CType = bool;
0123 
0124   static constexpr int64_t bytes_required(int64_t elements) {
0125     return bit_util::BytesForBits(elements);
0126   }
0127   constexpr static bool is_parameter_free = true;
0128   static inline std::shared_ptr<DataType> type_singleton() { return boolean(); }
0129 };
0130 /// @}
0131 
0132 /// \addtogroup c-type-traits
0133 template <>
0134 struct CTypeTraits<bool> : public TypeTraits<BooleanType> {
0135   using ArrowType = BooleanType;
0136 };
0137 
0138 #define PRIMITIVE_TYPE_TRAITS_DEF_(CType_, ArrowType_, ArrowArrayType, ArrowBuilderType, \
0139                                    ArrowScalarType, ArrowTensorType, SingletonFn)        \
0140   template <>                                                                            \
0141   struct TypeTraits<ArrowType_> {                                                        \
0142     using ArrayType = ArrowArrayType;                                                    \
0143     using BuilderType = ArrowBuilderType;                                                \
0144     using ScalarType = ArrowScalarType;                                                  \
0145     using TensorType = ArrowTensorType;                                                  \
0146     using CType = ArrowType_::c_type;                                                    \
0147     static constexpr int64_t bytes_required(int64_t elements) {                          \
0148       return elements * static_cast<int64_t>(sizeof(CType));                             \
0149     }                                                                                    \
0150     constexpr static bool is_parameter_free = true;                                      \
0151     static inline std::shared_ptr<DataType> type_singleton() { return SingletonFn(); }   \
0152   };                                                                                     \
0153                                                                                          \
0154   template <>                                                                            \
0155   struct CTypeTraits<CType_> : public TypeTraits<ArrowType_> {                           \
0156     using ArrowType = ArrowType_;                                                        \
0157   };
0158 
0159 #define PRIMITIVE_TYPE_TRAITS_DEF(CType, ArrowShort, SingletonFn)             \
0160   PRIMITIVE_TYPE_TRAITS_DEF_(                                                 \
0161       CType, ARROW_CONCAT(ArrowShort, Type), ARROW_CONCAT(ArrowShort, Array), \
0162       ARROW_CONCAT(ArrowShort, Builder), ARROW_CONCAT(ArrowShort, Scalar),    \
0163       ARROW_CONCAT(ArrowShort, Tensor), SingletonFn)
0164 
0165 PRIMITIVE_TYPE_TRAITS_DEF(uint8_t, UInt8, uint8)
0166 PRIMITIVE_TYPE_TRAITS_DEF(int8_t, Int8, int8)
0167 PRIMITIVE_TYPE_TRAITS_DEF(uint16_t, UInt16, uint16)
0168 PRIMITIVE_TYPE_TRAITS_DEF(int16_t, Int16, int16)
0169 PRIMITIVE_TYPE_TRAITS_DEF(uint32_t, UInt32, uint32)
0170 PRIMITIVE_TYPE_TRAITS_DEF(int32_t, Int32, int32)
0171 PRIMITIVE_TYPE_TRAITS_DEF(uint64_t, UInt64, uint64)
0172 PRIMITIVE_TYPE_TRAITS_DEF(int64_t, Int64, int64)
0173 PRIMITIVE_TYPE_TRAITS_DEF(float, Float, float32)
0174 PRIMITIVE_TYPE_TRAITS_DEF(double, Double, float64)
0175 
0176 #undef PRIMITIVE_TYPE_TRAITS_DEF
0177 #undef PRIMITIVE_TYPE_TRAITS_DEF_
0178 
0179 /// \addtogroup type-traits
0180 /// @{
0181 template <>
0182 struct TypeTraits<Date64Type> {
0183   using ArrayType = Date64Array;
0184   using BuilderType = Date64Builder;
0185   using ScalarType = Date64Scalar;
0186   using CType = Date64Type::c_type;
0187 
0188   static constexpr int64_t bytes_required(int64_t elements) {
0189     return elements * static_cast<int64_t>(sizeof(int64_t));
0190   }
0191   constexpr static bool is_parameter_free = true;
0192   static inline std::shared_ptr<DataType> type_singleton() { return date64(); }
0193 };
0194 
0195 template <>
0196 struct TypeTraits<Date32Type> {
0197   using ArrayType = Date32Array;
0198   using BuilderType = Date32Builder;
0199   using ScalarType = Date32Scalar;
0200   using CType = Date32Type::c_type;
0201 
0202   static constexpr int64_t bytes_required(int64_t elements) {
0203     return elements * static_cast<int64_t>(sizeof(int32_t));
0204   }
0205   constexpr static bool is_parameter_free = true;
0206   static inline std::shared_ptr<DataType> type_singleton() { return date32(); }
0207 };
0208 
0209 template <>
0210 struct TypeTraits<TimestampType> {
0211   using ArrayType = TimestampArray;
0212   using BuilderType = TimestampBuilder;
0213   using ScalarType = TimestampScalar;
0214   using CType = TimestampType::c_type;
0215 
0216   static constexpr int64_t bytes_required(int64_t elements) {
0217     return elements * static_cast<int64_t>(sizeof(int64_t));
0218   }
0219   constexpr static bool is_parameter_free = false;
0220 };
0221 
0222 template <>
0223 struct TypeTraits<DurationType> {
0224   using ArrayType = DurationArray;
0225   using BuilderType = DurationBuilder;
0226   using ScalarType = DurationScalar;
0227   using CType = DurationType::c_type;
0228 
0229   static constexpr int64_t bytes_required(int64_t elements) {
0230     return elements * static_cast<int64_t>(sizeof(int64_t));
0231   }
0232   constexpr static bool is_parameter_free = false;
0233 };
0234 
0235 template <>
0236 struct TypeTraits<DayTimeIntervalType> {
0237   using ArrayType = DayTimeIntervalArray;
0238   using BuilderType = DayTimeIntervalBuilder;
0239   using ScalarType = DayTimeIntervalScalar;
0240   using CType = DayTimeIntervalType::c_type;
0241 
0242   static constexpr int64_t bytes_required(int64_t elements) {
0243     return elements * static_cast<int64_t>(sizeof(DayTimeIntervalType::DayMilliseconds));
0244   }
0245   constexpr static bool is_parameter_free = true;
0246   static std::shared_ptr<DataType> type_singleton() { return day_time_interval(); }
0247 };
0248 
0249 template <>
0250 struct TypeTraits<MonthDayNanoIntervalType> {
0251   using ArrayType = MonthDayNanoIntervalArray;
0252   using BuilderType = MonthDayNanoIntervalBuilder;
0253   using ScalarType = MonthDayNanoIntervalScalar;
0254   using CType = MonthDayNanoIntervalType::c_type;
0255 
0256   static constexpr int64_t bytes_required(int64_t elements) {
0257     return elements *
0258            static_cast<int64_t>(sizeof(MonthDayNanoIntervalType::MonthDayNanos));
0259   }
0260   constexpr static bool is_parameter_free = true;
0261   static std::shared_ptr<DataType> type_singleton() { return month_day_nano_interval(); }
0262 };
0263 
0264 template <>
0265 struct TypeTraits<MonthIntervalType> {
0266   using ArrayType = MonthIntervalArray;
0267   using BuilderType = MonthIntervalBuilder;
0268   using ScalarType = MonthIntervalScalar;
0269   using CType = MonthIntervalType::c_type;
0270 
0271   static constexpr int64_t bytes_required(int64_t elements) {
0272     return elements * static_cast<int64_t>(sizeof(int32_t));
0273   }
0274   constexpr static bool is_parameter_free = true;
0275   static std::shared_ptr<DataType> type_singleton() { return month_interval(); }
0276 };
0277 
0278 template <>
0279 struct TypeTraits<Time32Type> {
0280   using ArrayType = Time32Array;
0281   using BuilderType = Time32Builder;
0282   using ScalarType = Time32Scalar;
0283   using CType = Time32Type::c_type;
0284 
0285   static constexpr int64_t bytes_required(int64_t elements) {
0286     return elements * static_cast<int64_t>(sizeof(int32_t));
0287   }
0288   constexpr static bool is_parameter_free = false;
0289 };
0290 
0291 template <>
0292 struct TypeTraits<Time64Type> {
0293   using ArrayType = Time64Array;
0294   using BuilderType = Time64Builder;
0295   using ScalarType = Time64Scalar;
0296   using CType = Time64Type::c_type;
0297 
0298   static constexpr int64_t bytes_required(int64_t elements) {
0299     return elements * static_cast<int64_t>(sizeof(int64_t));
0300   }
0301   constexpr static bool is_parameter_free = false;
0302 };
0303 
0304 template <>
0305 struct TypeTraits<HalfFloatType> {
0306   using ArrayType = HalfFloatArray;
0307   using BuilderType = HalfFloatBuilder;
0308   using ScalarType = HalfFloatScalar;
0309   using TensorType = HalfFloatTensor;
0310   using CType = uint16_t;
0311 
0312   static constexpr int64_t bytes_required(int64_t elements) {
0313     return elements * static_cast<int64_t>(sizeof(uint16_t));
0314   }
0315   constexpr static bool is_parameter_free = true;
0316   static inline std::shared_ptr<DataType> type_singleton() { return float16(); }
0317 };
0318 
0319 template <>
0320 struct TypeTraits<Decimal32Type> {
0321   using ArrayType = Decimal32Array;
0322   using BuilderType = Decimal32Builder;
0323   using ScalarType = Decimal32Scalar;
0324   using CType = Decimal32;
0325   constexpr static bool is_parameter_free = false;
0326 };
0327 
0328 template <>
0329 struct TypeTraits<Decimal64Type> {
0330   using ArrayType = Decimal64Array;
0331   using BuilderType = Decimal64Builder;
0332   using ScalarType = Decimal64Scalar;
0333   using CType = Decimal64;
0334   constexpr static bool is_parameter_free = false;
0335 };
0336 
0337 template <>
0338 struct TypeTraits<Decimal128Type> {
0339   using ArrayType = Decimal128Array;
0340   using BuilderType = Decimal128Builder;
0341   using ScalarType = Decimal128Scalar;
0342   using CType = Decimal128;
0343   constexpr static bool is_parameter_free = false;
0344 };
0345 
0346 template <>
0347 struct TypeTraits<Decimal256Type> {
0348   using ArrayType = Decimal256Array;
0349   using BuilderType = Decimal256Builder;
0350   using ScalarType = Decimal256Scalar;
0351   using CType = Decimal256;
0352   constexpr static bool is_parameter_free = false;
0353 };
0354 
0355 template <>
0356 struct TypeTraits<BinaryType> {
0357   using ArrayType = BinaryArray;
0358   using BuilderType = BinaryBuilder;
0359   using ScalarType = BinaryScalar;
0360   using OffsetType = Int32Type;
0361   constexpr static bool is_parameter_free = true;
0362   static inline std::shared_ptr<DataType> type_singleton() { return binary(); }
0363 };
0364 
0365 template <>
0366 struct TypeTraits<BinaryViewType> {
0367   using ArrayType = BinaryViewArray;
0368   using BuilderType = BinaryViewBuilder;
0369   using ScalarType = BinaryViewScalar;
0370   using CType = BinaryViewType::c_type;
0371   constexpr static bool is_parameter_free = true;
0372   static inline std::shared_ptr<DataType> type_singleton() { return binary_view(); }
0373 };
0374 
0375 template <>
0376 struct TypeTraits<LargeBinaryType> {
0377   using ArrayType = LargeBinaryArray;
0378   using BuilderType = LargeBinaryBuilder;
0379   using ScalarType = LargeBinaryScalar;
0380   using OffsetType = Int64Type;
0381   constexpr static bool is_parameter_free = true;
0382   static inline std::shared_ptr<DataType> type_singleton() { return large_binary(); }
0383 };
0384 
0385 template <>
0386 struct TypeTraits<FixedSizeBinaryType> {
0387   using ArrayType = FixedSizeBinaryArray;
0388   using BuilderType = FixedSizeBinaryBuilder;
0389   using ScalarType = FixedSizeBinaryScalar;
0390   // FixedSizeBinary doesn't have offsets per se, but string length is int32 sized
0391   using OffsetType = Int32Type;
0392   constexpr static bool is_parameter_free = false;
0393 };
0394 
0395 template <>
0396 struct TypeTraits<StringType> {
0397   using ArrayType = StringArray;
0398   using BuilderType = StringBuilder;
0399   using ScalarType = StringScalar;
0400   using OffsetType = Int32Type;
0401   constexpr static bool is_parameter_free = true;
0402   static inline std::shared_ptr<DataType> type_singleton() { return utf8(); }
0403 };
0404 
0405 template <>
0406 struct TypeTraits<StringViewType> {
0407   using ArrayType = StringViewArray;
0408   using BuilderType = StringViewBuilder;
0409   using ScalarType = StringViewScalar;
0410   using CType = BinaryViewType::c_type;
0411   constexpr static bool is_parameter_free = true;
0412   static inline std::shared_ptr<DataType> type_singleton() { return utf8_view(); }
0413 };
0414 
0415 template <>
0416 struct TypeTraits<LargeStringType> {
0417   using ArrayType = LargeStringArray;
0418   using BuilderType = LargeStringBuilder;
0419   using ScalarType = LargeStringScalar;
0420   using OffsetType = Int64Type;
0421   constexpr static bool is_parameter_free = true;
0422   static inline std::shared_ptr<DataType> type_singleton() { return large_utf8(); }
0423 };
0424 
0425 template <>
0426 struct TypeTraits<RunEndEncodedType> {
0427   using ArrayType = RunEndEncodedArray;
0428   using BuilderType = RunEndEncodedBuilder;
0429   using ScalarType = RunEndEncodedScalar;
0430 
0431   constexpr static bool is_parameter_free = false;
0432 };
0433 
0434 /// @}
0435 
0436 /// \addtogroup c-type-traits
0437 /// @{
0438 template <>
0439 struct CTypeTraits<std::string> : public TypeTraits<StringType> {
0440   using ArrowType = StringType;
0441 };
0442 
0443 template <>
0444 struct CTypeTraits<BinaryViewType::c_type> : public TypeTraits<BinaryViewType> {
0445   using ArrowType = BinaryViewType;
0446 };
0447 
0448 template <>
0449 struct CTypeTraits<const char*> : public CTypeTraits<std::string> {};
0450 
0451 template <size_t N>
0452 struct CTypeTraits<const char (&)[N]> : public CTypeTraits<std::string> {};
0453 
0454 template <>
0455 struct CTypeTraits<DayTimeIntervalType::DayMilliseconds>
0456     : public TypeTraits<DayTimeIntervalType> {
0457   using ArrowType = DayTimeIntervalType;
0458 };
0459 /// @}
0460 
0461 /// \addtogroup type-traits
0462 /// @{
0463 template <>
0464 struct TypeTraits<ListType> {
0465   using ArrayType = ListArray;
0466   using BuilderType = ListBuilder;
0467   using ScalarType = ListScalar;
0468   using OffsetType = Int32Type;
0469   using OffsetArrayType = Int32Array;
0470   using OffsetBuilderType = Int32Builder;
0471   using OffsetScalarType = Int32Scalar;
0472   constexpr static bool is_parameter_free = false;
0473   using LargeType = LargeListType;
0474 };
0475 
0476 template <>
0477 struct TypeTraits<LargeListType> {
0478   using ArrayType = LargeListArray;
0479   using BuilderType = LargeListBuilder;
0480   using ScalarType = LargeListScalar;
0481   using OffsetType = Int64Type;
0482   using OffsetArrayType = Int64Array;
0483   using OffsetBuilderType = Int64Builder;
0484   using OffsetScalarType = Int64Scalar;
0485   constexpr static bool is_parameter_free = false;
0486 };
0487 
0488 template <>
0489 struct TypeTraits<ListViewType> {
0490   using ArrayType = ListViewArray;
0491   using BuilderType = ListViewBuilder;
0492   using ScalarType = ListViewScalar;
0493   using OffsetType = Int32Type;
0494   using OffsetArrayType = Int32Array;
0495   using OffsetBuilderType = Int32Builder;
0496   using OffsetScalarType = Int32Scalar;
0497   constexpr static bool is_parameter_free = false;
0498   using LargeType = LargeListViewType;
0499 };
0500 
0501 template <>
0502 struct TypeTraits<LargeListViewType> {
0503   using ArrayType = LargeListViewArray;
0504   using BuilderType = LargeListViewBuilder;
0505   using ScalarType = LargeListViewScalar;
0506   using OffsetType = Int64Type;
0507   using OffsetArrayType = Int64Array;
0508   using OffsetBuilderType = Int64Builder;
0509   using OffsetScalarType = Int64Scalar;
0510   constexpr static bool is_parameter_free = false;
0511 };
0512 
0513 template <>
0514 struct TypeTraits<MapType> {
0515   using ArrayType = MapArray;
0516   using BuilderType = MapBuilder;
0517   using ScalarType = MapScalar;
0518   using OffsetType = Int32Type;
0519   using OffsetArrayType = Int32Array;
0520   using OffsetBuilderType = Int32Builder;
0521   constexpr static bool is_parameter_free = false;
0522 };
0523 
0524 template <>
0525 struct TypeTraits<FixedSizeListType> {
0526   using ArrayType = FixedSizeListArray;
0527   using BuilderType = FixedSizeListBuilder;
0528   using ScalarType = FixedSizeListScalar;
0529   constexpr static bool is_parameter_free = false;
0530 };
0531 /// @}
0532 
0533 /// \addtogroup c-type-traits
0534 template <typename CType>
0535 struct CTypeTraits<std::vector<CType>> : public TypeTraits<ListType> {
0536   using ArrowType = ListType;
0537 
0538   static inline std::shared_ptr<DataType> type_singleton() {
0539     return list(CTypeTraits<CType>::type_singleton());
0540   }
0541 };
0542 
0543 /// \addtogroup c-type-traits
0544 template <typename CType, std::size_t N>
0545 struct CTypeTraits<std::array<CType, N>> : public TypeTraits<FixedSizeListType> {
0546   using ArrowType = FixedSizeListType;
0547 
0548   static auto type_singleton() {
0549     return fixed_size_list(CTypeTraits<CType>::type_singleton(), N);
0550   }
0551 };
0552 
0553 /// \addtogroup type-traits
0554 /// @{
0555 template <>
0556 struct TypeTraits<StructType> {
0557   using ArrayType = StructArray;
0558   using BuilderType = StructBuilder;
0559   using ScalarType = StructScalar;
0560   constexpr static bool is_parameter_free = false;
0561 };
0562 
0563 template <>
0564 struct TypeTraits<SparseUnionType> {
0565   using ArrayType = SparseUnionArray;
0566   using BuilderType = SparseUnionBuilder;
0567   using ScalarType = SparseUnionScalar;
0568   constexpr static bool is_parameter_free = false;
0569 };
0570 
0571 template <>
0572 struct TypeTraits<DenseUnionType> {
0573   using ArrayType = DenseUnionArray;
0574   using BuilderType = DenseUnionBuilder;
0575   using ScalarType = DenseUnionScalar;
0576   constexpr static bool is_parameter_free = false;
0577 };
0578 
0579 template <>
0580 struct TypeTraits<DictionaryType> {
0581   using ArrayType = DictionaryArray;
0582   using ScalarType = DictionaryScalar;
0583   constexpr static bool is_parameter_free = false;
0584 };
0585 
0586 template <>
0587 struct TypeTraits<ExtensionType> {
0588   using ArrayType = ExtensionArray;
0589   using ScalarType = ExtensionScalar;
0590   constexpr static bool is_parameter_free = false;
0591 };
0592 /// @}
0593 
0594 namespace internal {
0595 
0596 template <typename... Ts>
0597 struct make_void {
0598   using type = void;
0599 };
0600 
0601 template <typename... Ts>
0602 using void_t = typename make_void<Ts...>::type;
0603 
0604 }  // namespace internal
0605 
0606 //
0607 // Useful type predicates
0608 //
0609 
0610 /// \addtogroup type-predicates
0611 /// @{
0612 
0613 // only in C++14
0614 template <bool B, typename T = void>
0615 using enable_if_t = typename std::enable_if<B, T>::type;
0616 
0617 template <typename T>
0618 using is_null_type = std::is_same<NullType, T>;
0619 
0620 template <typename T, typename R = void>
0621 using enable_if_null = enable_if_t<is_null_type<T>::value, R>;
0622 
0623 template <typename T>
0624 using is_boolean_type = std::is_same<BooleanType, T>;
0625 
0626 template <typename T, typename R = void>
0627 using enable_if_boolean = enable_if_t<is_boolean_type<T>::value, R>;
0628 
0629 template <typename T>
0630 using is_number_type = std::is_base_of<NumberType, T>;
0631 
0632 template <typename T, typename R = void>
0633 using enable_if_number = enable_if_t<is_number_type<T>::value, R>;
0634 
0635 template <typename T>
0636 using is_integer_type = std::is_base_of<IntegerType, T>;
0637 
0638 template <typename T, typename R = void>
0639 using enable_if_integer = enable_if_t<is_integer_type<T>::value, R>;
0640 
0641 template <typename T>
0642 using is_signed_integer_type =
0643     std::integral_constant<bool, is_integer_type<T>::value &&
0644                                      std::is_signed<typename T::c_type>::value>;
0645 
0646 template <typename T, typename R = void>
0647 using enable_if_signed_integer = enable_if_t<is_signed_integer_type<T>::value, R>;
0648 
0649 template <typename T>
0650 using is_unsigned_integer_type =
0651     std::integral_constant<bool, is_integer_type<T>::value &&
0652                                      std::is_unsigned<typename T::c_type>::value>;
0653 
0654 template <typename T, typename R = void>
0655 using enable_if_unsigned_integer = enable_if_t<is_unsigned_integer_type<T>::value, R>;
0656 
0657 // Note this will also include HalfFloatType which is represented by a
0658 // non-floating point primitive (uint16_t).
0659 template <typename T>
0660 using is_floating_type = std::is_base_of<FloatingPointType, T>;
0661 
0662 template <typename T, typename R = void>
0663 using enable_if_floating_point = enable_if_t<is_floating_type<T>::value, R>;
0664 
0665 // Half floats are special in that they behave physically like an unsigned
0666 // integer.
0667 template <typename T>
0668 using is_half_float_type = std::is_same<HalfFloatType, T>;
0669 
0670 template <typename T, typename R = void>
0671 using enable_if_half_float = enable_if_t<is_half_float_type<T>::value, R>;
0672 
0673 // Binary Types
0674 
0675 // Base binary refers to Binary/LargeBinary/String/LargeString
0676 template <typename T>
0677 using is_base_binary_type = std::is_base_of<BaseBinaryType, T>;
0678 
0679 template <typename T, typename R = void>
0680 using enable_if_base_binary = enable_if_t<is_base_binary_type<T>::value, R>;
0681 
0682 // Any binary excludes string from Base binary
0683 template <typename T>
0684 using is_binary_type =
0685     std::integral_constant<bool, std::is_same<BinaryType, T>::value ||
0686                                      std::is_same<LargeBinaryType, T>::value>;
0687 
0688 template <typename T, typename R = void>
0689 using enable_if_binary = enable_if_t<is_binary_type<T>::value, R>;
0690 
0691 template <typename T>
0692 using is_string_type =
0693     std::integral_constant<bool, std::is_same<StringType, T>::value ||
0694                                      std::is_same<LargeStringType, T>::value>;
0695 
0696 template <typename T, typename R = void>
0697 using enable_if_string = enable_if_t<is_string_type<T>::value, R>;
0698 
0699 template <typename T>
0700 using is_binary_view_like_type = std::is_base_of<BinaryViewType, T>;
0701 
0702 template <typename T>
0703 using is_binary_view_type = std::is_same<BinaryViewType, T>;
0704 
0705 template <typename T>
0706 using is_string_view_type = std::is_same<StringViewType, T>;
0707 
0708 template <typename T, typename R = void>
0709 using enable_if_binary_view_like = enable_if_t<is_binary_view_like_type<T>::value, R>;
0710 
0711 template <typename T, typename R = void>
0712 using enable_if_binary_view = enable_if_t<is_binary_view_type<T>::value, R>;
0713 
0714 template <typename T, typename R = void>
0715 using enable_if_string_view = enable_if_t<is_string_view_type<T>::value, R>;
0716 
0717 template <typename T>
0718 using is_string_like_type =
0719     std::integral_constant<bool, is_base_binary_type<T>::value && T::is_utf8>;
0720 
0721 template <typename T, typename R = void>
0722 using enable_if_string_like = enable_if_t<is_string_like_type<T>::value, R>;
0723 
0724 template <typename T, typename U, typename R = void>
0725 using enable_if_same = enable_if_t<std::is_same<T, U>::value, R>;
0726 
0727 // Note that this also includes DecimalType
0728 template <typename T>
0729 using is_fixed_size_binary_type = std::is_base_of<FixedSizeBinaryType, T>;
0730 
0731 template <typename T, typename R = void>
0732 using enable_if_fixed_size_binary = enable_if_t<is_fixed_size_binary_type<T>::value, R>;
0733 
0734 // This includes primitive, dictionary, and fixed-size-binary types
0735 template <typename T>
0736 using is_fixed_width_type = std::is_base_of<FixedWidthType, T>;
0737 
0738 template <typename T, typename R = void>
0739 using enable_if_fixed_width_type = enable_if_t<is_fixed_width_type<T>::value, R>;
0740 
0741 template <typename T>
0742 using is_binary_like_type =
0743     std::integral_constant<bool, (is_base_binary_type<T>::value &&
0744                                   !is_string_like_type<T>::value) ||
0745                                      is_fixed_size_binary_type<T>::value>;
0746 
0747 template <typename T, typename R = void>
0748 using enable_if_binary_like = enable_if_t<is_binary_like_type<T>::value, R>;
0749 
0750 template <typename T>
0751 using is_decimal_type = std::is_base_of<DecimalType, T>;
0752 
0753 template <typename T, typename R = void>
0754 using enable_if_decimal = enable_if_t<is_decimal_type<T>::value, R>;
0755 
0756 template <typename T>
0757 using is_decimal32_type = std::is_base_of<Decimal32Type, T>;
0758 
0759 template <typename T, typename R = void>
0760 using enable_if_decimal32 = enable_if_t<is_decimal32_type<T>::value, R>;
0761 
0762 template <typename T>
0763 using is_decimal64_type = std::is_base_of<Decimal64Type, T>;
0764 
0765 template <typename T, typename R = void>
0766 using enable_if_decimal64 = enable_if_t<is_decimal64_type<T>::value, R>;
0767 
0768 template <typename T>
0769 using is_decimal128_type = std::is_base_of<Decimal128Type, T>;
0770 
0771 template <typename T, typename R = void>
0772 using enable_if_decimal128 = enable_if_t<is_decimal128_type<T>::value, R>;
0773 
0774 template <typename T>
0775 using is_decimal256_type = std::is_base_of<Decimal256Type, T>;
0776 
0777 template <typename T, typename R = void>
0778 using enable_if_decimal256 = enable_if_t<is_decimal256_type<T>::value, R>;
0779 
0780 // Nested Types
0781 
0782 template <typename T>
0783 using is_nested_type = std::is_base_of<NestedType, T>;
0784 
0785 template <typename T, typename R = void>
0786 using enable_if_nested = enable_if_t<is_nested_type<T>::value, R>;
0787 
0788 template <typename T, typename R = void>
0789 using enable_if_not_nested = enable_if_t<!is_nested_type<T>::value, R>;
0790 
0791 template <typename T>
0792 using is_var_length_list_type =
0793     std::integral_constant<bool, std::is_base_of<LargeListType, T>::value ||
0794                                      std::is_base_of<ListType, T>::value>;
0795 
0796 template <typename T, typename R = void>
0797 using enable_if_var_size_list = enable_if_t<is_var_length_list_type<T>::value, R>;
0798 
0799 // DEPRECATED use is_var_length_list_type.
0800 template <typename T>
0801 using is_base_list_type = is_var_length_list_type<T>;
0802 
0803 // DEPRECATED use enable_if_var_size_list
0804 template <typename T, typename R = void>
0805 using enable_if_base_list = enable_if_var_size_list<T, R>;
0806 
0807 template <typename T>
0808 using is_fixed_size_list_type = std::is_same<FixedSizeListType, T>;
0809 
0810 template <typename T, typename R = void>
0811 using enable_if_fixed_size_list = enable_if_t<is_fixed_size_list_type<T>::value, R>;
0812 
0813 template <typename T>
0814 using is_list_type =
0815     std::integral_constant<bool, std::is_same<T, ListType>::value ||
0816                                      std::is_same<T, LargeListType>::value ||
0817                                      std::is_same<T, FixedSizeListType>::value>;
0818 
0819 template <typename T, typename R = void>
0820 using enable_if_list_type = enable_if_t<is_list_type<T>::value, R>;
0821 
0822 template <typename T>
0823 using is_list_view_type =
0824     std::disjunction<std::is_same<T, ListViewType>, std::is_same<T, LargeListViewType>>;
0825 
0826 template <typename T, typename R = void>
0827 using enable_if_list_view = enable_if_t<is_list_view_type<T>::value, R>;
0828 
0829 template <typename T>
0830 using is_list_like_type =
0831     std::integral_constant<bool, is_var_length_list_type<T>::value ||
0832                                      is_fixed_size_list_type<T>::value>;
0833 
0834 template <typename T, typename R = void>
0835 using enable_if_list_like = enable_if_t<is_list_like_type<T>::value, R>;
0836 
0837 template <typename T>
0838 using is_var_length_list_like_type =
0839     std::disjunction<is_var_length_list_type<T>, is_list_view_type<T>>;
0840 
0841 template <typename T, typename R = void>
0842 using enable_if_var_length_list_like =
0843     enable_if_t<is_var_length_list_like_type<T>::value, R>;
0844 
0845 template <typename T>
0846 using is_struct_type = std::is_base_of<StructType, T>;
0847 
0848 template <typename T, typename R = void>
0849 using enable_if_struct = enable_if_t<is_struct_type<T>::value, R>;
0850 
0851 template <typename T>
0852 using is_union_type = std::is_base_of<UnionType, T>;
0853 
0854 template <typename T, typename R = void>
0855 using enable_if_union = enable_if_t<is_union_type<T>::value, R>;
0856 
0857 // TemporalTypes
0858 
0859 template <typename T>
0860 using is_temporal_type = std::is_base_of<TemporalType, T>;
0861 
0862 template <typename T, typename R = void>
0863 using enable_if_temporal = enable_if_t<is_temporal_type<T>::value, R>;
0864 
0865 template <typename T>
0866 using is_date_type = std::is_base_of<DateType, T>;
0867 
0868 template <typename T, typename R = void>
0869 using enable_if_date = enable_if_t<is_date_type<T>::value, R>;
0870 
0871 template <typename T>
0872 using is_time_type = std::is_base_of<TimeType, T>;
0873 
0874 template <typename T, typename R = void>
0875 using enable_if_time = enable_if_t<is_time_type<T>::value, R>;
0876 
0877 template <typename T>
0878 using is_timestamp_type = std::is_base_of<TimestampType, T>;
0879 
0880 template <typename T, typename R = void>
0881 using enable_if_timestamp = enable_if_t<is_timestamp_type<T>::value, R>;
0882 
0883 template <typename T>
0884 using is_duration_type = std::is_base_of<DurationType, T>;
0885 
0886 template <typename T, typename R = void>
0887 using enable_if_duration = enable_if_t<is_duration_type<T>::value, R>;
0888 
0889 template <typename T>
0890 using is_interval_type = std::is_base_of<IntervalType, T>;
0891 
0892 template <typename T, typename R = void>
0893 using enable_if_interval = enable_if_t<is_interval_type<T>::value, R>;
0894 
0895 template <typename T>
0896 using is_run_end_encoded_type = std::is_base_of<RunEndEncodedType, T>;
0897 
0898 template <typename T, typename R = void>
0899 using enable_if_run_end_encoded = enable_if_t<is_run_end_encoded_type<T>::value, R>;
0900 
0901 template <typename T>
0902 using is_dictionary_type = std::is_base_of<DictionaryType, T>;
0903 
0904 template <typename T, typename R = void>
0905 using enable_if_dictionary = enable_if_t<is_dictionary_type<T>::value, R>;
0906 
0907 template <typename T>
0908 using is_extension_type = std::is_base_of<ExtensionType, T>;
0909 
0910 template <typename T, typename R = void>
0911 using enable_if_extension = enable_if_t<is_extension_type<T>::value, R>;
0912 
0913 // Attribute differentiation
0914 
0915 template <typename T>
0916 using is_primitive_ctype = std::is_base_of<PrimitiveCType, T>;
0917 
0918 template <typename T, typename R = void>
0919 using enable_if_primitive_ctype = enable_if_t<is_primitive_ctype<T>::value, R>;
0920 
0921 template <typename T>
0922 using has_c_type = std::integral_constant<bool, is_primitive_ctype<T>::value ||
0923                                                     is_temporal_type<T>::value>;
0924 
0925 template <typename T, typename R = void>
0926 using enable_if_has_c_type = enable_if_t<has_c_type<T>::value, R>;
0927 
0928 template <typename T>
0929 using has_string_view =
0930     std::integral_constant<bool, std::is_same<BinaryType, T>::value ||
0931                                      std::is_same<BinaryViewType, T>::value ||
0932                                      std::is_same<LargeBinaryType, T>::value ||
0933                                      std::is_same<StringType, T>::value ||
0934                                      std::is_same<StringViewType, T>::value ||
0935                                      std::is_same<LargeStringType, T>::value ||
0936                                      std::is_same<FixedSizeBinaryType, T>::value>;
0937 
0938 template <typename T, typename R = void>
0939 using enable_if_has_string_view = enable_if_t<has_string_view<T>::value, R>;
0940 
0941 template <typename T>
0942 using is_8bit_int = std::integral_constant<bool, std::is_same<UInt8Type, T>::value ||
0943                                                      std::is_same<Int8Type, T>::value>;
0944 
0945 template <typename T, typename R = void>
0946 using enable_if_8bit_int = enable_if_t<is_8bit_int<T>::value, R>;
0947 
0948 template <typename T>
0949 using is_parameter_free_type =
0950     std::integral_constant<bool, TypeTraits<T>::is_parameter_free>;
0951 
0952 template <typename T, typename R = void>
0953 using enable_if_parameter_free = enable_if_t<is_parameter_free_type<T>::value, R>;
0954 
0955 // Physical representation quirks
0956 
0957 template <typename T>
0958 using is_physical_signed_integer_type =
0959     std::integral_constant<bool,
0960                            is_signed_integer_type<T>::value ||
0961                                (is_temporal_type<T>::value && has_c_type<T>::value &&
0962                                 std::is_integral<typename T::c_type>::value)>;
0963 
0964 template <typename T, typename R = void>
0965 using enable_if_physical_signed_integer =
0966     enable_if_t<is_physical_signed_integer_type<T>::value, R>;
0967 
0968 template <typename T>
0969 using is_physical_unsigned_integer_type =
0970     std::integral_constant<bool, is_unsigned_integer_type<T>::value ||
0971                                      is_half_float_type<T>::value>;
0972 
0973 template <typename T, typename R = void>
0974 using enable_if_physical_unsigned_integer =
0975     enable_if_t<is_physical_unsigned_integer_type<T>::value, R>;
0976 
0977 template <typename T>
0978 using is_physical_integer_type =
0979     std::integral_constant<bool, is_physical_unsigned_integer_type<T>::value ||
0980                                      is_physical_signed_integer_type<T>::value>;
0981 
0982 template <typename T, typename R = void>
0983 using enable_if_physical_integer = enable_if_t<is_physical_integer_type<T>::value, R>;
0984 
0985 // Like is_floating_type but excluding half-floats which don't have a
0986 // float-like c type.
0987 template <typename T>
0988 using is_physical_floating_type =
0989     std::integral_constant<bool,
0990                            is_floating_type<T>::value && !is_half_float_type<T>::value>;
0991 
0992 template <typename T, typename R = void>
0993 using enable_if_physical_floating_point =
0994     enable_if_t<is_physical_floating_type<T>::value, R>;
0995 
0996 /// @}
0997 
0998 /// \addtogroup runtime-type-predicates
0999 /// @{
1000 
1001 /// \brief Check for an integer type (signed or unsigned)
1002 ///
1003 /// \param[in] type_id the type-id to check
1004 /// \return whether type-id is an integer type one
1005 constexpr bool is_integer(Type::type type_id) {
1006   switch (type_id) {
1007     case Type::UINT8:
1008     case Type::INT8:
1009     case Type::UINT16:
1010     case Type::INT16:
1011     case Type::UINT32:
1012     case Type::INT32:
1013     case Type::UINT64:
1014     case Type::INT64:
1015       return true;
1016     default:
1017       break;
1018   }
1019   return false;
1020 }
1021 
1022 /// \brief Check for a signed integer type
1023 ///
1024 /// \param[in] type_id the type-id to check
1025 /// \return whether type-id is a signed integer type one
1026 constexpr bool is_signed_integer(Type::type type_id) {
1027   switch (type_id) {
1028     case Type::INT8:
1029     case Type::INT16:
1030     case Type::INT32:
1031     case Type::INT64:
1032       return true;
1033     default:
1034       break;
1035   }
1036   return false;
1037 }
1038 
1039 /// \brief Check for an unsigned integer type
1040 ///
1041 /// \param[in] type_id the type-id to check
1042 /// \return whether type-id is an unsigned integer type one
1043 constexpr bool is_unsigned_integer(Type::type type_id) {
1044   switch (type_id) {
1045     case Type::UINT8:
1046     case Type::UINT16:
1047     case Type::UINT32:
1048     case Type::UINT64:
1049       return true;
1050     default:
1051       break;
1052   }
1053   return false;
1054 }
1055 
1056 /// \brief Check for a floating point type
1057 ///
1058 /// \param[in] type_id the type-id to check
1059 /// \return whether type-id is a floating point type one
1060 constexpr bool is_floating(Type::type type_id) {
1061   switch (type_id) {
1062     case Type::HALF_FLOAT:
1063     case Type::FLOAT:
1064     case Type::DOUBLE:
1065       return true;
1066     default:
1067       break;
1068   }
1069   return false;
1070 }
1071 
1072 /// \brief Check for a numeric type
1073 ///
1074 /// This predicate doesn't match decimals (see `is_decimal`).
1075 ///
1076 /// \param[in] type_id the type-id to check
1077 /// \return whether type-id is a numeric type one
1078 constexpr bool is_numeric(Type::type type_id) {
1079   switch (type_id) {
1080     case Type::UINT8:
1081     case Type::INT8:
1082     case Type::UINT16:
1083     case Type::INT16:
1084     case Type::UINT32:
1085     case Type::INT32:
1086     case Type::UINT64:
1087     case Type::INT64:
1088     case Type::HALF_FLOAT:
1089     case Type::FLOAT:
1090     case Type::DOUBLE:
1091       return true;
1092     default:
1093       break;
1094   }
1095   return false;
1096 }
1097 
1098 /// \brief Check for a decimal type
1099 ///
1100 /// \param[in] type_id the type-id to check
1101 /// \return whether type-id is a decimal type one
1102 constexpr bool is_decimal(Type::type type_id) {
1103   switch (type_id) {
1104     case Type::DECIMAL32:
1105     case Type::DECIMAL64:
1106     case Type::DECIMAL128:
1107     case Type::DECIMAL256:
1108       return true;
1109     default:
1110       break;
1111   }
1112   return false;
1113 }
1114 
1115 /// \brief Check for a type that can be used as a run-end in Run-End Encoded
1116 /// arrays
1117 ///
1118 /// \param[in] type_id the type-id to check
1119 /// \return whether type-id can represent a run-end value
1120 constexpr bool is_run_end_type(Type::type type_id) {
1121   switch (type_id) {
1122     case Type::INT16:
1123     case Type::INT32:
1124     case Type::INT64:
1125       return true;
1126     default:
1127       break;
1128   }
1129   return false;
1130 }
1131 
1132 /// \brief Check for a primitive type
1133 ///
1134 /// This predicate doesn't match null, decimals and binary-like types.
1135 ///
1136 /// \param[in] type_id the type-id to check
1137 /// \return whether type-id is a primitive type one
1138 constexpr bool is_primitive(Type::type type_id) {
1139   switch (type_id) {
1140     case Type::BOOL:
1141     case Type::UINT8:
1142     case Type::INT8:
1143     case Type::UINT16:
1144     case Type::INT16:
1145     case Type::UINT32:
1146     case Type::INT32:
1147     case Type::UINT64:
1148     case Type::INT64:
1149     case Type::HALF_FLOAT:
1150     case Type::FLOAT:
1151     case Type::DOUBLE:
1152     case Type::DATE32:
1153     case Type::DATE64:
1154     case Type::TIME32:
1155     case Type::TIME64:
1156     case Type::TIMESTAMP:
1157     case Type::DURATION:
1158     case Type::INTERVAL_MONTHS:
1159     case Type::INTERVAL_MONTH_DAY_NANO:
1160     case Type::INTERVAL_DAY_TIME:
1161       return true;
1162     default:
1163       break;
1164   }
1165   return false;
1166 }
1167 
1168 /// \brief Check for a base-binary-like type
1169 ///
1170 /// This predicate doesn't match fixed-size binary types and will otherwise
1171 /// match all binary- and string-like types regardless of offset width.
1172 ///
1173 /// \param[in] type_id the type-id to check
1174 /// \return whether type-id is a base-binary-like type one
1175 constexpr bool is_base_binary_like(Type::type type_id) {
1176   switch (type_id) {
1177     case Type::BINARY:
1178     case Type::LARGE_BINARY:
1179     case Type::STRING:
1180     case Type::LARGE_STRING:
1181       return true;
1182     default:
1183       break;
1184   }
1185   return false;
1186 }
1187 
1188 /// \brief Check for a binary-like type (i.e. with 32-bit offsets)
1189 ///
1190 /// \param[in] type_id the type-id to check
1191 /// \return whether type-id is a binary-like type one
1192 constexpr bool is_binary_like(Type::type type_id) {
1193   switch (type_id) {
1194     case Type::BINARY:
1195     case Type::STRING:
1196       return true;
1197     default:
1198       break;
1199   }
1200   return false;
1201 }
1202 
1203 /// \brief Check for a large-binary-like type (i.e. with 64-bit offsets)
1204 ///
1205 /// \param[in] type_id the type-id to check
1206 /// \return whether type-id is a large-binary-like type one
1207 constexpr bool is_large_binary_like(Type::type type_id) {
1208   switch (type_id) {
1209     case Type::LARGE_BINARY:
1210     case Type::LARGE_STRING:
1211       return true;
1212     default:
1213       break;
1214   }
1215   return false;
1216 }
1217 
1218 /// \brief Check for a binary (non-string) type
1219 ///
1220 /// \param[in] type_id the type-id to check
1221 /// \return whether type-id is a binary type one
1222 constexpr bool is_binary(Type::type type_id) {
1223   switch (type_id) {
1224     case Type::BINARY:
1225     case Type::LARGE_BINARY:
1226       return true;
1227     default:
1228       break;
1229   }
1230   return false;
1231 }
1232 
1233 /// \brief Check for a string type
1234 ///
1235 /// \param[in] type_id the type-id to check
1236 /// \return whether type-id is a string type one
1237 constexpr bool is_string(Type::type type_id) {
1238   switch (type_id) {
1239     case Type::STRING:
1240     case Type::LARGE_STRING:
1241       return true;
1242     default:
1243       break;
1244   }
1245   return false;
1246 }
1247 
1248 /// \brief Check for a binary-view-like type (i.e. string view and binary view)
1249 ///
1250 /// \param[in] type_id the type-id to check
1251 /// \return whether type-id is a binary-view-like type one
1252 constexpr bool is_binary_view_like(Type::type type_id) {
1253   switch (type_id) {
1254     case Type::STRING_VIEW:
1255     case Type::BINARY_VIEW:
1256       return true;
1257     default:
1258       break;
1259   }
1260   return false;
1261 }
1262 
1263 /// \brief Check for a temporal type
1264 ///
1265 /// \param[in] type_id the type-id to check
1266 /// \return whether type-id is a temporal type one
1267 constexpr bool is_temporal(Type::type type_id) {
1268   switch (type_id) {
1269     case Type::DATE32:
1270     case Type::DATE64:
1271     case Type::TIME32:
1272     case Type::TIME64:
1273     case Type::TIMESTAMP:
1274       return true;
1275     default:
1276       break;
1277   }
1278   return false;
1279 }
1280 
1281 /// \brief Check for a time type
1282 ///
1283 /// \param[in] type_id the type-id to check
1284 /// \return whether type-id is a primitive type one
1285 constexpr bool is_time(Type::type type_id) {
1286   switch (type_id) {
1287     case Type::TIME32:
1288     case Type::TIME64:
1289       return true;
1290     default:
1291       break;
1292   }
1293   return false;
1294 }
1295 
1296 /// \brief Check for a date type
1297 ///
1298 /// \param[in] type_id the type-id to check
1299 /// \return whether type-id is a primitive type one
1300 constexpr bool is_date(Type::type type_id) {
1301   switch (type_id) {
1302     case Type::DATE32:
1303     case Type::DATE64:
1304       return true;
1305     default:
1306       break;
1307   }
1308   return false;
1309 }
1310 
1311 /// \brief Check for an interval type
1312 ///
1313 /// \param[in] type_id the type-id to check
1314 /// \return whether type-id is an interval type one
1315 constexpr bool is_interval(Type::type type_id) {
1316   switch (type_id) {
1317     case Type::INTERVAL_MONTHS:
1318     case Type::INTERVAL_DAY_TIME:
1319     case Type::INTERVAL_MONTH_DAY_NANO:
1320       return true;
1321     default:
1322       break;
1323   }
1324   return false;
1325 }
1326 
1327 /// \brief Check for a dictionary type
1328 ///
1329 /// \param[in] type_id the type-id to check
1330 /// \return whether type-id is a dictionary type one
1331 constexpr bool is_dictionary(Type::type type_id) { return type_id == Type::DICTIONARY; }
1332 
1333 /// \brief Check for a fixed-size-binary type
1334 ///
1335 /// This predicate also matches decimals.
1336 /// \param[in] type_id the type-id to check
1337 /// \return whether type-id is a fixed-size-binary type one
1338 constexpr bool is_fixed_size_binary(Type::type type_id) {
1339   switch (type_id) {
1340     case Type::DECIMAL32:
1341     case Type::DECIMAL64:
1342     case Type::DECIMAL128:
1343     case Type::DECIMAL256:
1344     case Type::FIXED_SIZE_BINARY:
1345       return true;
1346     default:
1347       break;
1348   }
1349   return false;
1350 }
1351 
1352 /// \brief Check for a fixed-width type
1353 ///
1354 /// \param[in] type_id the type-id to check
1355 /// \return whether type-id is a fixed-width type one
1356 constexpr bool is_fixed_width(Type::type type_id) {
1357   return is_primitive(type_id) || is_dictionary(type_id) || is_fixed_size_binary(type_id);
1358 }
1359 
1360 /// \brief Check for a variable-length list type
1361 ///
1362 /// \param[in] type_id the type-id to check
1363 /// \return whether type-id is a variable-length list type one
1364 constexpr bool is_var_length_list(Type::type type_id) {
1365   switch (type_id) {
1366     case Type::LIST:
1367     case Type::LARGE_LIST:
1368     case Type::MAP:
1369       return true;
1370     default:
1371       break;
1372   }
1373   return false;
1374 }
1375 
1376 /// \brief Check for a list type
1377 ///
1378 /// \param[in] type_id the type-id to check
1379 /// \return whether type-id is a list type one
1380 constexpr bool is_list(Type::type type_id) {
1381   switch (type_id) {
1382     case Type::LIST:
1383     case Type::LARGE_LIST:
1384     case Type::FIXED_SIZE_LIST:
1385       return true;
1386     default:
1387       break;
1388   }
1389   return false;
1390 }
1391 
1392 /// \brief Check for a list-like type
1393 ///
1394 /// \param[in] type_id the type-id to check
1395 /// \return whether type-id is a list-like type one
1396 constexpr bool is_list_like(Type::type type_id) {
1397   switch (type_id) {
1398     case Type::LIST:
1399     case Type::LARGE_LIST:
1400     case Type::FIXED_SIZE_LIST:
1401     case Type::MAP:
1402       return true;
1403     default:
1404       break;
1405   }
1406   return false;
1407 }
1408 
1409 /// \brief Check for a var-length list or list-view like type
1410 ///
1411 /// \param[in] type_id the type-id to check
1412 /// \return whether type-id is a var-length list or list-view like type
1413 constexpr bool is_var_length_list_like(Type::type type_id) {
1414   switch (type_id) {
1415     case Type::LIST:
1416     case Type::LARGE_LIST:
1417     case Type::LIST_VIEW:
1418     case Type::LARGE_LIST_VIEW:
1419     case Type::MAP:
1420       return true;
1421     default:
1422       break;
1423   }
1424   return false;
1425 }
1426 
1427 /// \brief Check for a list-view type
1428 ///
1429 /// \param[in] type_id the type-id to check
1430 /// \return whether type-id is a list-view type one
1431 constexpr bool is_list_view(Type::type type_id) {
1432   switch (type_id) {
1433     case Type::LIST_VIEW:
1434     case Type::LARGE_LIST_VIEW:
1435       return true;
1436     default:
1437       break;
1438   }
1439   return false;
1440 }
1441 
1442 /// \brief Check for a nested type
1443 ///
1444 /// \param[in] type_id the type-id to check
1445 /// \return whether type-id is a nested type one
1446 constexpr bool is_nested(Type::type type_id) {
1447   switch (type_id) {
1448     case Type::LIST:
1449     case Type::LARGE_LIST:
1450     case Type::LIST_VIEW:
1451     case Type::LARGE_LIST_VIEW:
1452     case Type::FIXED_SIZE_LIST:
1453     case Type::MAP:
1454     case Type::STRUCT:
1455     case Type::SPARSE_UNION:
1456     case Type::DENSE_UNION:
1457     case Type::RUN_END_ENCODED:
1458       return true;
1459     default:
1460       break;
1461   }
1462   return false;
1463 }
1464 
1465 /// \brief Check for a union type
1466 ///
1467 /// \param[in] type_id the type-id to check
1468 /// \return whether type-id is a union type one
1469 constexpr bool is_union(Type::type type_id) {
1470   switch (type_id) {
1471     case Type::SPARSE_UNION:
1472     case Type::DENSE_UNION:
1473       return true;
1474     default:
1475       break;
1476   }
1477   return false;
1478 }
1479 
1480 /// \brief Return the values bit width of a type
1481 ///
1482 /// \param[in] type_id the type-id to check
1483 /// \return the values bit width, or 0 if the type does not have fixed-width values
1484 ///
1485 /// For Type::FIXED_SIZE_BINARY, you will instead need to inspect the concrete
1486 /// DataType to get this information.
1487 static inline int bit_width(Type::type type_id) {
1488   switch (type_id) {
1489     case Type::BOOL:
1490       return 1;
1491     case Type::UINT8:
1492     case Type::INT8:
1493       return 8;
1494     case Type::UINT16:
1495     case Type::INT16:
1496       return 16;
1497     case Type::UINT32:
1498     case Type::INT32:
1499     case Type::DATE32:
1500     case Type::TIME32:
1501       return 32;
1502     case Type::UINT64:
1503     case Type::INT64:
1504     case Type::DATE64:
1505     case Type::TIME64:
1506     case Type::TIMESTAMP:
1507     case Type::DURATION:
1508       return 64;
1509 
1510     case Type::HALF_FLOAT:
1511       return 16;
1512     case Type::FLOAT:
1513       return 32;
1514     case Type::DOUBLE:
1515       return 64;
1516 
1517     case Type::INTERVAL_MONTHS:
1518       return 32;
1519     case Type::INTERVAL_DAY_TIME:
1520       return 64;
1521     case Type::INTERVAL_MONTH_DAY_NANO:
1522       return 128;
1523 
1524     case Type::DECIMAL32:
1525       return 32;
1526     case Type::DECIMAL64:
1527       return 64;
1528     case Type::DECIMAL128:
1529       return 128;
1530     case Type::DECIMAL256:
1531       return 256;
1532 
1533     default:
1534       break;
1535   }
1536   return 0;
1537 }
1538 
1539 /// \brief Return the offsets bit width of a type
1540 ///
1541 /// \param[in] type_id the type-id to check
1542 /// \return the offsets bit width, or 0 if the type does not have offsets
1543 static inline int offset_bit_width(Type::type type_id) {
1544   switch (type_id) {
1545     case Type::STRING:
1546     case Type::BINARY:
1547     case Type::LIST:
1548     case Type::LIST_VIEW:
1549     case Type::MAP:
1550     case Type::DENSE_UNION:
1551       return 32;
1552     case Type::LARGE_STRING:
1553     case Type::LARGE_BINARY:
1554     case Type::LARGE_LIST:
1555     case Type::LARGE_LIST_VIEW:
1556       return 64;
1557     default:
1558       break;
1559   }
1560   return 0;
1561 }
1562 
1563 /// \brief Get the alignment a buffer should have to be considered "value aligned"
1564 ///
1565 /// Some buffers are frequently type-punned.  For example, in an int32 array the
1566 /// values buffer is frequently cast to int32_t*
1567 ///
1568 /// This sort of punning is technically only valid if the pointer is aligned to a
1569 /// proper width (e.g. 4 bytes in the case of int32).  However, most modern compilers
1570 /// are quite permissive if we get this wrong.  Note that this alignment is something
1571 /// that is guaranteed by malloc (e.g. new int32_t[] will return a buffer that is 4
1572 /// byte aligned) or common libraries (e.g. numpy) but it is not currently guaranteed
1573 /// by flight (GH-32276).
1574 ///
1575 /// We call this "value aligned" and this method will calculate that required alignment.
1576 ///
1577 /// \param type_id the type of the array containing the buffer
1578 ///                Note: this should be the indices type for a dictionary array since
1579 ///                A dictionary array's buffers are indices.  It should be the storage
1580 ///                type for an extension array.
1581 /// \param buffer_index the index of the buffer to check, for example 0 will typically
1582 ///                     give you the alignment expected of the validity buffer
1583 /// \return the required value alignment in bytes (1 if no alignment required)
1584 int RequiredValueAlignmentForBuffer(Type::type type_id, int buffer_index);
1585 
1586 /// \brief Check for an integer type (signed or unsigned)
1587 ///
1588 /// \param[in] type the type to check
1589 /// \return whether type is an integer type
1590 ///
1591 /// Convenience for checking using the type's id
1592 static inline bool is_integer(const DataType& type) { return is_integer(type.id()); }
1593 
1594 /// \brief Check for a signed integer type
1595 ///
1596 /// \param[in] type the type to check
1597 /// \return whether type is a signed integer type
1598 ///
1599 /// Convenience for checking using the type's id
1600 static inline bool is_signed_integer(const DataType& type) {
1601   return is_signed_integer(type.id());
1602 }
1603 
1604 /// \brief Check for an unsigned integer type
1605 ///
1606 /// \param[in] type the type to check
1607 /// \return whether type is an unsigned integer type
1608 ///
1609 /// Convenience for checking using the type's id
1610 static inline bool is_unsigned_integer(const DataType& type) {
1611   return is_unsigned_integer(type.id());
1612 }
1613 
1614 /// \brief Check for a floating point type
1615 ///
1616 /// \param[in] type the type to check
1617 /// \return whether type is a floating point type
1618 ///
1619 /// Convenience for checking using the type's id
1620 static inline bool is_floating(const DataType& type) { return is_floating(type.id()); }
1621 
1622 /// \brief Check for a numeric type (number except boolean type)
1623 ///
1624 /// \param[in] type the type to check
1625 /// \return whether type is a numeric type
1626 ///
1627 /// Convenience for checking using the type's id
1628 static inline bool is_numeric(const DataType& type) { return is_numeric(type.id()); }
1629 
1630 /// \brief Check for a decimal type
1631 ///
1632 /// \param[in] type the type to check
1633 /// \return whether type is a decimal type
1634 ///
1635 /// Convenience for checking using the type's id
1636 static inline bool is_decimal(const DataType& type) { return is_decimal(type.id()); }
1637 
1638 /// \brief Check for a primitive type
1639 ///
1640 /// \param[in] type the type to check
1641 /// \return whether type is a primitive type
1642 ///
1643 /// Convenience for checking using the type's id
1644 static inline bool is_primitive(const DataType& type) { return is_primitive(type.id()); }
1645 
1646 /// \brief Check for a binary or string-like type (except fixed-size binary)
1647 ///
1648 /// \param[in] type the type to check
1649 /// \return whether type is a binary or string-like type
1650 ///
1651 /// Convenience for checking using the type's id
1652 static inline bool is_base_binary_like(const DataType& type) {
1653   return is_base_binary_like(type.id());
1654 }
1655 
1656 /// \brief Check for a binary-like type
1657 ///
1658 /// \param[in] type the type to check
1659 /// \return whether type is a binary-like type
1660 ///
1661 /// Convenience for checking using the type's id
1662 static inline bool is_binary_like(const DataType& type) {
1663   return is_binary_like(type.id());
1664 }
1665 
1666 /// \brief Check for a large-binary-like type
1667 ///
1668 /// \param[in] type the type to check
1669 /// \return whether type is a large-binary-like type
1670 ///
1671 /// Convenience for checking using the type's id
1672 static inline bool is_large_binary_like(const DataType& type) {
1673   return is_large_binary_like(type.id());
1674 }
1675 
1676 /// \brief Check for a binary type
1677 ///
1678 /// \param[in] type the type to check
1679 /// \return whether type is a binary type
1680 ///
1681 /// Convenience for checking using the type's id
1682 static inline bool is_binary(const DataType& type) { return is_binary(type.id()); }
1683 
1684 /// \brief Check for a string type
1685 ///
1686 /// \param[in] type the type to check
1687 /// \return whether type is a string type
1688 ///
1689 /// Convenience for checking using the type's id
1690 static inline bool is_string(const DataType& type) { return is_string(type.id()); }
1691 
1692 /// \brief Check for a binary-view-like type
1693 ///
1694 /// \param[in] type the type to check
1695 /// \return whether type is a binary-view-like type
1696 ///
1697 /// Convenience for checking using the type's id
1698 static inline bool is_binary_view_like(const DataType& type) {
1699   return is_binary_view_like(type.id());
1700 }
1701 
1702 /// \brief Check for a temporal type, including time and timestamps for each unit
1703 ///
1704 /// \param[in] type the type to check
1705 /// \return whether type is a temporal type
1706 ///
1707 /// Convenience for checking using the type's id
1708 static inline bool is_temporal(const DataType& type) { return is_temporal(type.id()); }
1709 
1710 /// \brief Check for an interval type
1711 ///
1712 /// \param[in] type the type to check
1713 /// \return whether type is a interval type
1714 ///
1715 /// Convenience for checking using the type's id
1716 static inline bool is_interval(const DataType& type) { return is_interval(type.id()); }
1717 
1718 /// \brief Check for a dictionary type
1719 ///
1720 /// \param[in] type the type to check
1721 /// \return whether type is a dictionary type
1722 ///
1723 /// Convenience for checking using the type's id
1724 static inline bool is_dictionary(const DataType& type) {
1725   return is_dictionary(type.id());
1726 }
1727 
1728 /// \brief Check for a fixed-size-binary type
1729 ///
1730 /// \param[in] type the type to check
1731 /// \return whether type is a fixed-size-binary type
1732 ///
1733 /// Convenience for checking using the type's id
1734 static inline bool is_fixed_size_binary(const DataType& type) {
1735   return is_fixed_size_binary(type.id());
1736 }
1737 
1738 /// \brief Check for a fixed-width type
1739 ///
1740 /// \param[in] type the type to check
1741 /// \return whether type is a fixed-width type
1742 ///
1743 /// Convenience for checking using the type's id
1744 static inline bool is_fixed_width(const DataType& type) {
1745   return is_fixed_width(type.id());
1746 }
1747 
1748 /// \brief Check for a variable-length list type
1749 ///
1750 /// \param[in] type the type to check
1751 /// \return whether type is a variable-length list type
1752 ///
1753 /// Convenience for checking using the type's id
1754 static inline bool is_var_length_list(const DataType& type) {
1755   return is_var_length_list(type.id());
1756 }
1757 
1758 /// \brief Check for a list-like type
1759 ///
1760 /// \param[in] type the type to check
1761 /// \return whether type is a list-like type
1762 ///
1763 /// Convenience for checking using the type's id
1764 static inline bool is_list_like(const DataType& type) { return is_list_like(type.id()); }
1765 
1766 /// \brief Check for a var-length list or list-view like type
1767 ///
1768 /// \param[in] type the type to check
1769 /// \return whether type is a var-length list or list-view like type
1770 ///
1771 /// Convenience for checking using the type's id
1772 static inline bool is_var_length_list_like(const DataType& type) {
1773   return is_var_length_list_like(type.id());
1774 }
1775 
1776 /// \brief Check for a list-view type
1777 ///
1778 /// \param[in] type the type to check
1779 /// \return whether type is a list-view type
1780 ///
1781 /// Convenience for checking using the type's id
1782 static inline bool is_list_view(const DataType& type) { return is_list_view(type.id()); }
1783 
1784 /// \brief Check for a nested type
1785 ///
1786 /// \param[in] type the type to check
1787 /// \return whether type is a nested type
1788 ///
1789 /// Convenience for checking using the type's id
1790 static inline bool is_nested(const DataType& type) { return is_nested(type.id()); }
1791 
1792 /// \brief Check for a union type
1793 ///
1794 /// \param[in] type the type to check
1795 /// \return whether type is a union type
1796 ///
1797 /// Convenience for checking using the type's id
1798 static inline bool is_union(const DataType& type) { return is_union(type.id()); }
1799 
1800 /// @}
1801 
1802 }  // namespace arrow