Skip to content

Commit 777c844

Browse files
Mass 2 weight (#229)
* add mass to weight conversion capabilities and a few more tests * change the chinese unit extension to use the country code top level domain for china (cn). * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * make a numerical constant from standard gravity * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 85fa19d commit 777c844

7 files changed

+91
-19
lines changed

CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ endif()
1919
project(
2020
UNITS
2121
LANGUAGES CXX
22-
VERSION 0.5.1
22+
VERSION 0.6.0
2323
)
2424
include(CMakeDependentOption)
2525
include(CTest)

test/test_conversions1.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -697,3 +697,12 @@ TEST(invalid_conversions, invalid)
697697
double val = detail::extraValidConversions(2.3, precise::m, precise::lb);
698698
EXPECT_TRUE(std::isnan(val));
699699
}
700+
701+
TEST(UnitDefinitions, mass_to_weight)
702+
{
703+
using namespace units;
704+
EXPECT_NEAR(convert(1.0, N, kg), 0.101971621, test::tolerance);
705+
EXPECT_NEAR(convert(1.0, kg, N), constants::g0.value(), test::tolerance);
706+
707+
EXPECT_NEAR(convert(1.0, precise::lbf, kg), 0.45359237, test::tolerance);
708+
}

test/test_unit_strings.cpp

+41
Original file line numberDiff line numberDiff line change
@@ -1426,6 +1426,47 @@ TEST(mapTests, two_by_one)
14261426
<< ustring << " does not produce equivalent unit";
14271427
}
14281428
}
1429+
1430+
for (const auto& onechar : onecharunits) {
1431+
for (const auto& twochar : twocharunits) {
1432+
std::string ustring = onechar.first + ' ' + twochar.first;
1433+
auto unit = twochar.second * onechar.second;
1434+
EXPECT_EQ(unit_from_string(ustring), unit)
1435+
<< ustring << " does not produce equivalent unit";
1436+
}
1437+
}
1438+
}
1439+
1440+
// test combinations of 2 character units string and another 2 character unit
1441+
// strings for misinterpretation
1442+
TEST(mapTests, two_by_two)
1443+
{
1444+
const auto& map = detail::getUnitStringMap();
1445+
std::vector<std::pair<std::string, precise_unit>> twocharunits;
1446+
for (const auto& val : map) {
1447+
// fluid is a modifier that applies to several other units so can't be
1448+
// disambiguated
1449+
if (val.first.size() == 2 && val.first != "fl") {
1450+
if (val.first.front() > 0 && std::isalpha(val.first.front()) != 0) {
1451+
if (is_valid(val.second)) {
1452+
twocharunits.emplace_back(val);
1453+
}
1454+
}
1455+
}
1456+
}
1457+
1458+
for (const auto& twochar : twocharunits) {
1459+
for (const auto& twocharb : twocharunits) {
1460+
std::string ustring = twochar.first + ' ' + twocharb.first;
1461+
auto unit = twochar.second * twocharb.second;
1462+
EXPECT_EQ(unit_from_string(ustring), unit)
1463+
<< ustring << " does not produce equivalent unit";
1464+
1465+
std::string ustring2 = twocharb.first + ' ' + twochar.first;
1466+
EXPECT_EQ(unit_from_string(ustring2), unit)
1467+
<< ustring2 << " does not produce equivalent unit";
1468+
}
1469+
}
14291470
}
14301471
#endif
14311472

units/unit_definitions.hpp

+24-4
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ namespace constants {
2828
constexpr double invalid_conversion =
2929
std::numeric_limits<double>::signaling_NaN();
3030
constexpr double infinity = std::numeric_limits<double>::infinity();
31+
constexpr double standard_gravity = 9.80665;
3132
} // namespace constants
3233

3334
/// basic commodity definitions
@@ -335,10 +336,12 @@ namespace precise {
335336

336337
/// meter-gram-force system of units
337338
namespace gm {
338-
constexpr precise_unit pond{980.665, cgs::dyn};
339-
constexpr precise_unit hyl{9.80665, kg};
340-
constexpr precise_unit at{98066.5, Pa};
341-
constexpr precise_unit poncelet{980.665, W};
339+
constexpr precise_unit pond{
340+
constants::standard_gravity * 100.0,
341+
cgs::dyn};
342+
constexpr precise_unit hyl{constants::standard_gravity, kg};
343+
constexpr precise_unit at{constants::standard_gravity * 10000.0, Pa};
344+
constexpr precise_unit poncelet{constants::standard_gravity * 100.0, W};
342345
constexpr precise_unit PS{735.49875, W}; // metric horsepower
343346

344347
} // namespace gm
@@ -1921,6 +1924,23 @@ namespace detail {
19211924
}
19221925
return constants::invalid_conversion;
19231926
}
1927+
1928+
template<typename UX, typename UX2>
1929+
inline double
1930+
otherUsefulConversions(double val, const UX& start, const UX2& result)
1931+
{
1932+
if (start.has_same_base(N) && result.has_same_base(kg)) {
1933+
// weight to mass
1934+
return val * start.multiplier() / constants::standard_gravity /
1935+
result.multiplier();
1936+
}
1937+
if (start.has_same_base(kg) && result.has_same_base(N)) {
1938+
// mass to weight
1939+
return val * start.multiplier() * constants::standard_gravity /
1940+
result.multiplier();
1941+
}
1942+
return constants::invalid_conversion;
1943+
}
19241944
} // namespace detail
19251945

