Adds the sdi_toolBox library (temporary version)

This commit is contained in:
Sylvain Schneider
2026-03-12 16:31:18 +01:00
parent 0601326e2b
commit b5d0fef4d9
23 changed files with 28422 additions and 0 deletions

View File

@@ -0,0 +1,175 @@
#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;
}
//--------------------------------------------------------------

View File

@@ -0,0 +1,49 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include <chrono>
namespace sdi_toolBox::dateTime
{
//--------------------------------------------------------------
/**
* @brief Abstract interface for pause functionality.
*
* Provides a common interface for implementing pause or delay mechanisms.
* Derived classes must implement the wait() method to pause execution
* for a specified duration.
*/
class IPause
{
public:
using Duration = std::chrono::milliseconds;
public:
~IPause() = default; // Default destructor
IPause(const IPause &obj) = default; // Copy constructor
IPause(IPause &&obj) noexcept = default; // Move constructor
IPause &operator=(const IPause &obj) = default; // Copy assignment operator
IPause &operator=(IPause &&obj) noexcept = default; // Move assignment operator
/**
* @brief Pause execution for the specified duration.
* @param duration Duration of the pause.
*/
virtual void wait(const Duration &duration) const = 0;
protected:
IPause() = default; // Default constructor
};
//--------------------------------------------------------------
} // namespace sdi_toolBox::dateTime

View File

@@ -0,0 +1,100 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include <chrono>
namespace sdi_toolBox::dateTime
{
//--------------------------------------------------------------
/**
* @brief Abstract interface for timer functionality.
*
* Provides a common interface for timer implementations, allowing
* measurement of elapsed time and checking for timeouts.
* Derived classes must implement the now() method to provide the
* current time point.
*/
class ITimer
{
public:
using Clock = std::chrono::high_resolution_clock;
using TimePoint = Clock::time_point;
using Duration = std::chrono::milliseconds;
public:
virtual ~ITimer() = default; // Default destructor
ITimer(const ITimer &obj) = default; // Copy constructor
ITimer(ITimer &&obj) noexcept = default; // Move constructor
ITimer &operator=(const ITimer &obj) = default; // Copy assignment operator
ITimer &operator=(ITimer &&obj) noexcept = default; // Move assignment operator
/**
* @brief Resets the reference time point to the current time.
*/
void reset();
/**
* @brief Returns the current time point.
* @return The current time point as defined by the derived class.
*/
[[nodiscard]] virtual TimePoint now() const = 0;
/**
* @brief Returns the elapsed duration since the last reset.
* @return Duration since the last reset.
*/
[[nodiscard]] Duration getElapsed() const;
/**
* @brief Checks if the specified duration has elapsed since the last reset.
* @param duration The duration to check.
* @param autoReset If true, automatically resets the timer when the duration has elapsed.
* @return True if the duration has elapsed, false otherwise.
*/
[[nodiscard]] bool isElapsed(const Duration duration,
bool autoReset = false);
protected:
ITimer() = default; // Default constructor
TimePoint m_t0; // Timepoint t0 for elapsed time measurement
};
//--------------------------------------------------------------
/* Reset the timepoint t0 */
inline void ITimer::reset()
{
m_t0 = now();
}
//--------------------------------------------------------------
/* Get the elapsed time */
inline ITimer::Duration ITimer::getElapsed() const
{
return std::chrono::duration_cast<Duration>(now() - m_t0);
}
//--------------------------------------------------------------
/* Check if the specified delay has elapsed */
inline bool ITimer::isElapsed(const Duration duration, bool autoReset)
{
Duration elapsed = getElapsed();
if (elapsed >= duration)
{
if (autoReset)
reset();
return true;
}
return false;
}
//--------------------------------------------------------------
} // namespace sdi_toolBox::dateTime

View File

@@ -0,0 +1,59 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include "iPause.h"
#include <thread>
namespace sdi_toolBox::dateTime
{
//--------------------------------------------------------------
/**
* @brief Standard pause implementation.
*
* Implements IPause to provide a blocking pause using standard C++ mechanisms.
* The actual delay is performed using std::this_thread::sleep_for.
*/
class Pause : public IPause
{
public:
Pause() = default; // Default constructor
~Pause() = default; // Default destructor
Pause(const Pause &obj) = default; // Copy constructor
Pause(Pause &&obj) noexcept = default; // Move constructor
Pause &operator=(const Pause &obj) = default; // Copy assignment operator
Pause &operator=(Pause &&obj) noexcept = default; // Move assignment operator
explicit Pause(const Duration &duration); // Constructor
/**
* @brief Pause execution for the specified duration.
* @param duration Duration of the pause.
*/
void wait(const Duration &duration) const override;
};
//--------------------------------------------------------------
/* Constructor */
inline Pause::Pause(const Duration &duration)
{
wait(duration);
}
//--------------------------------------------------------------
/* Pause execution for the specified duration */
inline void Pause::wait(const Duration &duration) const
{
std::this_thread::sleep_for(duration);
}
//--------------------------------------------------------------
} // namespace sdi_toolBox::dateTime

View File

@@ -0,0 +1,55 @@
/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#include "iTimer.h"
namespace sdi_toolBox::dateTime
{
//--------------------------------------------------------------
/**
* @brief Standard timer implementation using std::chrono.
*
* Implements ITimer using std::chrono::high_resolution_clock for
* high-precision timing in standard C++ environments.
*/
class Timer : public ITimer
{
public:
Timer(); // Default constructor
~Timer() = default; // Default destructor
Timer(const Timer &obj) = default; // Copy constructor
Timer(Timer &&obj) noexcept = default; // Move constructor
Timer &operator=(const Timer &obj) = default; // Copy assignment operator
Timer &operator=(Timer &&obj) noexcept = default; // Move assignment operator
/**
* @brief Returns the current time point using std::chrono::high_resolution_clock.
* @return The current time point.
*/
[[nodiscard]] TimePoint now() const override;
};
//--------------------------------------------------------------
/* Default constructor */
inline Timer::Timer()
{
reset();
}
//--------------------------------------------------------------
/* Get the current timepoint */
inline Timer::TimePoint Timer::now() const
{
return Clock::now();
}
//--------------------------------------------------------------
} // namespace sdi_toolBox::dateTime