Logo ROOT  
Reference Guide
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
Loading...
Searching...
No Matches
Utils.hxx
Go to the documentation of this file.
1// Author: Enrico Guiraud, Danilo Piparo CERN 12/2016
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_RDFUTILS
12#define ROOT_RDFUTILS
13
14#include "ROOT/RSpan.hxx"
15#include <string_view>
16#include "ROOT/RVec.hxx"
17#include "ROOT/TypeTraits.hxx"
18#include "Rtypes.h"
19
20#include <array>
21#include <deque>
22#include <functional>
23#include <memory>
24#include <new> // std::hardware_destructive_interference_size
25#include <unordered_set>
26#include <shared_mutex>
27#include <string>
28#include <type_traits> // std::decay, std::false_type
29#include <vector>
30
31class TTree;
32class TTreeReader;
33
34
35namespace ROOT {
36namespace RDF {
37using ColumnNames_t = std::vector<std::string>;
38}
39
40class RLogChannel;
41
42namespace RDF {
43class RDataSource;
44}
45
46namespace Detail {
47namespace RDF {
48
50
52
53// fwd decl for ColumnName2ColumnTypeName
54class RDefineBase;
55
56// type used for tag dispatching
58};
59
60} // end ns Detail
61} // end ns RDF
62
63namespace Internal {
64namespace RDF {
65
66using namespace ROOT::TypeTraits;
67using namespace ROOT::Detail::RDF;
68using namespace ROOT::RDF;
69
70/// Check for container traits.
71///
72/// Note that for all uses in RDF we don't want to classify std::string as a container.
73/// Template specializations of IsDataContainer make it return `true` for std::span<T>, std::vector<bool> and
74/// RVec<bool>, which we do want to count as containers even though they do not satisfy all the traits tested by the
75/// generic IsDataContainer<T>.
76template <typename T>
78 using Test_t = std::decay_t<T>;
79
80 template <typename A>
81 static constexpr bool Test(A *pt, A const *cpt = nullptr, decltype(pt->begin()) * = nullptr,
82 decltype(pt->end()) * = nullptr, decltype(cpt->begin()) * = nullptr,
83 decltype(cpt->end()) * = nullptr, typename A::iterator *pi = nullptr,
84 typename A::const_iterator *pci = nullptr)
85 {
86 using It_t = typename A::iterator;
87 using CIt_t = typename A::const_iterator;
88 using V_t = typename A::value_type;
89 return std::is_same<decltype(pt->begin()), It_t>::value && std::is_same<decltype(pt->end()), It_t>::value &&
90 std::is_same<decltype(cpt->begin()), CIt_t>::value && std::is_same<decltype(cpt->end()), CIt_t>::value &&
91 std::is_same<decltype(**pi), V_t &>::value && std::is_same<decltype(**pci), V_t const &>::value &&
92 !std::is_same<T, std::string>::value;
93 }
94
95 template <typename A>
96 static constexpr bool Test(...)
97 {
98 return false;
99 }
100
101 static constexpr bool value = Test<Test_t>(nullptr);
102};
103
104template<>
105struct IsDataContainer<std::vector<bool>> {
106 static constexpr bool value = true;
107};
108
109template<>
111 static constexpr bool value = true;
112};
113
114template<typename T>
115struct IsDataContainer<std::span<T>> {
116 static constexpr bool value = true;
117};
118
119/// Detect whether a type is an instantiation of vector<T,A>
120template <typename>
121struct IsVector_t : public std::false_type {};
122
123template <typename T, typename A>
124struct IsVector_t<std::vector<T, A>> : public std::true_type {};
125
126std::string GetBranchOrLeafTypeName(TTree &t, const std::string &colName);
127
128const std::type_info &TypeName2TypeID(const std::string &name);
129
130std::string TypeID2TypeName(const std::type_info &id);
131
132std::string GetTypeNameWithOpts(const ROOT::RDF::RDataSource &df, std::string_view colName, bool vector2RVec);
133std::string
134ColumnName2ColumnTypeName(const std::string &colName, TTree *, RDataSource *, RDefineBase *, bool vector2RVec = true);
135
136char TypeName2ROOTTypeName(const std::string &b);
137
138unsigned int GetNSlots();
139
140/// `type` is TypeList if MustRemove is false, otherwise it is a TypeList with the first type removed
141template <bool MustRemove, typename TypeList>
145
146template <typename TypeList>
150
151template <bool MustRemove, typename TypeList>
153
154template <bool MustRemove, typename TypeList>
158
159template <typename TypeList>
164
165template <bool MustRemove, typename TypeList>
167
168// Check the value_type type of a type with a SFINAE to allow compilation in presence
169// fundamental types
170template <typename T,
171 bool IsDataContainer = IsDataContainer<std::decay_t<T>>::value || std::is_same<std::string, T>::value>
172struct ValueType {
173 using value_type = typename T::value_type;
174};
175
176template <typename T>
177struct ValueType<T, false> {
178 using value_type = T;
179};
180
181template <typename T>
183 using value_type = T;
184};
185
186std::vector<std::string> ReplaceDotWithUnderscore(const std::vector<std::string> &columnNames);
187
188/// Erase `that` element from vector `v`
189template <typename T>
190void Erase(const T &that, std::vector<T> &v)
191{
192 v.erase(std::remove(v.begin(), v.end(), that), v.end());
193}
194
195/// Declare code in the interpreter via the TInterpreter::Declare method, throw in case of errors
196void InterpreterDeclare(const std::string &code);
197
198/// Jit code in the interpreter with TInterpreter::Calc, throw in case of errors.
199/// The optional `context` parameter, if present, is mentioned in the error message.
200void InterpreterCalc(const std::string &code, const std::string &context = "");
201
202/// Whether custom column with name colName is an "internal" column such as rdfentry_ or rdfslot_
203bool IsInternalColumn(std::string_view colName);
204
205/// Get optimal column width for printing a table given the names and the desired minimal space between columns
206unsigned int GetColumnWidth(const std::vector<std::string>& names, const unsigned int minColumnSpace = 8u);
207
208// We could just check `#ifdef __cpp_lib_hardware_interference_size`, but at least on Mac 11
209// libc++ defines that macro but is missing the actual feature, so we use an ad-hoc ROOT macro instead.
210// See the relevant entry in cmake/modules/RootConfiguration.cmake for more info.
211#ifdef R__HAS_HARDWARE_INTERFERENCE_SIZE
212 // C++17 feature (so we can use inline variables)
213 inline constexpr std::size_t kCacheLineSize = std::hardware_destructive_interference_size;
214#else
215 // safe bet: assume the typical 64 bytes
216 static constexpr std::size_t kCacheLineSize = 64;
217#endif
218
219/// Stepping through CacheLineStep<T> values in a vector<T> brings you to a new cache line.
220/// Useful to avoid false sharing.
221template <typename T>
222constexpr std::size_t CacheLineStep() {
223 return (kCacheLineSize + sizeof(T) - 1) / sizeof(T);
224}
225
226void CheckReaderTypeMatches(const std::type_info &colType, const std::type_info &requestedType,
227 const std::string &colName);
228
229// TODO in C++17 this could be a lambda within FillHelper::Exec
230template <typename T>
231constexpr std::size_t FindIdxTrue(const T &arr)
232{
233 for (size_t i = 0; i < arr.size(); ++i) {
234 if (arr[i])
235 return i;
236 }
237 return arr.size();
238}
239
240// return type has to be decltype(auto) to preserve perfect forwarding
241template <std::size_t N, typename... Ts>
242decltype(auto) GetNthElement(Ts &&...args)
243{
244 auto tuple = std::forward_as_tuple(args...);
245 return std::get<N>(tuple);
246}
247
248#if __cplusplus >= 201703L
249template <class... Ts>
250using Disjunction = std::disjunction<Ts...>;
251#else
252template <class...>
253struct Disjunction : std::false_type {
254};
255template <class B1>
257};
258template <class B1, class... Bn>
259struct Disjunction<B1, Bn...> : std::conditional_t<bool(B1::value), B1, Disjunction<Bn...>> {
260};
261#endif
262
263bool IsStrInVec(const std::string &str, const std::vector<std::string> &vec);
264
265/// Return a vector with all elements of v1 and v2 and duplicates removed.
266/// Precondition: each of v1 and v2 must not have duplicate elements.
267template <typename T>
268std::vector<T> Union(const std::vector<T> &v1, const std::vector<T> &v2)
269{
270 std::vector<T> res = v1;
271
272 // Add the variations coming from the input columns
273 for (const auto &e : v2)
274 if (std::find(v1.begin(), v1.end(), e) == v1.end())
275 res.emplace_back(e);
276
277 return res;
278}
279
280/**
281 * \brief A Thread-safe cache for strings.
282 *
283 * This is used to generically store strings that are created in the computation
284 * graph machinery, for example when adding a new node.
285 */
287 std::unordered_set<std::string> fStrings{};
288 std::shared_mutex fMutex{};
289
290public:
291 /**
292 * \brief Inserts the input string in the cache and returns an iterator to the cached string.
293 *
294 * The function implements the following strategy for thread-safety:
295 * 1. Take a shared lock and early return if the string is already in the cache.
296 * 2. Release the shared lock and take an exclusive lock.
297 * 3. Check again if another thread filled the cache meanwhile. If so, return the cached value.
298 * 4. Insert the new value in the cache and return.
299 */
300 auto Insert(const std::string &string) -> decltype(fStrings)::const_iterator;
301};
302
303/**
304 * \brief Struct to wrap the call to a function with a guaranteed order of
305 * execution of its arguments.
306 * \tparam F Type of the callable.
307 * \tparam Args Variadic types of the arguments to the callable.
308 *
309 * The execution order is guaranteed by calling the function in the constructor
310 * thus enabling the exploitation of the list-initialization sequenced-before
311 * feature (See rule 9 at https://en.cppreference.com/w/cpp/language/eval_order).
312 */
314 template <typename F, typename... Args>
315 CallGuaranteedOrder(F &&f, Args &&...args)
316 {
317 f(std::forward<Args>(args)...);
318 }
319};
320
321template <typename T>
323{
324 const static std::shared_ptr<T> fgRawPtrCtrlBlock;
325 return std::shared_ptr<T>(fgRawPtrCtrlBlock, rawPtr);
326}
327
328} // end NS RDF
329} // end NS Internal
330} // end NS ROOT
331
332#endif // RDFUTILS
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
#define e(i)
Definition RSha256.hxx:103
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define N
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
A Thread-safe cache for strings.
Definition Utils.hxx:286
auto Insert(const std::string &string) -> decltype(fStrings)::const_iterator
Inserts the input string in the cache and returns an iterator to the cached string.
Definition RDFUtils.cxx:447
std::unordered_set< std::string > fStrings
Definition Utils.hxx:287
RDataSource defines an API that RDataFrame can use to read arbitrary data formats.
A log configuration for a channel, e.g.
Definition RLogger.hxx:98
const_iterator begin() const
const_iterator end() const
A "std::vector"-like collection of values implementing handy operation to analyse them.
Definition RVec.hxx:1529
A simple, robust and fast interface to read values from ROOT columnar datasets such as TTree,...
Definition TTreeReader.h:46
A TTree represents a columnar dataset.
Definition TTree.h:79
TPaveText * pt
#define F(x, y, z)
ROOT::RLogChannel & RDFLogChannel()
Definition RDFUtils.cxx:39
auto MakeAliasedSharedPtr(T *rawPtr)
Definition Utils.hxx:322
std::vector< std::string > ReplaceDotWithUnderscore(const std::vector< std::string > &columnNames)
Replace occurrences of '.
Definition RDFUtils.cxx:316
const std::type_info & TypeName2TypeID(const std::string &name)
Return the type_info associated to a name.
Definition RDFUtils.cxx:64
typename RemoveFirstTwoParametersIf< MustRemove, TypeList >::type RemoveFirstTwoParametersIf_t
Definition Utils.hxx:166
unsigned int GetNSlots()
Definition RDFUtils.cxx:303
decltype(auto) GetNthElement(Ts &&...args)
Definition Utils.hxx:242
static constexpr std::size_t kCacheLineSize
Definition Utils.hxx:216
char TypeName2ROOTTypeName(const std::string &b)
Convert type name (e.g.
Definition RDFUtils.cxx:261
std::string TypeID2TypeName(const std::type_info &id)
Returns the name of a type starting from its type_info An empty string is returned in case of failure...
Definition RDFUtils.cxx:121
bool IsStrInVec(const std::string &str, const std::vector< std::string > &vec)
Definition RDFUtils.cxx:442
void Erase(const T &that, std::vector< T > &v)
Erase that element from vector v
Definition Utils.hxx:190
unsigned int GetColumnWidth(const std::vector< std::string > &names, const unsigned int minColumnSpace=8u)
Get optimal column width for printing a table given the names and the desired minimal space between c...
Definition RDFUtils.cxx:393
std::string GetBranchOrLeafTypeName(TTree &t, const std::string &colName)
Return the typename of object colName stored in t, if any.
Definition RDFUtils.cxx:174
constexpr std::size_t CacheLineStep()
Stepping through CacheLineStep<T> values in a vector<T> brings you to a new cache line.
Definition Utils.hxx:222
std::string ColumnName2ColumnTypeName(const std::string &colName, TTree *, RDataSource *, RDefineBase *, bool vector2RVec=true)
Return a string containing the type of the given branch.
Definition RDFUtils.cxx:231
void InterpreterCalc(const std::string &code, const std::string &context="")
Jit code in the interpreter with TInterpreter::Calc, throw in case of errors.
Definition RDFUtils.cxx:347
void CheckReaderTypeMatches(const std::type_info &colType, const std::type_info &requestedType, const std::string &colName)
Definition RDFUtils.cxx:405
constexpr std::size_t FindIdxTrue(const T &arr)
Definition Utils.hxx:231
std::vector< T > Union(const std::vector< T > &v1, const std::vector< T > &v2)
Return a vector with all elements of v1 and v2 and duplicates removed.
Definition Utils.hxx:268
bool IsInternalColumn(std::string_view colName)
Whether custom column with name colName is an "internal" column such as rdfentry_ or rdfslot_.
Definition RDFUtils.cxx:384
std::string GetTypeNameWithOpts(const ROOT::RDF::RDataSource &ds, std::string_view colName, bool vector2RVec)
Definition RDFUtils.cxx:468
void InterpreterDeclare(const std::string &code)
Declare code in the interpreter via the TInterpreter::Declare method, throw in case of errors.
Definition RDFUtils.cxx:335
typename RemoveFirstParameterIf< MustRemove, TypeList >::type RemoveFirstParameterIf_t
Definition Utils.hxx:152
std::vector< std::string > ColumnNames_t
ROOT type_traits extensions.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Struct to wrap the call to a function with a guaranteed order of execution of its arguments.
Definition Utils.hxx:313
CallGuaranteedOrder(F &&f, Args &&...args)
Definition Utils.hxx:315
Check for container traits.
Definition Utils.hxx:77
static constexpr bool Test(A *pt, A const *cpt=nullptr, decltype(pt->begin()) *=nullptr, decltype(pt->end()) *=nullptr, decltype(cpt->begin()) *=nullptr, decltype(cpt->end()) *=nullptr, typename A::iterator *pi=nullptr, typename A::const_iterator *pci=nullptr)
Definition Utils.hxx:81
static constexpr bool Test(...)
Definition Utils.hxx:96
static constexpr bool value
Definition Utils.hxx:101
Detect whether a type is an instantiation of vector<T,A>
Definition Utils.hxx:121
type is TypeList if MustRemove is false, otherwise it is a TypeList with the first type removed
Definition Utils.hxx:142
typename RemoveFirstParameterIf< true, typeTmp >::type type
Definition Utils.hxx:162
typename RemoveFirstParameterIf< true, TypeList >::type typeTmp
Definition Utils.hxx:161
typename T::value_type value_type
Definition Utils.hxx:173
Lightweight storage for a collection of types.