Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RDisplay.hxx
Go to the documentation of this file.
1// Author: Enrico Guiraud, Danilo Piparo CERN, Massimo Tumolo Politecnico di Torino 08/2018
2
3/*************************************************************************
4 * Copyright (C) 1995-2018, Rene Brun and Fons Rademakers. *
5 * All rights reserved. *
6 * *
7 * For the licensing terms see $ROOTSYS/LICENSE. *
8 * For the list of contributors see $ROOTSYS/README/CREDITS. *
9 *************************************************************************/
10
11#ifndef ROOT_RDFDISPLAYER
12#define ROOT_RDFDISPLAYER
13
14#include "ROOT/RDF/Utils.hxx" // IsDataContainer, InterpreterCalc
15#include "ROOT/RVec.hxx"
16#include "ROOT/TypeTraits.hxx"
17#include "TClassEdit.h"
18
19#include <vector>
20#include <string>
21#include <iostream>
22#include <sstream>
23
24namespace ROOT {
25namespace Internal {
26namespace RDF {
27
28template<typename T>
30std::string PrettyPrintAddr(const void *const addr);
31
33private:
35 std::string fRepresentation;
37
38public:
39 RDisplayElement(const std::string &representation);
41 void SetPrint();
42 void SetIgnore();
43 void SetDots();
44 bool IsPrint() const;
45 bool IsIgnore() const;
46 bool IsDot() const;
47 const std::string &GetRepresentation() const;
48 bool IsEmpty() const;
49};
50} // namespace RDF
51} // namespace Internal
52
53namespace RDF {
54
55/**
56 * \class ROOT::RDF::RDisplay
57 * \ingroup dataframe
58 * This class is the textual representation of the content of a columnar dataset.
59 *
60 * This class is provided to the user, and it can be used to print on screen
61 * the entries of the dataset requested through the Display action in a compact
62 * representation or to return the full representation of the events as a string.
63 * In order to apply proper formatting the content is buffered in memory as strings.
64 */
65class RDisplay {
66 template<typename T>
68private:
69 using VecStr_t = std::vector<std::string>;
71 static constexpr char fgSeparator = ' '; ///< Spacing used to align the table entries
72 static constexpr unsigned fgMaxWidth = 80;
73
74 VecStr_t fTypes; ///< This attribute stores the type of each column. It is needed by the interpreter to print it.
75 std::vector<bool> fIsCollection; ///< True if the column contains a collection. Collections are treated differently
76 ///< during the printing.
77 std::vector<std::vector<DElement_t>> fTable; ///< String representation of the data to be printed.
78 std::vector<unsigned short> fWidths; ///< Tracks the maximum width of each column, based on the largest element.
79
80 VecStr_t fRepresentations; ///< Used by the JITted code to store the string representation of the data.
81 std::vector<VecStr_t> fCollectionsRepresentations; ///< Used by the JITted code to store the string representation of
82 ///< the data in case of collection. Each row corresponds to a
83 ///< column, each column to a value of the collection.
84
85 size_t fNColumns; ///< Number of columns to be printed
86
87 size_t fCurrentRow = 0; ///< Row that is being filled
88 size_t fNextRow = 1; ///< Next row to be filled.
89 size_t fCurrentColumn = 0; ///< Column that is being filled.
90
91 size_t fEntries; ///< Number of events to process for each column (i.e. number of rows).
92
93 ////////////////////////////////////////////////////////////////////////////
94 /// Appends a cling::printValue call to the stringstream.
95 /// \tparam T the type of the event to convert
96 /// \param[in] stream Where the conversion function call will be chained.
97 /// \param[in] element The event to convert to its string representation
98 /// \param[in] index To which column the event belongs to
99 /// \return false, the event is not a collection
100 template <typename T, typename std::enable_if<!ROOT::Internal::RDF::IsDataContainer<T>::value, int>::type = 0>
101 bool AddInterpreterString(std::stringstream &stream, T &element, const int &index)
102 {
103 stream << "*((std::string*)" << ROOT::Internal::RDF::PrettyPrintAddr(&(fRepresentations[index]))
104 << ") = cling::printValue((" << fTypes[index] << "*)" << ROOT::Internal::RDF::PrettyPrintAddr(&element) << ");";
105 return false;
106 }
107
108 ////////////////////////////////////////////////////////////////////////////
109 /// Appends collection.size() cling::printValue calls to the stringstream.
110 /// \tparam T the type of the event to convert
111 /// \param[in] stream Where the conversion function call will be chained.
112 /// \param[in] collection The event to convert to its string representation
113 /// \param[in] index To which column the event belongs to
114 /// \return true, the event is a collection
115 /// This function chains a sequence of call to cling::printValue, one for each element of the collection.
116 template <typename T, typename std::enable_if<ROOT::Internal::RDF::IsDataContainer<T>::value, int>::type = 0>
117 bool AddInterpreterString(std::stringstream &stream, T &collection, const int &index)
118 {
119 size_t collectionSize = std::distance(std::begin(collection), std::end(collection));
120 // Prepare the row to contain as many elements as the number of elements in the collection
121 fCollectionsRepresentations[index] = VecStr_t(collectionSize);
122
123 // Use GetSplit to get the encapsulated type of the collection. For example, GetSplit on
124 // std::vector<std::vector<int>> will return std::vector<int>
126 int nestedLoc = 0;
127 TClassEdit::GetSplit(fTypes[index].c_str(), output, nestedLoc);
128
129 // For each element, append a call and feed the proper type returned by GetSplit
130 for (size_t i = 0; i < collectionSize; ++i) {
131 stream << "*((std::string*)" << ROOT::Internal::RDF::PrettyPrintAddr(&(fCollectionsRepresentations[index][i]))
132 << ") = cling::printValue((" << output[1] << "*)"
133 << ROOT::Internal::RDF::PrettyPrintAddr(&(collection[i])) << ");";
134 }
135 return true;
136 }
137
138 ////////////////////////////////////////////////////////////////////////////
139 /// AddInterpreterString overload for arrays of chars.
140 ///
141 /// \param[in] charArr The character array to convert to string representation
142 /// \param[in] index To which column the event belongs
143 /// \return false, the event is not a collection
144 ///
145 /// This specialization for arrays of characters skips the cling::printValue
146 /// (i.e. appends nothing to the stream) and directly writes to fRepresentations the
147 /// string representation of the array of chars.
148 bool AddInterpreterString(std::stringstream &, ROOT::RVec<char> &charArr, const int &index)
149 {
150 // if null-terminated char array, do not copy the null terminator into std::string, it makes columns misaligned.
151 const auto length = charArr[charArr.size()-1] == '\0' ? charArr.size() - 1 : charArr.size();
152 const std::string arrAsStr(charArr.data(), length); // also works for non-null-terminated strings
153 fRepresentations[index] = arrAsStr;
154 return false; // do not treat this as a collection
155 }
156
157 ////////////////////////////////////////////////////////////////////////////
158 /// AddInterpreterString overload for arrays of booleans.
159 ///
160 /// \param[in] boolArr The bool array to convert to string representation
161 /// \param[in] index To which column the event belongs
162 /// \return true, the event is a collection
163 ///
164 /// This specialization for arrays of booleans skips the cling::printValue
165 /// (i.e. appends nothing to the stream) and directly writes to fCollectionsRepresentations the
166 /// string representation of the array of chars.
167 bool AddInterpreterString(std::stringstream &, ROOT::RVec<bool> &boolArr, const int &index)
168 {
169 fCollectionsRepresentations[index].reserve(boolArr.size());
170 for (bool b : boolArr)
171 fCollectionsRepresentations[index].push_back(b ? "true" : "false");
172
173 return true; // treat this as a collection
174 }
175
176
177 ////////////////////////////////////////////////////////////////////////////
178 /// Adds a single element to the next slot in the table
179 void AddToRow(const std::string &stringEle);
180
181 ////////////////////////////////////////////////////////////////////////////
182 /// Adds a collection to the table
183 ///
184 /// Starting from the slot, the elements are added one under the other, each
185 /// one using a single cell of an entire row
186 void AddCollectionToRow(const VecStr_t &collection);
187
188 ////////////////////////////////////////////////////////////////////////////
189 /// Moves to the next cell
190 ///
191 /// Moves to the next cell, and if the row is full moves to the next row.
192 void MovePosition();
193
194 ////////////////////////////////////////////////////////////////////////////
195 /// Get the number of columns that do NOT fit in the characters limit
196 size_t GetNColumnsToShorten() const;
197
198 ////////////////////////////////////////////////////////////////////////////
199 /// Adds a row of events to the table
200 template <typename... Columns>
201 void AddRow(Columns &... columns)
202 {
203 std::stringstream calc; // JITted code
204 int columnIndex = 0;
205 // Unwrapping the parameters to create the JITted code.
206 fIsCollection = {AddInterpreterString(calc, columns, columnIndex++)...};
207
208 // Let cling::printValue handle the conversion. This can be done only through cling-compiled code.
209 const std::string toJit = calc.str();
210 if (!toJit.empty())
211 ROOT::Internal::RDF::InterpreterCalc(calc.str(), "Display");
212
213 // Populate the fTable using the results of the JITted code.
214 for (size_t i = 0; i < fNColumns; ++i) {
215 if (fIsCollection[i]) {
217 } else {
219 }
220 }
221 // This row has been parsed
222 fEntries--;
223 }
224
225 ////////////////////////////////////////////////////////////////////////////
226 /// If the number of required rows has been parsed, returns false.
227 bool HasNext() { return fEntries > 0; }
228
229 void EnsureCurrentColumnWidth(size_t w);
230
231public:
232 ////////////////////////////////////////////////////////////////////////////
233 /// Creates an RDisplay to print the event values
234 /// \param[in] columnNames Columns to print
235 /// \param[in] types The type of each column
236 /// \param[in] entries How many events per column (row) must be processed.
237 RDisplay(const VecStr_t &columnNames, const VecStr_t &types, int entries);
238
239 ////////////////////////////////////////////////////////////////////////////
240 /// Prints the representation to the standard output
241 ///
242 /// Collections are shortened to the first and last element. The overall width
243 /// is shortened to a fixed number of columns that should fit the screen width.
244 void Print() const;
245
246 ////////////////////////////////////////////////////////////////////////////
247 /// Returns the representation as a string
248 std::string AsString() const;
249};
250
251} // namespace RDF
252} // namespace ROOT
253
254#endif
#define b(i)
Definition RSha256.hxx:100
int type
Definition TGX11.cxx:121
Helper class to let Display print compact tabular representations of the events.
Definition RDisplay.hxx:32
bool IsIgnore() const
Return if the cell has to be skipped.
bool IsDot() const
Return if the cell has to be replaced by "...".
const std::string & GetRepresentation() const
bool IsPrint() const
Return if the cell has to be printed.
void SetDots()
Flag this cell to be replaced by "...".
void SetPrint()
Flag this cell as to be printed.
void SetIgnore()
Flag this cell as to be skipped.
RDisplayElement()
Constructor assuming an empty representation to be printed.
This class is the textual representation of the content of a columnar dataset.
Definition RDisplay.hxx:65
bool AddInterpreterString(std::stringstream &, ROOT::RVec< bool > &boolArr, const int &index)
AddInterpreterString overload for arrays of booleans.
Definition RDisplay.hxx:167
void AddRow(Columns &... columns)
Adds a row of events to the table.
Definition RDisplay.hxx:201
size_t fEntries
Number of events to process for each column (i.e. number of rows).
Definition RDisplay.hxx:91
void AddCollectionToRow(const VecStr_t &collection)
Adds a collection to the table.
size_t fCurrentColumn
Column that is being filled.
Definition RDisplay.hxx:89
bool HasNext()
If the number of required rows has been parsed, returns false.
Definition RDisplay.hxx:227
std::vector< std::vector< DElement_t > > fTable
String representation of the data to be printed.
Definition RDisplay.hxx:77
std::vector< bool > fIsCollection
True if the column contains a collection.
Definition RDisplay.hxx:75
std::string AsString() const
Returns the representation as a string.
void AddToRow(const std::string &stringEle)
Adds a single element to the next slot in the table.
size_t fCurrentRow
Row that is being filled.
Definition RDisplay.hxx:87
VecStr_t fRepresentations
Used by the JITted code to store the string representation of the data.
Definition RDisplay.hxx:80
void MovePosition()
Moves to the next cell.
std::vector< unsigned short > fWidths
Tracks the maximum width of each column, based on the largest element.
Definition RDisplay.hxx:78
bool AddInterpreterString(std::stringstream &stream, T &collection, const int &index)
Appends collection.size() cling::printValue calls to the stringstream.
Definition RDisplay.hxx:117
static constexpr unsigned fgMaxWidth
Definition RDisplay.hxx:72
void EnsureCurrentColumnWidth(size_t w)
size_t fNextRow
Next row to be filled.
Definition RDisplay.hxx:88
bool AddInterpreterString(std::stringstream &, ROOT::RVec< char > &charArr, const int &index)
AddInterpreterString overload for arrays of chars.
Definition RDisplay.hxx:148
std::vector< std::string > VecStr_t
Definition RDisplay.hxx:69
void Print() const
Prints the representation to the standard output.
std::vector< VecStr_t > fCollectionsRepresentations
Used by the JITted code to store the string representation of the data in case of collection.
Definition RDisplay.hxx:81
size_t GetNColumnsToShorten() const
Get the number of columns that do NOT fit in the characters limit.
static constexpr char fgSeparator
Spacing used to align the table entries.
Definition RDisplay.hxx:71
bool AddInterpreterString(std::stringstream &stream, T &element, const int &index)
Appends a cling::printValue call to the stringstream.
Definition RDisplay.hxx:101
VecStr_t fTypes
This attribute stores the type of each column. It is needed by the interpreter to print it.
Definition RDisplay.hxx:74
size_t fNColumns
Number of columns to be printed.
Definition RDisplay.hxx:85
A "std::vector"-like collection of values implementing handy operation to analyse them.
Definition RVec.hxx:296
size_type size() const noexcept
Definition RVec.hxx:433
data_t data() noexcept
Definition RVec.hxx:416
std::string PrettyPrintAddr(const void *const addr)
Long64_t InterpreterCalc(const std::string &code, const std::string &context)
Definition RDFUtils.cxx:330
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
int GetSplit(const char *type, std::vector< std::string > &output, int &nestedLoc, EModType mode=TClassEdit::kNone)
Stores in output (after emptying it) the split type.
static void output(int code)
Definition gifencode.c:226