Logo ROOT  
Reference Guide
RField.hxx
Go to the documentation of this file.
1/// \file ROOT/RField.hxx
2/// \ingroup NTuple ROOT7
3/// \author Jakob Blomer <jblomer@cern.ch>
4/// \date 2018-10-09
5/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
6/// is welcome!
7
8/*************************************************************************
9 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
10 * All rights reserved. *
11 * *
12 * For the licensing terms see $ROOTSYS/LICENSE. *
13 * For the list of contributors see $ROOTSYS/README/CREDITS. *
14 *************************************************************************/
15
16#ifndef ROOT7_RField
17#define ROOT7_RField
18
19#include <ROOT/RColumn.hxx>
20#include <ROOT/RError.hxx>
22#include <ROOT/RFieldValue.hxx>
23#include <ROOT/RNTupleUtil.hxx>
24#include <ROOT/RSpan.hxx>
25#include <ROOT/RStringView.hxx>
26#include <ROOT/RVec.hxx>
27#include <ROOT/TypeTraits.hxx>
28
29#include <TGenericClassInfo.h>
30
31#include <algorithm>
32#include <array>
33#include <iostream>
34#include <iterator>
35#include <memory>
36#include <string>
37#include <type_traits>
38#include <typeinfo>
39#if __cplusplus >= 201703L
40#include <variant>
41#endif
42#include <vector>
43#include <utility>
44
45class TClass;
46
47namespace ROOT {
48namespace Experimental {
49
50class RCollectionField;
51class RCollectionNTupleWriter;
52class REntry;
53class RNTupleModel;
54
55namespace Detail {
56
57class RFieldVisitor;
58class RPageStorage;
59
60// clang-format off
61/**
62\class ROOT::Experimental::RFieldBase
63\ingroup NTuple
64\brief A field translates read and write calls from/to underlying columns to/from tree values
65
66A field is a serializable C++ type or a container for a collection of sub fields. The RFieldBase and its
67type-safe descendants provide the object to column mapper. They map C++ objects to primitive columns. The
68mapping is trivial for simple types such as 'double'. Complex types resolve to multiple primitive columns.
69The field knows based on its type and the field name the type(s) and name(s) of the columns.
70*/
71// clang-format on
73 friend class ROOT::Experimental::RCollectionField; // to move the fields from the collection model
74
75private:
76 /// The field name relative to its parent field
77 std::string fName;
78 /// The C++ type captured by this field
79 std::string fType;
80 /// The role of this field in the data model structure
82 /// For fixed sized arrays, the array length
83 std::size_t fNRepetitions;
84 /// A field on a trivial type that maps as-is to a single column
86 /// When the columns are connected to a page source or page sink, the field represents a field id in the
87 /// corresponding RNTuple descriptor. This on-disk ID is set in RPageSink::Create() for writing and by
88 /// RFieldDescriptor::CreateField() when recreating a field / model from the stored descriptor.
90 /// Free text set by the user
91 std::string fDescription;
92
93protected:
94 /// Collections and classes own sub fields
95 std::vector<std::unique_ptr<RFieldBase>> fSubFields;
96 /// Sub fields point to their mother field
98 /// Points into fColumns. All fields that have columns have a distinct main column. For simple fields
99 /// (float, int, ...), the principal column corresponds to the field type. For collection fields expect std::array,
100 /// the main column is the offset field. Class fields have no column of their own.
102 /// The columns are connected either to a sink or to a source (not to both); they are owned by the field.
103 std::vector<std::unique_ptr<RColumn>> fColumns;
104
105 /// Creates the backing columns corresponsing to the field type for writing
106 virtual void GenerateColumnsImpl() = 0;
107 /// Creates the backing columns corresponsing to the field type for reading.
108 /// The method should to check, using the page source and fOnDiskId, if the column types match
109 /// and throw if they don't.
110 virtual void GenerateColumnsImpl(const RNTupleDescriptor &desc) = 0;
111
112 /// Called by Clone(), which additionally copies the on-disk ID
113 virtual std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const = 0;
114
115 /// Operations on values of complex types, e.g. ones that involve multiple columns or for which no direct
116 /// column type exists.
117 virtual std::size_t AppendImpl(const RFieldValue &value);
118 virtual void ReadGlobalImpl(NTupleSize_t globalIndex, RFieldValue *value);
119 virtual void ReadInClusterImpl(const RClusterIndex &clusterIndex, RFieldValue *value) {
120 ReadGlobalImpl(fPrincipalColumn->GetGlobalIndex(clusterIndex), value);
121 }
122
123 /// Throws an exception if the column given by fOnDiskId and the columnIndex in the provided descriptor
124 /// is not of one of the requested types.
125 ROOT::Experimental::EColumnType EnsureColumnType(const std::vector<EColumnType> &requestedTypes,
126 unsigned int columnIndex, const RNTupleDescriptor &desc);
127
128public:
129 /// Iterates over the sub tree of fields in depth-first search order
131 private:
132 struct Position {
133 Position() : fFieldPtr(nullptr), fIdxInParent(-1) { }
134 Position(RFieldBase *fieldPtr, int idxInParent) : fFieldPtr(fieldPtr), fIdxInParent(idxInParent) { }
137 };
138 /// The stack of nodes visited when walking down the tree of fields
139 std::vector<Position> fStack;
140 public:
142 using iterator_category = std::forward_iterator_tag;
144 using difference_type = std::ptrdiff_t;
147
148 RSchemaIterator() { fStack.emplace_back(Position()); }
149 RSchemaIterator(pointer val, int idxInParent) { fStack.emplace_back(Position(val, idxInParent)); }
151 /// Given that the iterator points to a valid field which is not the end iterator, go to the next field
152 /// in depth-first search order
153 void Advance();
154
155 iterator operator++(int) /* postfix */ { auto r = *this; Advance(); return r; }
156 iterator& operator++() /* prefix */ { Advance(); return *this; }
157 reference operator* () const { return *fStack.back().fFieldPtr; }
158 pointer operator->() const { return fStack.back().fFieldPtr; }
159 bool operator==(const iterator& rh) const { return fStack.back().fFieldPtr == rh.fStack.back().fFieldPtr; }
160 bool operator!=(const iterator& rh) const { return fStack.back().fFieldPtr != rh.fStack.back().fFieldPtr; }
161 };
162
163 /// The constructor creates the underlying column objects and connects them to either a sink or a source.
165 std::size_t nRepetitions = 0);
166 RFieldBase(const RFieldBase&) = delete;
167 RFieldBase(RFieldBase&&) = default;
170 virtual ~RFieldBase();
171
172 /// Copies the field and its sub fields using a possibly new name and a new, unconnected set of columns
173 std::unique_ptr<RFieldBase> Clone(std::string_view newName) const;
174
175 /// Factory method to resurrect a field from the stored on-disk type information
176 static RResult<std::unique_ptr<RFieldBase>> Create(const std::string &fieldName, const std::string &typeName);
177 /// Check whether a given string is a valid field name
179
180 /// Generates an object of the field type and allocates new initialized memory according to the type.
182 /// Generates a tree value in a given location of size at least GetValueSize(). Assumes that where has been
183 /// allocated by malloc().
184 virtual RFieldValue GenerateValue(void *where) = 0;
185 /// Releases the resources acquired during GenerateValue (memory and constructor)
186 /// This implementation works for simple types but needs to be overwritten for complex ones
187 virtual void DestroyValue(const RFieldValue &value, bool dtorOnly = false);
188 /// Creates a value from a memory location with an already constructed object
189 virtual RFieldValue CaptureValue(void *where) = 0;
190 /// Creates the list of direct child values given a value for this field. E.g. a single value for the
191 /// correct variant or all the elements of a collection. The default implementation assumes no sub values
192 /// and returns an empty vector.
193 virtual std::vector<RFieldValue> SplitValue(const RFieldValue &value) const;
194 /// The number of bytes taken by a value of the appropriate type
195 virtual size_t GetValueSize() const = 0;
196 /// For many types, the alignment requirement is equal to the size; otherwise override.
197 virtual size_t GetAlignment() const { return GetValueSize(); }
198
199 /// Write the given value into columns. The value object has to be of the same type as the field.
200 /// Returns the number of uncompressed bytes written.
201 std::size_t Append(const RFieldValue& value) {
202 if (!fIsSimple)
203 return AppendImpl(value);
204
206 return value.fMappedElement.GetSize();
207 }
208
209 /// Populate a single value with data from the tree, which needs to be of the fitting type.
210 /// Reading copies data into the memory wrapped by the ntuple value.
211 void Read(NTupleSize_t globalIndex, RFieldValue *value) {
212 if (!fIsSimple) {
213 ReadGlobalImpl(globalIndex, value);
214 return;
215 }
216 fPrincipalColumn->Read(globalIndex, &value->fMappedElement);
217 }
218
219 void Read(const RClusterIndex &clusterIndex, RFieldValue *value) {
220 if (!fIsSimple) {
221 ReadInClusterImpl(clusterIndex, value);
222 return;
223 }
224 fPrincipalColumn->Read(clusterIndex, &value->fMappedElement);
225 }
226
227 /// Ensure that all received items are written from page buffers to the storage.
228 void Flush() const;
229 /// Perform housekeeping tasks for global to cluster-local index translation
230 virtual void CommitCluster() {}
231
232 /// Add a new subfield to the list of nested fields
233 void Attach(std::unique_ptr<Detail::RFieldBase> child);
234
235 std::string GetName() const { return fName; }
236 std::string GetType() const { return fType; }
238 std::size_t GetNRepetitions() const { return fNRepetitions; }
240 RFieldBase *GetParent() const { return fParent; }
241 std::vector<RFieldBase *> GetSubFields() const;
242 bool IsSimple() const { return fIsSimple; }
243 /// Get the field's description
244 std::string GetDescription() const { return fDescription; }
245 void SetDescription(std::string_view description) { fDescription = std::string(description); }
246
249
250 /// Fields and their columns live in the void until connected to a physical page storage. Only once connected, data
251 /// can be read or written. In order to find the field in the page storage, the field's on-disk ID has to be set.
252 void ConnectPageSink(RPageSink &pageSink);
253 void ConnectPageSource(RPageSource &pageSource);
254
255 /// Indicates an evolution of the mapping scheme from C++ type to columns
256 virtual RNTupleVersion GetFieldVersion() const { return RNTupleVersion(); }
257 /// Indicates an evolution of the C++ type itself
258 virtual RNTupleVersion GetTypeVersion() const { return RNTupleVersion(); }
259
260 RSchemaIterator begin();
261 RSchemaIterator end();
262
263 virtual void AcceptVisitor(RFieldVisitor &visitor) const;
264};
265
266} // namespace Detail
267
268
269
270/// The container field for an ntuple model, which itself has no physical representation
272protected:
273 std::unique_ptr<Detail::RFieldBase> CloneImpl(std::string_view newName) const;
274
275public:
276 RFieldZero() : Detail::RFieldBase("", "", ENTupleStructure::kRecord, false /* isSimple */) { }
277
278 void GenerateColumnsImpl() final {}
283 size_t GetValueSize() const final { return 0; }
284
285 /// Generates managed values for the top-level sub fields
286 std::unique_ptr<REntry> GenerateEntry() const;
287 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
288};
289
290/// The field for a class with dictionary
292private:
296 };
299 std::size_t fOffset;
300 };
301 /// Prefix used in the subfield names generated for base classes
302 static constexpr const char *kPrefixInherited{":"};
303
305 /// Additional information kept for each entry in `fSubFields`
306 std::vector<RSubFieldInfo> fSubFieldsInfo;
307 std::size_t fMaxAlignment = 1;
308
309private:
310 RClassField(std::string_view fieldName, std::string_view className, TClass *classp);
311 void Attach(std::unique_ptr<Detail::RFieldBase> child, RSubFieldInfo info);
312
313protected:
314 std::unique_ptr<Detail::RFieldBase> CloneImpl(std::string_view newName) const final;
315 std::size_t AppendImpl(const Detail::RFieldValue& value) final;
316 void ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue *value) final;
317 void ReadInClusterImpl(const RClusterIndex &clusterIndex, Detail::RFieldValue *value) final;
318
319public:
320 RClassField(std::string_view fieldName, std::string_view className);
321 RClassField(RClassField&& other) = default;
322 RClassField& operator =(RClassField&& other) = default;
323 ~RClassField() = default;
324
325 void GenerateColumnsImpl() final;
326 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
327 using Detail::RFieldBase::GenerateValue;
328 Detail::RFieldValue GenerateValue(void* where) override;
329 void DestroyValue(const Detail::RFieldValue& value, bool dtorOnly = false) final;
330 Detail::RFieldValue CaptureValue(void *where) final;
331 std::vector<Detail::RFieldValue> SplitValue(const Detail::RFieldValue &value) const final;
332 size_t GetValueSize() const override;
333 size_t GetAlignment() const final { return fMaxAlignment; }
334 void AcceptVisitor(Detail::RFieldVisitor &visitor) const override;
335};
336
337/// The field for an untyped record. The subfields are stored consequitively in a memory block, i.e.
338/// the memory layout is identical to one that a C++ struct would have
340private:
341 std::size_t fMaxAlignment = 1;
342 std::size_t fSize = 0;
343
344 std::size_t GetItemPadding(std::size_t baseOffset, std::size_t itemAlignment) const;
345
346protected:
347 std::unique_ptr<Detail::RFieldBase> CloneImpl(std::string_view newName) const final;
348 std::size_t AppendImpl(const Detail::RFieldValue& value) final;
349 void ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue *value) final;
350 void ReadInClusterImpl(const RClusterIndex &clusterIndex, Detail::RFieldValue *value) final;
351
352public:
353 RRecordField(std::string_view fieldName, std::vector<std::unique_ptr<Detail::RFieldBase>> &itemFields);
354 RRecordField(RRecordField&& other) = default;
356 ~RRecordField() = default;
357
358 void GenerateColumnsImpl() final {}
361 Detail::RFieldValue GenerateValue(void* where) final;
362 void DestroyValue(const Detail::RFieldValue& value, bool dtorOnly = false) final;
363 Detail::RFieldValue CaptureValue(void *where) final;
364 std::vector<Detail::RFieldValue> SplitValue(const Detail::RFieldValue &value) const final;
365 size_t GetValueSize() const final { return fSize; }
366 size_t GetAlignment() const final { return fMaxAlignment; }
367 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
368};
369
370/// The generic field for a (nested) std::vector<Type> except for std::vector<bool>
372private:
373 std::size_t fItemSize;
375
376protected:
377 std::unique_ptr<Detail::RFieldBase> CloneImpl(std::string_view newName) const final;
378 std::size_t AppendImpl(const Detail::RFieldValue& value) final;
379 void ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue *value) final;
380
381public:
382 RVectorField(std::string_view fieldName, std::unique_ptr<Detail::RFieldBase> itemField);
383 RVectorField(RVectorField&& other) = default;
385 ~RVectorField() = default;
386
387 void GenerateColumnsImpl() final;
388 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
389 using Detail::RFieldBase::GenerateValue;
390 Detail::RFieldValue GenerateValue(void* where) override;
391 void DestroyValue(const Detail::RFieldValue& value, bool dtorOnly = false) final;
392 Detail::RFieldValue CaptureValue(void *where) override;
393 std::vector<Detail::RFieldValue> SplitValue(const Detail::RFieldValue &value) const final;
394 size_t GetValueSize() const override { return sizeof(std::vector<char>); }
395 size_t GetAlignment() const final { return std::alignment_of<std::vector<char>>(); }
396 void CommitCluster() final;
397 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
398 void GetCollectionInfo(NTupleSize_t globalIndex, RClusterIndex *collectionStart, ClusterSize_t *size) const {
399 fPrincipalColumn->GetCollectionInfo(globalIndex, collectionStart, size);
400 }
401 void GetCollectionInfo(const RClusterIndex &clusterIndex, RClusterIndex *collectionStart, ClusterSize_t *size) const {
402 fPrincipalColumn->GetCollectionInfo(clusterIndex, collectionStart, size);
403 }
404};
405
406
407/// The generic field for fixed size arrays, which do not need an offset column
409private:
410 std::size_t fItemSize;
411 std::size_t fArrayLength;
412
413protected:
414 std::unique_ptr<Detail::RFieldBase> CloneImpl(std::string_view newName) const final;
415 std::size_t AppendImpl(const Detail::RFieldValue& value) final;
416 void ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue *value) final;
417 void ReadInClusterImpl(const RClusterIndex &clusterIndex, Detail::RFieldValue *value) final;
418
419public:
420 RArrayField(std::string_view fieldName, std::unique_ptr<Detail::RFieldBase> itemField, std::size_t arrayLength);
421 RArrayField(RArrayField &&other) = default;
422 RArrayField& operator =(RArrayField &&other) = default;
423 ~RArrayField() = default;
424
425 void GenerateColumnsImpl() final;
426 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
427 using Detail::RFieldBase::GenerateValue;
428 Detail::RFieldValue GenerateValue(void *where) override;
429 void DestroyValue(const Detail::RFieldValue &value, bool dtorOnly = false) final;
430 Detail::RFieldValue CaptureValue(void *where) final;
431 std::vector<Detail::RFieldValue> SplitValue(const Detail::RFieldValue &value) const final;
432 size_t GetLength() const { return fArrayLength; }
433 size_t GetValueSize() const final { return fItemSize * fArrayLength; }
434 size_t GetAlignment() const final { return fSubFields[0]->GetAlignment(); }
435 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
436};
437
438#if __cplusplus >= 201703L
439/// The generic field for std::variant types
440class RVariantField : public Detail::RFieldBase {
441private:
442 size_t fMaxItemSize = 0;
443 size_t fMaxAlignment = 1;
444 /// In the std::variant memory layout, at which byte number is the index stored
445 size_t fTagOffset = 0;
446 std::vector<ClusterSize_t::ValueType> fNWritten;
447
448 static std::string GetTypeList(const std::vector<Detail::RFieldBase *> &itemFields);
449 /// Extracts the index from an std::variant and transforms it into the 1-based index used for the switch column
450 std::uint32_t GetTag(void *variantPtr) const;
451 void SetTag(void *variantPtr, std::uint32_t tag) const;
452
453protected:
454 std::unique_ptr<Detail::RFieldBase> CloneImpl(std::string_view newName) const final;
455 std::size_t AppendImpl(const Detail::RFieldValue& value) final;
456 void ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue *value) final;
457
458public:
459 // TODO(jblomer): use std::span in signature
460 RVariantField(std::string_view fieldName, const std::vector<Detail::RFieldBase *> &itemFields);
461 RVariantField(RVariantField &&other) = default;
462 RVariantField& operator =(RVariantField &&other) = default;
463 ~RVariantField() = default;
464
465 void GenerateColumnsImpl() final;
466 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
467 using Detail::RFieldBase::GenerateValue;
468 Detail::RFieldValue GenerateValue(void *where) override;
469 void DestroyValue(const Detail::RFieldValue &value, bool dtorOnly = false) final;
470 Detail::RFieldValue CaptureValue(void *where) final;
471 size_t GetValueSize() const final;
472 size_t GetAlignment() const final { return fMaxAlignment; }
473 void CommitCluster() final;
474};
475#endif
476
477
478/// Classes with dictionaries that can be inspected by TClass
479template <typename T, typename=void>
480class RField : public RClassField {
481public:
482 static std::string TypeName() { return ROOT::Internal::GetDemangledTypeName(typeid(T)); }
484 static_assert(std::is_class<T>::value, "no I/O support for this basic C++ type");
485 }
486 RField(RField&& other) = default;
487 RField& operator =(RField&& other) = default;
488 ~RField() = default;
489
491 template <typename... ArgsT>
493 {
494 return Detail::RFieldValue(this, static_cast<T*>(where), std::forward<ArgsT>(args)...);
495 }
497};
498
499
500/// The collection field is only used for writing; when reading, untyped collections are projected to an std::vector
502private:
503 /// Save the link to the collection ntuple in order to reset the offset counter when committing the cluster
504 std::shared_ptr<RCollectionNTupleWriter> fCollectionNTuple;
505protected:
506 std::unique_ptr<Detail::RFieldBase> CloneImpl(std::string_view newName) const final;
507public:
508 static std::string TypeName() { return ""; }
510 std::shared_ptr<RCollectionNTupleWriter> collectionNTuple,
511 std::unique_ptr<RNTupleModel> collectionModel);
514 ~RCollectionField() = default;
515
516 void GenerateColumnsImpl() final;
517 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
518
519 using Detail::RFieldBase::GenerateValue;
520 ROOT::Experimental::Detail::RFieldValue GenerateValue(void* where) final {
521 return Detail::RFieldValue(
523 this, static_cast<ClusterSize_t*>(where));
524 }
526 return Detail::RFieldValue(true /* captureFlag */,
527 Detail::RColumnElement<ClusterSize_t>(static_cast<ClusterSize_t*>(where)), this, where);
528 }
529 size_t GetValueSize() const final { return 0; }
530 void CommitCluster() final;
531};
532
533
534/// Template specializations for concrete C++ types
535
536
537template <>
538class RField<ClusterSize_t> : public Detail::RFieldBase {
539protected:
540 std::unique_ptr<Detail::RFieldBase> CloneImpl(std::string_view newName) const final {
541 return std::make_unique<RField>(newName);
542 }
543
544public:
545 static std::string TypeName() { return "ROOT::Experimental::ClusterSize_t"; }
547 : Detail::RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, true /* isSimple */) {}
548 RField(RField&& other) = default;
549 RField& operator =(RField&& other) = default;
550 ~RField() = default;
551
553 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
554
556 return fPrincipalColumn->Map<ClusterSize_t>(globalIndex);
557 }
558 ClusterSize_t *Map(const RClusterIndex &clusterIndex) {
559 return fPrincipalColumn->Map<ClusterSize_t>(clusterIndex);
560 }
562 return fPrincipalColumn->MapV<ClusterSize_t>(globalIndex, nItems);
563 }
564 ClusterSize_t *MapV(const RClusterIndex &clusterIndex, NTupleSize_t &nItems) {
565 return fPrincipalColumn->MapV<ClusterSize_t>(clusterIndex, nItems);
566 }
567
569 template <typename... ArgsT>
571 {
572 return Detail::RFieldValue(
574 this, static_cast<ClusterSize_t*>(where), std::forward<ArgsT>(args)...);
575 }
578 return Detail::RFieldValue(true /* captureFlag */,
579 Detail::RColumnElement<ClusterSize_t>(static_cast<ClusterSize_t*>(where)), this, where);
580 }
581 size_t GetValueSize() const final { return sizeof(ClusterSize_t); }
582
583 /// Special help for offset fields
584 void GetCollectionInfo(NTupleSize_t globalIndex, RClusterIndex *collectionStart, ClusterSize_t *size) {
585 fPrincipalColumn->GetCollectionInfo(globalIndex, collectionStart, size);
586 }
587 void GetCollectionInfo(const RClusterIndex &clusterIndex, RClusterIndex *collectionStart, ClusterSize_t *size) {
588 fPrincipalColumn->GetCollectionInfo(clusterIndex, collectionStart, size);
589 }
590 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
591};
592
593
594template <>
595class RField<bool> : public Detail::RFieldBase {
596protected:
597 std::unique_ptr<Detail::RFieldBase> CloneImpl(std::string_view newName) const final {
598 return std::make_unique<RField>(newName);
599 }
600
601public:
602 static std::string TypeName() { return "bool"; }
604 : Detail::RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, true /* isSimple */) {}
605 RField(RField&& other) = default;
606 RField& operator =(RField&& other) = default;
607 ~RField() = default;
608
609 void GenerateColumnsImpl() final;
610 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
611
612 bool *Map(NTupleSize_t globalIndex) {
613 return fPrincipalColumn->Map<bool>(globalIndex);
614 }
615 bool *Map(const RClusterIndex &clusterIndex) {
616 return fPrincipalColumn->Map<bool>(clusterIndex);
617 }
618 bool *MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems) {
619 return fPrincipalColumn->MapV<bool>(globalIndex, nItems);
620 }
621 bool *MapV(const RClusterIndex &clusterIndex, NTupleSize_t &nItems) {
622 return fPrincipalColumn->MapV<bool>(clusterIndex, nItems);
623 }
624
626 template <typename... ArgsT>
628 {
629 return Detail::RFieldValue(
630 Detail::RColumnElement<bool>(static_cast<bool*>(where)),
631 this, static_cast<bool*>(where), std::forward<ArgsT>(args)...);
632 }
633 ROOT::Experimental::Detail::RFieldValue GenerateValue(void* where) final { return GenerateValue(where, false); }
635 return Detail::RFieldValue(true /* captureFlag */,
636 Detail::RColumnElement<bool>(static_cast<bool*>(where)), this, where);
637 }
638 size_t GetValueSize() const final { return sizeof(bool); }
639 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
640};
641
642template <>
643class RField<float> : public Detail::RFieldBase {
644protected:
645 std::unique_ptr<Detail::RFieldBase> CloneImpl(std::string_view newName) const final {
646 return std::make_unique<RField>(newName);
647 }
648
649public:
650 static std::string TypeName() { return "float"; }
652 : Detail::RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, true /* isSimple */) {}
653 RField(RField&& other) = default;
654 RField& operator =(RField&& other) = default;
655 ~RField() = default;
656
657 void GenerateColumnsImpl() final;
658 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
659
660 float *Map(NTupleSize_t globalIndex) {
661 return fPrincipalColumn->Map<float>(globalIndex);
662 }
663 float *Map(const RClusterIndex &clusterIndex) {
664 return fPrincipalColumn->Map<float>(clusterIndex);
665 }
666 float *MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems) {
667 return fPrincipalColumn->MapV<float>(globalIndex, nItems);
668 }
669 float *MapV(const RClusterIndex &clusterIndex, NTupleSize_t &nItems) {
670 return fPrincipalColumn->MapV<float>(clusterIndex, nItems);
671 }
672
674 template <typename... ArgsT>
676 {
677 return Detail::RFieldValue(
678 Detail::RColumnElement<float>(static_cast<float*>(where)),
679 this, static_cast<float*>(where), std::forward<ArgsT>(args)...);
680 }
681 ROOT::Experimental::Detail::RFieldValue GenerateValue(void* where) final { return GenerateValue(where, 0.0); }
683 return Detail::RFieldValue(true /* captureFlag */,
684 Detail::RColumnElement<float>(static_cast<float*>(where)), this, where);
685 }
686 size_t GetValueSize() const final { return sizeof(float); }
687 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
688};
689
690
691template <>
693protected:
694 std::unique_ptr<Detail::RFieldBase> CloneImpl(std::string_view newName) const final {
695 return std::make_unique<RField>(newName);
696 }
697
698public:
699 static std::string TypeName() { return "double"; }
701 : Detail::RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, true /* isSimple */) {}
702 RField(RField&& other) = default;
703 RField& operator =(RField&& other) = default;
704 ~RField() = default;
705
706 void GenerateColumnsImpl() final;
707 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
708
709 double *Map(NTupleSize_t globalIndex) {
710 return fPrincipalColumn->Map<double>(globalIndex);
711 }
712 double *Map(const RClusterIndex &clusterIndex) {
713 return fPrincipalColumn->Map<double>(clusterIndex);
714 }
715 double *MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems) {
716 return fPrincipalColumn->MapV<double>(globalIndex, nItems);
717 }
718 double *MapV(const RClusterIndex &clusterIndex, NTupleSize_t &nItems) {
719 return fPrincipalColumn->MapV<double>(clusterIndex, nItems);
720 }
721
723 template <typename... ArgsT>
725 {
726 return Detail::RFieldValue(
727 Detail::RColumnElement<double>(static_cast<double*>(where)),
728 this, static_cast<double*>(where), std::forward<ArgsT>(args)...);
729 }
730 ROOT::Experimental::Detail::RFieldValue GenerateValue(void* where) final { return GenerateValue(where, 0.0); }
732 return Detail::RFieldValue(true /* captureFlag */,
733 Detail::RColumnElement<double>(static_cast<double*>(where)), this, where);
734 }
735 size_t GetValueSize() const final { return sizeof(double); }
736 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
737};
738
739template <>
740class RField<char> : public Detail::RFieldBase {
741protected:
742 std::unique_ptr<Detail::RFieldBase> CloneImpl(std::string_view newName) const final {
743 return std::make_unique<RField>(newName);
744 }
745
746public:
747 static std::string TypeName() { return "char"; }
749 : Detail::RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, true /* isSimple */) {}
750 RField(RField&& other) = default;
751 RField& operator =(RField&& other) = default;
752 ~RField() = default;
753
754 void GenerateColumnsImpl() final;
755 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
756
757 char *Map(NTupleSize_t globalIndex) {
758 return fPrincipalColumn->Map<char>(globalIndex);
759 }
760 char *Map(const RClusterIndex &clusterIndex) {
761 return fPrincipalColumn->Map<char>(clusterIndex);
762 }
763 char *MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems) {
764 return fPrincipalColumn->MapV<char>(globalIndex, nItems);
765 }
766 char *MapV(const RClusterIndex &clusterIndex, NTupleSize_t &nItems) {
767 return fPrincipalColumn->MapV<char>(clusterIndex, nItems);
768 }
769
771 template <typename... ArgsT>
773 {
774 return Detail::RFieldValue(
775 Detail::RColumnElement<char>(static_cast<char*>(where)),
776 this, static_cast<char*>(where), std::forward<ArgsT>(args)...);
777 }
780 return Detail::RFieldValue(true /* captureFlag */,
781 Detail::RColumnElement<char>(static_cast<char*>(where)), this, where);
782 }
783 size_t GetValueSize() const final { return sizeof(char); }
784 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
785};
786
787template <>
788class RField<std::int8_t> : public Detail::RFieldBase {
789protected:
790 std::unique_ptr<Detail::RFieldBase> CloneImpl(std::string_view newName) const final {
791 return std::make_unique<RField>(newName);
792 }
793
794public:
795 static std::string TypeName() { return "std::int8_t"; }
797 : Detail::RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, true /* isSimple */) {}
798 RField(RField&& other) = default;
799 RField& operator =(RField&& other) = default;
800 ~RField() = default;
801
802 void GenerateColumnsImpl() final;
803 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
804
805 std::int8_t *Map(NTupleSize_t globalIndex) {
806 return fPrincipalColumn->Map<std::int8_t>(globalIndex);
807 }
808 std::int8_t *Map(const RClusterIndex &clusterIndex) {
809 return fPrincipalColumn->Map<std::int8_t>(clusterIndex);
810 }
811 std::int8_t *MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems) {
812 return fPrincipalColumn->MapV<std::int8_t>(globalIndex, nItems);
813 }
814 std::int8_t *MapV(const RClusterIndex &clusterIndex, NTupleSize_t &nItems) {
815 return fPrincipalColumn->MapV<std::int8_t>(clusterIndex, nItems);
816 }
817
819 template <typename... ArgsT>
820 ROOT::Experimental::Detail::RFieldValue GenerateValue(void *where, ArgsT&&... args)
821 {
822 return Detail::RFieldValue(
823 Detail::RColumnElement<std::int8_t>(static_cast<std::int8_t*>(where)),
824 this, static_cast<std::int8_t*>(where), std::forward<ArgsT>(args)...);
825 }
826 ROOT::Experimental::Detail::RFieldValue GenerateValue(void *where) final { return GenerateValue(where, 0); }
827 Detail::RFieldValue CaptureValue(void *where) final {
828 return Detail::RFieldValue(true /* captureFlag */,
829 Detail::RColumnElement<std::int8_t>(static_cast<std::int8_t*>(where)), this, where);
830 }
831 size_t GetValueSize() const final { return sizeof(std::int8_t); }
832 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
833};
834
835template <>
836class RField<std::uint8_t> : public Detail::RFieldBase {
837protected:
838 std::unique_ptr<Detail::RFieldBase> CloneImpl(std::string_view newName) const final {
839 return std::make_unique<RField>(newName);
840 }
841
842public:
843 static std::string TypeName() { return "std::uint8_t"; }
845 : Detail::RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, true /* isSimple */) {}
846 RField(RField&& other) = default;
847 RField& operator =(RField&& other) = default;
848 ~RField() = default;
849
850 void GenerateColumnsImpl() final;
851 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
852
853 std::uint8_t *Map(NTupleSize_t globalIndex) {
854 return fPrincipalColumn->Map<std::uint8_t>(globalIndex);
855 }
856 std::uint8_t *Map(const RClusterIndex &clusterIndex) {
857 return fPrincipalColumn->Map<std::uint8_t>(clusterIndex);
858 }
859 std::uint8_t *MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems) {
860 return fPrincipalColumn->MapV<std::uint8_t>(globalIndex, nItems);
861 }
862 std::uint8_t *MapV(const RClusterIndex &clusterIndex, NTupleSize_t &nItems) {
863 return fPrincipalColumn->MapV<std::uint8_t>(clusterIndex, nItems);
864 }
865
867 template <typename... ArgsT>
868 ROOT::Experimental::Detail::RFieldValue GenerateValue(void *where, ArgsT&&... args)
869 {
870 return Detail::RFieldValue(
871 Detail::RColumnElement<std::uint8_t>(static_cast<std::uint8_t*>(where)),
872 this, static_cast<std::uint8_t*>(where), std::forward<ArgsT>(args)...);
873 }
874 ROOT::Experimental::Detail::RFieldValue GenerateValue(void *where) final { return GenerateValue(where, 0); }
875 Detail::RFieldValue CaptureValue(void *where) final {
876 return Detail::RFieldValue(true /* captureFlag */,
877 Detail::RColumnElement<std::uint8_t>(static_cast<std::uint8_t*>(where)), this, where);
878 }
879 size_t GetValueSize() const final { return sizeof(std::uint8_t); }
880 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
881};
882
883template <>
884class RField<std::int16_t> : public Detail::RFieldBase {
885protected:
886 std::unique_ptr<Detail::RFieldBase> CloneImpl(std::string_view newName) const final {
887 return std::make_unique<RField>(newName);
888 }
889
890public:
891 static std::string TypeName() { return "std::int16_t"; }
893 : Detail::RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, true /* isSimple */) {}
894 RField(RField&& other) = default;
895 RField& operator =(RField&& other) = default;
896 ~RField() = default;
897
898 void GenerateColumnsImpl() final;
899 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
900
901 std::int16_t *Map(NTupleSize_t globalIndex) {
902 return fPrincipalColumn->Map<std::int16_t>(globalIndex);
903 }
904 std::int16_t *Map(const RClusterIndex &clusterIndex) {
905 return fPrincipalColumn->Map<std::int16_t>(clusterIndex);
906 }
907 std::int16_t *MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems) {
908 return fPrincipalColumn->MapV<std::int16_t>(globalIndex, nItems);
909 }
910 std::int16_t *MapV(const RClusterIndex &clusterIndex, NTupleSize_t &nItems) {
911 return fPrincipalColumn->MapV<std::int16_t>(clusterIndex, nItems);
912 }
913
915 template <typename... ArgsT>
916 ROOT::Experimental::Detail::RFieldValue GenerateValue(void* where, ArgsT&&... args)
917 {
918 return Detail::RFieldValue(
919 Detail::RColumnElement<std::int16_t>(static_cast<std::int16_t*>(where)),
920 this, static_cast<std::int16_t*>(where), std::forward<ArgsT>(args)...);
921 }
922 ROOT::Experimental::Detail::RFieldValue GenerateValue(void* where) final { return GenerateValue(where, 0); }
923 Detail::RFieldValue CaptureValue(void *where) final {
924 return Detail::RFieldValue(true /* captureFlag */,
925 Detail::RColumnElement<std::int16_t>(static_cast<std::int16_t*>(where)), this, where);
926 }
927 size_t GetValueSize() const final { return sizeof(std::int16_t); }
928 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
929};
930
931template <>
932class RField<std::uint16_t> : public Detail::RFieldBase {
933protected:
934 std::unique_ptr<Detail::RFieldBase> CloneImpl(std::string_view newName) const final {
935 return std::make_unique<RField>(newName);
936 }
937
938public:
939 static std::string TypeName() { return "std::uint16_t"; }
941 : Detail::RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, true /* isSimple */) {}
942 RField(RField&& other) = default;
943 RField& operator =(RField&& other) = default;
944 ~RField() = default;
945
946 void GenerateColumnsImpl() final;
947 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
948
949 std::uint16_t *Map(NTupleSize_t globalIndex) {
950 return fPrincipalColumn->Map<std::uint16_t>(globalIndex);
951 }
952 std::uint16_t *Map(const RClusterIndex &clusterIndex) {
953 return fPrincipalColumn->Map<std::uint16_t>(clusterIndex);
954 }
955 std::uint16_t *MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems) {
956 return fPrincipalColumn->MapV<std::uint16_t>(globalIndex, nItems);
957 }
958 std::uint16_t *MapV(const RClusterIndex &clusterIndex, NTupleSize_t &nItems) {
959 return fPrincipalColumn->MapV<std::uint16_t>(clusterIndex, nItems);
960 }
961
963 template <typename... ArgsT>
964 ROOT::Experimental::Detail::RFieldValue GenerateValue(void* where, ArgsT&&... args)
965 {
966 return Detail::RFieldValue(
967 Detail::RColumnElement<std::uint16_t>(static_cast<std::uint16_t*>(where)),
968 this, static_cast<std::uint16_t*>(where), std::forward<ArgsT>(args)...);
969 }
970 ROOT::Experimental::Detail::RFieldValue GenerateValue(void* where) final { return GenerateValue(where, 0); }
971 Detail::RFieldValue CaptureValue(void *where) final {
972 return Detail::RFieldValue(true /* captureFlag */,
973 Detail::RColumnElement<std::uint16_t>(static_cast<std::uint16_t*>(where)), this, where);
974 }
975 size_t GetValueSize() const final { return sizeof(std::uint16_t); }
976 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
977};
978
979template <>
980class RField<std::int32_t> : public Detail::RFieldBase {
981protected:
982 std::unique_ptr<Detail::RFieldBase> CloneImpl(std::string_view newName) const final {
983 return std::make_unique<RField>(newName);
984 }
985
986public:
987 static std::string TypeName() { return "std::int32_t"; }
989 : Detail::RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, true /* isSimple */) {}
990 RField(RField&& other) = default;
991 RField& operator =(RField&& other) = default;
992 ~RField() = default;
993
994 void GenerateColumnsImpl() final;
995 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
996
997 std::int32_t *Map(NTupleSize_t globalIndex) {
998 return fPrincipalColumn->Map<std::int32_t>(globalIndex);
999 }
1000 std::int32_t *Map(const RClusterIndex &clusterIndex) {
1001 return fPrincipalColumn->Map<std::int32_t>(clusterIndex);
1002 }
1003 std::int32_t *MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems) {
1004 return fPrincipalColumn->MapV<std::int32_t>(globalIndex, nItems);
1005 }
1006 std::int32_t *MapV(const RClusterIndex &clusterIndex, NTupleSize_t &nItems) {
1007 return fPrincipalColumn->MapV<std::int32_t>(clusterIndex, nItems);
1008 }
1009
1011 template <typename... ArgsT>
1012 ROOT::Experimental::Detail::RFieldValue GenerateValue(void* where, ArgsT&&... args)
1013 {
1014 return Detail::RFieldValue(
1015 Detail::RColumnElement<std::int32_t>(static_cast<std::int32_t*>(where)),
1016 this, static_cast<std::int32_t*>(where), std::forward<ArgsT>(args)...);
1017 }
1018 ROOT::Experimental::Detail::RFieldValue GenerateValue(void* where) final { return GenerateValue(where, 0); }
1019 Detail::RFieldValue CaptureValue(void *where) final {
1020 return Detail::RFieldValue(true /* captureFlag */,
1021 Detail::RColumnElement<std::int32_t>(static_cast<std::int32_t*>(where)), this, where);
1022 }
1023 size_t GetValueSize() const final { return sizeof(std::int32_t); }
1024 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
1025};
1026
1027template <>
1028class RField<std::uint32_t> : public Detail::RFieldBase {
1029protected:
1030 std::unique_ptr<Detail::RFieldBase> CloneImpl(std::string_view newName) const final {
1031 return std::make_unique<RField>(newName);
1032 }
1033
1034public:
1035 static std::string TypeName() { return "std::uint32_t"; }
1036 explicit RField(std::string_view name)
1037 : Detail::RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, true /* isSimple */) {}
1038 RField(RField&& other) = default;
1039 RField& operator =(RField&& other) = default;
1040 ~RField() = default;
1041
1042 void GenerateColumnsImpl() final;
1043 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
1044
1045 std::uint32_t *Map(NTupleSize_t globalIndex) {
1046 return fPrincipalColumn->Map<std::uint32_t>(globalIndex);
1047 }
1048 std::uint32_t *Map(const RClusterIndex clusterIndex) {
1049 return fPrincipalColumn->Map<std::uint32_t>(clusterIndex);
1050 }
1051 std::uint32_t *MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems) {
1052 return fPrincipalColumn->MapV<std::uint32_t>(globalIndex, nItems);
1053 }
1054 std::uint32_t *MapV(const RClusterIndex &clusterIndex, NTupleSize_t &nItems) {
1055 return fPrincipalColumn->MapV<std::uint32_t>(clusterIndex, nItems);
1056 }
1057
1059 template <typename... ArgsT>
1060 ROOT::Experimental::Detail::RFieldValue GenerateValue(void* where, ArgsT&&... args)
1061 {
1062 return Detail::RFieldValue(
1063 Detail::RColumnElement<std::uint32_t>(static_cast<std::uint32_t*>(where)),
1064 this, static_cast<std::uint32_t*>(where), std::forward<ArgsT>(args)...);
1065 }
1066 ROOT::Experimental::Detail::RFieldValue GenerateValue(void* where) final { return GenerateValue(where, 0); }
1067 Detail::RFieldValue CaptureValue(void *where) final {
1068 return Detail::RFieldValue(true /* captureFlag */,
1069 Detail::RColumnElement<std::uint32_t>(static_cast<std::uint32_t*>(where)), this, where);
1070 }
1071 size_t GetValueSize() const final { return sizeof(std::uint32_t); }
1072 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
1073};
1074
1075template <>
1076class RField<std::uint64_t> : public Detail::RFieldBase {
1077protected:
1078 std::unique_ptr<Detail::RFieldBase> CloneImpl(std::string_view newName) const final {
1079 return std::make_unique<RField>(newName);
1080 }
1081
1082public:
1083 static std::string TypeName() { return "std::uint64_t"; }
1084 explicit RField(std::string_view name)
1085 : Detail::RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, true /* isSimple */) {}
1086 RField(RField&& other) = default;
1087 RField& operator =(RField&& other) = default;
1088 ~RField() = default;
1089
1090 void GenerateColumnsImpl() final;
1091 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
1092
1093 std::uint64_t *Map(NTupleSize_t globalIndex) {
1094 return fPrincipalColumn->Map<std::uint64_t>(globalIndex);
1095 }
1096 std::uint64_t *Map(const RClusterIndex &clusterIndex) {
1097 return fPrincipalColumn->Map<std::uint64_t>(clusterIndex);
1098 }
1099 std::uint64_t *MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems) {
1100 return fPrincipalColumn->MapV<std::uint64_t>(globalIndex, nItems);
1101 }
1102 std::uint64_t *MapV(const RClusterIndex &clusterIndex, NTupleSize_t &nItems) {
1103 return fPrincipalColumn->MapV<std::uint64_t>(clusterIndex, nItems);
1104 }
1105
1107 template <typename... ArgsT>
1108 ROOT::Experimental::Detail::RFieldValue GenerateValue(void* where, ArgsT&&... args)
1109 {
1110 return Detail::RFieldValue(
1111 Detail::RColumnElement<std::uint64_t>(static_cast<std::uint64_t*>(where)),
1112 this, static_cast<std::uint64_t*>(where), std::forward<ArgsT>(args)...);
1113 }
1114 ROOT::Experimental::Detail::RFieldValue GenerateValue(void* where) final { return GenerateValue(where, 0); }
1115 Detail::RFieldValue CaptureValue(void *where) final {
1116 return Detail::RFieldValue(true /* captureFlag */,
1117 Detail::RColumnElement<std::uint64_t>(static_cast<std::uint64_t*>(where)), this, where);
1118 }
1119 size_t GetValueSize() const final { return sizeof(std::uint64_t); }
1120 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
1121};
1122
1123template <>
1124class RField<std::int64_t> : public Detail::RFieldBase {
1125protected:
1126 std::unique_ptr<Detail::RFieldBase> CloneImpl(std::string_view newName) const final {
1127 return std::make_unique<RField>(newName);
1128 }
1129
1130public:
1131 static std::string TypeName() { return "std::int64_t"; }
1132 explicit RField(std::string_view name)
1133 : Detail::RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, true /* isSimple */) {}
1134 RField(RField&& other) = default;
1135 RField& operator =(RField&& other) = default;
1136 ~RField() = default;
1137
1138 void GenerateColumnsImpl() final;
1139 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
1140
1141 std::int64_t *Map(NTupleSize_t globalIndex) {
1142 return fPrincipalColumn->Map<std::int64_t>(globalIndex);
1143 }
1144 std::int64_t *Map(const RClusterIndex &clusterIndex) {
1145 return fPrincipalColumn->Map<std::int64_t>(clusterIndex);
1146 }
1147 std::int64_t *MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems) {
1148 return fPrincipalColumn->MapV<std::int64_t>(globalIndex, nItems);
1149 }
1150 std::int64_t *MapV(const RClusterIndex &clusterIndex, NTupleSize_t &nItems) {
1151 return fPrincipalColumn->MapV<std::int64_t>(clusterIndex, nItems);
1152 }
1153
1155 template <typename... ArgsT>
1156 ROOT::Experimental::Detail::RFieldValue GenerateValue(void* where, ArgsT&&... args)
1157 {
1158 return Detail::RFieldValue(
1159 Detail::RColumnElement<std::int64_t>(static_cast<std::int64_t*>(where)),
1160 this, static_cast<std::int64_t*>(where), std::forward<ArgsT>(args)...);
1161 }
1162 ROOT::Experimental::Detail::RFieldValue GenerateValue(void* where) final { return GenerateValue(where, 0); }
1163 Detail::RFieldValue CaptureValue(void *where) final {
1164 return Detail::RFieldValue(true /* captureFlag */,
1165 Detail::RColumnElement<std::int64_t>(static_cast<std::int64_t*>(where)), this, where);
1166 }
1167 size_t GetValueSize() const final { return sizeof(std::int64_t); }
1168 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
1169};
1170
1171template <>
1172class RField<std::string> : public Detail::RFieldBase {
1173private:
1174 ClusterSize_t fIndex;
1175 Detail::RColumnElement<ClusterSize_t, EColumnType::kIndex> fElemIndex;
1176
1177 std::unique_ptr<Detail::RFieldBase> CloneImpl(std::string_view newName) const final {
1178 return std::make_unique<RField>(newName);
1179 }
1180 std::size_t AppendImpl(const ROOT::Experimental::Detail::RFieldValue& value) final;
1181 void ReadGlobalImpl(ROOT::Experimental::NTupleSize_t globalIndex,
1183
1184public:
1185 static std::string TypeName() { return "std::string"; }
1186 explicit RField(std::string_view name)
1187 : Detail::RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, false /* isSimple */)
1188 , fIndex(0), fElemIndex(&fIndex) {}
1189 RField(RField&& other) = default;
1190 RField& operator =(RField&& other) = default;
1191 ~RField() = default;
1192
1193 void GenerateColumnsImpl() final;
1194 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
1195
1196 using Detail::RFieldBase::GenerateValue;
1197 template <typename... ArgsT>
1198 ROOT::Experimental::Detail::RFieldValue GenerateValue(void* where, ArgsT&&... args)
1199 {
1200 return Detail::RFieldValue(this, static_cast<std::string*>(where), std::forward<ArgsT>(args)...);
1201 }
1202 ROOT::Experimental::Detail::RFieldValue GenerateValue(void* where) final { return GenerateValue(where, ""); }
1203 void DestroyValue(const Detail::RFieldValue& value, bool dtorOnly = false) {
1204 auto str = value.Get<std::string>();
1205 str->~basic_string(); // TODO(jblomer) C++17 std::destroy_at
1206 if (!dtorOnly)
1207 free(str);
1208 }
1209 Detail::RFieldValue CaptureValue(void *where) {
1210 return Detail::RFieldValue(true /* captureFlag */, this, where);
1211 }
1212 size_t GetValueSize() const final { return sizeof(std::string); }
1213 size_t GetAlignment() const final { return std::alignment_of<std::string>(); }
1214 void CommitCluster() final;
1215 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
1216};
1217
1218
1219template <typename ItemT, std::size_t N>
1220class RField<std::array<ItemT, N>> : public RArrayField {
1221 using ContainerT = typename std::array<ItemT, N>;
1222public:
1223 static std::string TypeName() {
1224 return "std::array<" + RField<ItemT>::TypeName() + "," + std::to_string(N) + ">";
1225 }
1226 explicit RField(std::string_view name)
1227 : RArrayField(name, std::make_unique<RField<ItemT>>(RField<ItemT>::TypeName()), N)
1228 {}
1229 RField(RField&& other) = default;
1230 RField& operator =(RField&& other) = default;
1231 ~RField() = default;
1232
1234 template <typename... ArgsT>
1235 ROOT::Experimental::Detail::RFieldValue GenerateValue(void *where, ArgsT&&... args)
1236 {
1237 return Detail::RFieldValue(this, static_cast<ContainerT*>(where), std::forward<ArgsT>(args)...);
1238 }
1239 ROOT::Experimental::Detail::RFieldValue GenerateValue(void *where) final {
1240 return GenerateValue(where, ContainerT());
1241 }
1242};
1243
1244
1245#if __cplusplus >= 201703L
1246template <typename... ItemTs>
1247class RField<std::variant<ItemTs...>> : public RVariantField {
1248 using ContainerT = typename std::variant<ItemTs...>;
1249private:
1250 template <typename HeadT, typename... TailTs>
1251 static std::string BuildItemTypes()
1252 {
1253 std::string result = RField<HeadT>::TypeName();
1254 if constexpr(sizeof...(TailTs) > 0)
1255 result += "," + BuildItemTypes<TailTs...>();
1256 return result;
1257 }
1258
1259 template <typename HeadT, typename... TailTs>
1260 static std::vector<Detail::RFieldBase *> BuildItemFields(unsigned int index = 0)
1261 {
1262 std::vector<Detail::RFieldBase *> result;
1263 result.emplace_back(new RField<HeadT>("variant" + std::to_string(index)));
1264 if constexpr(sizeof...(TailTs) > 0) {
1265 auto tailFields = BuildItemFields<TailTs...>(index + 1);
1266 result.insert(result.end(), tailFields.begin(), tailFields.end());
1267 }
1268 return result;
1269 }
1270
1271public:
1272 static std::string TypeName() { return "std::variant<" + BuildItemTypes<ItemTs...>() + ">"; }
1273 explicit RField(std::string_view name) : RVariantField(name, BuildItemFields<ItemTs...>()) {}
1274 RField(RField&& other) = default;
1275 RField& operator =(RField&& other) = default;
1276 ~RField() = default;
1277
1279 template <typename... ArgsT>
1280 ROOT::Experimental::Detail::RFieldValue GenerateValue(void *where, ArgsT&&... args)
1281 {
1282 return Detail::RFieldValue(this, static_cast<ContainerT*>(where), std::forward<ArgsT>(args)...);
1283 }
1284 ROOT::Experimental::Detail::RFieldValue GenerateValue(void *where) final {
1285 return GenerateValue(where, ContainerT());
1286 }
1287};
1288#endif
1289
1290template <typename ItemT>
1291class RField<std::vector<ItemT>> : public RVectorField {
1292 using ContainerT = typename std::vector<ItemT>;
1293public:
1294 static std::string TypeName() { return "std::vector<" + RField<ItemT>::TypeName() + ">"; }
1295 explicit RField(std::string_view name)
1296 : RVectorField(name, std::make_unique<RField<ItemT>>(RField<ItemT>::TypeName()))
1297 {}
1298 RField(RField&& other) = default;
1299 RField& operator =(RField&& other) = default;
1300 ~RField() = default;
1301
1303 template <typename... ArgsT>
1304 ROOT::Experimental::Detail::RFieldValue GenerateValue(void* where, ArgsT&&... args)
1305 {
1306 return Detail::RFieldValue(this, static_cast<ContainerT*>(where), std::forward<ArgsT>(args)...);
1307 }
1308 ROOT::Experimental::Detail::RFieldValue GenerateValue(void* where) final {
1309 return GenerateValue(where, ContainerT());
1310 }
1311 Detail::RFieldValue CaptureValue(void *where) final {
1312 return Detail::RFieldValue(true /* captureFlag */, this, where);
1313 }
1314 size_t GetValueSize() const final { return sizeof(ContainerT); }
1315};
1316
1317// std::vector<bool> is a template specialization and needs special treatment
1318template <>
1319class RField<std::vector<bool>> : public Detail::RFieldBase {
1320private:
1321 ClusterSize_t fNWritten{0};
1322
1323protected:
1324 std::unique_ptr<Detail::RFieldBase> CloneImpl(std::string_view newName) const final {
1325 return std::make_unique<RField>(newName);
1326 }
1327 std::size_t AppendImpl(const Detail::RFieldValue& value) final;
1328 void ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue *value) final;
1329 void GenerateColumnsImpl() final;
1330 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
1331
1332public:
1333 static std::string TypeName() { return "std::vector<bool>"; }
1334 explicit RField(std::string_view name);
1335 RField(RField&& other) = default;
1336 RField& operator =(RField&& other) = default;
1337 ~RField() = default;
1338
1340 template <typename... ArgsT>
1341 ROOT::Experimental::Detail::RFieldValue GenerateValue(void* where, ArgsT&&... args)
1342 {
1343 return Detail::RFieldValue(this, static_cast<std::vector<bool>*>(where), std::forward<ArgsT>(args)...);
1344 }
1345 ROOT::Experimental::Detail::RFieldValue GenerateValue(void* where) final {
1346 return GenerateValue(where, std::vector<bool>());
1347 }
1348 Detail::RFieldValue CaptureValue(void *where) final {
1349 return Detail::RFieldValue(true /* captureFlag */, this, where);
1350 }
1351 std::vector<Detail::RFieldValue> SplitValue(const Detail::RFieldValue &value) const final;
1352 void DestroyValue(const Detail::RFieldValue& value, bool dtorOnly = false) final;
1353
1354 size_t GetValueSize() const final { return sizeof(std::vector<bool>); }
1355 size_t GetAlignment() const final { return std::alignment_of<std::vector<bool>>(); }
1356 void CommitCluster() final { fNWritten = 0; }
1357 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
1358 void GetCollectionInfo(NTupleSize_t globalIndex, RClusterIndex *collectionStart, ClusterSize_t *size) const {
1359 fPrincipalColumn->GetCollectionInfo(globalIndex, collectionStart, size);
1360 }
1361 void GetCollectionInfo(const RClusterIndex &clusterIndex, RClusterIndex *collectionStart, ClusterSize_t *size) const
1362 {
1363 fPrincipalColumn->GetCollectionInfo(clusterIndex, collectionStart, size);
1364 }
1365};
1366
1367
1368/**
1369 * The RVec type has different layouts depending on the item type, therefore we cannot go with a generic
1370 * RVec implementation as we can with std::vector
1371 */
1372template <typename ItemT>
1375private:
1378
1379protected:
1380 std::unique_ptr<Detail::RFieldBase> CloneImpl(std::string_view newName) const final {
1381 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetName());
1382 return std::make_unique<RField<ROOT::VecOps::RVec<ItemT>>>(newName, std::move(newItemField));
1383 }
1384 std::size_t AppendImpl(const Detail::RFieldValue& value) final {
1385 auto typedValue = value.Get<ContainerT>();
1386 auto nbytes = 0;
1387 auto count = typedValue->size();
1388 for (unsigned i = 0; i < count; ++i) {
1389 auto itemValue = fSubFields[0]->CaptureValue(&typedValue->data()[i]);
1390 nbytes += fSubFields[0]->Append(itemValue);
1391 }
1393 fNWritten += count;
1394 fColumns[0]->Append(elemIndex);
1395 return nbytes + sizeof(elemIndex);
1396 }
1397 void ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue *value) final {
1398 auto typedValue = value->Get<ContainerT>();
1399 ClusterSize_t nItems;
1400 RClusterIndex collectionStart;
1401 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
1402 typedValue->resize(nItems);
1403 for (unsigned i = 0; i < nItems; ++i) {
1404 auto itemValue = fSubFields[0]->GenerateValue(&typedValue->data()[i]);
1405 fSubFields[0]->Read(collectionStart + i, &itemValue);
1406 }
1407 }
1408
1409public:
1410 RField(std::string_view fieldName, std::unique_ptr<Detail::RFieldBase> itemField)
1411 : ROOT::Experimental::Detail::RFieldBase(
1412 fieldName, "ROOT::VecOps::RVec<" + itemField->GetType() + ">", ENTupleStructure::kCollection, false)
1413 , fItemSize(itemField->GetValueSize()), fNWritten(0)
1414 {
1415 Attach(std::move(itemField));
1416 }
1418 : RField(name, std::make_unique<RField<ItemT>>(RField<ItemT>::TypeName()))
1419 {
1420 }
1421 RField(RField&& other) = default;
1422 RField& operator =(RField&& other) = default;
1423 ~RField() = default;
1424
1425 void GenerateColumnsImpl() final {
1426 RColumnModel modelIndex(EColumnType::kIndex, true /* isSorted*/);
1427 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
1428 Detail::RColumn::Create<ClusterSize_t, EColumnType::kIndex>(modelIndex, 0)));
1429 }
1430 // TODO(jblomer): update together with RVec 2.0
1431 void GenerateColumnsImpl(const RNTupleDescriptor & /*desc*/) final {
1432 GenerateColumnsImpl();
1433 }
1434 void DestroyValue(const Detail::RFieldValue& value, bool dtorOnly = false) final {
1435 auto vec = reinterpret_cast<ContainerT*>(value.GetRawPtr());
1436 vec->~RVec();
1437 if (!dtorOnly)
1438 free(vec);
1439 }
1440 void CommitCluster() final { fNWritten = 0; }
1441
1442 static std::string TypeName() { return "ROOT::VecOps::RVec<" + RField<ItemT>::TypeName() + ">"; }
1443
1445 template <typename... ArgsT>
1447 {
1448 return Detail::RFieldValue(this, static_cast<ContainerT*>(where), std::forward<ArgsT>(args)...);
1449 }
1451 return GenerateValue(where, ContainerT());
1452 }
1454 return Detail::RFieldValue(true /* captureFlag */, this, static_cast<ContainerT*>(where));
1455 }
1456 size_t GetValueSize() const final { return sizeof(ContainerT); }
1457 size_t GetAlignment() const final { return std::alignment_of<ContainerT>(); }
1458};
1459
1460/**
1461 * RVec<bool> needs special treatment due to std::vector<bool> sepcialization
1462 */
1463template <>
1466private:
1467 ClusterSize_t fNWritten{0};
1468
1469protected:
1470 std::unique_ptr<Detail::RFieldBase> CloneImpl(std::string_view newName) const final {
1471 return std::make_unique<RField<ROOT::VecOps::RVec<bool>>>(newName);
1472 }
1473 std::size_t AppendImpl(const Detail::RFieldValue& value) final {
1474 auto typedValue = value.Get<ContainerT>();
1475 auto count = typedValue->size();
1476 for (unsigned i = 0; i < count; ++i) {
1477 bool bval = (*typedValue)[i];
1478 auto itemValue = fSubFields[0]->CaptureValue(&bval);
1479 fSubFields[0]->Append(itemValue);
1480 }
1482 fNWritten += count;
1483 fColumns[0]->Append(elemIndex);
1484 return count + sizeof(elemIndex);
1485 }
1486 void ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue *value) final {
1487 auto typedValue = value->Get<ContainerT>();
1488 ClusterSize_t nItems;
1489 RClusterIndex collectionStart;
1490 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
1491 typedValue->resize(nItems);
1492 for (unsigned i = 0; i < nItems; ++i) {
1493 bool bval = (*typedValue)[i];
1494 auto itemValue = fSubFields[0]->GenerateValue(&bval);
1495 fSubFields[0]->Read(collectionStart + i, &itemValue);
1496 (*typedValue)[i] = bval;
1497 }
1498 }
1499
1500public:
1502 : ROOT::Experimental::Detail::RFieldBase(name, "ROOT::VecOps::RVec<bool>", ENTupleStructure::kCollection, false)
1503 {
1504 Attach(std::make_unique<RField<bool>>("bool"));
1505 }
1506 RField(RField&& other) = default;
1507 RField& operator =(RField&& other) = default;
1508 ~RField() = default;
1509
1510 void GenerateColumnsImpl() final {
1511 RColumnModel modelIndex(EColumnType::kIndex, true /* isSorted*/);
1512 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
1513 Detail::RColumn::Create<ClusterSize_t, EColumnType::kIndex>(modelIndex, 0)));
1514 }
1515 // TODO(jblomer): update together with RVec 2.0
1516 void GenerateColumnsImpl(const RNTupleDescriptor & /*desc*/) final {
1517 GenerateColumnsImpl();
1518 }
1519 void DestroyValue(const Detail::RFieldValue& value, bool dtorOnly = false) final {
1520 auto vec = reinterpret_cast<ContainerT*>(value.GetRawPtr());
1521 vec->~RVec();
1522 if (!dtorOnly)
1523 free(vec);
1524 }
1525 void CommitCluster() final { fNWritten = 0; }
1526
1527 static std::string TypeName() { return "ROOT::VecOps::RVec<bool>"; }
1528
1530 template <typename... ArgsT>
1532 {
1533 return Detail::RFieldValue(this, static_cast<ContainerT*>(where), std::forward<ArgsT>(args)...);
1534 }
1536 return GenerateValue(where, ContainerT());
1537 }
1539 return Detail::RFieldValue(true /* captureFlag */, this, static_cast<ContainerT*>(where));
1540 }
1541 size_t GetValueSize() const final { return sizeof(ContainerT); }
1542 size_t GetAlignment() const final { return std::alignment_of<ContainerT>(); }
1543};
1544
1545} // namespace Experimental
1546} // namespace ROOT
1547
1548#endif
double
Definition: Converters.cxx:939
uint8_t
Definition: Converters.cxx:876
ROOT::R::TRInterface & r
Definition: Object.C:4
ROOT::Experimental::RField< T > RField
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
#define N
XFontStruct * id
Definition: TGX11.cxx:109
char name[80]
Definition: TGX11.cxx:110
int type
Definition: TGX11.cxx:121
Binding & operator=(OUT(*fun)(void))
#define free
Definition: civetweb.c:1539
Pairs of C++ type and column type, like float and EColumnType::kReal32.
void Append(const RColumnElementBase &element)
Definition: RColumn.hxx:116
void Read(const NTupleSize_t globalIndex, RColumnElementBase *element)
Definition: RColumn.hxx:157
NTupleSize_t GetGlobalIndex(const RClusterIndex &clusterIndex)
Definition: RColumn.hxx:248
NTupleSize_t GetNElements() const
Definition: RColumn.hxx:307
void GetCollectionInfo(const NTupleSize_t globalIndex, RClusterIndex *collectionStart, ClusterSize_t *collectionSize)
For offset columns only, look at the two adjacent values that define a collection's coordinates.
Definition: RColumn.hxx:264
Iterates over the sub tree of fields in depth-first search order.
Definition: RField.hxx:130
void Advance()
Given that the iterator points to a valid field which is not the end iterator, go to the next field i...
Definition: RField.cxx:368
std::vector< Position > fStack
The stack of nodes visited when walking down the tree of fields.
Definition: RField.hxx:139
RFieldBase * GetParent() const
Definition: RField.hxx:240
virtual RFieldValue CaptureValue(void *where)=0
Creates a value from a memory location with an already constructed object.
std::string GetDescription() const
Get the field's description.
Definition: RField.hxx:244
void SetOnDiskId(DescriptorId_t id)
Definition: RField.hxx:248
virtual void GenerateColumnsImpl(const RNTupleDescriptor &desc)=0
Creates the backing columns corresponsing to the field type for reading.
virtual void GenerateColumnsImpl()=0
Creates the backing columns corresponsing to the field type for writing.
std::vector< std::unique_ptr< RFieldBase > > fSubFields
Collections and classes own sub fields.
Definition: RField.hxx:95
RFieldBase * fParent
Sub fields point to their mother field.
Definition: RField.hxx:97
RFieldBase(std::string_view name, std::string_view type, ENTupleStructure structure, bool isSimple, std::size_t nRepetitions=0)
The constructor creates the underlying column objects and connects them to either a sink or a source.
Definition: RField.cxx:119
std::size_t GetNRepetitions() const
Definition: RField.hxx:238
std::string fDescription
Free text set by the user.
Definition: RField.hxx:91
virtual void DestroyValue(const RFieldValue &value, bool dtorOnly=false)
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
Definition: RField.cxx:253
virtual RNTupleVersion GetTypeVersion() const
Indicates an evolution of the C++ type itself.
Definition: RField.hxx:258
DescriptorId_t GetOnDiskId() const
Definition: RField.hxx:247
void ConnectPageSink(RPageSink &pageSink)
Fields and their columns live in the void until connected to a physical page storage.
Definition: RField.cxx:324
ROOT::Experimental::EColumnType EnsureColumnType(const std::vector< EColumnType > &requestedTypes, unsigned int columnIndex, const RNTupleDescriptor &desc)
Throws an exception if the column given by fOnDiskId and the columnIndex in the provided descriptor i...
Definition: RField.cxx:291
void Flush() const
Ensure that all received items are written from page buffers to the storage.
Definition: RField.cxx:283
virtual void ReadInClusterImpl(const RClusterIndex &clusterIndex, RFieldValue *value)
Definition: RField.hxx:119
virtual void CommitCluster()
Perform housekeeping tasks for global to cluster-local index translation.
Definition: RField.hxx:230
virtual size_t GetAlignment() const
For many types, the alignment requirement is equal to the size; otherwise override.
Definition: RField.hxx:197
virtual std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const =0
Called by Clone(), which additionally copies the on-disk ID.
virtual size_t GetValueSize() const =0
The number of bytes taken by a value of the appropriate type.
void SetDescription(std::string_view description)
Definition: RField.hxx:245
virtual std::vector< RFieldValue > SplitValue(const RFieldValue &value) const
Creates the list of direct child values given a value for this field.
Definition: RField.cxx:260
static RResult< void > EnsureValidFieldName(std::string_view fieldName)
Check whether a given string is a valid field name.
Definition: RField.cxx:214
bool fIsSimple
A field on a trivial type that maps as-is to a single column.
Definition: RField.hxx:85
std::string fType
The C++ type captured by this field.
Definition: RField.hxx:79
static RResult< std::unique_ptr< RFieldBase > > Create(const std::string &fieldName, const std::string &typeName)
Factory method to resurrect a field from the stored on-disk type information.
Definition: RField.cxx:131
std::string fName
The field name relative to its parent field.
Definition: RField.hxx:77
virtual RNTupleVersion GetFieldVersion() const
Indicates an evolution of the mapping scheme from C++ type to columns.
Definition: RField.hxx:256
NTupleSize_t GetNElements() const
Definition: RField.hxx:239
void ConnectPageSource(RPageSource &pageSource)
Definition: RField.cxx:335
std::size_t Append(const RFieldValue &value)
Write the given value into columns.
Definition: RField.hxx:201
virtual std::size_t AppendImpl(const RFieldValue &value)
Operations on values of complex types, e.g.
Definition: RField.cxx:233
std::unique_ptr< RFieldBase > Clone(std::string_view newName) const
Copies the field and its sub fields using a possibly new name and a new, unconnected set of columns.
Definition: RField.cxx:225
std::size_t fNRepetitions
For fixed sized arrays, the array length.
Definition: RField.hxx:83
RFieldBase(const RFieldBase &)=delete
virtual void AcceptVisitor(RFieldVisitor &visitor) const
Definition: RField.cxx:346
DescriptorId_t fOnDiskId
When the columns are connected to a page source or page sink, the field represents a field id in the ...
Definition: RField.hxx:89
virtual void ReadGlobalImpl(NTupleSize_t globalIndex, RFieldValue *value)
Definition: RField.cxx:239
ENTupleStructure fStructure
The role of this field in the data model structure.
Definition: RField.hxx:81
void Read(const RClusterIndex &clusterIndex, RFieldValue *value)
Definition: RField.hxx:219
std::vector< std::unique_ptr< RColumn > > fColumns
The columns are connected either to a sink or to a source (not to both); they are owned by the field.
Definition: RField.hxx:103
void Attach(std::unique_ptr< Detail::RFieldBase > child)
Add a new subfield to the list of nested fields.
Definition: RField.cxx:265
std::vector< RFieldBase * > GetSubFields() const
Definition: RField.cxx:273
virtual RFieldValue GenerateValue(void *where)=0
Generates a tree value in a given location of size at least GetValueSize().
RFieldBase & operator=(const RFieldBase &)=delete
ENTupleStructure GetStructure() const
Definition: RField.hxx:237
void Read(NTupleSize_t globalIndex, RFieldValue *value)
Populate a single value with data from the tree, which needs to be of the fitting type.
Definition: RField.hxx:211
RFieldValue GenerateValue()
Generates an object of the field type and allocates new initialized memory according to the type.
Definition: RField.cxx:246
RColumn * fPrincipalColumn
Points into fColumns.
Definition: RField.hxx:101
RColumnElementBase fMappedElement
For simple types, the mapped element drills through the layers from the C++ data representation to th...
Definition: RFieldValue.hxx:53
Abstract base class for classes implementing the visitor design pattern.
Abstract interface to write data into an ntuple.
Abstract interface to read data from an ntuple.
The available trivial, native content types of a column.
The generic field for fixed size arrays, which do not need an offset column.
Definition: RField.hxx:408
std::vector< Detail::RFieldValue > SplitValue(const Detail::RFieldValue &value) const final
Creates the list of direct child values given a value for this field.
Definition: RField.cxx:1269
Detail::RFieldValue CaptureValue(void *where) final
Creates a value from a memory location with an already constructed object.
Definition: RField.cxx:1263
void ReadInClusterImpl(const RClusterIndex &clusterIndex, Detail::RFieldValue *value) final
Definition: RField.cxx:1225
void ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue *value) final
Definition: RField.cxx:1216
RArrayField(std::string_view fieldName, std::unique_ptr< Detail::RFieldBase > itemField, std::size_t arrayLength)
Definition: RField.cxx:1189
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
Definition: RField.cxx:1280
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
Definition: RField.cxx:1235
RArrayField & operator=(RArrayField &&other)=default
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
Definition: RField.hxx:433
RArrayField(RArrayField &&other)=default
void DestroyValue(const Detail::RFieldValue &value, bool dtorOnly=false) final
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
Definition: RField.cxx:1252
size_t GetAlignment() const final
For many types, the alignment requirement is equal to the size; otherwise override.
Definition: RField.hxx:434
std::size_t AppendImpl(const Detail::RFieldValue &value) final
Operations on values of complex types, e.g.
Definition: RField.cxx:1206
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
Definition: RField.cxx:1200
The field for a class with dictionary.
Definition: RField.hxx:291
Detail::RFieldValue CaptureValue(void *where) final
Creates a value from a memory location with an already constructed object.
Definition: RField.cxx:841
static constexpr const char * kPrefixInherited
Prefix used in the subfield names generated for base classes.
Definition: RField.hxx:302
size_t GetValueSize() const override
The number of bytes taken by a value of the appropriate type.
Definition: RField.cxx:859
void Attach(std::unique_ptr< Detail::RFieldBase > child, RSubFieldInfo info)
Definition: RField.cxx:783
std::vector< Detail::RFieldValue > SplitValue(const Detail::RFieldValue &value) const final
Creates the list of direct child values given a value for this field.
Definition: RField.cxx:848
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
Definition: RField.cxx:791
std::size_t AppendImpl(const Detail::RFieldValue &value) final
Operations on values of complex types, e.g.
Definition: RField.cxx:796
RClassField & operator=(RClassField &&other)=default
void AcceptVisitor(Detail::RFieldVisitor &visitor) const override
Definition: RField.cxx:864
size_t GetAlignment() const final
For many types, the alignment requirement is equal to the size; otherwise override.
Definition: RField.hxx:333
void ReadInClusterImpl(const RClusterIndex &clusterIndex, Detail::RFieldValue *value) final
Definition: RField.cxx:813
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
Definition: RField.cxx:821
RClassField(std::string_view fieldName, std::string_view className, TClass *classp)
Definition: RField.cxx:755
std::vector< RSubFieldInfo > fSubFieldsInfo
Additional information kept for each entry in fSubFields
Definition: RField.hxx:306
void ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue *value) final
Definition: RField.cxx:805
RClassField(RClassField &&other)=default
void DestroyValue(const Detail::RFieldValue &value, bool dtorOnly=false) final
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
Definition: RField.cxx:834
Addresses a column element or field item relative to a particular cluster, instead of a global NTuple...
The collection field is only used for writing; when reading, untyped collections are projected to an ...
Definition: RField.hxx:501
Detail::RFieldValue CaptureValue(void *where) final
Creates a value from a memory location with an already constructed object.
Definition: RField.hxx:525
static std::string TypeName()
Definition: RField.hxx:508
std::shared_ptr< RCollectionNTupleWriter > fCollectionNTuple
Save the link to the collection ntuple in order to reset the offset counter when committing the clust...
Definition: RField.hxx:504
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
Definition: RField.hxx:529
RCollectionField(RCollectionField &&other)=default
Holds the static meta-data of a column in a tree.
A field translates read and write calls from/to underlying columns to/from tree values.
Definition: RField.hxx:58
Represents transient storage of simple or complex C++ values.
Definition: RFieldValue.hxx:28
The container field for an ntuple model, which itself has no physical representation.
Definition: RField.hxx:271
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
Definition: RField.cxx:413
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const
Called by Clone(), which additionally copies the on-disk ID.
Definition: RField.cxx:395
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
Definition: RField.hxx:283
Detail::RFieldValue GenerateValue(void *)
Generates a tree value in a given location of size at least GetValueSize().
Definition: RField.hxx:281
std::unique_ptr< REntry > GenerateEntry() const
Generates managed values for the top-level sub fields.
Definition: RField.cxx:404
Detail::RFieldValue CaptureValue(void *) final
Creates a value from a memory location with an already constructed object.
Definition: RField.hxx:282
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
Definition: RField.hxx:278
void GenerateColumnsImpl(const RNTupleDescriptor &) final
Creates the backing columns corresponsing to the field type for reading.
Definition: RField.hxx:279
void GetCollectionInfo(const RClusterIndex &clusterIndex, RClusterIndex *collectionStart, ClusterSize_t *size)
Definition: RField.hxx:587
ClusterSize_t * MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems)
Definition: RField.hxx:561
ClusterSize_t * Map(const RClusterIndex &clusterIndex)
Definition: RField.hxx:558
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
Detail::RFieldValue CaptureValue(void *where) final
Creates a value from a memory location with an already constructed object.
Definition: RField.hxx:577
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
Definition: RField.hxx:581
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
ClusterSize_t * MapV(const RClusterIndex &clusterIndex, NTupleSize_t &nItems)
Definition: RField.hxx:564
void GetCollectionInfo(NTupleSize_t globalIndex, RClusterIndex *collectionStart, ClusterSize_t *size)
Special help for offset fields.
Definition: RField.hxx:584
ROOT::Experimental::Detail::RFieldValue GenerateValue(void *where, ArgsT &&... args)
Definition: RField.hxx:570
ROOT::Experimental::Detail::RFieldValue GenerateValue(void *where) final
Generates a tree value in a given location of size at least GetValueSize().
Definition: RField.hxx:576
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
Definition: RField.hxx:540
Detail::RFieldValue CaptureValue(void *where) final
Creates a value from a memory location with an already constructed object.
Definition: RField.hxx:1453
ROOT::Experimental::Detail::RFieldValue GenerateValue(void *where) final
Generates a tree value in a given location of size at least GetValueSize().
Definition: RField.hxx:1450
void ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue *value) final
Definition: RField.hxx:1397
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
Definition: RField.hxx:1456
std::size_t AppendImpl(const Detail::RFieldValue &value) final
Operations on values of complex types, e.g.
Definition: RField.hxx:1384
typename ROOT::VecOps::RVec< ItemT > ContainerT
Definition: RField.hxx:1374
void GenerateColumnsImpl(const RNTupleDescriptor &) final
Creates the backing columns corresponsing to the field type for reading.
Definition: RField.hxx:1431
RField(std::string_view fieldName, std::unique_ptr< Detail::RFieldBase > itemField)
Definition: RField.hxx:1410
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
Definition: RField.hxx:1380
size_t GetAlignment() const final
For many types, the alignment requirement is equal to the size; otherwise override.
Definition: RField.hxx:1457
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
Definition: RField.hxx:1425
ROOT::Experimental::Detail::RFieldValue GenerateValue(void *where, ArgsT &&... args)
Definition: RField.hxx:1446
void CommitCluster() final
Perform housekeeping tasks for global to cluster-local index translation.
Definition: RField.hxx:1440
void DestroyValue(const Detail::RFieldValue &value, bool dtorOnly=false) final
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
Definition: RField.hxx:1434
void DestroyValue(const Detail::RFieldValue &value, bool dtorOnly=false) final
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
Definition: RField.hxx:1519
Detail::RFieldValue CaptureValue(void *where) final
Creates a value from a memory location with an already constructed object.
Definition: RField.hxx:1538
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
Definition: RField.hxx:1510
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
Definition: RField.hxx:1470
std::size_t AppendImpl(const Detail::RFieldValue &value) final
Operations on values of complex types, e.g.
Definition: RField.hxx:1473
ROOT::Experimental::Detail::RFieldValue GenerateValue(void *where, ArgsT &&... args)
Definition: RField.hxx:1531
ROOT::Experimental::Detail::RFieldValue GenerateValue(void *where) final
Generates a tree value in a given location of size at least GetValueSize().
Definition: RField.hxx:1535
size_t GetAlignment() const final
For many types, the alignment requirement is equal to the size; otherwise override.
Definition: RField.hxx:1542
void CommitCluster() final
Perform housekeeping tasks for global to cluster-local index translation.
Definition: RField.hxx:1525
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
Definition: RField.hxx:1541
void GenerateColumnsImpl(const RNTupleDescriptor &) final
Creates the backing columns corresponsing to the field type for reading.
Definition: RField.hxx:1516
typename ROOT::VecOps::RVec< bool > ContainerT
Definition: RField.hxx:1465
void ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue *value) final
Definition: RField.hxx:1486
bool * MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems)
Definition: RField.hxx:618
RField(std::string_view name)
Definition: RField.hxx:603
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
Definition: RField.hxx:638
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
Definition: RField.hxx:597
bool * MapV(const RClusterIndex &clusterIndex, NTupleSize_t &nItems)
Definition: RField.hxx:621
static std::string TypeName()
Definition: RField.hxx:602
ROOT::Experimental::Detail::RFieldValue GenerateValue(void *where, ArgsT &&... args)
Definition: RField.hxx:627
RField(RField &&other)=default
bool * Map(const RClusterIndex &clusterIndex)
Definition: RField.hxx:615
Detail::RFieldValue CaptureValue(void *where) final
Creates a value from a memory location with an already constructed object.
Definition: RField.hxx:634
ROOT::Experimental::Detail::RFieldValue GenerateValue(void *where) final
Generates a tree value in a given location of size at least GetValueSize().
Definition: RField.hxx:633
char * MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems)
Definition: RField.hxx:763
RField(std::string_view name)
Definition: RField.hxx:748
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
Definition: RField.hxx:783
ROOT::Experimental::Detail::RFieldValue GenerateValue(void *where) final
Generates a tree value in a given location of size at least GetValueSize().
Definition: RField.hxx:778
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
Definition: RField.hxx:742
ROOT::Experimental::Detail::RFieldValue GenerateValue(void *where, ArgsT &&... args)
Definition: RField.hxx:772
Detail::RFieldValue CaptureValue(void *where) final
Creates a value from a memory location with an already constructed object.
Definition: RField.hxx:779
RField(RField &&other)=default
char * MapV(const RClusterIndex &clusterIndex, NTupleSize_t &nItems)
Definition: RField.hxx:766
static std::string TypeName()
Definition: RField.hxx:747
char * Map(const RClusterIndex &clusterIndex)
Definition: RField.hxx:760
Detail::RFieldValue CaptureValue(void *where) final
Creates a value from a memory location with an already constructed object.
Definition: RField.hxx:731
double * Map(const RClusterIndex &clusterIndex)
Definition: RField.hxx:712
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
Definition: RField.hxx:694
double * MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems)
Definition: RField.hxx:715
double * MapV(const RClusterIndex &clusterIndex, NTupleSize_t &nItems)
Definition: RField.hxx:718
RField(std::string_view name)
Definition: RField.hxx:700
ROOT::Experimental::Detail::RFieldValue GenerateValue(void *where, ArgsT &&... args)
Definition: RField.hxx:724
RField(RField &&other)=default
static std::string TypeName()
Definition: RField.hxx:699
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
Definition: RField.hxx:735
ROOT::Experimental::Detail::RFieldValue GenerateValue(void *where) final
Generates a tree value in a given location of size at least GetValueSize().
Definition: RField.hxx:730
static std::string TypeName()
Definition: RField.hxx:650
ROOT::Experimental::Detail::RFieldValue GenerateValue(void *where) final
Generates a tree value in a given location of size at least GetValueSize().
Definition: RField.hxx:681
RField(RField &&other)=default
float * MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems)
Definition: RField.hxx:666
float * MapV(const RClusterIndex &clusterIndex, NTupleSize_t &nItems)
Definition: RField.hxx:669
RField(std::string_view name)
Definition: RField.hxx:651
ROOT::Experimental::Detail::RFieldValue GenerateValue(void *where, ArgsT &&... args)
Definition: RField.hxx:675
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
Definition: RField.hxx:686
float * Map(const RClusterIndex &clusterIndex)
Definition: RField.hxx:663
Detail::RFieldValue CaptureValue(void *where) final
Creates a value from a memory location with an already constructed object.
Definition: RField.hxx:682
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
Definition: RField.hxx:645
Classes with dictionaries that can be inspected by TClass.
Definition: RField.hxx:480
RField(std::string_view name)
Definition: RField.hxx:483
ROOT::Experimental::Detail::RFieldValue GenerateValue(void *where, ArgsT &&... args)
Definition: RField.hxx:492
RField(RField &&other)=default
ROOT::Experimental::Detail::RFieldValue GenerateValue(void *where) final
Generates a tree value in a given location of size at least GetValueSize().
Definition: RField.hxx:496
static std::string TypeName()
Definition: RField.hxx:482
The on-storage meta-data of an ntuple.
For forward and backward compatibility, attach version information to the consitituents of the file f...
The field for an untyped record.
Definition: RField.hxx:339
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
Definition: RField.hxx:365
size_t GetAlignment() const final
For many types, the alignment requirement is equal to the size; otherwise override.
Definition: RField.hxx:366
RRecordField(RRecordField &&other)=default
std::size_t AppendImpl(const Detail::RFieldValue &value) final
Operations on values of complex types, e.g.
Definition: RField.cxx:902
void GenerateColumnsImpl(const RNTupleDescriptor &) final
Creates the backing columns corresponsing to the field type for reading.
Definition: RField.hxx:359
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
Definition: RField.cxx:894
std::size_t GetItemPadding(std::size_t baseOffset, std::size_t itemAlignment) const
Definition: RField.cxx:883
void ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue *value) final
Definition: RField.cxx:913
Detail::RFieldValue CaptureValue(void *where) final
Creates a value from a memory location with an already constructed object.
Definition: RField.cxx:956
std::vector< Detail::RFieldValue > SplitValue(const Detail::RFieldValue &value) const final
Creates the list of direct child values given a value for this field.
Definition: RField.cxx:963
void DestroyValue(const Detail::RFieldValue &value, bool dtorOnly=false) final
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
Definition: RField.cxx:943
RRecordField & operator=(RRecordField &&other)=default
void ReadInClusterImpl(const RClusterIndex &clusterIndex, Detail::RFieldValue *value) final
Definition: RField.cxx:923
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
Definition: RField.hxx:358
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
Definition: RField.cxx:975
RRecordField(std::string_view fieldName, std::vector< std::unique_ptr< Detail::RFieldBase > > &itemFields)
Definition: RField.cxx:871
RResult<void> has no data member and no Inspect() method but instead a Success() factory method.
Definition: RError.hxx:257
The class is used as a return type for operations that can fail; wraps a value of type T or an RError...
Definition: RError.hxx:195
The generic field for a (nested) std::vector<Type> except for std::vector<bool>
Definition: RField.hxx:371
Detail::RFieldValue CaptureValue(void *where) override
Creates a value from a memory location with an already constructed object.
Definition: RField.cxx:1070
void CommitCluster() final
Perform housekeeping tasks for global to cluster-local index translation.
Definition: RField.cxx:1088
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
Definition: RField.cxx:993
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
Definition: RField.cxx:1093
size_t GetValueSize() const override
The number of bytes taken by a value of the appropriate type.
Definition: RField.hxx:394
std::vector< Detail::RFieldValue > SplitValue(const Detail::RFieldValue &value) const final
Creates the list of direct child values given a value for this field.
Definition: RField.cxx:1076
void GetCollectionInfo(const RClusterIndex &clusterIndex, RClusterIndex *collectionStart, ClusterSize_t *size) const
Definition: RField.hxx:401
void ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue *value) final
Definition: RField.cxx:1014
void GetCollectionInfo(NTupleSize_t globalIndex, RClusterIndex *collectionStart, ClusterSize_t *size) const
Definition: RField.hxx:398
RVectorField & operator=(RVectorField &&other)=default
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
Definition: RField.cxx:1038
size_t GetAlignment() const final
For many types, the alignment requirement is equal to the size; otherwise override.
Definition: RField.hxx:395
RVectorField(std::string_view fieldName, std::unique_ptr< Detail::RFieldBase > itemField)
Definition: RField.cxx:983
void DestroyValue(const Detail::RFieldValue &value, bool dtorOnly=false) final
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
Definition: RField.cxx:1056
std::size_t AppendImpl(const Detail::RFieldValue &value) final
Operations on values of complex types, e.g.
Definition: RField.cxx:999
RVectorField(RVectorField &&other)=default
A "std::vector"-like collection of values implementing handy operation to analyse them.
Definition: RVec.hxx:1425
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition: TClass.h:80
auto Map(Args &&... args)
Create new collection applying a callable to the elements of the input collection.
Definition: RVec.hxx:2025
basic_string_view< char > string_view
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
Definition: RNTupleUtil.hxx:77
RClusterSize ClusterSize_t
Definition: RNTupleUtil.hxx:92
ENTupleStructure
The fields in the ntuple model tree can carry different structural information about the type system.
Definition: RNTupleUtil.hxx:67
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
constexpr DescriptorId_t kInvalidDescriptorId
std::string GetDemangledTypeName(const std::type_info &)
Returns a string with the demangled and normalized name for the given type.
double T(double x)
Definition: ChebyshevPol.h:34
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Type GetType(const std::string &Name)
Definition: Systematics.cxx:34
Wrap the 32bit integer in a struct in order to avoid template specialization clash with std::uint32_t...
Definition: RNTupleUtil.hxx:80
Definition: civetweb.c:2228