xo-unit: refactor: + currency/price abbrevs + separate abbrev .hpp

This commit is contained in:
Roland Conybeare 2024-04-22 16:03:17 -04:00
commit 1d175ee3f5
3 changed files with 211 additions and 163 deletions

View file

@ -3,168 +3,13 @@
#pragma once #pragma once
#include "native_unit.hpp" #include "native_unit.hpp"
#include "basis_unit_abbrev.hpp"
#include "xo/ratio/ratio.hpp" #include "xo/ratio/ratio.hpp"
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
namespace xo { namespace xo {
namespace qty { namespace qty {
using basis_unit2_abbrev_type = flatstring<16>;
using scalefactor_ratio_type = xo::ratio::ratio<std::int64_t>;
namespace abbrev {
// ----- units for dim::mass -----
static
constexpr basis_unit2_abbrev_type
mass_unit2_abbrev(const scalefactor_ratio_type & scalefactor)
{
if (scalefactor.num() == 1) {
switch (scalefactor.den()) {
case 1:
return basis_unit2_abbrev_type::from_chars("g");
case 1000:
return basis_unit2_abbrev_type::from_chars("mg");
case 1000000:
return basis_unit2_abbrev_type::from_chars("ug");
case 1000000000:
return basis_unit2_abbrev_type::from_chars("ng");
}
}
if (scalefactor.den() == 1) {
switch (scalefactor.num()) {
case 1000:
return basis_unit2_abbrev_type::from_chars("kg");
case 1000000:
return basis_unit2_abbrev_type::from_chars("t");
case 1000000000:
return basis_unit2_abbrev_type::from_chars("kt");
}
}
/* e.g. unit of '1000 grams' will have abbrev '1000g' in absence
* of a specialization for scaled_native_unit_abbrev
*/
return (basis_unit2_abbrev_type::from_flatstring
(flatstring_concat
(scalefactor.to_str<basis_unit2_abbrev_type::fixed_capacity>(),
native_unit2_v[static_cast<std::uint32_t>(dim::mass)].abbrev_str())));
}
// ----- units for dim::distance -----
static
constexpr basis_unit2_abbrev_type
distance_unit2_abbrev(const scalefactor_ratio_type & scalefactor)
{
if (scalefactor.num() == 1) {
switch (scalefactor.den()) {
case 1:
return basis_unit2_abbrev_type::from_chars("m");
case 1000:
return basis_unit2_abbrev_type::from_chars("mm");
case 1000000:
return basis_unit2_abbrev_type::from_chars("um");
case 1000000000:
return basis_unit2_abbrev_type::from_chars("nm");
}
}
if (scalefactor.den() == 1) {
switch (scalefactor.num()) {
case 1000:
return basis_unit2_abbrev_type::from_chars("km");
case 1000000:
return basis_unit2_abbrev_type::from_chars("Mm");
case 1000000000:
return basis_unit2_abbrev_type::from_chars("Gm");
}
}
/* e.g. unit of '1000 grams' will have abbrev '1000g' in absence
* of a specialization for scaled_native_unit_abbrev
*/
return (basis_unit2_abbrev_type::from_flatstring
(flatstring_concat
(scalefactor.to_str<basis_unit2_abbrev_type::fixed_capacity>(),
native_unit2_v[static_cast<std::uint32_t>(dim::mass)].abbrev_str())));
}
// ----- units for dim::time -----
static
constexpr basis_unit2_abbrev_type
time_unit2_abbrev(const scalefactor_ratio_type & scalefactor)
{
if (scalefactor.num() == 1) {
switch (scalefactor.den()) {
case 1:
return basis_unit2_abbrev_type::from_chars("s");
case 1000:
return basis_unit2_abbrev_type::from_chars("ms");
case 1000000:
return basis_unit2_abbrev_type::from_chars("us");
case 1000000000:
return basis_unit2_abbrev_type::from_chars("ns");
}
}
if (scalefactor.den() == 1) {
switch (scalefactor.num()) {
case 60:
return basis_unit2_abbrev_type::from_chars("min");
case 3600:
return basis_unit2_abbrev_type::from_chars("hr");
case 24*3600:
return basis_unit2_abbrev_type::from_chars("dy");
case 7*24*3600:
return basis_unit2_abbrev_type::from_chars("wk");
case 30*24*3600:
return basis_unit2_abbrev_type::from_chars("mo");
case 250*24*3600:
return basis_unit2_abbrev_type::from_chars("yr250");
case 360*24*3600:
return basis_unit2_abbrev_type::from_chars("yr360");
case 365*24*3600:
return basis_unit2_abbrev_type::from_chars("yr365");
}
}
/* e.g. unit of '1000 grams' will have abbrev '1000g' in absence
* of a specialization for scaled_native_unit_abbrev
*/
return (basis_unit2_abbrev_type::from_flatstring
(flatstring_concat
(scalefactor.to_str<basis_unit2_abbrev_type::fixed_capacity>(),
native_unit2_v[static_cast<std::uint32_t>(dim::mass)].abbrev_str())));
}
static
constexpr basis_unit2_abbrev_type
basis_unit2_abbrev(dim native_dim,
const scalefactor_ratio_type & scalefactor)
{
switch(native_dim) {
case dim::mass:
return mass_unit2_abbrev(scalefactor);
case dim::distance:
return distance_unit2_abbrev(scalefactor);
case dim::time:
return time_unit2_abbrev(scalefactor);
}
/* e.g. unit of '1000 grams' will have abbrev '1000g' in absence
* of a specialization for scaled_native_unit_abbrev
*/
return (basis_unit2_abbrev_type::from_flatstring
(flatstring_concat
(scalefactor.to_str<basis_unit2_abbrev_type::fixed_capacity>(),
native_unit2_v[static_cast<std::uint32_t>(native_dim)].abbrev_str())));
}
}; /*abbrev*/
/** @class basis_unit2 /** @class basis_unit2
* @brief A dimensionless multiple of a single natively-specified basis dimension * @brief A dimensionless multiple of a single natively-specified basis dimension
* *

View file

@ -0,0 +1,205 @@
/** @file basis_unit_abbrev.hpp
*
* Author: Roland Conybeare
**/
#pragma once
#include "native_unit.hpp"
#include "xo/ratio/ratio.hpp"
//#include <cstdint>
namespace xo {
namespace qty {
using basis_unit2_abbrev_type = flatstring<16>;
using scalefactor_ratio_type = xo::ratio::ratio<std::int64_t>;
namespace abbrev {
static
constexpr basis_unit2_abbrev_type
fallback_unit_abbrev(const scalefactor_ratio_type & scalefactor,
dim native_dim)
{
/* e.g. unit of '1000 grams' will have abbrev '1000g' in absence
* of a specialization for scaled_native_unit_abbrev
*/
return (basis_unit2_abbrev_type::from_flatstring
(flatstring_concat
(scalefactor.to_str<basis_unit2_abbrev_type::fixed_capacity>(),
native_unit2_v[static_cast<std::uint32_t>(native_dim)].abbrev_str())));
}
// ----- units for dim::mass -----
static
constexpr basis_unit2_abbrev_type
mass_unit2_abbrev(const scalefactor_ratio_type & scalefactor)
{
if (scalefactor.num() == 1) {
switch (scalefactor.den()) {
case 1:
return basis_unit2_abbrev_type::from_chars("g");
case 1000:
return basis_unit2_abbrev_type::from_chars("mg");
case 1000000:
return basis_unit2_abbrev_type::from_chars("ug");
case 1000000000:
return basis_unit2_abbrev_type::from_chars("ng");
}
}
if (scalefactor.den() == 1) {
switch (scalefactor.num()) {
case 1000:
return basis_unit2_abbrev_type::from_chars("kg");
case 1000000:
return basis_unit2_abbrev_type::from_chars("t");
case 1000000000:
return basis_unit2_abbrev_type::from_chars("kt");
}
}
return fallback_unit_abbrev(scalefactor, dim::mass);
}
// ----- units for dim::distance -----
static
constexpr basis_unit2_abbrev_type
distance_unit2_abbrev(const scalefactor_ratio_type & scalefactor)
{
if (scalefactor.num() == 1) {
switch (scalefactor.den()) {
case 1:
return basis_unit2_abbrev_type::from_chars("m");
case 1000:
return basis_unit2_abbrev_type::from_chars("mm");
case 1000000:
return basis_unit2_abbrev_type::from_chars("um");
case 1000000000:
return basis_unit2_abbrev_type::from_chars("nm");
}
}
if (scalefactor.den() == 1) {
switch (scalefactor.num()) {
case 1000:
return basis_unit2_abbrev_type::from_chars("km");
case 1000000:
return basis_unit2_abbrev_type::from_chars("Mm");
case 1000000000:
return basis_unit2_abbrev_type::from_chars("Gm");
}
}
return fallback_unit_abbrev(scalefactor, dim::distance);
}
// ----- units for dim::time -----
static
constexpr basis_unit2_abbrev_type
time_unit2_abbrev(const scalefactor_ratio_type & scalefactor)
{
if (scalefactor.num() == 1) {
switch (scalefactor.den()) {
case 1:
return basis_unit2_abbrev_type::from_chars("s");
case 1000:
return basis_unit2_abbrev_type::from_chars("ms");
case 1000000:
return basis_unit2_abbrev_type::from_chars("us");
case 1000000000:
return basis_unit2_abbrev_type::from_chars("ns");
}
}
if (scalefactor.den() == 1) {
switch (scalefactor.num()) {
case 60:
return basis_unit2_abbrev_type::from_chars("min");
case 3600:
return basis_unit2_abbrev_type::from_chars("hr");
case 24*3600:
return basis_unit2_abbrev_type::from_chars("dy");
case 7*24*3600:
return basis_unit2_abbrev_type::from_chars("wk");
case 30*24*3600:
return basis_unit2_abbrev_type::from_chars("mo");
case 250*24*3600:
return basis_unit2_abbrev_type::from_chars("yr250");
case 360*24*3600:
return basis_unit2_abbrev_type::from_chars("yr360");
case 365*24*3600:
return basis_unit2_abbrev_type::from_chars("yr365");
}
}
return fallback_unit_abbrev(scalefactor, dim::time);
}
// ----- units for dim::currency -----
static constexpr basis_unit2_abbrev_type
currency_unit2_abbrev(const scalefactor_ratio_type & scalefactor)
{
if (scalefactor.num() == 1) {
switch(scalefactor.den()) {
case 1:
return basis_unit2_abbrev_type::from_chars("ccy");
}
}
return fallback_unit_abbrev(scalefactor, dim::currency);
}
// ----- units for dim::price -----
static constexpr basis_unit2_abbrev_type
price_unit2_abbrev(const scalefactor_ratio_type & scalefactor)
{
if (scalefactor.num() == 1) {
switch(scalefactor.den()) {
case 1:
return basis_unit2_abbrev_type::from_chars("ccy");
}
}
return fallback_unit_abbrev(scalefactor, dim::price);
}
static
constexpr basis_unit2_abbrev_type
basis_unit2_abbrev(dim native_dim,
const scalefactor_ratio_type & scalefactor)
{
switch(native_dim) {
case dim::mass:
return mass_unit2_abbrev(scalefactor);
case dim::distance:
return distance_unit2_abbrev(scalefactor);
case dim::time:
return time_unit2_abbrev(scalefactor);
case dim::currency:
return currency_unit2_abbrev(scalefactor);
case dim::price:
return price_unit2_abbrev(scalefactor);
case dim::invalid:
case dim::n_dim:
break;
}
/* e.g. unit of '1000 grams' will have abbrev '1000g' in absence
* of a specialization for scaled_native_unit_abbrev
*/
return (basis_unit2_abbrev_type::from_flatstring
(flatstring_concat
(scalefactor.to_str<basis_unit2_abbrev_type::fixed_capacity>(),
native_unit2_v[static_cast<std::uint32_t>(native_dim)].abbrev_str())));
}
} /*namespace abbrev*/
} /*namespace qty*/
} /*namespace xo*/
/** end basis_unit_abbrev.hpp **/

View file

@ -1,4 +1,4 @@
/** @file dim_util2.hpp /** @file native_unit.hpp
* *
* Author: Roland Conybeare * Author: Roland Conybeare
**/ **/
@ -12,17 +12,17 @@ namespace xo {
namespace qty { namespace qty {
using native_unit2_abbrev_type = flatstring<8>; using native_unit2_abbrev_type = flatstring<8>;
/** @class native_unit2 /** @class native_unit
* *
* @brief Represent a native (built-in) unit. * @brief Represent a native (built-in) unit.
* *
* A basis_unit2 is expressed as a multiple of a native_unit2 * A basis_unit is expressed as a multiple of a native_unit
* *
**/ **/
struct native_unit { struct native_unit {
public: public:
constexpr native_unit(dim native_dim, constexpr native_unit(dim native_dim,
const native_unit2_abbrev_type & abbrev_str) const native_unit2_abbrev_type & abbrev_str)
: native_dim_{native_dim}, : native_dim_{native_dim},
abbrev_str_{abbrev_str} abbrev_str_{abbrev_str}
{} {}
@ -46,6 +46,4 @@ namespace xo {
} /*namespace qty*/ } /*namespace qty*/
} /*namespace xo*/ } /*namespace xo*/
/** end native_unit.hpp **/
/** end dim_util2.hpp **/