Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
StringUtils.cxx
Go to the documentation of this file.
1/// \file ROOT/StringUtils.hxx
2/// \author Jonas Rembser <jonas.rembser@cern.ch>
3/// \date 2021-08-09
4
5/*************************************************************************
6 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
7 * All rights reserved. *
8 * *
9 * For the licensing terms see $ROOTSYS/LICENSE. *
10 * For the list of contributors see $ROOTSYS/README/CREDITS. *
11 *************************************************************************/
12
13#include "ROOT/StringUtils.hxx"
14#include <sstream>
15#include <cmath>
16#include <ios>
17#include <cassert>
18
19namespace ROOT {
20
21/// Splits a string at each character in delims.
22/// The behavior mimics `str.split` from Python,
23/// \param[in] str String to tokenise.
24/// \param[in] delims One or more delimiters used to split the string.
25/// \param[in] skipEmpty Strip empty strings from the output.
26std::vector<std::string> Split(std::string_view str, std::string_view delims, bool skipEmpty /* =false */)
27{
28 std::vector<std::string> out;
29
30 std::size_t beg = 0;
31 std::size_t end = 0;
32 while ((end = str.find_first_of(delims, beg)) != std::string::npos) {
33 if (!skipEmpty || end > beg)
34 out.emplace_back(str.substr(beg, end - beg));
35 beg = end + 1;
36 }
37 if (!skipEmpty || str.size() > beg)
38 out.emplace_back(str.substr(beg, str.size() - beg));
39
40 return out;
41}
42
43std::pair<std::string_view, std::string_view> SplitAt(std::string_view str, char splitter)
44{
45 auto pos = str.find(splitter);
46 if (pos == std::string_view::npos)
47 return {str, ""};
48 return {str.substr(0, pos), str.substr(pos + 1)};
49}
50
51/**
52 * \brief Convert (round) a value and its uncertainty to string using one or two significant digits of the error
53 * \param error the error. If the error is negative or zero, only the value is returned with no specific rounding
54 * applied, using std::to_string
55 * \param cutoff should lay between 0 and 9. If first significant digit of error starts with value <= cutoff,
56 * use two significant digits instead of two for rounding. Set this value to zero to always use a
57 * single digit; set this value to 9 to always use two digits.
58 * \param delim delimiter between value and error printed into returned string, leave default for using ROOT's latex
59 * mode.
60 * \return a string with printed rounded value and error separated by "+/-" in ROOT latex mode \note The return
61 * format is `A+-B` using ios::fixed with the proper precision; for very large or very small values of the error, the
62 * format is changed from `A+-B` to (A'+-B')*1eX, with X being multiple of 3, respecting the corresponding precision.
63 * \see https://www.bipm.org/en/doi/10.59161/jcgm100-2008e, https://physics.nist.gov/cuu/Uncertainty/
64 */
65std::string Round(double value, double error, unsigned int cutoff, std::string_view delim)
66{
67 if (error <= 0.) {
68 return std::to_string(value);
69 }
70
71 int error_exponent_base10_rounded = std::floor(std::log10(error));
72 const auto error_magnitude_base10 = std::pow(10., error_exponent_base10_rounded);
73 const auto error_first_digit = static_cast<unsigned int>(error / error_magnitude_base10);
76 const double rescaled_error = error * std::pow(10., -1. * error_exponent_base10_rounded);
77 if (static_cast<unsigned int>(std::round(rescaled_error * 10) / 10) <= cutoff)
79 } else if (cutoff == 0 && error_first_digit == 9) {
80 const double rounded_rescaled_error = std::round(error * std::pow(10., -1. * error_exponent_base10_rounded));
88 }
89 const int factored_out_exponent_base10 = error <= 1e-3 ? static_cast<int>(std::floor(std::log10(error) / 3)) * 3
90 : static_cast<int>(std::log10(error) / 3) * 3;
91
92 std::stringstream result;
93 result.setf(std::ios::fixed);
96 } else {
97 result.precision(0);
98 }
100 result << "(";
101 result << std::round(value * std::pow(10., -error_exponent_base10_rounded)) /
103 result << delim;
104 result << std::round(error * std::pow(10., -error_exponent_base10_rounded)) /
108 return result.str();
109}
110
111} // namespace ROOT
#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.
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 value
std::string Round(double value, double error, unsigned int cutoff=1, std::string_view delim="#pm")
Convert (round) a value and its uncertainty to string using one or two significant digits of the erro...
std::vector< std::string > Split(std::string_view str, std::string_view delims, bool skipEmpty=false)
Splits a string at each character in delims.
std::pair< std::string_view, std::string_view > SplitAt(std::string_view str, char splitter)
Given a string str, returns a pair of string views into it: the first containing the substring preced...