19261946
} // namespace UNITS_NAMESPACE

units/units.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -2449,7 +2449,7 @@ using ckpair = std::pair<const char*, const char*>;
24492449
static precise_unit
24502450
localityModifiers(std::string unit, std::uint32_t match_flags)
24512451
{
2452-
static UNITS_CPP14_CONSTEXPR_OBJECT std::array<ckpair, 43>
2452+
static UNITS_CPP14_CONSTEXPR_OBJECT std::array<ckpair, 44>
24532453
internationlReplacements{{
24542454
ckpair{"internationaltable", "_IT"},
24552455
ckpair{"internationalsteamtable", "_IT"},
@@ -2483,7 +2483,8 @@ static precise_unit
24832483
ckpair{"apothecary", "_ap"},
24842484
ckpair{"apothecaries", "_ap"},
24852485
ckpair{"avoirdupois", "_av"},
2486-
ckpair{"Chinese", "_ch"},
2486+
ckpair{"Chinese", "_cn"},
2487+
ckpair{"chinese", "_cn"},
24872488
ckpair{"Canadian", "_can"},
24882489
ckpair{"canadian", "_can"},
24892490
ckpair{"survey", "_us"},
@@ -3855,7 +3856,7 @@ static bool cleanUnitString(std::string& unit_string, std::uint32_t match_flags)
38553856
changed = true;
38563857
}
38573858
}
3858-
if (c != std::string::npos) {
3859+
if (unit_string.find_first_of(spchar) != std::string::npos) {
38593860
// deal with some particular string with a space in them
38603861

38613862
// clean up some "per" words
@@ -3869,8 +3870,7 @@ static bool cleanUnitString(std::string& unit_string, std::uint32_t match_flags)
38693870
checkShortUnits(unit_string, match_flags);
38703871
auto fndP = unit_string.find(" of ");
38713872
while (fndP != std::string::npos) {
3872-
auto nchar = unit_string.find_first_not_of(
3873-
std::string(" \t\n\r") + '\0', fndP + 4);
3873+
auto nchar = unit_string.find_first_not_of(spchar, fndP + 4);
38743874
if (nchar != std::string::npos) {
38753875
if (unit_string[nchar] == '(' ||
38763876
unit_string[nchar] == '[') {

units/units.hpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,9 @@ double convert(double val, const UX& start, const UX2& result)
143143
return converted_val;
144144
}
145145
}
146-
return constants::invalid_conversion;
146+
// this is the last chance and will return invalid_result if it doesn't find
147+
// a match
148+
return detail::otherUsefulConversions(val, start, result);
147149
}
148150

149151
/// Convert a value from one unit base to another potentially involving pu base
@@ -2027,7 +2029,7 @@ namespace constants {
20272029

20282030
/// Standard gravity
20292031
constexpr precise_measurement
2030-
g0(9.80665, precise::m / precise::s / precise::s);
2032+
g0(constants::standard_gravity, precise::m / precise::s / precise::s);
20312033
/// Gravitational Constant
20322034
constexpr precise_measurement G(
20332035
6.67430e-11,

units/units_conversion_maps.hpp

+7-7
Original file line numberDiff line numberDiff line change
@@ -1651,17 +1651,17 @@ UNITS_CPP14_CONSTEXPR_OBJECT std::array<
16511651
{"cun", precise::chinese::cun},
16521652
{"cun(Chinese)",
16531653
precise::chinese::cun}, // interaction with cu for cubic
1654-
{"cun_ch", precise::chinese::cun},
1654+
{"cun_cn", precise::chinese::cun},
16551655
{"chi", precise::chinese::chi},
1656-
{"chi_ch", precise::chinese::chi},
1656+
{"chi_cn", precise::chinese::chi},
16571657
{"zhang", precise::chinese::zhang},
1658-
{"zhang_ch", precise::chinese::zhang},
1659-
{"li_ch", precise::chinese::li},
1660-
{"jin_ch", precise::chinese::jin},
1658+
{"zhang_cn", precise::chinese::zhang},
1659+
{"li_cn", precise::chinese::li},
1660+
{"jin_cn", precise::chinese::jin},
16611661
{"jin", precise::chinese::jin},
1662-
{"liang_ch", precise::chinese::liang},
1662+
{"liang_cn", precise::chinese::liang},
16631663
{"liang", precise::chinese::liang},
1664-
{"qian_ch", precise::chinese::qian},
1664+
{"qian_cn", precise::chinese::qian},
16651665
{"qian", precise::chinese::qian},
16661666
{"biweekly", precise_unit(0.5, precise::time::week.inv())},
16671667
{"fortnight", precise::time::fortnight},

0 commit comments

Comments
 (0)