feat(example): currency example now uses chrono::time_point and has better interfaces

This commit is contained in:
Mateusz Pusz
2024-10-01 19:53:02 +02:00
parent 74c55baebe
commit 4a98817c15

View File

@@ -24,6 +24,7 @@
#ifdef MP_UNITS_IMPORT_STD #ifdef MP_UNITS_IMPORT_STD
import std; import std;
#else #else
#include <chrono>
#include <concepts> #include <concepts>
#include <iostream> #include <iostream>
#include <map> #include <map>
@@ -66,8 +67,9 @@ static_assert(!std::equality_comparable_with<quantity<euro, int>, quantity<us_do
// if you have only a few currencies to handle // if you have only a few currencies to handle
template<Unit auto From, Unit auto To> template<Unit auto From, Unit auto To>
[[nodiscard]] double exchange_rate() [[nodiscard]] double exchange_rate(std::chrono::sys_seconds timestamp)
{ {
(void)timestamp; // get conversion ratios for this timestamp
if constexpr (From == us_dollar && To == euro) return 0.9215; if constexpr (From == us_dollar && To == euro) return 0.9215;
else if constexpr (From == euro && To == us_dollar) return 1.0848; else if constexpr (From == euro && To == us_dollar) return 1.0848;
// ... // ...
@@ -78,8 +80,9 @@ template<Unit auto From, Unit auto To>
[[nodiscard]] std::string_view to_string_view(Unit auto u) { return u.symbol.ascii().c_str(); } [[nodiscard]] std::string_view to_string_view(Unit auto u) { return u.symbol.ascii().c_str(); }
template<Unit auto From, Unit auto To> template<Unit auto From, Unit auto To>
[[nodiscard]] double exchange_rate() [[nodiscard]] double exchange_rate(std::chrono::sys_seconds timestamp)
{ {
(void)timestamp; // get conversion ratios for this timestamp
static const std::map<std::pair<std::string_view, std::string_view>, double> rates = { static const std::map<std::pair<std::string_view, std::string_view>, double> rates = {
{{"USD", "EUR"}, 0.9215}, {{"EUR", "USD"}, 1.0848}, {{"USD", "EUR"}, 0.9215}, {{"EUR", "USD"}, 1.0848},
// ... // ...
@@ -90,25 +93,29 @@ template<Unit auto From, Unit auto To>
#endif #endif
template<ReferenceOf<currency> auto To, ReferenceOf<currency> auto From, typename Rep> template<UnitOf<currency> auto To, QuantityOf<currency> From>
quantity<To, Rep> exchange_to(quantity<From, Rep> q) QuantityOf<currency> auto exchange_to(From q, std::chrono::sys_seconds timestamp)
{ {
return static_cast<Rep>(exchange_rate<q.unit, get_unit(To)>() * q.numerical_value()) * To; const auto rate = static_cast<From::rep>(exchange_rate<From::unit, To>(timestamp) * q.numerical_value_in(q.unit));
return rate * From::quantity_spec[To];
} }
template<ReferenceOf<currency> auto To, ReferenceOf<currency> auto From, auto PO, typename Rep> template<UnitOf<currency> auto To, QuantityPointOf<currency> From>
quantity_point<To, PO, Rep> exchange_to(quantity_point<From, PO, Rep> q) QuantityPointOf<currency> auto exchange_to(From qp, std::chrono::sys_seconds timestamp)
{ {
return quantity_point{ const auto rate = static_cast<From::rep>(exchange_rate<From::unit, To>(timestamp) *
static_cast<Rep>(exchange_rate<q.unit, get_unit(To)>() * q.quantity_from_zero().numerical_value_in(q.unit)) * To}; qp.quantity_from_zero().numerical_value_in(qp.unit));
return quantity_point{rate * From::quantity_spec[To], From::point_origin};
} }
int main() int main()
{ {
using namespace unit_symbols; using namespace unit_symbols;
using namespace std::chrono;
const auto timestamp = time_point_cast<seconds>(system_clock::now() - hours{24});
const quantity_point price_usd{100 * USD}; const quantity_point price_usd{100 * USD};
const quantity_point price_euro = exchange_to<euro>(price_usd); const quantity_point price_euro = exchange_to<euro>(price_usd, timestamp);
std::cout << price_usd.quantity_from_zero() << " -> " << price_euro.quantity_from_zero() << "\n"; std::cout << price_usd.quantity_from_zero() << " -> " << price_euro.quantity_from_zero() << "\n";
// std::cout << price_usd.quantity_from_zero() + price_euro.quantity_from_zero() << "\n"; // does // std::cout << price_usd.quantity_from_zero() + price_euro.quantity_from_zero() << "\n"; // does