Make 'Rect' a 'constexpr' class

This commit is contained in:
Vittorio Romeo 2021-12-17 07:36:50 +01:00
parent f6bd12c300
commit cfeb7651b5
6 changed files with 63 additions and 47 deletions

View File

@ -32,6 +32,7 @@
#include <SFML/Graphics/Color.hpp>
#include <SFML/System/Vector2.hpp>
#include <SFML/System/Vector3.hpp>
#include <cstddef>
namespace sf

View File

@ -29,7 +29,6 @@
// Headers
////////////////////////////////////////////////////////////
#include <SFML/System/Vector2.hpp>
#include <algorithm>
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<T>& position, const Vector2<T>& size);
constexpr Rect(const Vector2<T>& position, const Vector2<T>& size);
////////////////////////////////////////////////////////////
/// \brief Construct the rectangle from another type of rectangle
@ -90,7 +89,7 @@ public:
///
////////////////////////////////////////////////////////////
template <typename U>
explicit Rect(const Rect<U>& rectangle);
constexpr explicit Rect(const Rect<U>& 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<T>& point) const;
constexpr bool contains(const Vector2<T>& point) const;
////////////////////////////////////////////////////////////
/// \brief Check the intersection between two rectangles
@ -133,7 +132,7 @@ public:
/// \see contains
///
////////////////////////////////////////////////////////////
bool intersects(const Rect<T>& rectangle) const;
constexpr bool intersects(const Rect<T>& rectangle) const;
////////////////////////////////////////////////////////////
/// \brief Check the intersection between two rectangles
@ -149,7 +148,7 @@ public:
/// \see contains
///
////////////////////////////////////////////////////////////
bool intersects(const Rect<T>& rectangle, Rect<T>& intersection) const;
constexpr bool intersects(const Rect<T>& rectangle, Rect<T>& intersection) const;
////////////////////////////////////////////////////////////
/// \brief Get the position of the rectangle's top-left corner
@ -159,7 +158,7 @@ public:
/// \see getSize
///
////////////////////////////////////////////////////////////
sf::Vector2<T> getPosition() const;
constexpr Vector2<T> getPosition() const;
////////////////////////////////////////////////////////////
/// \brief Get the size of the rectangle
@ -169,7 +168,7 @@ public:
/// \see getPosition
///
////////////////////////////////////////////////////////////
sf::Vector2<T> getSize() const;
constexpr Vector2<T> getSize() const;
////////////////////////////////////////////////////////////
// Member data
@ -193,7 +192,7 @@ public:
///
////////////////////////////////////////////////////////////
template <typename T>
bool operator ==(const Rect<T>& left, const Rect<T>& right);
[[nodiscard]] constexpr bool operator ==(const Rect<T>& left, const Rect<T>& right);
////////////////////////////////////////////////////////////
/// \relates Rect
@ -208,7 +207,7 @@ bool operator ==(const Rect<T>& left, const Rect<T>& right);
///
////////////////////////////////////////////////////////////
template <typename T>
bool operator !=(const Rect<T>& left, const Rect<T>& right);
[[nodiscard]] constexpr bool operator !=(const Rect<T>& left, const Rect<T>& right);
#include <SFML/Graphics/Rect.inl>

View File

