From cfeb7651b5338cdf3e82961ed4f8f07120a2f057 Mon Sep 17 00:00:00 2001 From: Vittorio Romeo Date: Fri, 17 Dec 2021 07:36:50 +0100 Subject: [PATCH] Make 'Rect' a 'constexpr' class --- include/SFML/Graphics/Glsl.hpp | 1 + include/SFML/Graphics/Rect.hpp | 25 ++++----- include/SFML/Graphics/Rect.inl | 78 +++++++++++++++----------- include/SFML/Graphics/RenderTarget.hpp | 1 + include/SFML/Graphics/VertexBuffer.hpp | 1 + src/SFML/Graphics/VertexBuffer.cpp | 4 +- 6 files changed, 63 insertions(+), 47 deletions(-) diff --git a/include/SFML/Graphics/Glsl.hpp b/include/SFML/Graphics/Glsl.hpp index c21f6f438..00e372a34 100644 --- a/include/SFML/Graphics/Glsl.hpp +++ b/include/SFML/Graphics/Glsl.hpp @@ -32,6 +32,7 @@ #include #include #include +#include namespace sf diff --git a/include/SFML/Graphics/Rect.hpp b/include/SFML/Graphics/Rect.hpp index 685745536..fe257981d 100644 --- a/include/SFML/Graphics/Rect.hpp +++ b/include/SFML/Graphics/Rect.hpp @@ -29,7 +29,6 @@ // Headers //////////////////////////////////////////////////////////// #include -#include namespace sf @@ -50,7 +49,7 @@ public: /// Rect(0, 0, 0, 0)). /// //////////////////////////////////////////////////////////// - Rect(); + constexpr Rect(); //////////////////////////////////////////////////////////// /// \brief Construct the rectangle from its coordinates @@ -64,7 +63,7 @@ public: /// \param rectHeight Height of the rectangle /// //////////////////////////////////////////////////////////// - Rect(T rectLeft, T rectTop, T rectWidth, T rectHeight); + constexpr Rect(T rectLeft, T rectTop, T rectWidth, T rectHeight); //////////////////////////////////////////////////////////// /// \brief Construct the rectangle from position and size @@ -76,7 +75,7 @@ public: /// \param size Size of the rectangle /// //////////////////////////////////////////////////////////// - Rect(const Vector2& position, const Vector2& size); + constexpr Rect(const Vector2& position, const Vector2& size); //////////////////////////////////////////////////////////// /// \brief Construct the rectangle from another type of rectangle @@ -90,7 +89,7 @@ public: /// //////////////////////////////////////////////////////////// template - explicit Rect(const Rect& rectangle); + constexpr explicit Rect(const Rect& rectangle); //////////////////////////////////////////////////////////// /// \brief Check if a point is inside the rectangle's area @@ -106,7 +105,7 @@ public: /// \see intersects /// //////////////////////////////////////////////////////////// - bool contains(T x, T y) const; + constexpr bool contains(T x, T y) const; //////////////////////////////////////////////////////////// /// \brief Check if a point is inside the rectangle's area @@ -121,7 +120,7 @@ public: /// \see intersects /// //////////////////////////////////////////////////////////// - bool contains(const Vector2& point) const; + constexpr bool contains(const Vector2& point) const; //////////////////////////////////////////////////////////// /// \brief Check the intersection between two rectangles @@ -133,7 +132,7 @@ public: /// \see contains /// //////////////////////////////////////////////////////////// - bool intersects(const Rect& rectangle) const; + constexpr bool intersects(const Rect& rectangle) const; //////////////////////////////////////////////////////////// /// \brief Check the intersection between two rectangles @@ -149,7 +148,7 @@ public: /// \see contains /// //////////////////////////////////////////////////////////// - bool intersects(const Rect& rectangle, Rect& intersection) const; + constexpr bool intersects(const Rect& rectangle, Rect& intersection) const; //////////////////////////////////////////////////////////// /// \brief Get the position of the rectangle's top-left corner @@ -159,7 +158,7 @@ public: /// \see getSize /// //////////////////////////////////////////////////////////// - sf::Vector2 getPosition() const; + constexpr Vector2 getPosition() const; //////////////////////////////////////////////////////////// /// \brief Get the size of the rectangle @@ -169,7 +168,7 @@ public: /// \see getPosition /// //////////////////////////////////////////////////////////// - sf::Vector2 getSize() const; + constexpr Vector2 getSize() const; //////////////////////////////////////////////////////////// // Member data @@ -193,7 +192,7 @@ public: /// //////////////////////////////////////////////////////////// template -bool operator ==(const Rect& left, const Rect& right); +[[nodiscard]] constexpr bool operator ==(const Rect& left, const Rect& right); //////////////////////////////////////////////////////////// /// \relates Rect @@ -208,7 +207,7 @@ bool operator ==(const Rect& left, const Rect& right); /// //////////////////////////////////////////////////////////// template -bool operator !=(const Rect& left, const Rect& right); +[[nodiscard]] constexpr bool operator !=(const Rect& left, const Rect& right); #include diff --git a/include/SFML/Graphics/Rect.inl b/include/SFML/Graphics/Rect.inl index b6962fe16..ab51add9a 100644 --- a/include/SFML/Graphics/Rect.inl +++ b/include/SFML/Graphics/Rect.inl @@ -25,7 +25,7 @@ //////////////////////////////////////////////////////////// template -Rect::Rect() : +constexpr Rect::Rect() : left (0), top (0), width (0), @@ -37,7 +37,7 @@ height(0) //////////////////////////////////////////////////////////// template -Rect::Rect(T rectLeft, T rectTop, T rectWidth, T rectHeight) : +constexpr Rect::Rect(T rectLeft, T rectTop, T rectWidth, T rectHeight) : left (rectLeft), top (rectTop), width (rectWidth), @@ -49,7 +49,7 @@ height(rectHeight) //////////////////////////////////////////////////////////// template -Rect::Rect(const Vector2& position, const Vector2& size) : +constexpr Rect::Rect(const Vector2& position, const Vector2& size) : left (position.x), top (position.y), width (size.x), @@ -62,7 +62,7 @@ height(size.y) //////////////////////////////////////////////////////////// template template -Rect::Rect(const Rect& rectangle) : +constexpr Rect::Rect(const Rect& rectangle) : left (static_cast(rectangle.left)), top (static_cast(rectangle.top)), width (static_cast(rectangle.width)), @@ -73,15 +73,19 @@ height(static_cast(rectangle.height)) //////////////////////////////////////////////////////////// template -bool Rect::contains(T x, T y) const +constexpr bool Rect::contains(T x, T y) const { + // Not using 'std::min' and 'std::max' to avoid depending on '' + const auto min = [](T a, T b){ return (a < b) ? a : b; }; + const auto max = [](T a, T b){ return (a < b) ? b : a; }; + // Rectangles with negative dimensions are allowed, so we must handle them correctly // Compute the real min and max of the rectangle on both axes - T minX = std::min(left, static_cast(left + width)); - T maxX = std::max(left, static_cast(left + width)); - T minY = std::min(top, static_cast(top + height)); - T maxY = std::max(top, static_cast(top + height)); + const T minX = min(left, static_cast(left + width)); + const T maxX = max(left, static_cast(left + width)); + const T minY = min(top, static_cast(top + height)); + const T maxY = max(top, static_cast(top + height)); return (x >= minX) && (x < maxX) && (y >= minY) && (y < maxY); } @@ -89,7 +93,7 @@ bool Rect::contains(T x, T y) const //////////////////////////////////////////////////////////// template -bool Rect::contains(const Vector2& point) const +constexpr bool Rect::contains(const Vector2& point) const { return contains(point.x, point.y); } @@ -97,7 +101,7 @@ bool Rect::contains(const Vector2& point) const //////////////////////////////////////////////////////////// template -bool Rect::intersects(const Rect& rectangle) const +constexpr bool Rect::intersects(const Rect& rectangle) const { Rect intersection; return intersects(rectangle, intersection); @@ -106,27 +110,31 @@ bool Rect::intersects(const Rect& rectangle) const //////////////////////////////////////////////////////////// template -bool Rect::intersects(const Rect& rectangle, Rect& intersection) const +constexpr bool Rect::intersects(const Rect& rectangle, Rect& intersection) const { + // Not using 'std::min' and 'std::max' to avoid depending on '' + const auto min = [](T a, T b){ return (a < b) ? a : b; }; + const auto max = [](T a, T b){ return (a < b) ? b : a; }; + // Rectangles with negative dimensions are allowed, so we must handle them correctly // Compute the min and max of the first rectangle on both axes - T r1MinX = std::min(left, static_cast(left + width)); - T r1MaxX = std::max(left, static_cast(left + width)); - T r1MinY = std::min(top, static_cast(top + height)); - T r1MaxY = std::max(top, static_cast(top + height)); + const T r1MinX = min(left, static_cast(left + width)); + const T r1MaxX = max(left, static_cast(left + width)); + const T r1MinY = min(top, static_cast(top + height)); + const T r1MaxY = max(top, static_cast(top + height)); // Compute the min and max of the second rectangle on both axes - T r2MinX = std::min(rectangle.left, static_cast(rectangle.left + rectangle.width)); - T r2MaxX = std::max(rectangle.left, static_cast(rectangle.left + rectangle.width)); - T r2MinY = std::min(rectangle.top, static_cast(rectangle.top + rectangle.height)); - T r2MaxY = std::max(rectangle.top, static_cast(rectangle.top + rectangle.height)); + const T r2MinX = min(rectangle.left, static_cast(rectangle.left + rectangle.width)); + const T r2MaxX = max(rectangle.left, static_cast(rectangle.left + rectangle.width)); + const T r2MinY = min(rectangle.top, static_cast(rectangle.top + rectangle.height)); + const T r2MaxY = max(rectangle.top, static_cast(rectangle.top + rectangle.height)); // Compute the intersection boundaries - T interLeft = std::max(r1MinX, r2MinX); - T interTop = std::max(r1MinY, r2MinY); - T interRight = std::min(r1MaxX, r2MaxX); - T interBottom = std::min(r1MaxY, r2MaxY); + const T interLeft = max(r1MinX, r2MinX); + const T interTop = max(r1MinY, r2MinY); + const T interRight = min(r1MaxX, r2MaxX); + const T interBottom = min(r1MaxY, r2MaxY); // If the intersection is valid (positive non zero area), then there is an intersection if ((interLeft < interRight) && (interTop < interBottom)) @@ -141,22 +149,26 @@ bool Rect::intersects(const Rect& rectangle, Rect& intersection) const } } -template -sf::Vector2 Rect::getPosition() const -{ - return sf::Vector2(left, top); -} +//////////////////////////////////////////////////////////// template -sf::Vector2 Rect::getSize() const +constexpr Vector2 Rect::getPosition() const { - return sf::Vector2(width, height); + return Vector2(left, top); } //////////////////////////////////////////////////////////// template -inline bool operator ==(const Rect& left, const Rect& right) +constexpr Vector2 Rect::getSize() const +{ + return Vector2(width, height); +} + + +//////////////////////////////////////////////////////////// +template +constexpr bool operator ==(const Rect& left, const Rect& right) { return (left.left == right.left) && (left.width == right.width) && (left.top == right.top) && (left.height == right.height); @@ -165,7 +177,7 @@ inline bool operator ==(const Rect& left, const Rect& right) //////////////////////////////////////////////////////////// template -inline bool operator !=(const Rect& left, const Rect& right) +constexpr bool operator !=(const Rect& left, const Rect& right) { return !(left == right); } diff --git a/include/SFML/Graphics/RenderTarget.hpp b/include/SFML/Graphics/RenderTarget.hpp index 71b12dde1..95a874b4f 100644 --- a/include/SFML/Graphics/RenderTarget.hpp +++ b/include/SFML/Graphics/RenderTarget.hpp @@ -37,6 +37,7 @@ #include #include #include +#include namespace sf diff --git a/include/SFML/Graphics/VertexBuffer.hpp b/include/SFML/Graphics/VertexBuffer.hpp index f0b655768..edb523b00 100644 --- a/include/SFML/Graphics/VertexBuffer.hpp +++ b/include/SFML/Graphics/VertexBuffer.hpp @@ -32,6 +32,7 @@ #include #include #include +#include namespace sf diff --git a/src/SFML/Graphics/VertexBuffer.cpp b/src/SFML/Graphics/VertexBuffer.cpp index 366177d6a..1a98fceda 100644 --- a/src/SFML/Graphics/VertexBuffer.cpp +++ b/src/SFML/Graphics/VertexBuffer.cpp @@ -30,8 +30,10 @@ #include #include #include -#include #include +#include +#include +#include namespace {