#include <iostream>
#include <chrono>
#include <ratio>
#include <vector>
#include <numeric>
#include <algorithm>
template <class Rep, class Period = std::ratio<1> >
using tmp_t = std::chrono::duration<Rep, Period>;
typedef tmp_t<int64_t> dollar_t;
typedef tmp_t<int64_t, std::ratio<1,100>> cent_t;
//typedef tmp_t<int64_t, std::ratio<1,100>> store_money_t;
struct store_money_t : cent_t {
store_money_t(cent_t::rep v = 0, bool null = false) : cent_t(v), is_null(null) {}
store_money_t(cent_t c) : cent_t(c) {}
store_money_t(dollar_t d) : cent_t(d) {}
bool is_null = false;
};
dollar_t dollar_lost_cents_cast(cent_t cents) { return std::chrono::duration_cast<dollar_t>(cents); }
std::ostream& operator<<(std::ostream& os, store_money_t store_money) {
os << store_money.count()/100 << "." << store_money.count()%100;
return os;
}
store_money_t null_money(0, true);
bool not_null_money(store_money_t &m) { return !m.is_null; }
int main() {
// example
store_money_t store_money = dollar_t(2) + cent_t(20);
store_money += dollar_t(7);
store_money += cent_t(18);
cent_t cents = store_money;
dollar_t dollars = dollar_lost_cents_cast(cents);
std::cout << "dollar_lost_cents_cast = " << dollar_lost_cents_cast(store_money).count() <<
", store_money = " << store_money << std::endl;
// INSERT INTO Table ( Column1 ) VALUES ( 0), ( null ), ( 6 )
// SELECT AVG( Column1 ) FROM Table
std::vector<store_money_t> user_accounts = { cent_t(0), null_money, dollar_t(6) };
store_money_t sum = std::accumulate (user_accounts.begin(), user_accounts.end(), store_money_t());
std::cout << "sum = " << sum << std::endl;
store_money_t::rep count = std::count_if(user_accounts.begin(), user_accounts.end(), not_null_money);
std::cout << "count = " << count << std::endl;
store_money_t avg = sum / count;
std::cout << "avg = " << avg << std::endl;
// SELECT 0 + null + 6 FROM dual
store_money_t sum_select_statment = cent_t(0) + null_money + dollar_t(6);
std::cout << "sum_select_statment = " << sum_select_statment << std::endl;
return 0;
}