File indexing completed on 2025-09-17 09:14:20
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef ROOT_RField_Fundamental
0015 #define ROOT_RField_Fundamental
0016
0017 #ifndef ROOT_RField
0018 #error "Please include RField.hxx!"
0019 #endif
0020
0021 #include <ROOT/RColumn.hxx>
0022 #include <ROOT/RFieldBase.hxx>
0023 #include <ROOT/RNTupleUtil.hxx>
0024
0025 #include <cstddef>
0026 #include <memory>
0027 #include <string>
0028 #include <string_view>
0029 #include <type_traits>
0030
0031 namespace ROOT {
0032 namespace Experimental {
0033
0034 namespace Detail {
0035 class RFieldVisitor;
0036 }
0037
0038 }
0039
0040
0041
0042
0043
0044 template <>
0045 class RField<void> : public RFieldBase {
0046 public:
0047 static std::string TypeName() { return "void"; }
0048
0049 RField() = delete;
0050 RField(const RField &) = delete;
0051 RField &operator=(const RField &) = delete;
0052 };
0053
0054
0055
0056
0057
0058
0059
0060 extern template class RSimpleField<bool>;
0061
0062 template <>
0063 class RField<bool> final : public RSimpleField<bool> {
0064 protected:
0065 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
0066 {
0067 return std::make_unique<RField>(newName);
0068 }
0069
0070 const RColumnRepresentations &GetColumnRepresentations() const final;
0071
0072 public:
0073 static std::string TypeName() { return "bool"; }
0074 explicit RField(std::string_view name) : RSimpleField(name, TypeName()) {}
0075 RField(RField &&other) = default;
0076 RField &operator=(RField &&other) = default;
0077 ~RField() final = default;
0078
0079 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
0080 };
0081
0082 extern template class RSimpleField<char>;
0083
0084 template <>
0085 class RField<char> final : public RSimpleField<char> {
0086 protected:
0087 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
0088 {
0089 return std::make_unique<RField>(newName);
0090 }
0091
0092 const RColumnRepresentations &GetColumnRepresentations() const final;
0093
0094 public:
0095 static std::string TypeName() { return "char"; }
0096 explicit RField(std::string_view name) : RSimpleField(name, TypeName()) {}
0097 RField(RField &&other) = default;
0098 RField &operator=(RField &&other) = default;
0099 ~RField() final = default;
0100
0101 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
0102 };
0103
0104
0105
0106
0107
0108 template <typename T>
0109 class RIntegralField {
0110
0111 RIntegralField() = delete;
0112 };
0113
0114 extern template class RSimpleField<std::int8_t>;
0115
0116 template <>
0117 class RIntegralField<std::int8_t> : public RSimpleField<std::int8_t> {
0118 protected:
0119 const RColumnRepresentations &GetColumnRepresentations() const final;
0120
0121 public:
0122 static std::string TypeName() { return "std::int8_t"; }
0123 explicit RIntegralField(std::string_view name) : RSimpleField(name, TypeName()) {}
0124 RIntegralField(RIntegralField &&other) = default;
0125 RIntegralField &operator=(RIntegralField &&other) = default;
0126 ~RIntegralField() override = default;
0127
0128 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
0129 };
0130
0131 extern template class RSimpleField<std::uint8_t>;
0132
0133 template <>
0134 class RIntegralField<std::uint8_t> : public RSimpleField<std::uint8_t> {
0135 protected:
0136 const RColumnRepresentations &GetColumnRepresentations() const final;
0137
0138 public:
0139 static std::string TypeName() { return "std::uint8_t"; }
0140 explicit RIntegralField(std::string_view name) : RSimpleField(name, TypeName()) {}
0141 RIntegralField(RIntegralField &&other) = default;
0142 RIntegralField &operator=(RIntegralField &&other) = default;
0143 ~RIntegralField() override = default;
0144
0145 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
0146 };
0147
0148 extern template class RSimpleField<std::int16_t>;
0149
0150 template <>
0151 class RIntegralField<std::int16_t> : public RSimpleField<std::int16_t> {
0152 protected:
0153 const RColumnRepresentations &GetColumnRepresentations() const final;
0154
0155 public:
0156 static std::string TypeName() { return "std::int16_t"; }
0157 explicit RIntegralField(std::string_view name) : RSimpleField(name, TypeName()) {}
0158 RIntegralField(RIntegralField &&other) = default;
0159 RIntegralField &operator=(RIntegralField &&other) = default;
0160 ~RIntegralField() override = default;
0161
0162 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
0163 };
0164
0165 extern template class RSimpleField<std::uint16_t>;
0166
0167 template <>
0168 class RIntegralField<std::uint16_t> : public RSimpleField<std::uint16_t> {
0169 protected:
0170 const RColumnRepresentations &GetColumnRepresentations() const final;
0171
0172 public:
0173 static std::string TypeName() { return "std::uint16_t"; }
0174 explicit RIntegralField(std::string_view name) : RSimpleField(name, TypeName()) {}
0175 RIntegralField(RIntegralField &&other) = default;
0176 RIntegralField &operator=(RIntegralField &&other) = default;
0177 ~RIntegralField() override = default;
0178
0179 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
0180 };
0181
0182 extern template class RSimpleField<std::int32_t>;
0183
0184 template <>
0185 class RIntegralField<std::int32_t> : public RSimpleField<std::int32_t> {
0186 protected:
0187 const RColumnRepresentations &GetColumnRepresentations() const final;
0188
0189 public:
0190 static std::string TypeName() { return "std::int32_t"; }
0191 explicit RIntegralField(std::string_view name) : RSimpleField(name, TypeName()) {}
0192 RIntegralField(RIntegralField &&other) = default;
0193 RIntegralField &operator=(RIntegralField &&other) = default;
0194 ~RIntegralField() override = default;
0195
0196 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
0197 };
0198
0199 extern template class RSimpleField<std::uint32_t>;
0200
0201 template <>
0202 class RIntegralField<std::uint32_t> : public RSimpleField<std::uint32_t> {
0203 protected:
0204 const RColumnRepresentations &GetColumnRepresentations() const final;
0205
0206 public:
0207 static std::string TypeName() { return "std::uint32_t"; }
0208 explicit RIntegralField(std::string_view name) : RSimpleField(name, TypeName()) {}
0209 RIntegralField(RIntegralField &&other) = default;
0210 RIntegralField &operator=(RIntegralField &&other) = default;
0211 ~RIntegralField() override = default;
0212
0213 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
0214 };
0215
0216 extern template class RSimpleField<std::int64_t>;
0217
0218 template <>
0219 class RIntegralField<std::int64_t> : public RSimpleField<std::int64_t> {
0220 protected:
0221 const RColumnRepresentations &GetColumnRepresentations() const final;
0222
0223 public:
0224 static std::string TypeName() { return "std::int64_t"; }
0225 explicit RIntegralField(std::string_view name) : RSimpleField(name, TypeName()) {}
0226 RIntegralField(RIntegralField &&other) = default;
0227 RIntegralField &operator=(RIntegralField &&other) = default;
0228 ~RIntegralField() override = default;
0229
0230 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
0231 };
0232
0233 extern template class RSimpleField<std::uint64_t>;
0234
0235 template <>
0236 class RIntegralField<std::uint64_t> : public RSimpleField<std::uint64_t> {
0237 protected:
0238 const RColumnRepresentations &GetColumnRepresentations() const final;
0239
0240 public:
0241 static std::string TypeName() { return "std::uint64_t"; }
0242 explicit RIntegralField(std::string_view name) : RSimpleField(name, TypeName()) {}
0243 RIntegralField(RIntegralField &&other) = default;
0244 RIntegralField &operator=(RIntegralField &&other) = default;
0245 ~RIntegralField() override = default;
0246
0247 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
0248 };
0249
0250 namespace Internal {
0251
0252 template <typename T>
0253 struct RIntegralTypeMap {
0254 using type = T;
0255 };
0256
0257
0258
0259
0260
0261 template <>
0262 struct RIntegralTypeMap<signed char> {
0263 static_assert(sizeof(signed char) == sizeof(std::int8_t));
0264 using type = std::int8_t;
0265 };
0266 template <>
0267 struct RIntegralTypeMap<unsigned char> {
0268 static_assert(sizeof(unsigned char) == sizeof(std::uint8_t));
0269 using type = std::uint8_t;
0270 };
0271 template <>
0272 struct RIntegralTypeMap<short> {
0273 static_assert(sizeof(short) == sizeof(std::int16_t));
0274 using type = std::int16_t;
0275 };
0276 template <>
0277 struct RIntegralTypeMap<unsigned short> {
0278 static_assert(sizeof(unsigned short) == sizeof(std::uint16_t));
0279 using type = std::uint16_t;
0280 };
0281 template <>
0282 struct RIntegralTypeMap<int> {
0283 static_assert(sizeof(int) == sizeof(std::int32_t));
0284 using type = std::int32_t;
0285 };
0286 template <>
0287 struct RIntegralTypeMap<unsigned int> {
0288 static_assert(sizeof(unsigned int) == sizeof(std::uint32_t));
0289 using type = std::uint32_t;
0290 };
0291 template <>
0292 struct RIntegralTypeMap<long> {
0293 static_assert(sizeof(long) == sizeof(std::int32_t) || sizeof(long) == sizeof(std::int64_t));
0294 using type = std::conditional_t<sizeof(long) == sizeof(std::int32_t), std::int32_t, std::int64_t>;
0295 };
0296 template <>
0297 struct RIntegralTypeMap<unsigned long> {
0298 static_assert(sizeof(unsigned long) == sizeof(std::uint32_t) || sizeof(unsigned long) == sizeof(std::uint64_t));
0299 using type = std::conditional_t<sizeof(unsigned long) == sizeof(std::uint32_t), std::uint32_t, std::uint64_t>;
0300 };
0301 template <>
0302 struct RIntegralTypeMap<long long> {
0303 static_assert(sizeof(long long) == sizeof(std::int64_t));
0304 using type = std::int64_t;
0305 };
0306 template <>
0307 struct RIntegralTypeMap<unsigned long long> {
0308 static_assert(sizeof(unsigned long long) == sizeof(std::uint64_t));
0309 using type = std::uint64_t;
0310 };
0311 }
0312
0313 template <typename T>
0314 class RField<T, typename std::enable_if<std::is_integral_v<T>>::type> final
0315 : public RIntegralField<typename Internal::RIntegralTypeMap<T>::type> {
0316 using MappedType = typename Internal::RIntegralTypeMap<T>::type;
0317 static_assert(sizeof(T) == sizeof(MappedType), "invalid size of mapped type");
0318 static_assert(std::is_signed_v<T> == std::is_signed_v<MappedType>, "invalid signedness of mapped type");
0319 using BaseType = RIntegralField<MappedType>;
0320
0321 protected:
0322 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
0323 {
0324 return std::make_unique<RField>(newName);
0325 }
0326
0327 public:
0328 RField(std::string_view name) : RIntegralField<MappedType>(name) {}
0329 RField(RField &&other) = default;
0330 RField &operator=(RField &&other) = default;
0331 ~RField() final = default;
0332
0333 T *Map(ROOT::NTupleSize_t globalIndex) { return reinterpret_cast<T *>(this->BaseType::Map(globalIndex)); }
0334 T *Map(RNTupleLocalIndex localIndex) { return reinterpret_cast<T *>(this->BaseType::Map(localIndex)); }
0335 T *MapV(ROOT::NTupleSize_t globalIndex, ROOT::NTupleSize_t &nItems)
0336 {
0337 return reinterpret_cast<T *>(this->BaseType::MapV(globalIndex, nItems));
0338 }
0339 T *MapV(RNTupleLocalIndex localIndex, ROOT::NTupleSize_t &nItems)
0340 {
0341 return reinterpret_cast<T *>(this->BaseType::MapV(localIndex, nItems));
0342 }
0343 };
0344
0345
0346
0347
0348
0349 extern template class RSimpleField<double>;
0350 extern template class RSimpleField<float>;
0351
0352 template <typename T>
0353 class RRealField : public RSimpleField<T> {
0354 using Base = RSimpleField<T>;
0355
0356 using Base::fAvailableColumns;
0357 using Base::fColumnRepresentatives;
0358 using Base::fPrincipalColumn;
0359
0360 std::size_t fBitWidth = sizeof(T) * 8;
0361 double fValueMin = std::numeric_limits<T>::min();
0362 double fValueMax = std::numeric_limits<T>::max();
0363
0364 protected:
0365
0366 RRealField(std::string_view name, const RRealField &source)
0367 : RSimpleField<T>(name, source.GetTypeName()),
0368 fBitWidth(source.fBitWidth),
0369 fValueMin(source.fValueMin),
0370 fValueMax(source.fValueMax)
0371 {
0372 }
0373
0374 void GenerateColumns() final
0375 {
0376 const auto r = Base::GetColumnRepresentatives();
0377 const auto n = r.size();
0378 fAvailableColumns.reserve(n);
0379 for (std::uint16_t i = 0; i < n; ++i) {
0380 auto &column = fAvailableColumns.emplace_back(ROOT::Internal::RColumn::Create<T>(r[i][0], 0, i));
0381 if (r[i][0] == ROOT::ENTupleColumnType::kReal32Trunc) {
0382 column->SetBitsOnStorage(fBitWidth);
0383 } else if (r[i][0] == ROOT::ENTupleColumnType::kReal32Quant) {
0384 column->SetBitsOnStorage(fBitWidth);
0385 column->SetValueRange(fValueMin, fValueMax);
0386 }
0387 }
0388 fPrincipalColumn = fAvailableColumns[0].get();
0389 }
0390
0391 void GenerateColumns(const ROOT::RNTupleDescriptor &desc) final
0392 {
0393 std::uint16_t representationIndex = 0;
0394 do {
0395 const auto &onDiskTypes = Base::EnsureCompatibleColumnTypes(desc, representationIndex);
0396 if (onDiskTypes.empty())
0397 break;
0398
0399 auto &column =
0400 fAvailableColumns.emplace_back(ROOT::Internal::RColumn::Create<T>(onDiskTypes[0], 0, representationIndex));
0401 if (onDiskTypes[0] == ROOT::ENTupleColumnType::kReal32Trunc) {
0402 const auto &fdesc = desc.GetFieldDescriptor(Base::GetOnDiskId());
0403 const auto &coldesc = desc.GetColumnDescriptor(fdesc.GetLogicalColumnIds()[0]);
0404 column->SetBitsOnStorage(coldesc.GetBitsOnStorage());
0405 } else if (onDiskTypes[0] == ROOT::ENTupleColumnType::kReal32Quant) {
0406 const auto &fdesc = desc.GetFieldDescriptor(Base::GetOnDiskId());
0407 const auto &coldesc = desc.GetColumnDescriptor(fdesc.GetLogicalColumnIds()[0]);
0408 assert(coldesc.GetValueRange().has_value());
0409 const auto [valMin, valMax] = *coldesc.GetValueRange();
0410 column->SetBitsOnStorage(coldesc.GetBitsOnStorage());
0411 column->SetValueRange(valMin, valMax);
0412 }
0413 fColumnRepresentatives.emplace_back(onDiskTypes);
0414 if (representationIndex > 0) {
0415 fAvailableColumns[0]->MergeTeams(*fAvailableColumns[representationIndex]);
0416 }
0417
0418 representationIndex++;
0419 } while (true);
0420 fPrincipalColumn = fAvailableColumns[0].get();
0421 }
0422
0423 ~RRealField() override = default;
0424
0425 public:
0426 using Base::SetColumnRepresentatives;
0427
0428 RRealField(std::string_view name, std::string_view typeName) : RSimpleField<T>(name, typeName) {}
0429 RRealField(RRealField &&other) = default;
0430 RRealField &operator=(RRealField &&other) = default;
0431
0432
0433
0434
0435 void SetHalfPrecision() { SetColumnRepresentatives({{ROOT::ENTupleColumnType::kReal16}}); }
0436
0437
0438
0439
0440
0441
0442
0443 void SetTruncated(std::size_t nBits)
0444 {
0445 const auto &[minBits, maxBits] =
0446 ROOT::Internal::RColumnElementBase::GetValidBitRange(ROOT::ENTupleColumnType::kReal32Trunc);
0447 if (nBits < minBits || nBits > maxBits) {
0448 throw RException(R__FAIL("SetTruncated() argument nBits = " + std::to_string(nBits) +
0449 " is out of valid range [" + std::to_string(minBits) + ", " +
0450 std::to_string(maxBits) + "])"));
0451 }
0452 SetColumnRepresentatives({{ROOT::ENTupleColumnType::kReal32Trunc}});
0453 fBitWidth = nBits;
0454 }
0455
0456
0457
0458
0459
0460
0461
0462
0463 void SetQuantized(T minValue, T maxValue, std::size_t nBits)
0464 {
0465 const auto &[minBits, maxBits] =
0466 ROOT::Internal::RColumnElementBase::GetValidBitRange(ROOT::ENTupleColumnType::kReal32Quant);
0467 if (nBits < minBits || nBits > maxBits) {
0468 throw RException(R__FAIL("SetQuantized() argument nBits = " + std::to_string(nBits) +
0469 " is out of valid range [" + std::to_string(minBits) + ", " +
0470 std::to_string(maxBits) + "])"));
0471 }
0472 SetColumnRepresentatives({{ROOT::ENTupleColumnType::kReal32Quant}});
0473 fBitWidth = nBits;
0474 fValueMin = minValue;
0475 fValueMax = maxValue;
0476 }
0477 };
0478
0479 template <>
0480 class RField<float> final : public RRealField<float> {
0481 const RColumnRepresentations &GetColumnRepresentations() const final;
0482
0483 RField(std::string_view name, const RField &source) : RRealField<float>(name, source) {}
0484
0485 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
0486 {
0487 return std::unique_ptr<RField>(new RField(newName, *this));
0488 }
0489
0490 public:
0491 static std::string TypeName() { return "float"; }
0492
0493 explicit RField(std::string_view name) : RRealField<float>(name, TypeName()) {}
0494
0495 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
0496 };
0497
0498 template <>
0499 class RField<double> final : public RRealField<double> {
0500 const RColumnRepresentations &GetColumnRepresentations() const final;
0501
0502 RField(std::string_view name, const RField &source) : RRealField<double>(name, source) {}
0503
0504 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
0505 {
0506 return std::unique_ptr<RField>(new RField(newName, *this));
0507 }
0508
0509 public:
0510 static std::string TypeName() { return "double"; }
0511
0512 explicit RField(std::string_view name) : RRealField<double>(name, TypeName()) {}
0513
0514 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
0515
0516
0517 void SetDouble32();
0518 };
0519
0520 }
0521
0522 #endif