#include #include #include #include #include template constexpr int constlog10(T v){ return v <= 0 ?( std::abort(), 0 ):( (v <= 1 && v*10 > 1) || (v >= 1 && v/10 < 1) ?( 0 ):( v < 1 ?( constlog10(v * 10) - 1 ):( constlog10(v / 10) + 1 ) ) ); } constexpr unsigned constpow10(unsigned v){ return v == 0 ? 1 : constpow10(v - 1) * 10; ; } template void dump_duration(S&& target, const T& dur){ constexpr int punit3 = constlog10(T::period::num) - constlog10(T::period::den); using pr = std::ratio< T::period::num * constpow10(punit3<0 ? -punit3 : 0), T::period::den * constpow10(punit3>0 ? punit3 : 0) >; if(dur.count() == 0){ target << "0s"; return; } int unit3 = std::log10(dur.count()); char prefix_small[] = "munp"; char prefix_big[] = "kMGT"; char prefix = 0; int uunit3 = unit3 + punit3; if(uunit3 < 0){ int ud = -uunit3 % 3 - 3; unit3 += ud; uunit3 += ud; if(uunit3 < -12){ unit3 += -uunit3 - 12; uunit3 = -12; } }else{ int ud = uunit3 % 3; unit3 -= ud; uunit3 -= ud; if(uunit3 > 12){ unit3 -= uunit3 - 12; uunit3 = 12; } } if(uunit3 < 0){ prefix = prefix_small[-uunit3 / 3 - 1]; }else if(uunit3 > 0){ prefix = prefix_big[uunit3 / 3 - 1]; } auto cnt = dur.count(); if(unit3 < 0){ cnt *= constpow10(-unit3); }else{ cnt /= constpow10(unit3); } cnt *= pr::num; cnt /= pr::den; target << cnt; if(prefix){ target << prefix; } target << "s"; } template void dump_duration(S&& target, const T& dur){ dump_duration( std::forward(target), std::chrono::duration_cast< std::chrono::duration >(dur) ); } int main(){ auto start = std::chrono::steady_clock::now(); dump_duration(std::cout, std::chrono::duration>(1)); std::cout << '\n'; dump_duration(std::cout, std::chrono::duration>(1)); std::cout << '\n'; dump_duration(std::cout, std::chrono::duration>(1)); std::cout << '\n'; auto end = std::chrono::steady_clock::now(); std::cout << "proc time: "; dump_duration(std::cout, end - start); std::cout << '\n'; return 0; }