From cf859223ab2a6d3a3879abcfc081370b936a5970 Mon Sep 17 00:00:00 2001
From: Robert <robert.trololo@gmail.com>
Date: Sat, 24 Apr 2021 00:58:38 +0200
Subject: [PATCH] Added operators to Time

---
 include/structures/Time.hpp |  57 +++++++++++++-
 src/structures/Time.cpp     | 145 +++++++++++++++++++++++++++++++++---
 2 files changed, 186 insertions(+), 16 deletions(-)

diff --git a/include/structures/Time.hpp b/include/structures/Time.hpp
index e7ea9ef..aaf5dfa 100644
--- a/include/structures/Time.hpp
+++ b/include/structures/Time.hpp
@@ -15,15 +15,48 @@ public:
 	Int32 AsMilliseconds() const;
 	Int64 AsMicroseconds() const;
 
-	template<typename Duration = std::chrono::seconds> Duration AsChrono() const;
+	template<typename Rep = Int64, typename Period = std::ratio<1>> std::chrono::duration<Rep, Period> AsChrono() const;
 	std::chrono::seconds AsChronoSeconds() const;
 	std::chrono::milliseconds AsChronoMilliseconds() const;
 	std::chrono::microseconds AsChronoMicroseconds() const;
 
+	template<typename Rep, typename Period> friend Time Create(const Rep& duration);
+	template<typename Rep, typename Period> friend Time Create(const std::chrono::duration<Rep, Period>& duration);
 	friend Time Seconds(float seconds);
 	friend Time Milliseconds(Int32 milliseconds);
 	friend Time Microseconds(Int64 microseconds);
 
+	friend bool operator==(const Time& left, const Time& right);
+	friend bool operator!=(const Time& left, const Time& right);
+	friend bool operator<(const Time& left, const Time& right);
+	friend bool operator>(const Time& left, const Time& right);
+	friend bool operator<=(const Time& left, const Time& right);
+	friend bool operator>=(const Time& left, const Time& right);
+
+	friend Time operator-(const Time& right);
+
+	friend Time operator+(const Time& left, const Time& right);
+	friend Time& operator+=(Time& left, const Time& right);
+
+	friend Time operator-(const Time& left, const Time& right);
+	friend Time& operator-=(Time& left, const Time& right);
+
+	friend Time operator*(const Time& left, float right);
+	friend Time operator*(const Time& left, Int64 right);
+	friend Time operator*(float left, const Time& right);
+	friend Time operator*(Int64 left, const Time& right);
+	friend Time& operator*=(Time& left, float right);
+	friend Time& operator*=(Time& left, Int64 right);
+
+	friend Time operator/(const Time& left, float right);
+	friend Time operator/(const Time& left, Int64 right);
+	friend Time& operator/=(Time& left, float right);
+	friend Time& operator/=(Time& left, Int64 right);
+	friend float operator/(const Time& left, const Time& right);
+
+	friend Time operator%(const Time& left, const Time& right);
+	friend Time& operator%=(Time& left, const Time& right);
+
 private:
 	std::chrono::duration<Int64, std::micro> microseconds;
 };
@@ -35,10 +68,26 @@ inline Rep Time::AsValue() const
 	return std::chrono::duration_cast<std::chrono::duration<Rep, Period>>(microseconds).count();
 }
 
-template<typename Duration>
-inline Duration Time::AsChrono() const
+template<typename Rep, typename Period>
+inline std::chrono::duration<Rep, Period> Time::AsChrono() const
 {
-	return std::chrono::duration_cast<Duration>(microseconds);
+	return std::chrono::duration_cast<std::chrono::duration<Rep, Period>>(microseconds);
+}
+
+template<typename Rep = Int64, typename Period = std::ratio<1>>
+inline Time Create(const Rep& duration)
+{
+	Time newTime;
+	newTime.microseconds = std::chrono::duration_cast<std::chrono::duration<Int64, std::micro>>(std::chrono::duration<Rep, Period>(duration));
+	return newTime;
+}
+
+template<typename Rep = Int64, typename Period = std::ratio<1>>
+inline Time Create(const std::chrono::duration<Rep, Period>& duration)
+{
+	Time newTime;
+	newTime.microseconds = std::chrono::duration_cast<std::chrono::duration<Int64, std::micro>>(duration);
+	return newTime;
 }
 
 SDLU_END
