Use std::optional to remove extra sf::Rect::intersects overload

This commit is contained in:
Chris Thrasher 2021-12-31 16:42:53 -07:00 committed by Vittorio Romeo
parent 0ad6d1815c
commit 7c80f302e4
3 changed files with 19 additions and 57 deletions

View File

@ -29,6 +29,7 @@
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/System/Vector2.hpp> #include <SFML/System/Vector2.hpp>
#include <optional>
namespace sf namespace sf
@ -87,7 +88,7 @@ public:
/// ///
/// \return True if the point is inside, false otherwise /// \return True if the point is inside, false otherwise
/// ///
/// \see intersects /// \see findIntersection
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
constexpr bool contains(const Vector2<T>& point) const; constexpr bool contains(const Vector2<T>& point) const;
@ -97,28 +98,12 @@ public:
/// ///
/// \param rectangle Rectangle to test /// \param rectangle Rectangle to test
/// ///
/// \return True if rectangles overlap, false otherwise /// \return Intersection rectangle if intersecting, std::nullopt otherwise
/// ///
/// \see contains /// \see contains
/// ///
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
constexpr bool intersects(const Rect<T>& rectangle) const; constexpr std::optional<Rect<T>> findIntersection(const Rect<T>& rectangle) const;
////////////////////////////////////////////////////////////
/// \brief Check the intersection between two rectangles
///
/// This overload returns the overlapped rectangle in the
/// \a intersection parameter.
///
/// \param rectangle Rectangle to test
/// \param intersection Rectangle to be filled with the intersection
///
/// \return True if rectangles overlap, false otherwise
///
/// \see contains
///
////////////////////////////////////////////////////////////
constexpr bool intersects(const Rect<T>& rectangle, Rect<T>& intersection) const;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Get the position of the rectangle's top-left corner /// \brief Get the position of the rectangle's top-left corner
@ -236,7 +221,7 @@ using FloatRect = Rect<float>;
/// ///
/// // Test the intersection between r1 and r2 /// // Test the intersection between r1 and r2
/// sf::IntRect result; /// sf::IntRect result;
/// bool b3 = r1.intersects(r2, result); // true /// bool b3 = r1.findIntersection(r2, result); // true
/// // result == (4, 2, 16, 3) /// // result == (4, 2, 16, 3)
/// \endcode /// \endcode
/// ///

View File

@ -81,16 +81,7 @@ constexpr bool Rect<T>::contains(const Vector2<T>& point) const
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
template <typename T> template <typename T>
constexpr bool Rect<T>::intersects(const Rect<T>& rectangle) const constexpr std::optional<Rect<T>> Rect<T>::findIntersection(const Rect<T>& rectangle) const
{
Rect<T> intersection;
return intersects(rectangle, intersection);
}
////////////////////////////////////////////////////////////
template <typename T>
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>' // 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 min = [](T a, T b){ return (a < b) ? a : b; };
@ -119,13 +110,11 @@ constexpr bool Rect<T>::intersects(const Rect<T>& rectangle, Rect<T>& intersecti
// If the intersection is valid (positive non zero area), then there is an intersection // If the intersection is valid (positive non zero area), then there is an intersection
if ((interLeft < interRight) && (interTop < interBottom)) if ((interLeft < interRight) && (interTop < interBottom))
{ {
intersection = Rect<T>({interLeft, interTop}, {interRight - interLeft, interBottom - interTop}); return Rect<T>({interLeft, interTop}, {interRight - interLeft, interBottom - interTop});
return true;
} }
else else
{ {
intersection = Rect<T>({0, 0}, {0, 0}); return std::nullopt;
return false;
} }
} }

View File

@ -69,31 +69,19 @@ TEST_CASE("sf::Rect class template - [graphics]")
SUBCASE("Intersection") SUBCASE("Intersection")
{ {
SUBCASE("intersects(Rect)") const sf::IntRect rectangle({0, 0}, {10, 10});
{ const sf::IntRect intersectingRectangle({5, 5}, {10, 10});
sf::IntRect rectangle({0, 0}, {10, 10});
sf::IntRect intersectingRectangle({5, 5}, {10, 10});
sf::IntRect nonIntersectingRectangle({-5, -5}, {5, 5});
CHECK(rectangle.intersects(intersectingRectangle) == true); const auto intersectionResult = rectangle.findIntersection(intersectingRectangle);
CHECK(rectangle.intersects(nonIntersectingRectangle) == false); REQUIRE(intersectionResult.has_value());
} CHECK(intersectionResult->top == 5);
CHECK(intersectionResult->left == 5);
CHECK(intersectionResult->width == 5);
CHECK(intersectionResult->height == 5);
SUBCASE("intersects(Rect, Rect)") const sf::IntRect nonIntersectingRectangle({-5, -5}, {5, 5});
{ CHECK_FALSE(rectangle.findIntersection(nonIntersectingRectangle).has_value());
sf::IntRect rectangle({0, 0}, {10, 10}); CHECK_FALSE(rectangle.findIntersection(nonIntersectingRectangle));
sf::IntRect intersectingRectangle({5, 5}, {10, 10});
sf::IntRect nonIntersectingRectangle({-5, -5}, {5, 5});
sf::IntRect intersectionResult;
CHECK(rectangle.intersects(intersectingRectangle, intersectionResult) == true);
CHECK(intersectionResult.top == 5);
CHECK(intersectionResult.left == 5);
CHECK(intersectionResult.width == 5);
CHECK(intersectionResult.height == 5);
CHECK(rectangle.intersects(nonIntersectingRectangle, intersectionResult) == false);
}
} }
SUBCASE("Comparison operations") SUBCASE("Comparison operations")