Functions
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 1569 of file quantities.h.

1570 {
1571  using Quantity_t = Quantity;
1572  using value_t = typename Quantity_t::value_t;
1573  using unit_t = typename Quantity_t::unit_t;
1574  using baseunit_t = typename unit_t::baseunit_t;
1575 
1576  // --- BEGIN -- static initialization ----------------------------------------
1577  using namespace std::string_literals;
1578 
1579  using PrefixMap_t = std::map<std::string, value_t>;
1580  using PrefixValue_t = typename PrefixMap_t::value_type;
1581  static PrefixMap_t const factors {
1582  PrefixValue_t{ "a"s, 1e-18 },
1583  PrefixValue_t{ "f"s, 1e-15 },
1584  PrefixValue_t{ "p"s, 1e-12 },
1585  PrefixValue_t{ "n"s, 1e-09 },
1586  PrefixValue_t{ "u"s, 1e-06 },
1587  PrefixValue_t{ "m"s, 1e-03 },
1588  PrefixValue_t{ "c"s, 1e-02 },
1589  PrefixValue_t{ "d"s, 1e-01 },
1590  PrefixValue_t{ ""s, 1e+00 },
1591  PrefixValue_t{ "da"s, 1e+01 },
1592  PrefixValue_t{ "h"s, 1e+02 },
1593  PrefixValue_t{ "k"s, 1e+03 },
1594  PrefixValue_t{ "M"s, 1e+06 },
1595  PrefixValue_t{ "G"s, 1e+09 },
1596  PrefixValue_t{ "T"s, 1e+12 },
1597  PrefixValue_t{ "P"s, 1e+15 },
1598  PrefixValue_t{ "E"s, 1e+18 }
1599  }; // factors
1600  static auto const composePrefixPattern = [](auto b, auto e) -> std::string
1601  {
1602  std::string pattern = "(";
1603  if (b != e) {
1604  pattern += b->first;
1605  while (++b != e) { pattern += '|'; pattern += b->first; }
1606  }
1607  return pattern += ")";
1608  };
1609  static std::string const prefixPattern
1610  = composePrefixPattern(factors.begin(), factors.end());
1611  // --- END -- static initialization ------------------------------------------
1612 
1613  std::regex const unitPattern {
1614  "[[:blank:]]*(" + prefixPattern + "?"
1615  + util::to_string(baseunit_t::symbol) + ")[[:blank:]]*$"
1616  };
1617 
1618  std::smatch unitMatch;
1619  if (!std::regex_search(str, unitMatch, unitPattern)) {
1620  if (!unitOptional) {
1621  throw MissingUnit("Unit is mandatory and must derive from '"
1622  + util::to_string(baseunit_t::symbol) + "' (parsing: '" + str + "')"
1623  );
1624  }
1625  return { str, value_t{ 1 } };
1626  }
1627 
1628  //
1629  // we do have a unit:
1630  //
1631 
1632  // " 7 cm " => [0] full match (" cm ") [1] unit ("cm") [2] unit prefix ("c")
1633  auto const iFactor = factors.find(unitMatch.str(2U));
1634  if (iFactor == factors.end()) {
1635  throw InvalidUnitPrefix(
1636  "Unit '" + unitMatch.str(1U)
1637  + "' has unsupported prefix '" + unitMatch.str(2U)
1638  + "' (parsing '" + str + "')"
1639  );
1640  }
1641 
1642  return {
1643  str.substr(0U, str.length() - unitMatch.length()),
1644  static_cast<value_t>(unit_t::scale(iFactor->second))
1645  };
1646 
1647 } // util::quantities::details::readUnit()
uint length() const
Definition: qcstring.h:195
std::string string
Definition: nybbler.cc:12
int find(char c, int index=0, bool cs=TRUE) const
Definition: qcstring.cpp:41
const double e
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string.
std::string pattern
Definition: regex_t.cc:35
static bool * b
Definition: config.cpp:1043
static QCString * s
Definition: config.cpp:1042
static QCString str