@ -25,7 +25,7 @@
////////////////////////////////////////////////////////////
template <typename T>
Rect<T>::Rect() :
constexpr Rect<T>::Rect() :
left (0),
top (0),
width (0),
@ -37,7 +37,7 @@ height(0)
////////////////////////////////////////////////////////////
template <typename T>
Rect<T>::Rect(T rectLeft, T rectTop, T rectWidth, T rectHeight) :
constexpr Rect<T>::Rect(T rectLeft, T rectTop, T rectWidth, T rectHeight) :
left (rectLeft),
top (rectTop),
width (rectWidth),
@ -49,7 +49,7 @@ height(rectHeight)
////////////////////////////////////////////////////////////
template <typename T>
Rect<T>::Rect(const Vector2<T>& position, const Vector2<T>& size) :
constexpr Rect<T>::Rect(const Vector2<T>& position, const Vector2<T>& size) :
left (position.x),
top (position.y),
width (size.x),
@ -62,7 +62,7 @@ height(size.y)
////////////////////////////////////////////////////////////
template <typename T>
template <typename U>
Rect<T>::Rect(const Rect<U>& rectangle) :
constexpr Rect<T>::Rect(const Rect<U>& rectangle) :
left (static_cast<T>(rectangle.left)),
top (static_cast<T>(rectangle.top)),
width (static_cast<T>(rectangle.width)),
@ -73,15 +73,19 @@ height(static_cast<T>(rectangle.height))
////////////////////////////////////////////////////////////
template <typename T>
bool Rect<T>::contains(T x, T y) const
constexpr bool Rect<T>::contains(T x, T y) const
{
// Not using 'std::min' and 'std::max' to avoid depending on '<algorithm>'
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<T>(left + width));
T maxX = std::max(left, static_cast<T>(left + width));
T minY = std::min(top, static_cast<T>(top + height));
T maxY = std::max(top, static_cast<T>(top + height));
const T minX = min(left, static_cast<T>(left + width));
const T maxX = max(left, static_cast<T>(left + width));
const T minY = min(top, static_cast<T>(top + height));
const T maxY = max(top, static_cast<T>(top + height));
return (x >= minX) && (x < maxX) && (y >= minY) && (y < maxY);
}
@ -89,7 +93,7 @@ bool Rect<T>::contains(T x, T y) const
////////////////////////////////////////////////////////////
template <typename T>
bool Rect<T>::contains(const Vector2<T>& point) const
constexpr bool Rect<T>::contains(const Vector2<T>& point) const
{
return contains(point.x, point.y);
}
@ -97,7 +101,7 @@ bool Rect<T>::contains(const Vector2<T>& point) const
////////////////////////////////////////////////////////////
template <typename T>
bool Rect<T>::intersects(const Rect<T>& rectangle) const
constexpr bool Rect<T>::intersects(const Rect<T>& rectangle) const
{
Rect<T> intersection;
return intersects(rectangle, intersection);
@ -106,27 +110,31 @@ bool Rect<T>::intersects(const Rect<T>& rectangle) const
////////////////////////////////////////////////////////////
template <typename T>
bool Rect<T>::intersects(const Rect<T>& rectangle, Rect<T>& intersection) const
constexpr bool Rect<T>::intersects(const Rect<T>& rectangle, Rect<T>& intersection) const
{
// Not using 'std::min' and 'std::max' to avoid depending on '<algorithm>'
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<T>(left + width));
T r1MaxX = std::max(left, static_cast<T>(left + width));
T r1MinY = std::min(top, static_cast<T>(top + height));
T r1MaxY = std::max(top, static_cast<T>(top + height));
const T r1MinX = min(left, static_cast<T>(left + width));
const T r1MaxX = max(left, static_cast<T>(left + width));
const T r1MinY = min(top, static_cast<T>(top + height));
const T r1MaxY = max(top, static_cast<T>(top + height));
// Compute the min and max of the second rectangle on both axes
T r2MinX = std::min(rectangle.left, static_cast<T>(rectangle.left + rectangle.width));
T r2MaxX = std::max(rectangle.left, static_cast<T>(rectangle.left + rectangle.width));
T r2MinY = std::min(rectangle.top, static_cast<T>(rectangle.top + rectangle.height));
T r2MaxY = std::max(rectangle.top, static_cast<T>(rectangle.top + rectangle.height));
const T r2MinX = min(rectangle.left, static_cast<T>(rectangle.left + rectangle.width));
const T r2MaxX = max(rectangle.left, static_cast<T>(rectangle.left + rectangle.width));
const T r2MinY = min(rectangle.top, static_cast<T>(rectangle.top + rectangle.height));
const T r2MaxY = max(rectangle.top, static_cast<T>(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<T>::intersects(const Rect<T>& rectangle, Rect<T>& intersection) const
}
}
template <typename T>
sf::Vector2<T> Rect<T>::getPosition() const
{
return sf::Vector2<T>(left, top);
}
////////////////////////////////////////////////////////////
template <typename T>
sf::Vector2<T> Rect<T>::getSize() const
constexpr Vector2<T> Rect<T>::getPosition() const
{
return sf::Vector2<T>(width, height);
return Vector2<T>(left, top);
}
////////////////////////////////////////////////////////////
template <typename T>
inline bool operator ==(const Rect<T>& left, const Rect<T>& right)
constexpr Vector2<T> Rect<T>::getSize() const
{
return Vector2<T>(width, height);
}
////////////////////////////////////////////////////////////
template <typename T>
constexpr bool operator ==(const Rect<T>& left, const Rect<T>& 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<T>& left, const Rect<T>& right)
////////////////////////////////////////////////////////////
template <typename T>
inline bool operator !=(const Rect<T>& left, const Rect<T>& right)
constexpr bool operator !=(const Rect<T>& left, const Rect<T>& right)
{
return !(left == right);
}

View File

@ -37,6 +37,7 @@
#include <SFML/Graphics/RenderStates.hpp>
#include <SFML/Graphics/PrimitiveType.hpp>
#include <SFML/Graphics/Vertex.hpp>
#include <cstddef>
namespace sf

View File

@ -32,6 +32,7 @@
#include <SFML/Graphics/PrimitiveType.hpp>
#include <SFML/Graphics/Drawable.hpp>
#include <SFML/Window/GlResource.hpp>
#include <cstddef>
namespace sf

View File

@ -30,8 +30,10 @@
#include <SFML/Graphics/Vertex.hpp>
#include <SFML/Graphics/GLCheck.hpp>
#include <SFML/System/Err.hpp>
#include <cstring>
#include <mutex>
#include <utility>
#include <cstddef>
#include <cstring>
namespace
{