Skip to content

Commit

Permalink
feat(example): currency example now uses chrono::time_point and has…
Browse files Browse the repository at this point in the history
… better interfaces
  • Loading branch information
mpusz committed Oct 1, 2024
1 parent 74c55ba commit 4a98817
Showing 1 changed file with 17 additions and 10 deletions.
27 changes: 17 additions & 10 deletions example/currency.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#ifdef MP_UNITS_IMPORT_STD
import std;
#else
#include <chrono>
#include <concepts>
#include <iostream>
#include <map>
Expand Down Expand Up @@ -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
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;
else if constexpr (From == euro && To == us_dollar) return 1.0848;
// ...
Expand All @@ -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(); }

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 = {
{{"USD", "EUR"}, 0.9215}, {{"EUR", "USD"}, 1.0848},
// ...
Expand All @@ -90,25 +93,29 @@ template<Unit auto From, Unit auto To>

#endif

template<ReferenceOf<currency> auto To, ReferenceOf<currency> auto From, typename Rep>
quantity<To, Rep> exchange_to(quantity<From, Rep> q)
template<UnitOf<currency> auto To, QuantityOf<currency> From>
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>
quantity_point<To, PO, Rep> exchange_to(quantity_point<From, PO, Rep> q)
template<UnitOf<currency> auto To, QuantityPointOf<currency> From>
QuantityPointOf<currency> auto exchange_to(From qp, std::chrono::sys_seconds timestamp)
{
return quantity_point{
static_cast<Rep>(exchange_rate<q.unit, get_unit(To)>() * q.quantity_from_zero().numerical_value_in(q.unit)) * To};
const auto rate = static_cast<From::rep>(exchange_rate<From::unit, To>(timestamp) *
qp.quantity_from_zero().numerical_value_in(qp.unit));
return quantity_point{rate * From::quantity_spec[To], From::point_origin};
}

int main()
{
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_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"; // does
Expand Down

0 comments on commit 4a98817

Please sign in to comment.