\ No newline at end of file
diff --git a/src/structures/Time.cpp b/src/structures/Time.cpp
index f20d88e..def608a 100644
--- a/src/structures/Time.cpp
+++ b/src/structures/Time.cpp
@@ -25,38 +25,159 @@ Int64 Time::AsMicroseconds() const
 
 std::chrono::seconds Time::AsChronoSeconds() const
 {
-	return AsChrono<std::chrono::seconds>();
+	return AsChrono<long long, std::ratio<1>>();
 }
 
 std::chrono::milliseconds Time::AsChronoMilliseconds() const
 {
-	return AsChrono<std::chrono::milliseconds>();
+	return AsChrono<long long, std::milli>();
 }
 
 std::chrono::microseconds Time::AsChronoMicroseconds() const
 {
-	return AsChrono<std::chrono::microseconds>();
+	return AsChrono<long long, std::micro>();
 }
 
 Time Seconds(float seconds)
 {
-	Time newTime;
-	newTime.microseconds = std::chrono::duration_cast<std::chrono::duration<Int64, std::micro>>(std::chrono::duration<float>(seconds));
-	return newTime;
+	return Create<float>(seconds);
 }
 
 Time Milliseconds(Int32 milliseconds)
 {
-	Time newTime;
-	newTime.microseconds = std::chrono::duration_cast<std::chrono::duration<Int64, std::micro>>(std::chrono::duration<Int32, std::milli>(milliseconds));
-	return newTime;
+	return Create<Int32, std::milli>(milliseconds);
 }
 
 Time Microseconds(Int64 microseconds)
 {
-	Time newTime;
-	newTime.microseconds = std::chrono::duration<Int64, std::micro>(microseconds);
-	return newTime;
+	return Create<Int64, std::micro>(microseconds);
+}
+
+bool operator==(const Time& left, const Time& right)
+{
+	return (left.microseconds == right.microseconds);
+}
+
+bool operator!=(const Time& left, const Time& right)
+{
+	return (left.microseconds != right.microseconds);
+}
+
+bool operator<(const Time& left, const Time& right)
+{
+	return (left.microseconds < right.microseconds);
+}
+
+bool operator>(const Time& left, const Time& right)
+{
+	return (left.microseconds > right.microseconds);
+}
+
+bool operator<=(const Time& left, const Time& right)
+{
+	return (left.microseconds <= right.microseconds);
+}
+
+bool operator>=(const Time& left, const Time& right)
+{
+	return (left.microseconds >= right.microseconds);
+}
+
+Time operator-(const Time& right)
+{
+	return Create(-right.microseconds);
+}
+
+Time operator+(const Time& left, const Time& right)
+{
+	return Create(left.microseconds + right.microseconds);
+}
+
+Time& operator+=(Time& left, const Time& right)
+{
+	left = left + right;
+	return left;
+}
+
+Time operator-(const Time& left, const Time& right)
+{
+	return Create(left.microseconds - right.microseconds);
+}
+
+Time& operator-=(Time& left, const Time& right)
+{
+	left = left - right;
+	return left;
+}
+
+Time operator*(const Time& left, float right)
+{
+	return Create(left.microseconds * right);
+}
+
+Time operator*(const Time& left, Int64 right)
+{
+	return Create(left.microseconds * right);
+}
+
+Time operator*(float left, const Time& right)
+{
+	return (right * left);
+}
+
+Time operator*(Int64 left, const Time& right)
+{
+	return (right * left);
+}
+
+Time& operator*=(Time& left, float right)
+{
+	left = left * right;
+	return left;
+}
+
+Time& operator*=(Time& left, Int64 right)
+{
+	left = left * right;
+	return left;
+}
+
+Time operator/(const Time& left, float right)
+{
+	return Create(left.microseconds / right);
+}
+
+Time operator/(const Time& left, Int64 right)
+{
+	return Create(left.microseconds / right);
+}
+
+Time& operator/=(Time& left, float right)
+{
+	left = left / right;
+	return left;
+}
+
+Time& operator/=(Time& left, Int64 right)
+{
+	left = left / right;
+	return left;
+}
+
+float operator/(const Time& left, const Time& right)
+{
+	return ((float)(left.AsMicroseconds()) / (float)(right.AsMicroseconds()));
+}
+
+Time operator%(const Time& left, const Time& right)
+{
+	return Create(left.microseconds % right.microseconds);
+}
+
+Time& operator%=(Time& left, const Time& right)
+{
+	left = left % right;
+	return left;
 }
 
 SDLU_END
\ No newline at end of file