LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
util::quantities::details Namespace Reference

Functions

template<typename Quantity >
std::pair< std::string, typename Quantity::value_t > readUnit (std::string const &str, bool unitOptional=false)
 Parses the unit of a string representing a Quantity. More...
 

Function Documentation

template<typename Quantity >
std::pair< std::string, typename Quantity::value_t > util::quantities::details::readUnit ( std::string const &  str,
bool  unitOptional = false 
)

Parses the unit of a string representing a Quantity.

Template Parameters
Quantitythe quantity being represented
Parameters
strthe string to be parsed
unitOptional(default: false) whether unit is not required
Returns
a pair: the unparsed part of str and the factor for parsed unit
Exceptions
MissingUnits does not contain the required unit
ValueErrorthe numerical value in s is not parseable
ExtraCharactersErrorspurious characters after the numeric value (including an unrecognised unit prefix)

Definition at line 1474 of file quantities.h.

References e, scale, and util::to_string().

1477 {
1478  using Quantity_t = Quantity;
1479  using value_t = typename Quantity_t::value_t;
1480  using unit_t = typename Quantity_t::unit_t;
1481  using baseunit_t = typename unit_t::baseunit_t;
1482 
1483  // --- BEGIN -- static initialization ----------------------------------------
1484  using namespace std::string_literals;
1485 
1486  using PrefixMap_t = std::map<std::string, value_t>;
1487  using PrefixValue_t = typename PrefixMap_t::value_type;
1488  static PrefixMap_t const factors{PrefixValue_t{"a"s, 1e-18},
1489  PrefixValue_t{"f"s, 1e-15},
1490  PrefixValue_t{"p"s, 1e-12},
1491  PrefixValue_t{"n"s, 1e-09},
1492  PrefixValue_t{"u"s, 1e-06},
1493  PrefixValue_t{"m"s, 1e-03},
1494  PrefixValue_t{"c"s, 1e-02},
1495  PrefixValue_t{"d"s, 1e-01},
1496  PrefixValue_t{""s, 1e+00},
1497  PrefixValue_t{"da"s, 1e+01},
1498  PrefixValue_t{"h"s, 1e+02},
1499  PrefixValue_t{"k"s, 1e+03},
1500  PrefixValue_t{"M"s, 1e+06},
1501  PrefixValue_t{"G"s, 1e+09},
1502  PrefixValue_t{"T"s, 1e+12},
1503  PrefixValue_t{"P"s, 1e+15},
1504  PrefixValue_t{"E"s, 1e+18}}; // factors
1505  static auto const composePrefixPattern = [](auto b, auto e) -> std::string {
1506  std::string pattern = "(";
1507  if (b != e) {
1508  pattern += b->first;
1509  while (++b != e) {
1510  pattern += '|';
1511  pattern += b->first;
1512  }
1513  }
1514  return pattern += ")";
1515  };
1516  static std::string const prefixPattern = composePrefixPattern(factors.begin(), factors.end());
1517  // --- END -- static initialization ------------------------------------------
1518 
1519  std::regex const unitPattern{"[[:blank:]]*(" + prefixPattern + "?" +
1520  util::to_string(baseunit_t::symbol) + ")[[:blank:]]*$"};
1521 
1522  std::smatch unitMatch;
1523  if (!std::regex_search(str, unitMatch, unitPattern)) {
1524  if (!unitOptional) {
1525  throw MissingUnit("Unit is mandatory and must derive from '" +
1526  util::to_string(baseunit_t::symbol) + "' (parsing: '" + str + "')");
1527  }
1528  return {str, value_t{1}};
1529  }
1530 
1531  //
1532  // we do have a unit:
1533  //
1534 
1535  // " 7 cm " => [0] full match (" cm ") [1] unit ("cm") [2] unit prefix ("c")
1536  auto const iFactor = factors.find(unitMatch.str(2U));
1537  if (iFactor == factors.end()) {
1538  throw InvalidUnitPrefix("Unit '" + unitMatch.str(1U) + "' has unsupported prefix '" +
1539  unitMatch.str(2U) + "' (parsing '" + str + "')");
1540  }
1541 
1542  return {str.substr(0U, str.length() - unitMatch.length()),
1543  static_cast<value_t>(unit_t::scale(iFactor->second))};
1544 
1545 } // util::quantities::details::readUnit()
Double_t scale
Definition: plot.C:24
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string.
Float_t e
Definition: plot.C:35