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
39namespace Internal {
40std::unique_ptr<RFieldBase> CreateEmulatedField(std::string_view fieldName,
41 std::vector<std::unique_ptr<RFieldBase>> itemFields,
42 std::string_view emulatedFromType);
43}
44
45/// The field for an untyped record. The subfields are stored consequitively in a memory block, i.e.
46/// the memory layout is identical to one that a C++ struct would have
47class RRecordField : public RFieldBase {
48 friend std::unique_ptr<RFieldBase> Internal::CreateEmulatedField(std::string_view fieldName,
49 std::vector<std::unique_ptr<RFieldBase>> itemFields,
50 std::string_view emulatedFromType);
51
52 class RRecordDeleter : public RDeleter {
53 private:
54 std::vector<std::unique_ptr<RDeleter>> fItemDeleters;
55 std::vector<std::size_t> fOffsets;
56
57 public:
58 RRecordDeleter(std::vector<std::unique_ptr<RDeleter>> itemDeleters, const std::vector<std::size_t> &offsets)
59 : fItemDeleters(std::move(itemDeleters)), fOffsets(offsets)
60 {
61 }
62 void operator()(void *objPtr, bool dtorOnly) final;
63 };
64
65 RRecordField(std::string_view name, const RRecordField &source); // Used by CloneImpl()
66
67 /// If `emulatedFromType` is non-empty, this field was created as a replacement for a ClassField that we lack a
68 /// dictionary for and reconstructed from the on-disk information.
69 RRecordField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> itemFields,
70 std::string_view emulatedFromType);
71
72protected:
73 std::size_t fMaxAlignment = 1;
74 std::size_t fSize = 0;
75 std::vector<std::size_t> fOffsets;
76
77 std::size_t GetItemPadding(std::size_t baseOffset, std::size_t itemAlignment) const;
78
79 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
80
81 void ConstructValue(void *where) const final;
82 std::unique_ptr<RDeleter> GetDeleter() const final;
83
84 std::size_t AppendImpl(const void *from) final;
85 void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
87
88 RRecordField(std::string_view fieldName, std::string_view typeName);
89
90 void AttachItemFields(std::vector<std::unique_ptr<RFieldBase>> itemFields);
91
92 template <std::size_t N>
93 void AttachItemFields(std::array<std::unique_ptr<RFieldBase>, N> itemFields)
94 {
96 for (unsigned i = 0; i < N; ++i) {
98 fSize += GetItemPadding(fSize, itemFields[i]->GetAlignment()) + itemFields[i]->GetValueSize();
99 fTraits &= itemFields[i]->GetTraits();
100 Attach(std::move(itemFields[i]));
101 }
102 // Trailing padding: although this is implementation-dependent, most add enough padding to comply with the
103 // requirements of the type with strictest alignment
105 }
106
107public:
108 /// Construct a RRecordField based on a vector of child fields. The ownership of the child fields is transferred
109 /// to the RRecordField instance.
110 RRecordField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> itemFields);
113 ~RRecordField() override = default;
114
115 std::vector<RValue> SplitValue(const RValue &value) const final;
117 {
118 // The minimum size is 1 to support having vectors of empty records
119 return std::max<size_t>(1ul, fSize);
120 }
123
124 const std::vector<std::size_t> &GetOffsets() const { return fOffsets; }
125};
126
127////////////////////////////////////////////////////////////////////////////////
128/// Template specializations for C++ std::pair
129////////////////////////////////////////////////////////////////////////////////
130
131/// The generic field for `std::pair<T1, T2>` types
132class RPairField : public RRecordField {
133private:
134 static std::string GetTypeList(const std::array<std::unique_ptr<RFieldBase>, 2> &itemFields);
135
136protected:
137 RPairField(std::string_view fieldName, std::array<std::unique_ptr<RFieldBase>, 2> itemFields,
138 const std::array<std::size_t, 2> &offsets);
139
140public:
141 RPairField(std::string_view fieldName, std::array<std::unique_ptr<RFieldBase>, 2> itemFields);
144 ~RPairField() override = default;
145};
146
147template <typename T1, typename T2>
148class RField<std::pair<T1, T2>> final : public RPairField {
149 using ContainerT = typename std::pair<T1, T2>;
150
151private:
152 static std::array<std::unique_ptr<RFieldBase>, 2> BuildItemFields()
153 {
154 return {std::make_unique<RField<T1>>("_0"), std::make_unique<RField<T2>>("_1")};
155 }
156
157 static std::array<std::size_t, 2> BuildItemOffsets()
158 {
159 auto pair = ContainerT();
160 auto offsetFirst = reinterpret_cast<std::uintptr_t>(&(pair.first)) - reinterpret_cast<std::uintptr_t>(&pair);
161 auto offsetSecond = reinterpret_cast<std::uintptr_t>(&(pair.second)) - reinterpret_cast<std::uintptr_t>(&pair);
162 return {offsetFirst, offsetSecond};
163 }
164
165public:
166 static std::string TypeName() { return "std::pair<" + RField<T1>::TypeName() + "," + RField<T2>::TypeName() + ">"; }
167 explicit RField(std::string_view name) : RPairField(name, BuildItemFields(), BuildItemOffsets())
168 {
169 R__ASSERT(fMaxAlignment >= std::max(alignof(T1), alignof(T2)));
170 R__ASSERT(fSize >= sizeof(ContainerT));
171 }
172 RField(RField &&other) = default;
173 RField &operator=(RField &&other) = default;
175};
176
177////////////////////////////////////////////////////////////////////////////////
178/// Template specializations for C++ std::tuple
179////////////////////////////////////////////////////////////////////////////////
180
181/// The generic field for `std::tuple<Ts...>` types
183private:
184 static std::string GetTypeList(const std::vector<std::unique_ptr<RFieldBase>> &itemFields);
185
186protected:
187 RTupleField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> itemFields,
188 const std::vector<std::size_t> &offsets);
189
190public:
191 RTupleField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> itemFields);
194 ~RTupleField() override = default;
195};
196
197template <typename... ItemTs>
198class RField<std::tuple<ItemTs...>> final : public RTupleField {
199 using ContainerT = typename std::tuple<ItemTs...>;
200
201private:
202 template <typename HeadT, typename... TailTs>
203 static std::string BuildItemTypes()
204 {
205 std::string result = RField<HeadT>::TypeName();
206 if constexpr (sizeof...(TailTs) > 0)
207 result += "," + BuildItemTypes<TailTs...>();
208 return result;
209 }
210
211 template <typename HeadT, typename... TailTs>
212 static void _BuildItemFields(std::vector<std::unique_ptr<RFieldBase>> &itemFields, unsigned int index = 0)
213 {
214 itemFields.emplace_back(new RField<HeadT>("_" + std::to_string(index)));
215 if constexpr (sizeof...(TailTs) > 0)
216 _BuildItemFields<TailTs...>(itemFields, index + 1);
217 }
218 static std::vector<std::unique_ptr<RFieldBase>> BuildItemFields()
219 {
220 std::vector<std::unique_ptr<RFieldBase>> result;
221 _BuildItemFields<ItemTs...>(result);
222 return result;
223 }
224
225 template <unsigned Index, typename HeadT, typename... TailTs>
226 static void _BuildItemOffsets(std::vector<std::size_t> &offsets, const ContainerT &tuple)
227 {
228 auto offset =
229 reinterpret_cast<std::uintptr_t>(&std::get<Index>(tuple)) - reinterpret_cast<std::uintptr_t>(&tuple);
230 offsets.emplace_back(offset);
231 if constexpr (sizeof...(TailTs) > 0)
232 _BuildItemOffsets<Index + 1, TailTs...>(offsets, tuple);
233 }
234 static std::vector<std::size_t> BuildItemOffsets()
235 {
236 std::vector<std::size_t> result;
237 _BuildItemOffsets<0, ItemTs...>(result, ContainerT());
238 return result;
239 }
240
241public:
242 static std::string TypeName() { return "std::tuple<" + BuildItemTypes<ItemTs...>() + ">"; }
243 explicit RField(std::string_view name) : RTupleField(name, BuildItemFields(), BuildItemOffsets())
244 {
245 R__ASSERT(fMaxAlignment >= std::max({alignof(ItemTs)...}));
246 R__ASSERT(fSize >= sizeof(ContainerT));
247 }
248 RField(RField &&other) = default;
249 RField &operator=(RField &&other) = default;
251};
252
253} // namespace Experimental
254} // namespace ROOT
255
256#endif
dim_t fSize
ROOT::Experimental::RField< T > RField
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.
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.
std::uint32_t fTraits
Properties of the type that allow for optimizations of collections of that type.
void Attach(std::unique_ptr< RFieldBase > child)
Add a new subfield to the list of nested fields.
@ kTraitTrivialType
Shorthand for types that are both trivially constructible and destructible.
Classes with dictionaries that can be inspected by TClass.
Definition RField.hxx:287
RField & operator=(RField &&other)=default
static std::string TypeName()
Definition RField.hxx:289
Template specializations for C++ std::pair.
~RPairField() override=default
RPairField(std::string_view fieldName, std::array< std::unique_ptr< RFieldBase >, 2 > itemFields, const std::array< std::size_t, 2 > &offsets)
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:614
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
void ReadInClusterImpl(RNTupleLocalIndex localIndex, void *to) final
Definition RField.cxx:600
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
Definition RField.cxx:579
RRecordField(RRecordField &&other)=default
RRecordField(std::string_view name, const RRecordField &source)
Definition RField.cxx:502
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:633
std::size_t GetItemPadding(std::size_t baseOffset, std::size_t itemAlignment) const
Definition RField.cxx:568
std::unique_ptr< RDeleter > GetDeleter() const final
Definition RField.cxx:622
~RRecordField() override=default
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
Definition RField.cxx:584
const std::vector< std::size_t > & GetOffsets() const
RRecordField & operator=(RRecordField &&other)=default
void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final
Definition RField.cxx:593
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
Definition RField.cxx:644
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:607
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
Addresses a column element or field item relative to a particular cluster, instead of a global NTuple...
#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:534
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...