From ed201ce87a681f8e907c0dcf1f2b76ab9d7815ff Mon Sep 17 00:00:00 2001 From: Vittorio Romeo Date: Sat, 18 Dec 2021 19:58:23 +0100 Subject: [PATCH] Make 'Color' a 'constexpr' class --- include/SFML/Graphics/Color.hpp | 46 +++++----- include/SFML/Graphics/Color.inl | 149 +++++++++++++++++++++++++++++++ src/SFML/Graphics/CMakeLists.txt | 1 + src/SFML/Graphics/Color.cpp | 109 ---------------------- 4 files changed, 174 insertions(+), 131 deletions(-) create mode 100644 include/SFML/Graphics/Color.inl diff --git a/include/SFML/Graphics/Color.hpp b/include/SFML/Graphics/Color.hpp index 94fbe40b..24db35e1 100644 --- a/include/SFML/Graphics/Color.hpp +++ b/include/SFML/Graphics/Color.hpp @@ -37,7 +37,7 @@ namespace sf /// \brief Utility class for manipulating RGBA colors /// //////////////////////////////////////////////////////////// -class SFML_GRAPHICS_API Color +class Color { public: @@ -48,7 +48,7 @@ public: /// sf::Color(0, 0, 0, 255). /// //////////////////////////////////////////////////////////// - Color(); + constexpr Color(); //////////////////////////////////////////////////////////// /// \brief Construct the color from its 4 RGBA components @@ -59,7 +59,7 @@ public: /// \param alpha Alpha (opacity) component (in the range [0, 255]) /// //////////////////////////////////////////////////////////// - Color(Uint8 red, Uint8 green, Uint8 blue, Uint8 alpha = 255); + constexpr Color(Uint8 red, Uint8 green, Uint8 blue, Uint8 alpha = 255); //////////////////////////////////////////////////////////// /// \brief Construct the color from 32-bit unsigned integer @@ -67,7 +67,7 @@ public: /// \param color Number containing the RGBA components (in that order) /// //////////////////////////////////////////////////////////// - explicit Color(Uint32 color); + constexpr explicit Color(Uint32 color); //////////////////////////////////////////////////////////// /// \brief Retrieve the color as a 32-bit unsigned integer @@ -75,20 +75,20 @@ public: /// \return Color represented as a 32-bit unsigned integer /// //////////////////////////////////////////////////////////// - Uint32 toInteger() const; + constexpr Uint32 toInteger() const; //////////////////////////////////////////////////////////// // Static member data //////////////////////////////////////////////////////////// - static const Color Black; //!< Black predefined color - static const Color White; //!< White predefined color - static const Color Red; //!< Red predefined color - static const Color Green; //!< Green predefined color - static const Color Blue; //!< Blue predefined color - static const Color Yellow; //!< Yellow predefined color - static const Color Magenta; //!< Magenta predefined color - static const Color Cyan; //!< Cyan predefined color - static const Color Transparent; //!< Transparent (black) predefined color + SFML_GRAPHICS_API static const Color Black; //!< Black predefined color + SFML_GRAPHICS_API static const Color White; //!< White predefined color + SFML_GRAPHICS_API static const Color Red; //!< Red predefined color + SFML_GRAPHICS_API static const Color Green; //!< Green predefined color + SFML_GRAPHICS_API static const Color Blue; //!< Blue predefined color + SFML_GRAPHICS_API static const Color Yellow; //!< Yellow predefined color + SFML_GRAPHICS_API static const Color Magenta; //!< Magenta predefined color + SFML_GRAPHICS_API static const Color Cyan; //!< Cyan predefined color + SFML_GRAPHICS_API static const Color Transparent; //!< Transparent (black) predefined color //////////////////////////////////////////////////////////// // Member data @@ -111,7 +111,7 @@ public: /// \return True if colors are equal, false if they are different /// //////////////////////////////////////////////////////////// -SFML_GRAPHICS_API bool operator ==(const Color& left, const Color& right); +[[nodiscard]] constexpr bool operator ==(const Color& left, const Color& right); //////////////////////////////////////////////////////////// /// \relates Color @@ -125,7 +125,7 @@ SFML_GRAPHICS_API bool operator ==(const Color& left, const Color& right); /// \return True if colors are different, false if they are equal /// //////////////////////////////////////////////////////////// -SFML_GRAPHICS_API bool operator !=(const Color& left, const Color& right); +[[nodiscard]] constexpr bool operator !=(const Color& left, const Color& right); //////////////////////////////////////////////////////////// /// \relates Color @@ -140,7 +140,7 @@ SFML_GRAPHICS_API bool operator !=(const Color& left, const Color& right); /// \return Result of \a left + \a right /// //////////////////////////////////////////////////////////// -SFML_GRAPHICS_API Color operator +(const Color& left, const Color& right); +[[nodiscard]] constexpr Color operator +(const Color& left, const Color& right); //////////////////////////////////////////////////////////// /// \relates Color @@ -155,7 +155,7 @@ SFML_GRAPHICS_API Color operator +(const Color& left, const Color& right); /// \return Result of \a left - \a right /// //////////////////////////////////////////////////////////// -SFML_GRAPHICS_API Color operator -(const Color& left, const Color& right); +[[nodiscard]] constexpr Color operator -(const Color& left, const Color& right); //////////////////////////////////////////////////////////// /// \relates Color @@ -172,7 +172,7 @@ SFML_GRAPHICS_API Color operator -(const Color& left, const Color& right); /// \return Result of \a left * \a right /// //////////////////////////////////////////////////////////// -SFML_GRAPHICS_API Color operator *(const Color& left, const Color& right); +[[nodiscard]] constexpr Color operator *(const Color& left, const Color& right); //////////////////////////////////////////////////////////// /// \relates Color @@ -188,7 +188,7 @@ SFML_GRAPHICS_API Color operator *(const Color& left, const Color& right); /// \return Reference to \a left /// //////////////////////////////////////////////////////////// -SFML_GRAPHICS_API Color& operator +=(Color& left, const Color& right); +constexpr Color& operator +=(Color& left, const Color& right); //////////////////////////////////////////////////////////// /// \relates Color @@ -204,7 +204,7 @@ SFML_GRAPHICS_API Color& operator +=(Color& left, const Color& right); /// \return Reference to \a left /// //////////////////////////////////////////////////////////// -SFML_GRAPHICS_API Color& operator -=(Color& left, const Color& right); +constexpr Color& operator -=(Color& left, const Color& right); //////////////////////////////////////////////////////////// /// \relates Color @@ -222,7 +222,9 @@ SFML_GRAPHICS_API Color& operator -=(Color& left, const Color& right); /// \return Reference to \a left /// //////////////////////////////////////////////////////////// -SFML_GRAPHICS_API Color& operator *=(Color& left, const Color& right); +constexpr Color& operator *=(Color& left, const Color& right); + +#include } // namespace sf diff --git a/include/SFML/Graphics/Color.inl b/include/SFML/Graphics/Color.inl new file mode 100644 index 00000000..42e6dd7b --- /dev/null +++ b/include/SFML/Graphics/Color.inl @@ -0,0 +1,149 @@ +//////////////////////////////////////////////////////////// +// +// 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 Color::Color() : +r(0), +g(0), +b(0), +a(255) +{ + +} + + +//////////////////////////////////////////////////////////// +constexpr Color::Color(Uint8 red, Uint8 green, Uint8 blue, Uint8 alpha) : +r(red), +g(green), +b(blue), +a(alpha) +{ + +} + + +//////////////////////////////////////////////////////////// +constexpr Color::Color(Uint32 color) : +r(static_cast((color & 0xff000000) >> 24)), +g(static_cast((color & 0x00ff0000) >> 16)), +b(static_cast((color & 0x0000ff00) >> 8)), +a(static_cast(color & 0x000000ff)) +{ + +} + + +//////////////////////////////////////////////////////////// +constexpr Uint32 Color::toInteger() const +{ + return static_cast((r << 24) | (g << 16) | (b << 8) | a); +} + + +//////////////////////////////////////////////////////////// +constexpr bool operator ==(const Color& left, const Color& right) +{ + return (left.r == right.r) && + (left.g == right.g) && + (left.b == right.b) && + (left.a == right.a); +} + + +//////////////////////////////////////////////////////////// +constexpr bool operator !=(const Color& left, const Color& right) +{ + return !(left == right); +} + + +//////////////////////////////////////////////////////////// +constexpr Color operator +(const Color& left, const Color& right) +{ + const auto clampedAdd = [](Uint8 lhs, Uint8 rhs) -> Uint8 + { + const int intResult = static_cast(lhs) + static_cast(rhs); + return static_cast(intResult < 255 ? intResult : 255); + }; + + return Color(clampedAdd(left.r, right.r), + clampedAdd(left.g, right.g), + clampedAdd(left.b, right.b), + clampedAdd(left.a, right.a)); +} + + +//////////////////////////////////////////////////////////// +constexpr Color operator -(const Color& left, const Color& right) +{ + const auto clampedSub = [](Uint8 lhs, Uint8 rhs) -> Uint8 + { + const int intResult = static_cast(lhs) - static_cast(rhs); + return static_cast(intResult > 0 ? intResult : 0); + }; + + return Color(clampedSub(left.r, right.r), + clampedSub(left.g, right.g), + clampedSub(left.b, right.b), + clampedSub(left.a, right.a)); +} + + +//////////////////////////////////////////////////////////// +constexpr Color operator *(const Color& left, const Color& right) +{ + const auto scaledMul = [](Uint8 lhs, Uint8 rhs) -> Uint8 + { + const auto uint16Result = static_cast(static_cast(lhs) * static_cast(rhs)); + return static_cast(uint16Result / 255u); + }; + + return Color(scaledMul(left.r, right.r), + scaledMul(left.g, right.g), + scaledMul(left.b, right.b), + scaledMul(left.a, right.a)); +} + + +//////////////////////////////////////////////////////////// +constexpr Color& operator +=(Color& left, const Color& right) +{ + return left = left + right; +} + + +//////////////////////////////////////////////////////////// +constexpr Color& operator -=(Color& left, const Color& right) +{ + return left = left - right; +} + + +//////////////////////////////////////////////////////////// +constexpr Color& operator *=(Color& left, const Color& right) +{ + return left = left * right; +} diff --git a/src/SFML/Graphics/CMakeLists.txt b/src/SFML/Graphics/CMakeLists.txt index a939a988..36320089 100644 --- a/src/SFML/Graphics/CMakeLists.txt +++ b/src/SFML/Graphics/CMakeLists.txt @@ -8,6 +8,7 @@ set(SRC ${INCROOT}/BlendMode.hpp ${SRCROOT}/Color.cpp ${INCROOT}/Color.hpp + ${INCROOT}/Color.inl ${INCROOT}/Export.hpp ${SRCROOT}/Font.cpp ${INCROOT}/Font.hpp diff --git a/src/SFML/Graphics/Color.cpp b/src/SFML/Graphics/Color.cpp index c2429ee7..3289fc80 100644 --- a/src/SFML/Graphics/Color.cpp +++ b/src/SFML/Graphics/Color.cpp @@ -26,7 +26,6 @@ // Headers //////////////////////////////////////////////////////////// #include -#include namespace sf @@ -44,112 +43,4 @@ const Color Color::Magenta(255, 0, 255); const Color Color::Cyan(0, 255, 255); const Color Color::Transparent(0, 0, 0, 0); - -//////////////////////////////////////////////////////////// -Color::Color() : -r(0), -g(0), -b(0), -a(255) -{ - -} - - -//////////////////////////////////////////////////////////// -Color::Color(Uint8 red, Uint8 green, Uint8 blue, Uint8 alpha) : -r(red), -g(green), -b(blue), -a(alpha) -{ - -} - - -//////////////////////////////////////////////////////////// -Color::Color(Uint32 color) : -r(static_cast((color & 0xff000000) >> 24)), -g(static_cast((color & 0x00ff0000) >> 16)), -b((color & 0x0000ff00) >> 8 ), -a((color & 0x000000ff) >> 0 ) -{ - -} - - -//////////////////////////////////////////////////////////// -Uint32 Color::toInteger() const -{ - return static_cast((r << 24) | (g << 16) | (b << 8) | a); -} - - -//////////////////////////////////////////////////////////// -bool operator ==(const Color& left, const Color& right) -{ - return (left.r == right.r) && - (left.g == right.g) && - (left.b == right.b) && - (left.a == right.a); -} - - -//////////////////////////////////////////////////////////// -bool operator !=(const Color& left, const Color& right) -{ - return !(left == right); -} - - -//////////////////////////////////////////////////////////// -Color operator +(const Color& left, const Color& right) -{ - return Color(Uint8(std::min(int(left.r) + right.r, 255)), - Uint8(std::min(int(left.g) + right.g, 255)), - Uint8(std::min(int(left.b) + right.b, 255)), - Uint8(std::min(int(left.a) + right.a, 255))); -} - - -//////////////////////////////////////////////////////////// -Color operator -(const Color& left, const Color& right) -{ - return Color(Uint8(std::max(int(left.r) - right.r, 0)), - Uint8(std::max(int(left.g) - right.g, 0)), - Uint8(std::max(int(left.b) - right.b, 0)), - Uint8(std::max(int(left.a) - right.a, 0))); -} - - -//////////////////////////////////////////////////////////// -Color operator *(const Color& left, const Color& right) -{ - return Color(Uint8(int(left.r) * right.r / 255), - Uint8(int(left.g) * right.g / 255), - Uint8(int(left.b) * right.b / 255), - Uint8(int(left.a) * right.a / 255)); -} - - -//////////////////////////////////////////////////////////// -Color& operator +=(Color& left, const Color& right) -{ - return left = left + right; -} - - -//////////////////////////////////////////////////////////// -Color& operator -=(Color& left, const Color& right) -{ - return left = left - right; -} - - -//////////////////////////////////////////////////////////// -Color& operator *=(Color& left, const Color& right) -{ - return left = left * right; -} - } // namespace sf