#pragma once #include #include #include //-------------------------------------------------------------- class Age { public: Age() = default; // Default constructor virtual ~Age() = default; // Default destructor Age(const Age &obj) = default; // Copy constructor Age(Age &&obj) noexcept = default; // Move constructor Age &operator=(const Age &obj) = default; // Copy assignment operator Age &operator=(Age &&obj) noexcept = default; // Move assignment operator explicit Age(std::chrono::nanoseconds age); // Constructor void set(std::chrono::nanoseconds age); // Convert age in microseconds to days, hours, minutes, seconds, milliseconds and microseconds std::chrono::microseconds getAge() const; // Return age in microseconds std::chrono::days getDays() const; // Return days part in age std::chrono::hours getHours() const; // Return hours part in age std::chrono::minutes getMinutes() const; // Return minutes part in age std::chrono::seconds getSeconds() const; // Return seconds part in age std::chrono::milliseconds getMilliseconds() const; // Return milliseconds part in age std::chrono::microseconds getMicroseconds() const; // Return microseconds part in age std::chrono::nanoseconds getNanoseconds() const; // Return nanoseconds part in age std::string toString(bool show_ms = true, bool show_us = false, bool show_ns = false) const; // Return age as a string in format "[d] H:m:s.ms.us.ns" void testAge() const; // Test function to verify the correctness of the Age class implementation protected: std::chrono::nanoseconds m_age = std::chrono::nanoseconds(0); std::chrono::days m_days = std::chrono::days(0); std::chrono::hours m_hours = std::chrono::hours(0); std::chrono::minutes m_minutes = std::chrono::minutes(0); std::chrono::seconds m_seconds = std::chrono::seconds(0); std::chrono::milliseconds m_milliseconds = std::chrono::milliseconds(0); std::chrono::microseconds m_microseconds = std::chrono::microseconds(0); std::chrono::nanoseconds m_nanoseconds = std::chrono::nanoseconds(0); }; //-------------------------------------------------------------- /* Constructor */ inline Age::Age(const std::chrono::nanoseconds age) { set(age); } //-------------------------------------------------------------- /* Convert age in microseconds to days, hours, minutes, seconds, milliseconds and microseconds */ inline void Age::set(std::chrono::nanoseconds age) { constexpr auto max_ns = std::chrono::nanoseconds::max().count(); // For an int64_t storage, the maximum value corresponds to more than 106752 days constexpr auto min_ns = std::chrono::nanoseconds::min().count(); if (age.count() > max_ns || age.count() < min_ns) throw std::overflow_error("Duration exceeds the limits of std::chrono::nanoseconds"); if (age < std::chrono::nanoseconds(0)) throw std::invalid_argument("Age cannot be negative"); m_age = age; m_days = std::chrono::duration_cast(age); age -= m_days; m_hours = std::chrono::duration_cast(age); age -= m_hours; m_minutes = std::chrono::duration_cast(age); age -= m_minutes; m_seconds = std::chrono::duration_cast(age); age -= m_seconds; m_milliseconds = std::chrono::duration_cast(age); age -= m_milliseconds; m_microseconds = std::chrono::duration_cast(age); age -= m_microseconds; m_nanoseconds = age; } //-------------------------------------------------------------- /* Return age in microseconds */ inline std::chrono::microseconds Age::getAge() const { return std::chrono::duration_cast(m_age); } //-------------------------------------------------------------- /* Return days part in age */ inline std::chrono::days Age::getDays() const { return m_days; } //-------------------------------------------------------------- /* Return hours part in age */ inline std::chrono::hours Age::getHours() const { return m_hours; } //-------------------------------------------------------------- /* Return minutes part in age */ inline std::chrono::minutes Age::getMinutes() const { return m_minutes; } //-------------------------------------------------------------- /* Return seconds part in age */ inline std::chrono::seconds Age::getSeconds() const { return m_seconds; } //-------------------------------------------------------------- /* Return milliseconds part in age */ inline std::chrono::milliseconds Age::getMilliseconds() const { return m_milliseconds; } //-------------------------------------------------------------- /* Return microseconds part in age */ inline std::chrono::microseconds Age::getMicroseconds() const { return m_microseconds; } //-------------------------------------------------------------- /* Return nanoseconds part in age */ inline std::chrono::nanoseconds Age::getNanoseconds() const { return m_nanoseconds; } //-------------------------------------------------------------- /* Return age as a string in format "[d] H:m:s.ms.us.ns". * The show_ms, show_us and show_ns parameters control whether * to include milliseconds, microseconds and nanoseconds in the * output string. */ inline std::string Age::toString(const bool show_ms, const bool show_us, const bool show_ns) const { std::ostringstream oss; // Add days if greater than 0 if (m_days.count() > 0) oss << std::format("[{}] ", m_days.count()); // Add hours, minutes and seconds oss << std::format("{:02}:{:02}:{:02}", m_hours.count(), m_minutes.count(), m_seconds.count()); // Add milliseconds, microseconds and nanoseconds if requested if (show_ms || show_us || show_ns) oss << std::format(".{:03}", m_milliseconds.count()); if (show_us || show_ns) oss << std::format("{:03}", m_microseconds.count()); if (show_ns) oss << std::format("{:03}", m_nanoseconds.count()); return oss.str(); } //-------------------------------------------------------------- /* Test function to verify the correctness of the Age class implementation */ inline void Age::testAge() const { const Age age(std::chrono::nanoseconds(90061001001)); // 1 day, 1 hour, 1 minute, 1 second, 1 millisecond, 1 microsecond, 1 nanosecond assert(age.getDays().count() == 1); assert(age.getHours().count() == 1); assert(age.getMinutes().count() == 1); assert(age.getSeconds().count() == 1); assert(age.getMilliseconds().count() == 1); assert(age.getMicroseconds().count() == 1); assert(age.getNanoseconds().count() == 1); std::cout << "All tests passed!" << std::endl; } //--------------------------------------------------------------