29 inline static const std::map<std::string, std::pair<double,std::array<int,7>>>
base_units =
31 {
"1", {1.0, {0,0,0,0,0,0,0}}},
32 {
"m", {1.0, {1,0,0,0,0,0,0}}},
33 {
"s", {1.0, {0,1,0,0,0,0,0}}},
34 {
"kg", {1.0, {0,0,1,0,0,0,0}}},
35 {
"K", {1.0, {0,0,0,1,0,0,0}}},
36 {
"A", {1.0, {0,0,0,0,1,0,0}}},
37 {
"mol",{1.0, {0,0,0,0,0,1,0}}},
38 {
"cd", {1.0, {0,0,0,0,0,0,1}}}
261 Unit(
const std::pair<
double, std::array<int, 7>>& p) : std::pair<double, std::array<int, 7>>(p) {}
271 static Unit Parse(std::string unit,
bool verbose =
false)
274 std::vector<std::string> split;
275 std::stringstream ss(unit);
277 while (std::getline(ss, item,
'_')) {
278 split.push_back(item);
280 if (split.size() == 2)
282 return Parse(std::stod(split[0]),split[1], verbose);
284 else if (split.size() == 1)
294 value = std::strtod(unit.c_str(), &end);
298 if (end != unit.data() && *end ==
'\0')
312 throw std::runtime_error(
"Invalid unit string "+unit);
325 for (
auto parsed_unit : parsed_units)
327 std::cout << parsed_unit.first <<
" " << parsed_unit.second << std::endl;
331 for (
auto &p : parsed_units)
333 const std::string &token = p.first;
346 double factor = pair.first;
347 const std::string &subunit_str = pair.second;
351 t.first *= std::pow(factor, exp);
357 throw std::runtime_error(
"Unknown unit token: " + token);
440 auto join = [] (std::vector<std::string>vec,std::string sep){
441 std::ostringstream oss;
442 for (
size_t i = 0; i < vec.size(); ++i) {
444 if (i < vec.size() - 1) {
451 std::vector<std::string> num, den;
452 for (
unsigned int i = 0 ; i < this->second.size(); i++)
454 if (this->second[i] > 1)
455 num.push_back(
normalization[i].first +
"^" + std::to_string(this->second[i]));
456 else if (this->second[i] == 1)
458 else if (this->second[i] == -1)
460 else if (this->second[i] < -1)
461 den.push_back(
normalization[i].first +
"^" + std::to_string(std::abs(this->second[i])));
465 if (num.size()) ret = join(num,
"*");
467 if (den.size()) ret +=
"/" + join(den,
"/");