diff --git a/tree/dataframe/inc/ROOT/RDF/RDisplay.hxx b/tree/dataframe/inc/ROOT/RDF/RDisplay.hxx index 08c9409fef18f..caae8e6a0e9cd 100644 --- a/tree/dataframe/inc/ROOT/RDF/RDisplay.hxx +++ b/tree/dataframe/inc/ROOT/RDF/RDisplay.hxx @@ -19,6 +19,7 @@ #include #include #include +#include namespace ROOT { namespace Internal { @@ -90,17 +91,51 @@ private: size_t fNMaxCollectionElements = 10; // threshold on number of elements in collections to be Print() //////////////////////////////////////////////////////////////////////////// - /// Appends a cling::printValue call to the stringstream. + /// Appends a cling::printValue call to the stringstream + /// This overload works for non-collection data types which are also not + /// trivially representable as strings. /// \tparam T the type of the event to convert /// \param[in] stream Where the conversion function call will be chained. /// \param[in] element The event to convert to its string representation /// \param[in] index To which column the event belongs to /// \return false, the event is not a collection - template ::value, int> = 0> + template && !ROOT::Internal::RDF::IsDataContainer::value, int> = 0> bool AddInterpreterString(std::stringstream &stream, T &element, const int &index) { stream << "*((std::string*)" << ROOT::Internal::RDF::PrettyPrintAddr(&(fRepresentations[index])) - << ") = cling::printValue((" << fTypes[index] << "*)" << ROOT::Internal::RDF::PrettyPrintAddr(&element) << ");"; + << ") = cling::printValue((" << fTypes[index] << "*)" << ROOT::Internal::RDF::PrettyPrintAddr(&element) + << ");"; + return false; + } + + //////////////////////////////////////////////////////////////////////////// + /// Appends a string if the T type is an arithmetic type. + /// This overload works for arithmetic data types that are trivially + /// convertible to string. + /// \tparam T the type of the event to convert + /// \param[in] element The event to convert to its string representation + /// \param[in] index To which column the event belongs to + /// \return false, the event is not a collection + template , int> = 0> + bool AddInterpreterString(std::stringstream &, T &element, const int &index) + { + // Short-circuit the logic and just insert the string representation of + // the symple type at the right index. + fRepresentations[index] = std::to_string(element); + return false; + } + + //////////////////////////////////////////////////////////////////////////// + /// Appends a string if the T type is boolean. + /// \param[in] element The event to convert to its string representation + /// \param[in] index To which column the event belongs to + /// \return false, the event is not a collection + bool AddInterpreterString(std::stringstream &, bool &element, const int &index) + { + // Short-circuit the logic and just insert the string representation of + // the boolean value at the right index. + fRepresentations[index] = (element ? "true" : "false"); return false; } @@ -112,7 +147,9 @@ private: /// \param[in] index To which column the event belongs to /// \return true, the event is a collection /// This function chains a sequence of call to cling::printValue, one for each element of the collection. - template ::value, int> = 0> + template ::value && + !std::is_arithmetic_v, + int> = 0> bool AddInterpreterString(std::stringstream &stream, T &collection, const int &index) { size_t collectionSize = std::distance(std::begin(collection), std::end(collection)); @@ -134,6 +171,53 @@ private: return true; } + //////////////////////////////////////////////////////////////////////////// + /// Represent a collection of values as a collection of strings. + /// \tparam T the type of the event to convert. This must be a collection of + /// values of arithmetic type, but not boolean. + /// \param[in] collection The event to convert to its string representation + /// \param[in] index To which column the event belongs to + /// \return true, the event is a collection + template ::value && + std::is_arithmetic_v && + !std::is_same_v, + int> = 0> + bool AddInterpreterString(std::stringstream &, T &collection, const int &index) + { + auto collectionSize = std::distance(std::begin(collection), std::end(collection)); + VecStr_t collectionRepr(collectionSize); + std::generate(collectionRepr.begin(), collectionRepr.end(), [i = 0, &collection]() mutable { + auto valRepr = std::to_string(collection[i]); + i++; + return valRepr; + }); + fCollectionsRepresentations[index] = std::move(collectionRepr); + return true; + } + + //////////////////////////////////////////////////////////////////////////// + /// Represent a collection of booleans as a collection of strings. + /// \tparam T the type of the event to convert. This must be a collection of + /// boolean values. + /// \param[in] collection The event to convert to its string representation + /// \param[in] index To which column the event belongs to + /// \return true, the event is a collection + template ::value && + std::is_same_v, + int> = 0> + bool AddInterpreterString(std::stringstream &, T &collection, const int &index) + { + auto collectionSize = std::distance(std::begin(collection), std::end(collection)); + VecStr_t collectionRepr(collectionSize); + std::generate(collectionRepr.begin(), collectionRepr.end(), [i = 0, &collection]() mutable { + auto valRepr = (collection[i] ? "true" : "false"); + i++; + return valRepr; + }); + fCollectionsRepresentations[index] = std::move(collectionRepr); + return true; + } + //////////////////////////////////////////////////////////////////////////// /// AddInterpreterString overload for arrays of chars. /// @@ -153,28 +237,6 @@ private: return false; // do not treat this as a collection } - //////////////////////////////////////////////////////////////////////////// - /// AddInterpreterString overload for arrays of booleans. - /// - /// \param[in] boolArr The bool array to convert to string representation - /// \param[in] index To which column the event belongs - /// \return true, the event is a collection - /// - /// This specialization for arrays of booleans skips the cling::printValue - /// (i.e. appends nothing to the stream) and directly writes to fCollectionsRepresentations the - /// string representation of the array of chars. - bool AddInterpreterString(std::stringstream &, ROOT::RVec &boolArr, const int &index) - { - auto &collRepr = fCollectionsRepresentations[index]; - collRepr.clear(); - collRepr.reserve(boolArr.size()); - for (bool b : boolArr) - collRepr.push_back(b ? "true" : "false"); - - return true; // treat this as a collection - } - - //////////////////////////////////////////////////////////////////////////// /// Adds a single element to the next slot in the table void AddToRow(const std::string &stringEle);