Back to home page

EIC code displayed by LXR

 
 

    


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

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 // Object model for scalar (non-Array) values. Not intended for use with large
0019 // amounts of data
0020 
0021 #pragma once
0022 
0023 #include <iosfwd>
0024 #include <memory>
0025 #include <ratio>
0026 #include <string>
0027 #include <string_view>
0028 #include <utility>
0029 #include <vector>
0030 
0031 #include "arrow/compare.h"
0032 #include "arrow/extension_type.h"
0033 #include "arrow/result.h"
0034 #include "arrow/status.h"
0035 #include "arrow/type.h"
0036 #include "arrow/type_fwd.h"
0037 #include "arrow/type_traits.h"
0038 #include "arrow/util/compare.h"
0039 #include "arrow/util/decimal.h"
0040 #include "arrow/util/visibility.h"
0041 #include "arrow/visit_type_inline.h"
0042 
0043 namespace arrow {
0044 
0045 class Array;
0046 
0047 /// \brief Base class for scalar values
0048 ///
0049 /// A Scalar represents a single value with a specific DataType.
0050 /// Scalars are useful for passing single value inputs to compute functions,
0051 /// or for representing individual array elements (with a non-trivial
0052 /// wrapping cost, though).
0053 struct ARROW_EXPORT Scalar : public std::enable_shared_from_this<Scalar>,
0054                              public util::EqualityComparable<Scalar> {
0055   virtual ~Scalar() = default;
0056 
0057   /// \brief The type of the scalar value
0058   std::shared_ptr<DataType> type;
0059 
0060   /// \brief Whether the value is valid (not null) or not
0061   bool is_valid = false;
0062 
0063   bool Equals(const Scalar& other,
0064               const EqualOptions& options = EqualOptions::Defaults()) const;
0065 
0066   bool ApproxEquals(const Scalar& other,
0067                     const EqualOptions& options = EqualOptions::Defaults()) const;
0068 
0069   struct ARROW_EXPORT Hash {
0070     size_t operator()(const Scalar& scalar) const { return scalar.hash(); }
0071 
0072     size_t operator()(const std::shared_ptr<Scalar>& scalar) const {
0073       return scalar->hash();
0074     }
0075   };
0076 
0077   size_t hash() const;
0078 
0079   std::string ToString() const;
0080 
0081   /// \brief Perform cheap validation checks
0082   ///
0083   /// This is O(k) where k is the number of descendents.
0084   ///
0085   /// \return Status
0086   Status Validate() const;
0087 
0088   /// \brief Perform extensive data validation checks
0089   ///
0090   /// This is potentially O(k*n) where k is the number of descendents and n
0091   /// is the length of descendents (if list scalars are involved).
0092   ///
0093   /// \return Status
0094   Status ValidateFull() const;
0095 
0096   static Result<std::shared_ptr<Scalar>> Parse(const std::shared_ptr<DataType>& type,
0097                                                std::string_view repr);
0098 
0099   // TODO(bkietz) add compute::CastOptions
0100   Result<std::shared_ptr<Scalar>> CastTo(std::shared_ptr<DataType> to) const;
0101 
0102   /// \brief Apply the ScalarVisitor::Visit() method specialized to the scalar type
0103   Status Accept(ScalarVisitor* visitor) const;
0104 
0105   /// \brief EXPERIMENTAL Enable obtaining shared_ptr<Scalar> from a const
0106   /// Scalar& context.
0107   std::shared_ptr<Scalar> GetSharedPtr() const {
0108     return const_cast<Scalar*>(this)->shared_from_this();
0109   }
0110 
0111  protected:
0112   Scalar(std::shared_ptr<DataType> type, bool is_valid)
0113       : type(std::move(type)), is_valid(is_valid) {}
0114 };
0115 
0116 ARROW_EXPORT void PrintTo(const Scalar& scalar, std::ostream* os);
0117 
0118 /// \defgroup concrete-scalar-classes Concrete Scalar subclasses
0119 ///
0120 /// @{
0121 
0122 /// \brief A scalar value for NullType. Never valid
0123 struct ARROW_EXPORT NullScalar : public Scalar {
0124  public:
0125   using TypeClass = NullType;
0126 
0127   NullScalar() : Scalar{null(), false} {}
0128 };
0129 
0130 /// @}
0131 
0132 namespace internal {
0133 
0134 constexpr auto kScalarScratchSpaceSize = sizeof(int64_t) * 2;
0135 
0136 template <typename Impl>
0137 struct ArraySpanFillFromScalarScratchSpace {
0138   //  16 bytes of scratch space to enable ArraySpan to be a view onto any
0139   //  Scalar- including binary scalars where we need to create a buffer
0140   //  that looks like two 32-bit or 64-bit offsets.
0141   alignas(int64_t) mutable uint8_t scratch_space_[kScalarScratchSpaceSize];
0142 
0143  private:
0144   template <typename... Args>
0145   explicit ArraySpanFillFromScalarScratchSpace(Args&&... args) {
0146     Impl::FillScratchSpace(scratch_space_, std::forward<Args>(args)...);
0147   }
0148 
0149   ArraySpanFillFromScalarScratchSpace() = delete;
0150 
0151   friend Impl;
0152 };
0153 
0154 struct ARROW_EXPORT PrimitiveScalarBase : public Scalar {
0155   explicit PrimitiveScalarBase(std::shared_ptr<DataType> type)
0156       : Scalar(std::move(type), false) {}
0157 
0158   using Scalar::Scalar;
0159   /// \brief Get a const pointer to the value of this scalar. May be null.
0160   virtual const void* data() const = 0;
0161   /// \brief Get an immutable view of the value of this scalar as bytes.
0162   virtual std::string_view view() const = 0;
0163 };
0164 
0165 template <typename T, typename CType = typename T::c_type>
0166 struct PrimitiveScalar : public PrimitiveScalarBase {
0167   using PrimitiveScalarBase::PrimitiveScalarBase;
0168   using TypeClass = T;
0169   using ValueType = CType;
0170 
0171   // Non-null constructor.
0172   PrimitiveScalar(ValueType value, std::shared_ptr<DataType> type)
0173       : PrimitiveScalarBase(std::move(type), true), value(value) {}
0174 
0175   explicit PrimitiveScalar(std::shared_ptr<DataType> type)
0176       : PrimitiveScalarBase(std::move(type), false) {}
0177 
0178   ValueType value{};
0179 
0180   const void* data() const override { return &value; }
0181   std::string_view view() const override {
0182     return std::string_view(reinterpret_cast<const char*>(&value), sizeof(ValueType));
0183   };
0184 };
0185 
0186 }  // namespace internal
0187 
0188 /// \addtogroup concrete-scalar-classes Concrete Scalar subclasses
0189 ///
0190 /// @{
0191 
0192 struct ARROW_EXPORT BooleanScalar : public internal::PrimitiveScalar<BooleanType, bool> {
0193   using Base = internal::PrimitiveScalar<BooleanType, bool>;
0194   using Base::Base;
0195 
0196   explicit BooleanScalar(bool value) : Base(value, boolean()) {}
0197 
0198   BooleanScalar() : Base(boolean()) {}
0199 };
0200 
0201 template <typename T>
0202 struct NumericScalar : public internal::PrimitiveScalar<T> {
0203   using Base = typename internal::PrimitiveScalar<T>;
0204   using Base::Base;
0205   using TypeClass = typename Base::TypeClass;
0206   using ValueType = typename Base::ValueType;
0207 
0208   explicit NumericScalar(ValueType value)
0209       : Base(value, TypeTraits<T>::type_singleton()) {}
0210 
0211   NumericScalar() : Base(TypeTraits<T>::type_singleton()) {}
0212 };
0213 
0214 struct ARROW_EXPORT Int8Scalar : public NumericScalar<Int8Type> {
0215   using NumericScalar<Int8Type>::NumericScalar;
0216 };
0217 
0218 struct ARROW_EXPORT Int16Scalar : public NumericScalar<Int16Type> {
0219   using NumericScalar<Int16Type>::NumericScalar;
0220 };
0221 
0222 struct ARROW_EXPORT Int32Scalar : public NumericScalar<Int32Type> {
0223   using NumericScalar<Int32Type>::NumericScalar;
0224 };
0225 
0226 struct ARROW_EXPORT Int64Scalar : public NumericScalar<Int64Type> {
0227   using NumericScalar<Int64Type>::NumericScalar;
0228 };
0229 
0230 struct ARROW_EXPORT UInt8Scalar : public NumericScalar<UInt8Type> {
0231   using NumericScalar<UInt8Type>::NumericScalar;
0232 };
0233 
0234 struct ARROW_EXPORT UInt16Scalar : public NumericScalar<UInt16Type> {
0235   using NumericScalar<UInt16Type>::NumericScalar;
0236 };
0237 
0238 struct ARROW_EXPORT UInt32Scalar : public NumericScalar<UInt32Type> {
0239   using NumericScalar<UInt32Type>::NumericScalar;
0240 };
0241 
0242 struct ARROW_EXPORT UInt64Scalar : public NumericScalar<UInt64Type> {
0243   using NumericScalar<UInt64Type>::NumericScalar;
0244 };
0245 
0246 struct ARROW_EXPORT HalfFloatScalar : public NumericScalar<HalfFloatType> {
0247   using NumericScalar<HalfFloatType>::NumericScalar;
0248 };
0249 
0250 struct ARROW_EXPORT FloatScalar : public NumericScalar<FloatType> {
0251   using NumericScalar<FloatType>::NumericScalar;
0252 };
0253 
0254 struct ARROW_EXPORT DoubleScalar : public NumericScalar<DoubleType> {
0255   using NumericScalar<DoubleType>::NumericScalar;
0256 };
0257 
0258 struct ARROW_EXPORT BaseBinaryScalar : public internal::PrimitiveScalarBase {
0259   using ValueType = std::shared_ptr<Buffer>;
0260 
0261   // The value is not supposed to be modified after construction, because subclasses have
0262   // a scratch space whose content need to be kept consistent with the value. It is also
0263   // the user of this class's responsibility to ensure that the buffer is not written to
0264   // accidentally.
0265   const std::shared_ptr<Buffer> value = NULLPTR;
0266 
0267   const void* data() const override {
0268     return value ? reinterpret_cast<const void*>(value->data()) : NULLPTR;
0269   }
0270   std::string_view view() const override {
0271     return value ? std::string_view(*value) : std::string_view();
0272   }
0273 
0274   explicit BaseBinaryScalar(std::shared_ptr<DataType> type)
0275       : internal::PrimitiveScalarBase(std::move(type)) {}
0276 
0277   BaseBinaryScalar(std::shared_ptr<Buffer> value, std::shared_ptr<DataType> type)
0278       : internal::PrimitiveScalarBase{std::move(type), true}, value(std::move(value)) {}
0279 
0280   BaseBinaryScalar(std::string s, std::shared_ptr<DataType> type);
0281 };
0282 
0283 struct ARROW_EXPORT BinaryScalar
0284     : public BaseBinaryScalar,
0285       private internal::ArraySpanFillFromScalarScratchSpace<BinaryScalar> {
0286   using TypeClass = BinaryType;
0287   using ArraySpanFillFromScalarScratchSpace =
0288       internal::ArraySpanFillFromScalarScratchSpace<BinaryScalar>;
0289 
0290   explicit BinaryScalar(std::shared_ptr<DataType> type)
0291       : BaseBinaryScalar(std::move(type)),
0292         ArraySpanFillFromScalarScratchSpace(this->value) {}
0293 
0294   BinaryScalar(std::shared_ptr<Buffer> value, std::shared_ptr<DataType> type)
0295       : BaseBinaryScalar(std::move(value), std::move(type)),
0296         ArraySpanFillFromScalarScratchSpace(this->value) {}
0297 
0298   BinaryScalar(std::string s, std::shared_ptr<DataType> type)
0299       : BaseBinaryScalar(std::move(s), std::move(type)),
0300         ArraySpanFillFromScalarScratchSpace(this->value) {}
0301 
0302   explicit BinaryScalar(std::shared_ptr<Buffer> value)
0303       : BinaryScalar(std::move(value), binary()) {}
0304 
0305   explicit BinaryScalar(std::string s) : BinaryScalar(std::move(s), binary()) {}
0306 
0307   BinaryScalar() : BinaryScalar(binary()) {}
0308 
0309  private:
0310   static void FillScratchSpace(uint8_t* scratch_space,
0311                                const std::shared_ptr<Buffer>& value);
0312 
0313   friend ArraySpan;
0314   friend ArraySpanFillFromScalarScratchSpace;
0315 };
0316 
0317 struct ARROW_EXPORT StringScalar : public BinaryScalar {
0318   using BinaryScalar::BinaryScalar;
0319   using TypeClass = StringType;
0320 
0321   explicit StringScalar(std::shared_ptr<Buffer> value)
0322       : StringScalar(std::move(value), utf8()) {}
0323 
0324   explicit StringScalar(std::string s) : BinaryScalar(std::move(s), utf8()) {}
0325 
0326   StringScalar() : StringScalar(utf8()) {}
0327 };
0328 
0329 struct ARROW_EXPORT BinaryViewScalar
0330     : public BaseBinaryScalar,
0331       private internal::ArraySpanFillFromScalarScratchSpace<BinaryViewScalar> {
0332   using TypeClass = BinaryViewType;
0333   using ArraySpanFillFromScalarScratchSpace =
0334       internal::ArraySpanFillFromScalarScratchSpace<BinaryViewScalar>;
0335 
0336   explicit BinaryViewScalar(std::shared_ptr<DataType> type)
0337       : BaseBinaryScalar(std::move(type)),
0338         ArraySpanFillFromScalarScratchSpace(this->value) {}
0339 
0340   BinaryViewScalar(std::shared_ptr<Buffer> value, std::shared_ptr<DataType> type)
0341       : BaseBinaryScalar(std::move(value), std::move(type)),
0342         ArraySpanFillFromScalarScratchSpace(this->value) {}
0343 
0344   BinaryViewScalar(std::string s, std::shared_ptr<DataType> type)
0345       : BaseBinaryScalar(std::move(s), std::move(type)),
0346         ArraySpanFillFromScalarScratchSpace(this->value) {}
0347 
0348   explicit BinaryViewScalar(std::shared_ptr<Buffer> value)
0349       : BinaryViewScalar(std::move(value), binary_view()) {}
0350 
0351   explicit BinaryViewScalar(std::string s)
0352       : BinaryViewScalar(std::move(s), binary_view()) {}
0353 
0354   BinaryViewScalar() : BinaryViewScalar(binary_view()) {}
0355 
0356   std::string_view view() const override { return std::string_view(*this->value); }
0357 
0358  private:
0359   static void FillScratchSpace(uint8_t* scratch_space,
0360                                const std::shared_ptr<Buffer>& value);
0361 
0362   friend ArraySpan;
0363   friend ArraySpanFillFromScalarScratchSpace;
0364 };
0365 
0366 struct ARROW_EXPORT StringViewScalar : public BinaryViewScalar {
0367   using BinaryViewScalar::BinaryViewScalar;
0368   using TypeClass = StringViewType;
0369 
0370   explicit StringViewScalar(std::shared_ptr<Buffer> value)
0371       : StringViewScalar(std::move(value), utf8_view()) {}
0372 
0373   explicit StringViewScalar(std::string s)
0374       : BinaryViewScalar(std::move(s), utf8_view()) {}
0375 
0376   StringViewScalar() : StringViewScalar(utf8_view()) {}
0377 };
0378 
0379 struct ARROW_EXPORT LargeBinaryScalar
0380     : public BaseBinaryScalar,
0381       private internal::ArraySpanFillFromScalarScratchSpace<LargeBinaryScalar> {
0382   using TypeClass = LargeBinaryType;
0383   using ArraySpanFillFromScalarScratchSpace =
0384       internal::ArraySpanFillFromScalarScratchSpace<LargeBinaryScalar>;
0385 
0386   explicit LargeBinaryScalar(std::shared_ptr<DataType> type)
0387       : BaseBinaryScalar(std::move(type)),
0388         ArraySpanFillFromScalarScratchSpace(this->value) {}
0389 
0390   LargeBinaryScalar(std::shared_ptr<Buffer> value, std::shared_ptr<DataType> type)
0391       : BaseBinaryScalar(std::move(value), std::move(type)),
0392         ArraySpanFillFromScalarScratchSpace(this->value) {}
0393 
0394   LargeBinaryScalar(std::string s, std::shared_ptr<DataType> type)
0395       : BaseBinaryScalar(std::move(s), std::move(type)),
0396         ArraySpanFillFromScalarScratchSpace(this->value) {}
0397 
0398   explicit LargeBinaryScalar(std::shared_ptr<Buffer> value)
0399       : LargeBinaryScalar(std::move(value), large_binary()) {}
0400 
0401   explicit LargeBinaryScalar(std::string s)
0402       : LargeBinaryScalar(std::move(s), large_binary()) {}
0403 
0404   LargeBinaryScalar() : LargeBinaryScalar(large_binary()) {}
0405 
0406  private:
0407   static void FillScratchSpace(uint8_t* scratch_space,
0408                                const std::shared_ptr<Buffer>& value);
0409 
0410   friend ArraySpan;
0411   friend ArraySpanFillFromScalarScratchSpace;
0412 };
0413 
0414 struct ARROW_EXPORT LargeStringScalar : public LargeBinaryScalar {
0415   using LargeBinaryScalar::LargeBinaryScalar;
0416   using TypeClass = LargeStringType;
0417 
0418   explicit LargeStringScalar(std::shared_ptr<Buffer> value)
0419       : LargeStringScalar(std::move(value), large_utf8()) {}
0420 
0421   explicit LargeStringScalar(std::string s)
0422       : LargeBinaryScalar(std::move(s), large_utf8()) {}
0423 
0424   LargeStringScalar() : LargeStringScalar(large_utf8()) {}
0425 };
0426 
0427 struct ARROW_EXPORT FixedSizeBinaryScalar : public BinaryScalar {
0428   using TypeClass = FixedSizeBinaryType;
0429 
0430   FixedSizeBinaryScalar(std::shared_ptr<Buffer> value, std::shared_ptr<DataType> type,
0431                         bool is_valid = true);
0432 
0433   explicit FixedSizeBinaryScalar(const std::shared_ptr<Buffer>& value,
0434                                  bool is_valid = true);
0435 
0436   explicit FixedSizeBinaryScalar(std::string s, bool is_valid = true);
0437 };
0438 
0439 template <typename T>
0440 struct TemporalScalar : internal::PrimitiveScalar<T> {
0441   using internal::PrimitiveScalar<T>::PrimitiveScalar;
0442   using ValueType = typename internal::PrimitiveScalar<T>::ValueType;
0443 
0444   TemporalScalar(ValueType value, std::shared_ptr<DataType> type)
0445       : internal::PrimitiveScalar<T>(std::move(value), type) {}
0446 };
0447 
0448 template <typename T>
0449 struct DateScalar : public TemporalScalar<T> {
0450   using TemporalScalar<T>::TemporalScalar;
0451   using ValueType = typename TemporalScalar<T>::ValueType;
0452 
0453   explicit DateScalar(ValueType value)
0454       : TemporalScalar<T>(std::move(value), TypeTraits<T>::type_singleton()) {}
0455   DateScalar() : TemporalScalar<T>(TypeTraits<T>::type_singleton()) {}
0456 };
0457 
0458 struct ARROW_EXPORT Date32Scalar : public DateScalar<Date32Type> {
0459   using DateScalar<Date32Type>::DateScalar;
0460 };
0461 
0462 struct ARROW_EXPORT Date64Scalar : public DateScalar<Date64Type> {
0463   using DateScalar<Date64Type>::DateScalar;
0464 };
0465 
0466 template <typename T>
0467 struct TimeScalar : public TemporalScalar<T> {
0468   using TemporalScalar<T>::TemporalScalar;
0469 
0470   TimeScalar(typename TemporalScalar<T>::ValueType value, TimeUnit::type unit)
0471       : TimeScalar(std::move(value), std::make_shared<T>(unit)) {}
0472 };
0473 
0474 struct ARROW_EXPORT Time32Scalar : public TimeScalar<Time32Type> {
0475   using TimeScalar<Time32Type>::TimeScalar;
0476 };
0477 
0478 struct ARROW_EXPORT Time64Scalar : public TimeScalar<Time64Type> {
0479   using TimeScalar<Time64Type>::TimeScalar;
0480 };
0481 
0482 struct ARROW_EXPORT TimestampScalar : public TemporalScalar<TimestampType> {
0483   using TemporalScalar<TimestampType>::TemporalScalar;
0484 
0485   TimestampScalar(typename TemporalScalar<TimestampType>::ValueType value,
0486                   TimeUnit::type unit, std::string tz = "")
0487       : TimestampScalar(std::move(value), timestamp(unit, std::move(tz))) {}
0488 
0489   static Result<TimestampScalar> FromISO8601(std::string_view iso8601,
0490                                              TimeUnit::type unit);
0491 };
0492 
0493 template <typename T>
0494 struct IntervalScalar : public TemporalScalar<T> {
0495   using TemporalScalar<T>::TemporalScalar;
0496   using ValueType = typename TemporalScalar<T>::ValueType;
0497 
0498   explicit IntervalScalar(ValueType value)
0499       : TemporalScalar<T>(value, TypeTraits<T>::type_singleton()) {}
0500   IntervalScalar() : TemporalScalar<T>(TypeTraits<T>::type_singleton()) {}
0501 };
0502 
0503 struct ARROW_EXPORT MonthIntervalScalar : public IntervalScalar<MonthIntervalType> {
0504   using IntervalScalar<MonthIntervalType>::IntervalScalar;
0505 };
0506 
0507 struct ARROW_EXPORT DayTimeIntervalScalar : public IntervalScalar<DayTimeIntervalType> {
0508   using IntervalScalar<DayTimeIntervalType>::IntervalScalar;
0509 };
0510 
0511 struct ARROW_EXPORT MonthDayNanoIntervalScalar
0512     : public IntervalScalar<MonthDayNanoIntervalType> {
0513   using IntervalScalar<MonthDayNanoIntervalType>::IntervalScalar;
0514 };
0515 
0516 struct ARROW_EXPORT DurationScalar : public TemporalScalar<DurationType> {
0517   using TemporalScalar<DurationType>::TemporalScalar;
0518 
0519   DurationScalar(typename TemporalScalar<DurationType>::ValueType value,
0520                  TimeUnit::type unit)
0521       : DurationScalar(std::move(value), duration(unit)) {}
0522 
0523   // Convenience constructors for a DurationScalar from std::chrono::nanoseconds
0524   template <template <typename, typename> class StdDuration, typename Rep>
0525   explicit DurationScalar(StdDuration<Rep, std::nano> d)
0526       : DurationScalar{DurationScalar(d.count(), duration(TimeUnit::NANO))} {}
0527 
0528   // Convenience constructors for a DurationScalar from std::chrono::microseconds
0529   template <template <typename, typename> class StdDuration, typename Rep>
0530   explicit DurationScalar(StdDuration<Rep, std::micro> d)
0531       : DurationScalar{DurationScalar(d.count(), duration(TimeUnit::MICRO))} {}
0532 
0533   // Convenience constructors for a DurationScalar from std::chrono::milliseconds
0534   template <template <typename, typename> class StdDuration, typename Rep>
0535   explicit DurationScalar(StdDuration<Rep, std::milli> d)
0536       : DurationScalar{DurationScalar(d.count(), duration(TimeUnit::MILLI))} {}
0537 
0538   // Convenience constructors for a DurationScalar from std::chrono::seconds
0539   // or from units which are whole numbers of seconds
0540   template <template <typename, typename> class StdDuration, typename Rep, intmax_t Num>
0541   explicit DurationScalar(StdDuration<Rep, std::ratio<Num, 1>> d)
0542       : DurationScalar{DurationScalar(d.count() * Num, duration(TimeUnit::SECOND))} {}
0543 };
0544 
0545 template <typename TYPE_CLASS, typename VALUE_TYPE>
0546 struct DecimalScalar : public internal::PrimitiveScalarBase {
0547   using internal::PrimitiveScalarBase::PrimitiveScalarBase;
0548   using TypeClass = TYPE_CLASS;
0549   using ValueType = VALUE_TYPE;
0550 
0551   DecimalScalar(ValueType value, std::shared_ptr<DataType> type)
0552       : internal::PrimitiveScalarBase(std::move(type), true), value(value) {}
0553 
0554   const void* data() const override {
0555     return reinterpret_cast<const void*>(value.native_endian_bytes());
0556   }
0557 
0558   std::string_view view() const override {
0559     return std::string_view(reinterpret_cast<const char*>(value.native_endian_bytes()),
0560                             ValueType::kByteWidth);
0561   }
0562 
0563   ValueType value;
0564 };
0565 
0566 struct ARROW_EXPORT Decimal32Scalar : public DecimalScalar<Decimal32Type, Decimal32> {
0567   using DecimalScalar::DecimalScalar;
0568 };
0569 
0570 struct ARROW_EXPORT Decimal64Scalar : public DecimalScalar<Decimal64Type, Decimal64> {
0571   using DecimalScalar::DecimalScalar;
0572 };
0573 
0574 struct ARROW_EXPORT Decimal128Scalar : public DecimalScalar<Decimal128Type, Decimal128> {
0575   using DecimalScalar::DecimalScalar;
0576 };
0577 
0578 struct ARROW_EXPORT Decimal256Scalar : public DecimalScalar<Decimal256Type, Decimal256> {
0579   using DecimalScalar::DecimalScalar;
0580 };
0581 
0582 struct ARROW_EXPORT BaseListScalar : public Scalar {
0583   using ValueType = std::shared_ptr<Array>;
0584 
0585   BaseListScalar(std::shared_ptr<Array> value, std::shared_ptr<DataType> type,
0586                  bool is_valid = true);
0587 
0588   // The value is not supposed to be modified after construction, because subclasses have
0589   // a scratch space whose content need to be kept consistent with the value. It is also
0590   // the user of this class's responsibility to ensure that the array is not modified
0591   // accidentally.
0592   const std::shared_ptr<Array> value;
0593 };
0594 
0595 struct ARROW_EXPORT ListScalar
0596     : public BaseListScalar,
0597       private internal::ArraySpanFillFromScalarScratchSpace<ListScalar> {
0598   using TypeClass = ListType;
0599   using ArraySpanFillFromScalarScratchSpace =
0600       internal::ArraySpanFillFromScalarScratchSpace<ListScalar>;
0601 
0602   ListScalar(std::shared_ptr<Array> value, std::shared_ptr<DataType> type,
0603              bool is_valid = true)
0604       : BaseListScalar(std::move(value), std::move(type), is_valid),
0605         ArraySpanFillFromScalarScratchSpace(this->value) {}
0606 
0607   explicit ListScalar(std::shared_ptr<Array> value, bool is_valid = true);
0608 
0609  private:
0610   static void FillScratchSpace(uint8_t* scratch_space,
0611                                const std::shared_ptr<Array>& value);
0612 
0613   friend ArraySpan;
0614   friend ArraySpanFillFromScalarScratchSpace;
0615 };
0616 
0617 struct ARROW_EXPORT LargeListScalar
0618     : public BaseListScalar,
0619       private internal::ArraySpanFillFromScalarScratchSpace<LargeListScalar> {
0620   using TypeClass = LargeListType;
0621   using ArraySpanFillFromScalarScratchSpace =
0622       internal::ArraySpanFillFromScalarScratchSpace<LargeListScalar>;
0623 
0624   LargeListScalar(std::shared_ptr<Array> value, std::shared_ptr<DataType> type,
0625                   bool is_valid = true)
0626       : BaseListScalar(std::move(value), std::move(type), is_valid),
0627         ArraySpanFillFromScalarScratchSpace(this->value) {}
0628 
0629   explicit LargeListScalar(std::shared_ptr<Array> value, bool is_valid = true);
0630 
0631  private:
0632   static void FillScratchSpace(uint8_t* scratch_space,
0633                                const std::shared_ptr<Array>& value);
0634 
0635   friend ArraySpan;
0636   friend ArraySpanFillFromScalarScratchSpace;
0637 };
0638 
0639 struct ARROW_EXPORT ListViewScalar
0640     : public BaseListScalar,
0641       private internal::ArraySpanFillFromScalarScratchSpace<ListViewScalar> {
0642   using TypeClass = ListViewType;
0643   using ArraySpanFillFromScalarScratchSpace =
0644       internal::ArraySpanFillFromScalarScratchSpace<ListViewScalar>;
0645 
0646   ListViewScalar(std::shared_ptr<Array> value, std::shared_ptr<DataType> type,
0647                  bool is_valid = true)
0648       : BaseListScalar(std::move(value), std::move(type), is_valid),
0649         ArraySpanFillFromScalarScratchSpace(this->value) {}
0650 
0651   explicit ListViewScalar(std::shared_ptr<Array> value, bool is_valid = true);
0652 
0653  private:
0654   static void FillScratchSpace(uint8_t* scratch_space,
0655                                const std::shared_ptr<Array>& value);
0656 
0657   friend ArraySpan;
0658   friend ArraySpanFillFromScalarScratchSpace;
0659 };
0660 
0661 struct ARROW_EXPORT LargeListViewScalar
0662     : public BaseListScalar,
0663       private internal::ArraySpanFillFromScalarScratchSpace<LargeListViewScalar> {
0664   using TypeClass = LargeListViewType;
0665   using ArraySpanFillFromScalarScratchSpace =
0666       internal::ArraySpanFillFromScalarScratchSpace<LargeListViewScalar>;
0667 
0668   LargeListViewScalar(std::shared_ptr<Array> value, std::shared_ptr<DataType> type,
0669                       bool is_valid = true)
0670       : BaseListScalar(std::move(value), std::move(type), is_valid),
0671         ArraySpanFillFromScalarScratchSpace(this->value) {}
0672 
0673   explicit LargeListViewScalar(std::shared_ptr<Array> value, bool is_valid = true);
0674 
0675  private:
0676   static void FillScratchSpace(uint8_t* scratch_space,
0677                                const std::shared_ptr<Array>& value);
0678 
0679   friend ArraySpan;
0680   friend ArraySpanFillFromScalarScratchSpace;
0681 };
0682 
0683 struct ARROW_EXPORT MapScalar
0684     : public BaseListScalar,
0685       private internal::ArraySpanFillFromScalarScratchSpace<MapScalar> {
0686   using TypeClass = MapType;
0687   using ArraySpanFillFromScalarScratchSpace =
0688       internal::ArraySpanFillFromScalarScratchSpace<MapScalar>;
0689 
0690   MapScalar(std::shared_ptr<Array> value, std::shared_ptr<DataType> type,
0691             bool is_valid = true)
0692       : BaseListScalar(std::move(value), std::move(type), is_valid),
0693         ArraySpanFillFromScalarScratchSpace(this->value) {}
0694 
0695   explicit MapScalar(std::shared_ptr<Array> value, bool is_valid = true);
0696 
0697  private:
0698   static void FillScratchSpace(uint8_t* scratch_space,
0699                                const std::shared_ptr<Array>& value);
0700 
0701   friend ArraySpan;
0702   friend ArraySpanFillFromScalarScratchSpace;
0703 };
0704 
0705 struct ARROW_EXPORT FixedSizeListScalar : public BaseListScalar {
0706   using TypeClass = FixedSizeListType;
0707 
0708   FixedSizeListScalar(std::shared_ptr<Array> value, std::shared_ptr<DataType> type,
0709                       bool is_valid = true);
0710 
0711   explicit FixedSizeListScalar(std::shared_ptr<Array> value, bool is_valid = true);
0712 };
0713 
0714 struct ARROW_EXPORT StructScalar : public Scalar {
0715   using TypeClass = StructType;
0716   using ValueType = std::vector<std::shared_ptr<Scalar>>;
0717 
0718   ScalarVector value;
0719 
0720   Result<std::shared_ptr<Scalar>> field(FieldRef ref) const;
0721 
0722   StructScalar(ValueType value, std::shared_ptr<DataType> type, bool is_valid = true)
0723       : Scalar(std::move(type), is_valid), value(std::move(value)) {}
0724 
0725   static Result<std::shared_ptr<StructScalar>> Make(ValueType value,
0726                                                     std::vector<std::string> field_names);
0727 };
0728 
0729 struct ARROW_EXPORT UnionScalar : public Scalar {
0730   // The type code is not supposed to be modified after construction, because the scratch
0731   // space's content need to be kept consistent with it.
0732   const int8_t type_code;
0733 
0734   virtual const std::shared_ptr<Scalar>& child_value() const = 0;
0735 
0736  protected:
0737   UnionScalar(std::shared_ptr<DataType> type, int8_t type_code, bool is_valid)
0738       : Scalar(std::move(type), is_valid), type_code(type_code) {}
0739 
0740   struct UnionScratchSpace {
0741     alignas(int64_t) int8_t type_code;
0742     alignas(int64_t) uint8_t offsets[sizeof(int32_t) * 2];
0743   };
0744   static_assert(sizeof(UnionScratchSpace) <= internal::kScalarScratchSpaceSize);
0745 
0746   friend ArraySpan;
0747 };
0748 
0749 struct ARROW_EXPORT SparseUnionScalar
0750     : public UnionScalar,
0751       private internal::ArraySpanFillFromScalarScratchSpace<SparseUnionScalar> {
0752   using TypeClass = SparseUnionType;
0753   using ArraySpanFillFromScalarScratchSpace =
0754       internal::ArraySpanFillFromScalarScratchSpace<SparseUnionScalar>;
0755 
0756   // Even though only one of the union values is relevant for this scalar, we
0757   // nonetheless construct a vector of scalars, one per union value, to have
0758   // enough data to reconstruct a valid ArraySpan of length 1 from this scalar
0759   using ValueType = std::vector<std::shared_ptr<Scalar>>;
0760   // The value is not supposed to be modified after construction, because the scratch
0761   // space's content need to be kept consistent with the value. It is also the user of
0762   // this class's responsibility to ensure that the scalars of the vector is not modified
0763   // to accidentally.
0764   const ValueType value;
0765 
0766   // The value index corresponding to the active type code
0767   int child_id;
0768 
0769   SparseUnionScalar(ValueType value, int8_t type_code, std::shared_ptr<DataType> type);
0770 
0771   const std::shared_ptr<Scalar>& child_value() const override {
0772     return this->value[this->child_id];
0773   }
0774 
0775   /// \brief Construct a SparseUnionScalar from a single value, versus having
0776   /// to construct a vector of scalars
0777   static std::shared_ptr<Scalar> FromValue(std::shared_ptr<Scalar> value, int field_index,
0778                                            std::shared_ptr<DataType> type);
0779 
0780  private:
0781   static void FillScratchSpace(uint8_t* scratch_space, int8_t type_code);
0782 
0783   friend ArraySpan;
0784   friend ArraySpanFillFromScalarScratchSpace;
0785 };
0786 
0787 struct ARROW_EXPORT DenseUnionScalar
0788     : public UnionScalar,
0789       private internal::ArraySpanFillFromScalarScratchSpace<DenseUnionScalar> {
0790   using TypeClass = DenseUnionType;
0791   using ArraySpanFillFromScalarScratchSpace =
0792       internal::ArraySpanFillFromScalarScratchSpace<DenseUnionScalar>;
0793 
0794   // For DenseUnionScalar, we can make a valid ArraySpan of length 1 from this
0795   // scalar
0796   using ValueType = std::shared_ptr<Scalar>;
0797   // The value is not supposed to be modified after construction, because the scratch
0798   // space's content need to be kept consistent with the value. It is also the user of
0799   // this class's responsibility to ensure that the elements of the vector is not modified
0800   // accidentally.
0801   const ValueType value;
0802 
0803   const std::shared_ptr<Scalar>& child_value() const override { return this->value; }
0804 
0805   DenseUnionScalar(ValueType value, int8_t type_code, std::shared_ptr<DataType> type)
0806       : UnionScalar(std::move(type), type_code, value->is_valid),
0807         ArraySpanFillFromScalarScratchSpace(type_code),
0808         value(std::move(value)) {}
0809 
0810  private:
0811   static void FillScratchSpace(uint8_t* scratch_space, int8_t type_code);
0812 
0813   friend ArraySpan;
0814   friend ArraySpanFillFromScalarScratchSpace;
0815 };
0816 
0817 struct ARROW_EXPORT RunEndEncodedScalar
0818     : public Scalar,
0819       private internal::ArraySpanFillFromScalarScratchSpace<RunEndEncodedScalar> {
0820   using TypeClass = RunEndEncodedType;
0821   using ValueType = std::shared_ptr<Scalar>;
0822   using ArraySpanFillFromScalarScratchSpace =
0823       internal::ArraySpanFillFromScalarScratchSpace<RunEndEncodedScalar>;
0824 
0825   // The value is not supposed to be modified after construction, because the scratch
0826   // space's content need to be kept consistent with the value. It is also the user of
0827   // this class's responsibility to ensure that the wrapped scalar is not modified
0828   // accidentally.
0829   const ValueType value;
0830 
0831   RunEndEncodedScalar(std::shared_ptr<Scalar> value, std::shared_ptr<DataType> type);
0832 
0833   /// \brief Constructs a NULL RunEndEncodedScalar
0834   explicit RunEndEncodedScalar(const std::shared_ptr<DataType>& type);
0835 
0836   ~RunEndEncodedScalar() override;
0837 
0838   const std::shared_ptr<DataType>& run_end_type() const {
0839     return ree_type().run_end_type();
0840   }
0841 
0842   const std::shared_ptr<DataType>& value_type() const { return ree_type().value_type(); }
0843 
0844  private:
0845   const TypeClass& ree_type() const { return internal::checked_cast<TypeClass&>(*type); }
0846 
0847   static void FillScratchSpace(uint8_t* scratch_space, const DataType& type);
0848 
0849   friend ArraySpan;
0850   friend ArraySpanFillFromScalarScratchSpace;
0851 };
0852 
0853 /// \brief A Scalar value for DictionaryType
0854 ///
0855 /// `is_valid` denotes the validity of the `index`, regardless of
0856 /// the corresponding value in the `dictionary`.
0857 struct ARROW_EXPORT DictionaryScalar : public internal::PrimitiveScalarBase {
0858   using TypeClass = DictionaryType;
0859   struct ValueType {
0860     std::shared_ptr<Scalar> index;
0861     std::shared_ptr<Array> dictionary;
0862   } value;
0863 
0864   explicit DictionaryScalar(std::shared_ptr<DataType> type);
0865 
0866   DictionaryScalar(ValueType value, std::shared_ptr<DataType> type, bool is_valid = true)
0867       : internal::PrimitiveScalarBase(std::move(type), is_valid),
0868         value(std::move(value)) {}
0869 
0870   static std::shared_ptr<DictionaryScalar> Make(std::shared_ptr<Scalar> index,
0871                                                 std::shared_ptr<Array> dict);
0872 
0873   Result<std::shared_ptr<Scalar>> GetEncodedValue() const;
0874 
0875   const void* data() const override {
0876     return internal::checked_cast<internal::PrimitiveScalarBase&>(*value.index).data();
0877   }
0878   std::string_view view() const override {
0879     return internal::checked_cast<const internal::PrimitiveScalarBase&>(*value.index)
0880         .view();
0881   }
0882 };
0883 
0884 /// \brief A Scalar value for ExtensionType
0885 ///
0886 /// The value is the underlying storage scalar.
0887 /// `is_valid` must only be true if `value` is non-null and `value->is_valid` is true
0888 struct ARROW_EXPORT ExtensionScalar : public Scalar {
0889   using TypeClass = ExtensionType;
0890   using ValueType = std::shared_ptr<Scalar>;
0891 
0892   ExtensionScalar(std::shared_ptr<Scalar> storage, std::shared_ptr<DataType> type,
0893                   bool is_valid = true)
0894       : Scalar(std::move(type), is_valid), value(std::move(storage)) {}
0895 
0896   template <typename Storage,
0897             typename = enable_if_t<std::is_base_of<Scalar, Storage>::value>>
0898   ExtensionScalar(Storage&& storage, std::shared_ptr<DataType> type, bool is_valid = true)
0899       : ExtensionScalar(std::make_shared<Storage>(std::move(storage)), std::move(type),
0900                         is_valid) {}
0901 
0902   std::shared_ptr<Scalar> value;
0903 };
0904 
0905 /// @}
0906 
0907 namespace internal {
0908 
0909 inline Status CheckBufferLength(...) { return Status::OK(); }
0910 
0911 ARROW_EXPORT Status CheckBufferLength(const FixedSizeBinaryType* t,
0912                                       const std::shared_ptr<Buffer>* b);
0913 
0914 }  // namespace internal
0915 
0916 template <typename ValueRef>
0917 struct MakeScalarImpl;
0918 
0919 /// \defgroup scalar-factories Scalar factory functions
0920 ///
0921 /// @{
0922 
0923 /// \brief Scalar factory for null scalars
0924 ARROW_EXPORT
0925 std::shared_ptr<Scalar> MakeNullScalar(std::shared_ptr<DataType> type);
0926 
0927 /// \brief Scalar factory for non-null scalars
0928 template <typename Value>
0929 Result<std::shared_ptr<Scalar>> MakeScalar(std::shared_ptr<DataType> type,
0930                                            Value&& value) {
0931   return MakeScalarImpl<Value&&>{type, std::forward<Value>(value), NULLPTR}.Finish();
0932 }
0933 
0934 /// \brief Type-inferring scalar factory for non-null scalars
0935 ///
0936 /// Construct a Scalar instance with a DataType determined by the input C++ type.
0937 /// (for example Int8Scalar for a int8_t input).
0938 /// Only non-parametric primitive types and String are supported.
0939 template <typename Value, typename Traits = CTypeTraits<typename std::decay<Value>::type>,
0940           typename ScalarType = typename Traits::ScalarType,
0941           typename Enable = decltype(ScalarType(std::declval<Value>(),
0942                                                 Traits::type_singleton()))>
0943 std::shared_ptr<Scalar> MakeScalar(Value value) {
0944   return std::make_shared<ScalarType>(std::move(value), Traits::type_singleton());
0945 }
0946 
0947 inline std::shared_ptr<Scalar> MakeScalar(std::string value) {
0948   return std::make_shared<StringScalar>(std::move(value));
0949 }
0950 
0951 inline std::shared_ptr<Scalar> MakeScalar(const std::shared_ptr<Scalar>& scalar) {
0952   return scalar;
0953 }
0954 /// @}
0955 
0956 template <typename ValueRef>
0957 struct MakeScalarImpl {
0958   template <typename T, typename ScalarType = typename TypeTraits<T>::ScalarType,
0959             typename ValueType = typename ScalarType::ValueType,
0960             typename Enable = typename std::enable_if<
0961                 std::is_constructible<ScalarType, ValueType,
0962                                       std::shared_ptr<DataType>>::value &&
0963                 std::is_convertible<ValueRef, ValueType>::value>::type>
0964   Status Visit(const T& t) {
0965     ARROW_RETURN_NOT_OK(internal::CheckBufferLength(&t, &value_));
0966     // `static_cast<ValueRef>` makes a rvalue if ValueRef is `ValueType&&`
0967     out_ = std::make_shared<ScalarType>(
0968         static_cast<ValueType>(static_cast<ValueRef>(value_)), std::move(type_));
0969     return Status::OK();
0970   }
0971 
0972   Status Visit(const ExtensionType& t) {
0973     ARROW_ASSIGN_OR_RAISE(auto storage,
0974                           MakeScalar(t.storage_type(), static_cast<ValueRef>(value_)));
0975     out_ = std::make_shared<ExtensionScalar>(std::move(storage), type_);
0976     return Status::OK();
0977   }
0978 
0979   // Enable constructing string/binary scalars (but not decimal, etc) from std::string
0980   template <typename T>
0981   enable_if_t<
0982       std::is_same<typename std::remove_reference<ValueRef>::type, std::string>::value &&
0983           (is_base_binary_type<T>::value || std::is_same<T, FixedSizeBinaryType>::value),
0984       Status>
0985   Visit(const T& t) {
0986     using ScalarType = typename TypeTraits<T>::ScalarType;
0987     out_ = std::make_shared<ScalarType>(Buffer::FromString(std::move(value_)),
0988                                         std::move(type_));
0989     return Status::OK();
0990   }
0991 
0992   Status Visit(const DataType& t) {
0993     return Status::NotImplemented("constructing scalars of type ", t,
0994                                   " from unboxed values");
0995   }
0996 
0997   Result<std::shared_ptr<Scalar>> Finish() && {
0998     ARROW_RETURN_NOT_OK(VisitTypeInline(*type_, this));
0999     return std::move(out_);
1000   }
1001 
1002   std::shared_ptr<DataType> type_;
1003   ValueRef value_;
1004   std::shared_ptr<Scalar> out_;
1005 };
1006 
1007 }  // namespace arrow