Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RFieldRecord.hxx
Go to the documentation of this file.
1/// \file ROOT/RField/Fundamental.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_Record
17#define ROOT7_RField_Record
18
19#ifndef ROOT7_RField
20#error "Please include RField.hxx!"
21#endif
22
23#include <ROOT/RFieldBase.hxx>
24#include <ROOT/RNTupleUtil.hxx>
25
26#include <string>
27#include <string_view>
28#include <tuple>
29#include <utility>
30#include <vector>
31
32namespace ROOT {
33namespace Experimental {
34
35namespace Detail {
36class RFieldVisitor;
37} // namespace Detail
38
39/// The field for an untyped record. The subfields are stored consequitively in a memory block, i.e.
40/// the memory layout is identical to one that a C++ struct would have
41class RRecordField : public RFieldBase {
42private:
43 class RRecordDeleter : public RDeleter {
44 private:
45 std::vector<std::unique_ptr<RDeleter>> fItemDeleters;
46 std::vector<std::size_t> fOffsets;
47
48 public:
49 RRecordDeleter(std::vector<std::unique_ptr<RDeleter>> itemDeleters, const std::vector<std::size_t> &offsets)
50 : fItemDeleters(std::move(itemDeleters)), fOffsets(offsets)
51 {
52 }
53 void operator()(void *objPtr, bool dtorOnly) final;
54 };
55
56 RRecordField(std::string_view name, const RRecordField &source); // Used by CloneImpl()
57
58protected:
59 std::size_t fMaxAlignment = 1;
60 std::size_t fSize = 0;
61 std::vector<std::size_t> fOffsets;
62
63 std::size_t GetItemPadding(std::size_t baseOffset, std::size_t itemAlignment) const;
64
65 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
66
67 void ConstructValue(void *where) const final;
68 std::unique_ptr<RDeleter> GetDeleter() const final;
69
70 std::size_t AppendImpl(const void *from) final;
71 void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final;
72 void ReadInClusterImpl(RClusterIndex clusterIndex, void *to) final;
73
74 RRecordField(std::string_view fieldName, std::string_view typeName);
75
76 void AttachItemFields(std::vector<std::unique_ptr<RFieldBase>> itemFields);
77
78 template <std::size_t N>
79 void AttachItemFields(std::array<std::unique_ptr<RFieldBase>, N> itemFields)
80 {
82 for (unsigned i = 0; i < N; ++i) {
83 fMaxAlignment = std::max(fMaxAlignment, itemFields[i]->GetAlignment());
84 fSize += GetItemPadding(fSize, itemFields[i]->GetAlignment()) + itemFields[i]->GetValueSize();
85 fTraits &= itemFields[i]->GetTraits();
86 Attach(std::move(itemFields[i]));
87 }
88 // Trailing padding: although this is implementation-dependent, most add enough padding to comply with the
89 // requirements of the type with strictest alignment
91 }
92
93public:
94 /// Construct a RRecordField based on a vector of child fields. The ownership of the child fields is transferred
95 /// to the RRecordField instance.
96 RRecordField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> itemFields);
97 RRecordField(RRecordField &&other) = default;
98 RRecordField &operator=(RRecordField &&other) = default;
99 ~RRecordField() override = default;
100
101 std::vector<RValue> SplitValue(const RValue &value) const final;
102 size_t GetValueSize() const final { return fSize; }
103 size_t GetAlignment() const final { return fMaxAlignment; }
104 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
105
106 const std::vector<std::size_t> &GetOffsets() const { return fOffsets; }
107};
108
109////////////////////////////////////////////////////////////////////////////////
110/// Template specializations for C++ std::pair
111////////////////////////////////////////////////////////////////////////////////
112
113/// The generic field for `std::pair<T1, T2>` types
114class RPairField : public RRecordField {
115private:
116 static std::string GetTypeList(const std::array<std::unique_ptr<RFieldBase>, 2> &itemFields);
117
118protected:
119 RPairField(std::string_view fieldName, std::array<std::unique_ptr<RFieldBase>, 2> itemFields,
120 const std::array<std::size_t, 2> &offsets);
121
122public:
123 RPairField(std::string_view fieldName, std::array<std::unique_ptr<RFieldBase>, 2> itemFields);
124 RPairField(RPairField &&other) = default;
125 RPairField &operator=(RPairField &&other) = default;
126 ~RPairField() override = default;
127};
128
129template <typename T1, typename T2>
130class RField<std::pair<T1, T2>> final : public RPairField {
131 using ContainerT = typename std::pair<T1, T2>;
132
133private:
134 static std::array<std::unique_ptr<RFieldBase>, 2> BuildItemFields()
135 {
136 return {std::make_unique<RField<T1>>("_0"), std::make_unique<RField<T2>>("_1")};
137 }
138
139 static std::array<std::size_t, 2> BuildItemOffsets()
140 {
141 auto pair = ContainerT();
142 auto offsetFirst = reinterpret_cast<std::uintptr_t>(&(pair.first)) - reinterpret_cast<std::uintptr_t>(&pair);
143 auto offsetSecond = reinterpret_cast<std::uintptr_t>(&(pair.second)) - reinterpret_cast<std::uintptr_t>(&pair);
144 return {offsetFirst, offsetSecond};
145 }
146
147public:
148 static std::string TypeName() { return "std::pair<" + RField<T1>::TypeName() + "," + RField<T2>::TypeName() + ">"; }
149 explicit RField(std::string_view name) : RPairField(name, BuildItemFields(), BuildItemOffsets())
150 {
151 R__ASSERT(fMaxAlignment >= std::max(alignof(T1), alignof(T2)));
152 R__ASSERT(fSize >= sizeof(ContainerT));
153 }
154 RField(RField &&other) = default;
155 RField &operator=(RField &&other) = default;
156 ~RField() final = default;
157};
158
159////////////////////////////////////////////////////////////////////////////////
160/// Template specializations for C++ std::tuple
161////////////////////////////////////////////////////////////////////////////////
162
163/// The generic field for `std::tuple<Ts...>` types
164class RTupleField : public RRecordField {
165private:
166 static std::string GetTypeList(const std::vector<std::unique_ptr<RFieldBase>> &itemFields);
167
168protected:
169 RTupleField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> itemFields,
170 const std::vector<std::size_t> &offsets);
171
172public:
173 RTupleField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> itemFields);
174 RTupleField(RTupleField &&other) = default;
175 RTupleField &operator=(RTupleField &&other) = default;
176 ~RTupleField() override = default;
177};
178
179template <typename... ItemTs>
180class RField<std::tuple<ItemTs...>> final : public RTupleField {
181 using ContainerT = typename std::tuple<ItemTs...>;
182
183private:
184 template <typename HeadT, typename... TailTs>
185 static std::string BuildItemTypes()
186 {
187 std::string result = RField<HeadT>::TypeName();
188 if constexpr (sizeof...(TailTs) > 0)
189 result += "," + BuildItemTypes<TailTs...>();
190 return result;
191 }
192
193 template <typename HeadT, typename... TailTs>
194 static void _BuildItemFields(std::vector<std::unique_ptr<RFieldBase>> &itemFields, unsigned int index = 0)
195 {
196 itemFields.emplace_back(new RField<HeadT>("_" + std::to_string(index)));
197 if constexpr (sizeof...(TailTs) > 0)
198 _BuildItemFields<TailTs...>(itemFields, index + 1);
199 }
200 static std::vector<std::unique_ptr<RFieldBase>> BuildItemFields()
201 {
202 std::vector<std::unique_ptr<RFieldBase>> result;
203 _BuildItemFields<ItemTs...>(result);
204 return result;
205 }
206
207 template <unsigned Index, typename HeadT, typename... TailTs>
208 static void _BuildItemOffsets(std::vector<std::size_t> &offsets, const ContainerT &tuple)
209 {
210 auto offset =
211 reinterpret_cast<std::uintptr_t>(&std::get<Index>(tuple)) - reinterpret_cast<std::uintptr_t>(&tuple);
212 offsets.emplace_back(offset);
213 if constexpr (sizeof...(TailTs) > 0)
214 _BuildItemOffsets<Index + 1, TailTs...>(offsets, tuple);
215 }
216 static std::vector<std::size_t> BuildItemOffsets()
217 {
218 std::vector<std::size_t> result;
219 _BuildItemOffsets<0, ItemTs...>(result, ContainerT());
220 return result;
221 }
222
223public:
224 static std::string TypeName() { return "std::tuple<" + BuildItemTypes<ItemTs...>() + ">"; }
225 explicit RField(std::string_view name) : RTupleField(name, BuildItemFields(), BuildItemOffsets())
226 {
227 R__ASSERT(fMaxAlignment >= std::max({alignof(ItemTs)...}));
228 R__ASSERT(fSize >= sizeof(ContainerT));
229 }
230 RField(RField &&other) = default;
231 RField &operator=(RField &&other) = default;
232 ~RField() final = default;
233};
234
235} // namespace Experimental
236} // namespace ROOT
237
238#endif
dim_t fSize
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:125
#define N
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
char name[80]
Definition TGX11.cxx:110
Abstract base class for classes implementing the visitor design pattern.
Addresses a column element or field item relative to a particular cluster, instead of a global NTuple...
A functor to release the memory acquired by CreateValue (memory and constructor).
Points to an object with RNTuple I/O support and keeps a pointer to the corresponding field.
A field translates read and write calls from/to underlying columns to/from tree values.
void Attach(std::unique_ptr< RFieldBase > child)
Add a new subfield to the list of nested fields.
int fTraits
Properties of the type that allow for optimizations of collections of that type.
static constexpr int kTraitTrivialType
Shorthand for types that are both trivially constructible and destructible.
Classes with dictionaries that can be inspected by TClass.
Definition RField.hxx:242
RField & operator=(RField &&other)=default
static std::string TypeName()
Definition RField.hxx:244
Template specializations for C++ std::pair.
~RPairField() override=default
static std::string GetTypeList(const std::array< std::unique_ptr< RFieldBase >, 2 > &itemFields)
RPairField(RPairField &&other)=default
RPairField & operator=(RPairField &&other)=default
void operator()(void *objPtr, bool dtorOnly) final
Definition RField.cxx:596
std::vector< std::unique_ptr< RDeleter > > fItemDeleters
RRecordDeleter(std::vector< std::unique_ptr< RDeleter > > itemDeleters, const std::vector< std::size_t > &offsets)
The field for an untyped record.
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
size_t GetAlignment() const final
As a rule of thumb, the alignment is equal to the size of the type.
std::vector< std::size_t > fOffsets
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
Definition RField.cxx:561
void ReadInClusterImpl(RClusterIndex clusterIndex, void *to) final
Definition RField.cxx:582
RRecordField(RRecordField &&other)=default
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
Definition RField.cxx:575
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given a value for this field.
Definition RField.cxx:615
std::size_t GetItemPadding(std::size_t baseOffset, std::size_t itemAlignment) const
Definition RField.cxx:550
std::unique_ptr< RDeleter > GetDeleter() const final
Definition RField.cxx:604
~RRecordField() override=default
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
Definition RField.cxx:566
const std::vector< std::size_t > & GetOffsets() const
RRecordField & operator=(RRecordField &&other)=default
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
Definition RField.cxx:626
void ConstructValue(void *where) const final
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
Definition RField.cxx:589
void AttachItemFields(std::vector< std::unique_ptr< RFieldBase > > itemFields)
Template specializations for C++ std::tuple.
RTupleField & operator=(RTupleField &&other)=default
static std::string GetTypeList(const std::vector< std::unique_ptr< RFieldBase > > &itemFields)
~RTupleField() override=default
RTupleField(RTupleField &&other)=default
RooCmdArg Index(RooCategory &icat)
#define T2
Definition md5.inl:147
#define T1
Definition md5.inl:146
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...