| #include <chrono> | |
| #include <ostream> | |
| #define WIDEN_(C, S) ::std::__format::_Widen<C>(S, L##S) | |
| #define WIDEN(S) WIDEN_(CharT, S) | |
| template<typename Ret = void, typename Under = long> | |
| struct Rep | |
| { | |
| using Return | |
| = std::conditional_t<std::is_void_v<Ret>, Rep, Ret>; | |
| Rep(Under v = 0) : val(v) {} | |
| template<typename ORet, typename OUnder> | |
| Rep(Rep<ORet, OUnder> o) : val(o.val) {} | |
| operator Under() const | |
| { return val; } | |
| Return | |
| operator+() const | |
| { return val; } | |
| Rep | |
| operator-() const | |
| { return -val; } | |
| friend Rep | |
| operator+(Rep lhs, Rep rhs) | |
| { return lhs.val + rhs.val; } | |
| friend Rep | |
| operator-(Rep lhs, Rep rhs) | |
| { return lhs.val - rhs.val; } | |
| friend Rep | |
| operator*(Rep lhs, Rep rhs) | |
| { return lhs.val * rhs.val; } | |
| friend Rep | |
| operator/(Rep lhs, Rep rhs) | |
| { return lhs.val / rhs.val; } | |
| friend auto operator<=>(Rep, Rep) = default; | |
| template<typename CharT> | |
| friend std::basic_ostream<CharT>& | |
| operator<<(std::basic_ostream<CharT>& os, const Rep& t) | |
| { return os << t.val << WIDEN("[via <<]"); } | |
| Under val; | |
| }; | |
| template<typename Ret, typename Under1, typename Under2> | |
| struct std::common_type<Rep<Ret, Under1>, Rep<Ret, Under2>> | |
| { | |
| using type = Rep<Ret, std::common_type_t<Under1, Under2>>; | |
| }; | |
| template<typename Ret, typename Under, typename Other> | |
| requires std::is_integral_v<Other> | |
| struct std::common_type<Rep<Ret, Under>, Other> | |
| { | |
| using type = Rep<Ret, std::common_type_t<Under, Other>>; | |
| }; | |
| template<typename Ret, typename Under, typename Other> | |
| requires std::is_integral_v<Other> | |
| struct std::common_type<Other, Rep<Ret, Under>> | |
| : std::common_type<Rep<Ret, Under>, Other> | |
| { }; | |
| template<typename Ret, typename Under> | |
| struct std::numeric_limits<Rep<Ret, Under>> | |
| : std::numeric_limits<Under> | |
| { }; | |
| template<typename Ret, typename Under, typename CharT> | |
| struct std::formatter<Rep<Ret, Under>, CharT> | |
| : std::formatter<Under, CharT> | |
| { | |
| template<typename Out> | |
| typename std::basic_format_context<Out, CharT>::iterator | |
| format(const Rep<Ret>& t, std::basic_format_context<Out, CharT>& ctx) const | |
| { | |
| constexpr std::basic_string_view<CharT> suffix = WIDEN("[via format]"); | |
| auto out = std::formatter<Under, CharT>::format(t.val, ctx); | |
| return std::ranges::copy(suffix, out).out; | |
| } | |
| }; | |