#include <cmath>
#include <cstdlib>
#include <iostream>
#include <ratio>
#include <chrono>

template<class T>
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<class T, class S>
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<class O, class T, class S>
void dump_duration(S&& target, const T& dur){
    dump_duration(
        std::forward<S>(target),
        std::chrono::duration_cast<
            std::chrono::duration<O, typename T::period>
        >(dur)
    );
}

int main(){
    auto start = std::chrono::steady_clock::now();
    dump_duration(std::cout,
        std::chrono::duration<int, std::ratio<1, 1000>>(1));
    std::cout << '\n';
    dump_duration(std::cout,
        std::chrono::duration<int, std::ratio<1, 1>>(1));
    std::cout << '\n';
    dump_duration(std::cout,
        std::chrono::duration<int, std::ratio<1000, 1>>(1));
    std::cout << '\n';
    auto end = std::chrono::steady_clock::now();

    std::cout << "proc time: ";
    dump_duration<double>(std::cout, end - start);
    std::cout << '\n';
    return 0;
}