From 5ba65805688f86093464f6dc32b8a768a76dedb1 Mon Sep 17 00:00:00 2001 From: Vittorio Romeo Date: Fri, 24 Dec 2021 15:12:50 +0100 Subject: [PATCH] Make 'Time' a 'constexpr' class --- include/SFML/System/Time.hpp | 76 +++++----- include/SFML/System/Time.inl | 247 +++++++++++++++++++++++++++++++++ src/SFML/System/CMakeLists.txt | 1 + src/SFML/System/Time.cpp | 226 +----------------------------- test/System/Time.cpp | 12 ++ 5 files changed, 301 insertions(+), 261 deletions(-) create mode 100644 include/SFML/System/Time.inl diff --git a/include/SFML/System/Time.hpp b/include/SFML/System/Time.hpp index 001f2110..b231ed44 100644 --- a/include/SFML/System/Time.hpp +++ b/include/SFML/System/Time.hpp @@ -37,7 +37,7 @@ namespace sf /// \brief Represents a time value /// //////////////////////////////////////////////////////////// -class SFML_SYSTEM_API Time +class Time { public: @@ -47,7 +47,7 @@ public: /// Sets the time value to zero. /// //////////////////////////////////////////////////////////// - Time(); + constexpr Time(); //////////////////////////////////////////////////////////// /// \brief Return the time value as a number of seconds @@ -57,7 +57,7 @@ public: /// \see asMilliseconds, asMicroseconds /// //////////////////////////////////////////////////////////// - float asSeconds() const; + constexpr float asSeconds() const; //////////////////////////////////////////////////////////// /// \brief Return the time value as a number of milliseconds @@ -67,7 +67,7 @@ public: /// \see asSeconds, asMicroseconds /// //////////////////////////////////////////////////////////// - Int32 asMilliseconds() const; + constexpr Int32 asMilliseconds() const; //////////////////////////////////////////////////////////// /// \brief Return the time value as a number of microseconds @@ -77,18 +77,18 @@ public: /// \see asSeconds, asMilliseconds /// //////////////////////////////////////////////////////////// - Int64 asMicroseconds() const; + constexpr Int64 asMicroseconds() const; //////////////////////////////////////////////////////////// // Static member data //////////////////////////////////////////////////////////// - static const Time Zero; //!< Predefined "zero" time value + SFML_SYSTEM_API static const Time Zero; //!< Predefined "zero" time value private: - friend SFML_SYSTEM_API Time seconds(float); - friend SFML_SYSTEM_API Time milliseconds(Int32); - friend SFML_SYSTEM_API Time microseconds(Int64); + friend constexpr Time seconds(float); + friend constexpr Time milliseconds(Int32); + friend constexpr Time microseconds(Int64); //////////////////////////////////////////////////////////// /// \brief Construct from a number of microseconds @@ -99,7 +99,7 @@ private: /// \param microseconds Number of microseconds /// //////////////////////////////////////////////////////////// - explicit Time(Int64 microseconds); + constexpr explicit Time(Int64 microseconds); private: @@ -120,7 +120,7 @@ private: /// \see milliseconds, microseconds /// //////////////////////////////////////////////////////////// -SFML_SYSTEM_API Time seconds(float amount); +constexpr Time seconds(float amount); //////////////////////////////////////////////////////////// /// \relates Time @@ -133,7 +133,7 @@ SFML_SYSTEM_API Time seconds(float amount); /// \see seconds, microseconds /// //////////////////////////////////////////////////////////// -SFML_SYSTEM_API Time milliseconds(Int32 amount); +constexpr Time milliseconds(Int32 amount); //////////////////////////////////////////////////////////// /// \relates Time @@ -146,7 +146,7 @@ SFML_SYSTEM_API Time milliseconds(Int32 amount); /// \see seconds, milliseconds /// //////////////////////////////////////////////////////////// -SFML_SYSTEM_API Time microseconds(Int64 amount); +constexpr Time microseconds(Int64 amount); //////////////////////////////////////////////////////////// /// \relates Time @@ -158,7 +158,7 @@ SFML_SYSTEM_API Time microseconds(Int64 amount); /// \return True if both time values are equal /// //////////////////////////////////////////////////////////// -SFML_SYSTEM_API bool operator ==(Time left, Time right); +[[nodiscard]] constexpr bool operator ==(Time left, Time right); //////////////////////////////////////////////////////////// /// \relates Time @@ -170,7 +170,7 @@ SFML_SYSTEM_API bool operator ==(Time left, Time right); /// \return True if both time values are different /// //////////////////////////////////////////////////////////// -SFML_SYSTEM_API bool operator !=(Time left, Time right); +[[nodiscard]] constexpr bool operator !=(Time left, Time right); //////////////////////////////////////////////////////////// /// \relates Time @@ -182,7 +182,7 @@ SFML_SYSTEM_API bool operator !=(Time left, Time right); /// \return True if \a left is lesser than \a right /// //////////////////////////////////////////////////////////// -SFML_SYSTEM_API bool operator <(Time left, Time right); +[[nodiscard]] constexpr bool operator <(Time left, Time right); //////////////////////////////////////////////////////////// /// \relates Time @@ -194,7 +194,7 @@ SFML_SYSTEM_API bool operator <(Time left, Time right); /// \return True if \a left is greater than \a right /// //////////////////////////////////////////////////////////// -SFML_SYSTEM_API bool operator >(Time left, Time right); +[[nodiscard]] constexpr bool operator >(Time left, Time right); //////////////////////////////////////////////////////////// /// \relates Time @@ -206,7 +206,7 @@ SFML_SYSTEM_API bool operator >(Time left, Time right); /// \return True if \a left is lesser or equal than \a right /// //////////////////////////////////////////////////////////// -SFML_SYSTEM_API bool operator <=(Time left, Time right); +[[nodiscard]] constexpr bool operator <=(Time left, Time right); //////////////////////////////////////////////////////////// /// \relates Time @@ -218,7 +218,7 @@ SFML_SYSTEM_API bool operator <=(Time left, Time right); /// \return True if \a left is greater or equal than \a right /// //////////////////////////////////////////////////////////// -SFML_SYSTEM_API bool operator >=(Time left, Time right); +[[nodiscard]] constexpr bool operator >=(Time left, Time right); //////////////////////////////////////////////////////////// /// \relates Time @@ -229,7 +229,7 @@ SFML_SYSTEM_API bool operator >=(Time left, Time right); /// \return Opposite of the time value /// //////////////////////////////////////////////////////////// -SFML_SYSTEM_API Time operator -(Time right); +[[nodiscard]] constexpr Time operator -(Time right); //////////////////////////////////////////////////////////// /// \relates Time @@ -241,7 +241,7 @@ SFML_SYSTEM_API Time operator -(Time right); /// \return Sum of the two times values /// //////////////////////////////////////////////////////////// -SFML_SYSTEM_API Time operator +(Time left, Time right); +[[nodiscard]] constexpr Time operator +(Time left, Time right); //////////////////////////////////////////////////////////// /// \relates Time @@ -253,7 +253,7 @@ SFML_SYSTEM_API Time operator +(Time left, Time right); /// \return Sum of the two times values /// //////////////////////////////////////////////////////////// -SFML_SYSTEM_API Time& operator +=(Time& left, Time right); +constexpr Time& operator +=(Time& left, Time right); //////////////////////////////////////////////////////////// /// \relates Time @@ -265,7 +265,7 @@ SFML_SYSTEM_API Time& operator +=(Time& left, Time right); /// \return Difference of the two times values /// //////////////////////////////////////////////////////////// -SFML_SYSTEM_API Time operator -(Time left, Time right); +[[nodiscard]] constexpr Time operator -(Time left, Time right); //////////////////////////////////////////////////////////// /// \relates Time @@ -277,7 +277,7 @@ SFML_SYSTEM_API Time operator -(Time left, Time right); /// \return Difference of the two times values /// //////////////////////////////////////////////////////////// -SFML_SYSTEM_API Time& operator -=(Time& left, Time right); +constexpr Time& operator -=(Time& left, Time right); //////////////////////////////////////////////////////////// /// \relates Time @@ -289,7 +289,7 @@ SFML_SYSTEM_API Time& operator -=(Time& left, Time right); /// \return \a left multiplied by \a right /// //////////////////////////////////////////////////////////// -SFML_SYSTEM_API Time operator *(Time left, float right); +[[nodiscard]] constexpr Time operator *(Time left, float right); //////////////////////////////////////////////////////////// /// \relates Time @@ -301,7 +301,7 @@ SFML_SYSTEM_API Time operator *(Time left, float right); /// \return \a left multiplied by \a right /// //////////////////////////////////////////////////////////// -SFML_SYSTEM_API Time operator *(Time left, Int64 right); +[[nodiscard]] constexpr Time operator *(Time left, Int64 right); //////////////////////////////////////////////////////////// /// \relates Time @@ -313,7 +313,7 @@ SFML_SYSTEM_API Time operator *(Time left, Int64 right); /// \return \a left multiplied by \a right /// //////////////////////////////////////////////////////////// -SFML_SYSTEM_API Time operator *(float left, Time right); +[[nodiscard]] constexpr Time operator *(float left, Time right); //////////////////////////////////////////////////////////// /// \relates Time @@ -325,7 +325,7 @@ SFML_SYSTEM_API Time operator *(float left, Time right); /// \return \a left multiplied by \a right /// //////////////////////////////////////////////////////////// -SFML_SYSTEM_API Time operator *(Int64 left, Time right); +[[nodiscard]] constexpr Time operator *(Int64 left, Time right); //////////////////////////////////////////////////////////// /// \relates Time @@ -337,7 +337,7 @@ SFML_SYSTEM_API Time operator *(Int64 left, Time right); /// \return \a left multiplied by \a right /// //////////////////////////////////////////////////////////// -SFML_SYSTEM_API Time& operator *=(Time& left, float right); +constexpr Time& operator *=(Time& left, float right); //////////////////////////////////////////////////////////// /// \relates Time @@ -349,7 +349,7 @@ SFML_SYSTEM_API Time& operator *=(Time& left, float right); /// \return \a left multiplied by \a right /// //////////////////////////////////////////////////////////// -SFML_SYSTEM_API Time& operator *=(Time& left, Int64 right); +constexpr Time& operator *=(Time& left, Int64 right); //////////////////////////////////////////////////////////// /// \relates Time @@ -361,7 +361,7 @@ SFML_SYSTEM_API Time& operator *=(Time& left, Int64 right); /// \return \a left divided by \a right /// //////////////////////////////////////////////////////////// -SFML_SYSTEM_API Time operator /(Time left, float right); +[[nodiscard]] constexpr Time operator /(Time left, float right); //////////////////////////////////////////////////////////// /// \relates Time @@ -373,7 +373,7 @@ SFML_SYSTEM_API Time operator /(Time left, float right); /// \return \a left divided by \a right /// //////////////////////////////////////////////////////////// -SFML_SYSTEM_API Time operator /(Time left, Int64 right); +[[nodiscard]] constexpr Time operator /(Time left, Int64 right); //////////////////////////////////////////////////////////// /// \relates Time @@ -385,7 +385,7 @@ SFML_SYSTEM_API Time operator /(Time left, Int64 right); /// \return \a left divided by \a right /// //////////////////////////////////////////////////////////// -SFML_SYSTEM_API Time& operator /=(Time& left, float right); +constexpr Time& operator /=(Time& left, float right); //////////////////////////////////////////////////////////// /// \relates Time @@ -397,7 +397,7 @@ SFML_SYSTEM_API Time& operator /=(Time& left, float right); /// \return \a left divided by \a right /// //////////////////////////////////////////////////////////// -SFML_SYSTEM_API Time& operator /=(Time& left, Int64 right); +constexpr Time& operator /=(Time& left, Int64 right); //////////////////////////////////////////////////////////// /// \relates Time @@ -409,7 +409,7 @@ SFML_SYSTEM_API Time& operator /=(Time& left, Int64 right); /// \return \a left divided by \a right /// //////////////////////////////////////////////////////////// -SFML_SYSTEM_API float operator /(Time left, Time right); +[[nodiscard]] constexpr float operator /(Time left, Time right); //////////////////////////////////////////////////////////// /// \relates Time @@ -421,7 +421,7 @@ SFML_SYSTEM_API float operator /(Time left, Time right); /// \return \a left modulo \a right /// //////////////////////////////////////////////////////////// -SFML_SYSTEM_API Time operator %(Time left, Time right); +[[nodiscard]] constexpr Time operator %(Time left, Time right); //////////////////////////////////////////////////////////// /// \relates Time @@ -433,7 +433,9 @@ SFML_SYSTEM_API Time operator %(Time left, Time right); /// \return \a left modulo \a right /// //////////////////////////////////////////////////////////// -SFML_SYSTEM_API Time& operator %=(Time& left, Time right); +constexpr Time& operator %=(Time& left, Time right); + +#include } // namespace sf diff --git a/include/SFML/System/Time.inl b/include/SFML/System/Time.inl new file mode 100644 index 00000000..217c524d --- /dev/null +++ b/include/SFML/System/Time.inl @@ -0,0 +1,247 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2021 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////// +constexpr Time::Time() : +m_microseconds(0) +{ +} + + +//////////////////////////////////////////////////////////// +constexpr float Time::asSeconds() const +{ + return static_cast(static_cast(m_microseconds) / 1000000.0); +} + + +//////////////////////////////////////////////////////////// +constexpr Int32 Time::asMilliseconds() const +{ + return static_cast(m_microseconds / 1000); +} + + +//////////////////////////////////////////////////////////// +constexpr Int64 Time::asMicroseconds() const +{ + return m_microseconds; +} + + +//////////////////////////////////////////////////////////// +constexpr Time::Time(Int64 microseconds) : +m_microseconds(microseconds) +{ +} + + +//////////////////////////////////////////////////////////// +constexpr Time seconds(float amount) +{ + return Time(static_cast(amount * 1000000)); +} + + +//////////////////////////////////////////////////////////// +constexpr Time milliseconds(Int32 amount) +{ + return Time(static_cast(amount) * 1000); +} + + +//////////////////////////////////////////////////////////// +constexpr Time microseconds(Int64 amount) +{ + return Time(amount); +} + + +//////////////////////////////////////////////////////////// +constexpr bool operator ==(Time left, Time right) +{ + return left.asMicroseconds() == right.asMicroseconds(); +} + + +//////////////////////////////////////////////////////////// +constexpr bool operator !=(Time left, Time right) +{ + return left.asMicroseconds() != right.asMicroseconds(); +} + + +//////////////////////////////////////////////////////////// +constexpr bool operator <(Time left, Time right) +{ + return left.asMicroseconds() < right.asMicroseconds(); +} + + +//////////////////////////////////////////////////////////// +constexpr bool operator >(Time left, Time right) +{ + return left.asMicroseconds() > right.asMicroseconds(); +} + + +//////////////////////////////////////////////////////////// +constexpr bool operator <=(Time left, Time right) +{ + return left.asMicroseconds() <= right.asMicroseconds(); +} + + +//////////////////////////////////////////////////////////// +constexpr bool operator >=(Time left, Time right) +{ + return left.asMicroseconds() >= right.asMicroseconds(); +} + + +//////////////////////////////////////////////////////////// +constexpr Time operator -(Time right) +{ + return microseconds(-right.asMicroseconds()); +} + + +//////////////////////////////////////////////////////////// +constexpr Time operator +(Time left, Time right) +{ + return microseconds(left.asMicroseconds() + right.asMicroseconds()); +} + + +//////////////////////////////////////////////////////////// +constexpr Time& operator +=(Time& left, Time right) +{ + return left = left + right; +} + + +//////////////////////////////////////////////////////////// +constexpr Time operator -(Time left, Time right) +{ + return microseconds(left.asMicroseconds() - right.asMicroseconds()); +} + + +//////////////////////////////////////////////////////////// +constexpr Time& operator -=(Time& left, Time right) +{ + return left = left - right; +} + + +//////////////////////////////////////////////////////////// +constexpr Time operator *(Time left, float right) +{ + return seconds(left.asSeconds() * right); +} + + +//////////////////////////////////////////////////////////// +constexpr Time operator *(Time left, Int64 right) +{ + return microseconds(left.asMicroseconds() * right); +} + + +//////////////////////////////////////////////////////////// +constexpr Time operator *(float left, Time right) +{ + return right * left; +} + + +//////////////////////////////////////////////////////////// +constexpr Time operator *(Int64 left, Time right) +{ + return right * left; +} + + +//////////////////////////////////////////////////////////// +constexpr Time& operator *=(Time& left, float right) +{ + return left = left * right; +} + + +//////////////////////////////////////////////////////////// +constexpr Time& operator *=(Time& left, Int64 right) +{ + return left = left * right; +} + + +//////////////////////////////////////////////////////////// +constexpr Time operator /(Time left, float right) +{ + return seconds(left.asSeconds() / right); +} + + +//////////////////////////////////////////////////////////// +constexpr Time operator /(Time left, Int64 right) +{ + return microseconds(left.asMicroseconds() / right); +} + + +//////////////////////////////////////////////////////////// +constexpr Time& operator /=(Time& left, float right) +{ + return left = left / right; +} + + +//////////////////////////////////////////////////////////// +constexpr Time& operator /=(Time& left, Int64 right) +{ + return left = left / right; +} + + +//////////////////////////////////////////////////////////// +constexpr float operator /(Time left, Time right) +{ + return left.asSeconds() / right.asSeconds(); +} + + +//////////////////////////////////////////////////////////// +constexpr Time operator %(Time left, Time right) +{ + return microseconds(left.asMicroseconds() % right.asMicroseconds()); +} + + +//////////////////////////////////////////////////////////// +constexpr Time& operator %=(Time& left, Time right) +{ + return left = left % right; +} diff --git a/src/SFML/System/CMakeLists.txt b/src/SFML/System/CMakeLists.txt index ada9e13f..b3753f89 100644 --- a/src/SFML/System/CMakeLists.txt +++ b/src/SFML/System/CMakeLists.txt @@ -18,6 +18,7 @@ set(SRC ${INCROOT}/String.inl ${SRCROOT}/Time.cpp ${INCROOT}/Time.hpp + ${INCROOT}/Time.inl ${INCROOT}/Utf.hpp ${INCROOT}/Utf.inl ${INCROOT}/Vector2.hpp diff --git a/src/SFML/System/Time.cpp b/src/SFML/System/Time.cpp index f13183ca..588d4722 100644 --- a/src/SFML/System/Time.cpp +++ b/src/SFML/System/Time.cpp @@ -31,230 +31,8 @@ namespace sf { //////////////////////////////////////////////////////////// +// Static member data +//////////////////////////////////////////////////////////// const Time Time::Zero; - -//////////////////////////////////////////////////////////// -Time::Time() : -m_microseconds(0) -{ -} - - -//////////////////////////////////////////////////////////// -float Time::asSeconds() const -{ - return static_cast(static_cast(m_microseconds) / 1000000.0); -} - - -//////////////////////////////////////////////////////////// -Int32 Time::asMilliseconds() const -{ - return static_cast(m_microseconds / 1000); -} - - -//////////////////////////////////////////////////////////// -Int64 Time::asMicroseconds() const -{ - return m_microseconds; -} - - -//////////////////////////////////////////////////////////// -Time::Time(Int64 microseconds) : -m_microseconds(microseconds) -{ -} - - -//////////////////////////////////////////////////////////// -Time seconds(float amount) -{ - return Time(static_cast(amount * 1000000)); -} - - -//////////////////////////////////////////////////////////// -Time milliseconds(Int32 amount) -{ - return Time(static_cast(amount) * 1000); -} - - -//////////////////////////////////////////////////////////// -Time microseconds(Int64 amount) -{ - return Time(amount); -} - - -//////////////////////////////////////////////////////////// -bool operator ==(Time left, Time right) -{ - return left.asMicroseconds() == right.asMicroseconds(); -} - - -//////////////////////////////////////////////////////////// -bool operator !=(Time left, Time right) -{ - return left.asMicroseconds() != right.asMicroseconds(); -} - - -//////////////////////////////////////////////////////////// -bool operator <(Time left, Time right) -{ - return left.asMicroseconds() < right.asMicroseconds(); -} - - -//////////////////////////////////////////////////////////// -bool operator >(Time left, Time right) -{ - return left.asMicroseconds() > right.asMicroseconds(); -} - - -//////////////////////////////////////////////////////////// -bool operator <=(Time left, Time right) -{ - return left.asMicroseconds() <= right.asMicroseconds(); -} - - -//////////////////////////////////////////////////////////// -bool operator >=(Time left, Time right) -{ - return left.asMicroseconds() >= right.asMicroseconds(); -} - - -//////////////////////////////////////////////////////////// -Time operator -(Time right) -{ - return microseconds(-right.asMicroseconds()); -} - - -//////////////////////////////////////////////////////////// -Time operator +(Time left, Time right) -{ - return microseconds(left.asMicroseconds() + right.asMicroseconds()); -} - - -//////////////////////////////////////////////////////////// -Time& operator +=(Time& left, Time right) -{ - return left = left + right; -} - - -//////////////////////////////////////////////////////////// -Time operator -(Time left, Time right) -{ - return microseconds(left.asMicroseconds() - right.asMicroseconds()); -} - - -//////////////////////////////////////////////////////////// -Time& operator -=(Time& left, Time right) -{ - return left = left - right; -} - - -//////////////////////////////////////////////////////////// -Time operator *(Time left, float right) -{ - return seconds(left.asSeconds() * right); -} - - -//////////////////////////////////////////////////////////// -Time operator *(Time left, Int64 right) -{ - return microseconds(left.asMicroseconds() * right); -} - - -//////////////////////////////////////////////////////////// -Time operator *(float left, Time right) -{ - return right * left; -} - - -//////////////////////////////////////////////////////////// -Time operator *(Int64 left, Time right) -{ - return right * left; -} - - -//////////////////////////////////////////////////////////// -Time& operator *=(Time& left, float right) -{ - return left = left * right; -} - - -//////////////////////////////////////////////////////////// -Time& operator *=(Time& left, Int64 right) -{ - return left = left * right; -} - - -//////////////////////////////////////////////////////////// -Time operator /(Time left, float right) -{ - return seconds(left.asSeconds() / right); -} - - -//////////////////////////////////////////////////////////// -Time operator /(Time left, Int64 right) -{ - return microseconds(left.asMicroseconds() / right); -} - - -//////////////////////////////////////////////////////////// -Time& operator /=(Time& left, float right) -{ - return left = left / right; -} - - -//////////////////////////////////////////////////////////// -Time& operator /=(Time& left, Int64 right) -{ - return left = left / right; -} - - -//////////////////////////////////////////////////////////// -float operator /(Time left, Time right) -{ - return left.asSeconds() / right.asSeconds(); -} - - -//////////////////////////////////////////////////////////// -Time operator %(Time left, Time right) -{ - return microseconds(left.asMicroseconds() % right.asMicroseconds()); -} - - -//////////////////////////////////////////////////////////// -Time& operator %=(Time& left, Time right) -{ - return left = left % right; -} - } // namespace sf diff --git a/test/System/Time.cpp b/test/System/Time.cpp index 92727392..b2ef629a 100644 --- a/test/System/Time.cpp +++ b/test/System/Time.cpp @@ -201,4 +201,16 @@ TEST_CASE("sf::Time class - [system]") CHECK(time == sf::milliseconds(1)); } } + + SUBCASE("Constexpr support") + { + constexpr auto result = [] + { + sf::Time time = sf::milliseconds(100); + time %= sf::milliseconds(99); + return time; + }(); + + static_assert(result == sf::milliseconds(1)); + } }