#include <chrono>
#include <iostream>
#include <tuple>
using day_t = std::chrono::duration<long long, std::ratio<3600 * 24>>;
template<typename> struct duration_traits {};
#define DURATION_TRAITS(Duration, Singular, Plural) \
template<> struct duration_traits<Duration> { \
constexpr static const char* singular = Singular; \
constexpr static const char* plural = Plural; \
}
DURATION_TRAITS(std::chrono::milliseconds, "millisecond", "milliseconds");
DURATION_TRAITS(std::chrono::seconds, "second", "seconds");
DURATION_TRAITS(std::chrono::minutes, "minute", "minutes");
DURATION_TRAITS(std::chrono::hours, "hour", "hours");
DURATION_TRAITS(day_t, "day", "days");
using divisions = std::tuple<std::chrono::milliseconds,
std::chrono::seconds,
std::chrono::minutes,
std::chrono::hours,
day_t>;
namespace detail {
template<typename...> struct print_duration_impl_ {};
template<typename Head, typename... Tail>
struct print_duration_impl_<Head, Tail...> {
template <typename Duration>
static bool print(std::ostream& os, Duration& dur) {
const auto started_printing = print_duration_impl_<Tail...>::print(os, dur);
const auto n = std::chrono::duration_cast<Head>(dur);
const auto count = n.count();
if (count == 0) {
return started_printing;
}
if (started_printing) {
os << ' ';
}
using traits = duration_traits<Head>;
os << count << ' ' << (count == 1 ? traits::singular : traits::plural);
dur -= n;
return true;
}
};
template<> struct print_duration_impl_<> {
template <typename Duration>
static bool print(std::ostream& os, Duration& dur) {
return false;
}
};
template<typename...> struct print_duration {};
template<typename... Args>
struct print_duration<std::tuple<Args...>> {
template<typename Duration>
static void print(std::ostream& os, Duration dur) {
print_duration_impl_<Args...>::print(os, dur);
}
};
}
template<typename Rep, typename Period>
std::ostream& operator<<(std::ostream& os, const std::chrono::duration<Rep, Period>& dur) {
detail::print_duration<divisions>::print(os, dur);
return os;
}
#include <thread>
int main() {
auto start = std::chrono::system_clock::now();
std::this_thread::sleep_for(std::chrono::milliseconds(1492));
auto end = std::chrono::system_clock::now();
std::cout << (end - start) << std::endl;
return 0;
}
I2luY2x1ZGUgPGNocm9ubz4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHVwbGU+Cgp1c2luZyBkYXlfdCA9IHN0ZDo6Y2hyb25vOjpkdXJhdGlvbjxsb25nIGxvbmcsIHN0ZDo6cmF0aW88MzYwMCAqIDI0Pj47Cgp0ZW1wbGF0ZTx0eXBlbmFtZT4gc3RydWN0IGR1cmF0aW9uX3RyYWl0cyB7fTsKI2RlZmluZSBEVVJBVElPTl9UUkFJVFMoRHVyYXRpb24sIFNpbmd1bGFyLCBQbHVyYWwpIFwKCXRlbXBsYXRlPD4gc3RydWN0IGR1cmF0aW9uX3RyYWl0czxEdXJhdGlvbj4geyBcCgkJY29uc3RleHByIHN0YXRpYyBjb25zdCBjaGFyKiBzaW5ndWxhciA9IFNpbmd1bGFyOyBcCgkJY29uc3RleHByIHN0YXRpYyBjb25zdCBjaGFyKiBwbHVyYWwgPSBQbHVyYWw7IFwKCX0KCkRVUkFUSU9OX1RSQUlUUyhzdGQ6OmNocm9ubzo6bWlsbGlzZWNvbmRzLCAibWlsbGlzZWNvbmQiLCAibWlsbGlzZWNvbmRzIik7CkRVUkFUSU9OX1RSQUlUUyhzdGQ6OmNocm9ubzo6c2Vjb25kcywgInNlY29uZCIsICJzZWNvbmRzIik7CkRVUkFUSU9OX1RSQUlUUyhzdGQ6OmNocm9ubzo6bWludXRlcywgIm1pbnV0ZSIsICJtaW51dGVzIik7CkRVUkFUSU9OX1RSQUlUUyhzdGQ6OmNocm9ubzo6aG91cnMsICJob3VyIiwgImhvdXJzIik7CkRVUkFUSU9OX1RSQUlUUyhkYXlfdCwgImRheSIsICJkYXlzIik7Cgp1c2luZyBkaXZpc2lvbnMgPSBzdGQ6OnR1cGxlPHN0ZDo6Y2hyb25vOjptaWxsaXNlY29uZHMsIAoJCQkJICAgICAgICAgICAgIHN0ZDo6Y2hyb25vOjpzZWNvbmRzLCAKCQkJCSAgICAgICAgICAgICBzdGQ6OmNocm9ubzo6bWludXRlcywgCgkJCQkgICAgICAgICAgICAgc3RkOjpjaHJvbm86OmhvdXJzLCAKCQkJCSAgICAgICAgICAgICBkYXlfdD47CgpuYW1lc3BhY2UgZGV0YWlsIHsKdGVtcGxhdGU8dHlwZW5hbWUuLi4+IHN0cnVjdCBwcmludF9kdXJhdGlvbl9pbXBsXyB7fTsKCnRlbXBsYXRlPHR5cGVuYW1lIEhlYWQsIHR5cGVuYW1lLi4uIFRhaWw+CnN0cnVjdCBwcmludF9kdXJhdGlvbl9pbXBsXzxIZWFkLCBUYWlsLi4uPiB7CiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgRHVyYXRpb24+CiAgICBzdGF0aWMgYm9vbCBwcmludChzdGQ6Om9zdHJlYW0mIG9zLCBEdXJhdGlvbiYgZHVyKSB7CiAgICAgICAgY29uc3QgYXV0byBzdGFydGVkX3ByaW50aW5nID0gcHJpbnRfZHVyYXRpb25faW1wbF88VGFpbC4uLj46OnByaW50KG9zLCBkdXIpOwoKICAgICAgICBjb25zdCBhdXRvIG4gPSBzdGQ6OmNocm9ubzo6ZHVyYXRpb25fY2FzdDxIZWFkPihkdXIpOwogICAgICAgIGNvbnN0IGF1dG8gY291bnQgPSBuLmNvdW50KCk7CgogICAgICAgIGlmIChjb3VudCA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiBzdGFydGVkX3ByaW50aW5nOwogICAgICAgIH0KCiAgICAgICAgaWYgKHN0YXJ0ZWRfcHJpbnRpbmcpIHsKICAgICAgICAgICAgb3MgPDwgJyAnOwogICAgICAgIH0KCiAgICAgICAgdXNpbmcgdHJhaXRzID0gZHVyYXRpb25fdHJhaXRzPEhlYWQ+OwogICAgICAgIG9zIDw8IGNvdW50IDw8ICcgJyA8PCAoY291bnQgPT0gMSA/IHRyYWl0czo6c2luZ3VsYXIgOiB0cmFpdHM6OnBsdXJhbCk7CiAgICAgICAgZHVyIC09IG47CiAgICAgICAgCiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9Cn07Cgp0ZW1wbGF0ZTw+IHN0cnVjdCBwcmludF9kdXJhdGlvbl9pbXBsXzw+IHsKICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBEdXJhdGlvbj4KICAgIHN0YXRpYyBib29sIHByaW50KHN0ZDo6b3N0cmVhbSYgb3MsIER1cmF0aW9uJiBkdXIpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9Cn07Cgp0ZW1wbGF0ZTx0eXBlbmFtZS4uLj4gc3RydWN0IHByaW50X2R1cmF0aW9uIHt9OwoKdGVtcGxhdGU8dHlwZW5hbWUuLi4gQXJncz4Kc3RydWN0IHByaW50X2R1cmF0aW9uPHN0ZDo6dHVwbGU8QXJncy4uLj4+IHsKICAgIHRlbXBsYXRlPHR5cGVuYW1lIER1cmF0aW9uPgogICAgc3RhdGljIHZvaWQgcHJpbnQoc3RkOjpvc3RyZWFtJiBvcywgRHVyYXRpb24gZHVyKSB7CiAgICAgICAgcHJpbnRfZHVyYXRpb25faW1wbF88QXJncy4uLj46OnByaW50KG9zLCBkdXIpOwogICAgfQp9Owp9Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBSZXAsIHR5cGVuYW1lIFBlcmlvZD4Kc3RkOjpvc3RyZWFtJiBvcGVyYXRvcjw8KHN0ZDo6b3N0cmVhbSYgb3MsIGNvbnN0IHN0ZDo6Y2hyb25vOjpkdXJhdGlvbjxSZXAsIFBlcmlvZD4mIGR1cikgewogICAgZGV0YWlsOjpwcmludF9kdXJhdGlvbjxkaXZpc2lvbnM+OjpwcmludChvcywgZHVyKTsKICAgIHJldHVybiBvczsKfQoKI2luY2x1ZGUgPHRocmVhZD4KCmludCBtYWluKCkgewogICAgYXV0byBzdGFydCA9IHN0ZDo6Y2hyb25vOjpzeXN0ZW1fY2xvY2s6Om5vdygpOwogICAgc3RkOjp0aGlzX3RocmVhZDo6c2xlZXBfZm9yKHN0ZDo6Y2hyb25vOjptaWxsaXNlY29uZHMoMTQ5MikpOwogICAgYXV0byBlbmQgPSBzdGQ6OmNocm9ubzo6c3lzdGVtX2Nsb2NrOjpub3coKTsKCiAgICBzdGQ6OmNvdXQgPDwgKGVuZCAtIHN0YXJ0KSA8PCBzdGQ6OmVuZGw7CgogICAgcmV0dXJuIDA7Cn0=