176 lines
6.8 KiB
C++
176 lines
6.8 KiB
C++
#pragma once
|
|
|
|
#include <cassert>
|
|
#include <chrono>
|
|
#include <iostream>
|
|
|
|
//--------------------------------------------------------------
|
|
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<std::chrono::days>(age);
|
|
age -= m_days;
|
|
|
|
m_hours = std::chrono::duration_cast<std::chrono::hours>(age);
|
|
age -= m_hours;
|
|
|
|
m_minutes = std::chrono::duration_cast<std::chrono::minutes>(age);
|
|
age -= m_minutes;
|
|
|
|
m_seconds = std::chrono::duration_cast<std::chrono::seconds>(age);
|
|
age -= m_seconds;
|
|
|
|
m_milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(age);
|
|
age -= m_milliseconds;
|
|
|
|
m_microseconds = std::chrono::duration_cast<std::chrono::microseconds>(age);
|
|
age -= m_microseconds;
|
|
|
|
m_nanoseconds = age;
|
|
}
|
|
//--------------------------------------------------------------
|
|
/* Return age in microseconds */
|
|
inline std::chrono::microseconds Age::getAge() const
|
|
{
|
|
return std::chrono::duration_cast<std::chrono::microseconds>(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;
|
|
}
|
|
//--------------------------------------------------------------
|