Logo ROOT  
Reference Guide
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
Loading...
Searching...
No Matches
RFieldRecord.hxx
Go to the documentation of this file.
1/// \file ROOT/RField/Fundamental.hxx
2/// \ingroup NTuple
3/// \author Jakob Blomer <jblomer@cern.ch>
4/// \date 2018-10-09
5
6/*************************************************************************
7 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
8 * All rights reserved. *
9 * *
10 * For the licensing terms see $ROOTSYS/LICENSE. *
11 * For the list of contributors see $ROOTSYS/README/CREDITS. *
12 *************************************************************************/
13
14#ifndef ROOT_RField_Record
15#define ROOT_RField_Record
16
17#ifndef ROOT_RField
18#error "Please include RField.hxx!"
19#endif
20
21#include <ROOT/RFieldBase.hxx>
22#include <ROOT/RNTupleUtil.hxx>
23
24#include <string>
25#include <string_view>
26#include <tuple>
27#include <utility>
28#include <vector>
29
30namespace ROOT {
31
32namespace Detail {
33class RFieldVisitor;
34} // namespace Detail
35
36namespace Internal {
37std::unique_ptr<RFieldBase> CreateEmulatedField(std::string_view fieldName,
38 std::vector<std::unique_ptr<RFieldBase>> itemFields,
39 std::string_view emulatedFromType);
40}
41
42/// The field for an untyped record. The subfields are stored consequitively in a memory block, i.e.
43/// the memory layout is identical to one that a C++ struct would have
44class RRecordField : public RFieldBase {
45 friend std::unique_ptr<RFieldBase> Internal::CreateEmulatedField(std::string_view fieldName,
46 std::vector<std::unique_ptr<RFieldBase>> itemFields,
47 std::string_view emulatedFromType);
48
49 class RRecordDeleter : public RDeleter {
50 private:
51 std::vector<std::unique_ptr<RDeleter>> fItemDeleters;
52 std::vector<std::size_t> fOffsets;
53
54 public:
55 RRecordDeleter(std::vector<std::unique_ptr<RDeleter>> itemDeleters, const std::vector<std::size_t> &offsets)
56 : fItemDeleters(std::move(itemDeleters)), fOffsets(offsets)
57 {
58 }
59 void operator()(void *objPtr, bool dtorOnly) final;
60 };
61
62 RRecordField(std::string_view name, const RRecordField &source); // Used by CloneImpl()
63
64 /// If `emulatedFromType` is non-empty, this field was created as a replacement for a ClassField that we lack a
65 /// dictionary for and reconstructed from the on-disk information.
66 RRecordField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> itemFields,
67 std::string_view emulatedFromType);
68
69protected:
70 std::size_t fMaxAlignment = 1;
71 std::size_t fSize = 0;
72 std::vector<std::size_t> fOffsets;
73
74 std::size_t GetItemPadding(std::size_t baseOffset, std::size_t itemAlignment) const;
75
76 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
77
78 void ConstructValue(void *where) const final;
79 std::unique_ptr<RDeleter> GetDeleter() const final;
80
81 std::size_t AppendImpl(const void *from) final;
84
85 RRecordField(std::string_view fieldName, std::string_view typeName);
86
87 void AttachItemFields(std::vector<std::unique_ptr<RFieldBase>> itemFields);
88
89 template <std::size_t N>
90 void AttachItemFields(std::array<std::unique_ptr<RFieldBase>, N> itemFields)
91 {
93 for (unsigned i = 0; i < N; ++i) {
95 fSize += GetItemPadding(fSize, itemFields[i]->GetAlignment()) + itemFields[i]->GetValueSize();
96 fTraits &= itemFields[i]->GetTraits();
97 Attach(std::move(itemFields[i]));
98 }
99 // Trailing padding: although this is implementation-dependent, most add enough padding to comply with the
100 // requirements of the type with strictest alignment
102 }
103
104public:
105 /// Construct a RRecordField based on a vector of child fields. The ownership of the child fields is transferred
106 /// to the RRecordField instance.
107 RRecordField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> itemFields);
110 ~RRecordField() override = default;
111
112 std::vector<RValue> SplitValue(const RValue &value) const final;
114 {
115 // The minimum size is 1 to support having vectors of empty records
116 return std::max<size_t>(1ul, fSize);
117 }
120
121 const std::vector<std::size_t> &GetOffsets() const { return fOffsets; }
122};
123
124////////////////////////////////////////////////////////////////////////////////
125/// Template specializations for C++ std::pair
126////////////////////////////////////////////////////////////////////////////////
127
128/// The generic field for `std::pair<T1, T2>` types
129class RPairField : public RRecordField {
130private:
131 static std::string GetTypeList(const std::array<std::unique_ptr<RFieldBase>, 2> &itemFields);
132
133protected:
134 RPairField(std::string_view fieldName, std::array<std::unique_ptr<RFieldBase>, 2> itemFields,
135 const std::array<std::size_t, 2> &offsets);
136
137public:
138 RPairField(std::string_view fieldName, std::array<std::unique_ptr<RFieldBase>, 2> itemFields);
141 ~RPairField() override = default;
142};
143
144template <typename T1, typename T2>
145class RField<std::pair<T1, T2>> final : public RPairField {
146 using ContainerT = typename std::pair<T1, T2>;
147
148private:
149 static std::array<std::unique_ptr<RFieldBase>, 2> BuildItemFields()
150 {
151 return {std::make_unique<RField<T1>>("_0"), std::make_unique<RField<T2>>("_1")};
152 }
153
154 static std::array<std::size_t, 2> BuildItemOffsets()
155 {
156 auto pair = ContainerT();
157 auto offsetFirst = reinterpret_cast<std::uintptr_t>(&(pair.first)) - reinterpret_cast<std::uintptr_t>(&pair);
158 auto offsetSecond = reinterpret_cast<std::uintptr_t>(&(pair.second)) - reinterpret_cast<std::uintptr_t>(&pair);
159 return {offsetFirst, offsetSecond};
160 }
161
162public:
163 static std::string TypeName() { return "std::pair<" + RField<T1>::TypeName() + "," + RField<T2>::TypeName() + ">"; }
164 explicit RField(std::string_view name) : RPairField(name, BuildItemFields(), BuildItemOffsets())
165 {
166 R__ASSERT(fMaxAlignment >= std::max(alignof(T1), alignof(T2)));
167 R__ASSERT(fSize >= sizeof(ContainerT));
168 }
169 RField(RField &&other) = default;
170 RField &operator=(RField &&other) = default;
172};
173
174////////////////////////////////////////////////////////////////////////////////
175/// Template specializations for C++ std::tuple
176////////////////////////////////////////////////////////////////////////////////
177
178/// The generic field for `std::tuple<Ts...>` types
180private:
181 static std::string GetTypeList(const std::vector<std::unique_ptr<RFieldBase>> &itemFields);
182
183protected:
184 RTupleField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> itemFields,
185 const std::vector<std::size_t> &offsets);
186
187public:
188 RTupleField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> itemFields);
191 ~RTupleField() override = default;
192};
193
194template <typename... ItemTs>
195class RField<std::tuple<ItemTs...>> final : public RTupleField {
196 using ContainerT = typename std::tuple<ItemTs...>;
197
198private:
199 template <typename HeadT, typename... TailTs>
200 static std::string BuildItemTypes()
201 {
202 std::string result = RField<HeadT>::TypeName();
203 if constexpr (sizeof...(TailTs) > 0)
204 result += "," + BuildItemTypes<TailTs...>();
205 return result;
206 }
207
208 template <typename HeadT, typename... TailTs>
209 static void _BuildItemFields(std::vector<std::unique_ptr<RFieldBase>> &itemFields, unsigned int index = 0)
210 {
211 itemFields.emplace_back(new RField<HeadT>("_" + std::to_string(index)));
212 if constexpr (sizeof...(TailTs) > 0)
213 _BuildItemFields<TailTs...>(itemFields, index + 1);
214 }
215 static std::vector<std::unique_ptr<RFieldBase>> BuildItemFields()
216 {
217 std::vector<std::unique_ptr<RFieldBase>> result;
218 _BuildItemFields<ItemTs...>(result);
219 return result;
220 }
221
222 template <unsigned Index, typename HeadT, typename... TailTs>
223 static void _BuildItemOffsets(std::vector<std::size_t> &offsets, const ContainerT &tuple)
224 {
225 auto offset =
226 reinterpret_cast<std::uintptr_t>(&std::get<Index>(tuple)) - reinterpret_cast<std::uintptr_t>(&tuple);
227 offsets.emplace_back(offset);
228 if constexpr (sizeof...(TailTs) > 0)
229 _BuildItemOffsets<Index + 1, TailTs...>(offsets, tuple);
230 }
231 static std::vector<std::size_t> BuildItemOffsets()
232 {
233 std::vector<std::size_t> result;
234 _BuildItemOffsets<0, ItemTs...>(result, ContainerT());
235 return result;
236 }
237
238public:
239 static std::string TypeName() { return "std::tuple<" + BuildItemTypes<ItemTs...>() + ">"; }
240 explicit RField(std::string_view name) : RTupleField(name, BuildItemFields(), BuildItemOffsets())
241 {
242 R__ASSERT(fMaxAlignment >= std::max({alignof(ItemTs)...}));
243 R__ASSERT(fSize >= sizeof(ContainerT));
244 }
245 RField(RField &&other) = default;
246 RField &operator=(RField &&other) = default;
248};
249
250} // namespace ROOT
251
252#endif
dim_t fSize
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#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.
std::size_t fMaxAlignment
Definition RField.hxx:143
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.
std::uint32_t fTraits
Properties of the type that allow for optimizations of collections of that type.
@ kTraitTrivialType
Shorthand for types that are both trivially constructible and destructible.
Classes with dictionaries that can be inspected by TClass.
Definition RField.hxx:283
~RField() final=default
RField & operator=(RField &&other)=default
static std::string TypeName()
Definition RField.hxx:285
RField(std::string_view name)
Definition RField.hxx:286
Addresses a column element or field item relative to a particular cluster, instead of a global NTuple...
Template specializations for C++ std::pair.
static std::string GetTypeList(const std::array< std::unique_ptr< RFieldBase >, 2 > &itemFields)
~RPairField() override=default
RPairField(std::string_view fieldName, std::array< std::unique_ptr< RFieldBase >, 2 > itemFields, const std::array< std::size_t, 2 > &offsets)
RPairField(RPairField &&other)=default
RPairField & operator=(RPairField &&other)=default
std::vector< std::size_t > fOffsets
RRecordDeleter(std::vector< std::unique_ptr< RDeleter > > itemDeleters, const std::vector< std::size_t > &offsets)
std::vector< std::unique_ptr< RDeleter > > fItemDeleters
void operator()(void *objPtr, bool dtorOnly) final
Definition RField.cxx:589
The field for an untyped record.
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given an existing value for this field.
Definition RField.cxx:607
std::size_t fMaxAlignment
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
Definition RField.cxx:554
void ReadInClusterImpl(RNTupleLocalIndex localIndex, void *to) final
Definition RField.cxx:575
size_t GetAlignment() const final
As a rule of thumb, the alignment is equal to the size of the type.
RRecordField & operator=(RRecordField &&other)=default
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
RRecordField(std::string_view name, const RRecordField &source)
Definition RField.cxx:482
void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final
Definition RField.cxx:618
std::unique_ptr< RDeleter > GetDeleter() const final
Definition RField.cxx:597
void AttachItemFields(std::vector< std::unique_ptr< RFieldBase > > itemFields)
Definition RField.cxx:498
RRecordField(RRecordField &&other)=default
std::size_t GetItemPadding(std::size_t baseOffset, std::size_t itemAlignment) const
Definition RField.cxx:544
void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final
Definition RField.cxx:568
~RRecordField() override=default
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:582
std::vector< std::size_t > fOffsets
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
Definition RField.cxx:559
const std::vector< std::size_t > & GetOffsets() const
Template specializations for C++ std::tuple.
~RTupleField() override=default
RTupleField(RTupleField &&other)=default
static std::string GetTypeList(const std::vector< std::unique_ptr< RFieldBase > > &itemFields)
RTupleField & operator=(RTupleField &&other)=default
#define T2
Definition md5.inl:147
#define T1
Definition md5.inl:146
std::unique_ptr< RFieldBase > CreateEmulatedField(std::string_view fieldName, std::vector< std::unique_ptr< RFieldBase > > itemFields, std::string_view emulatedFromType)
Definition RField.cxx:513
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.