Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: sf::Rect  (Read 2120 times)

0 Members and 1 Guest are viewing this topic.

Garwin

  • Jr. Member
  • **
  • Posts: 59
    • View Profile
sf::Rect
« on: February 04, 2024, 09:12:06 am »
I have looked at the implementation of the Rectangle class and I was surprised to find static_cast.

Why is static_cast there?

from SFML 3.0 branch
template <typename T>
constexpr bool Rect<T>::contains(const Vector2<T>& point) const
{
    // Not using &#39;std::min&#39; and &#39;std::max&#39; to avoid depending on &#39;<algorithm>&#39;
    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
    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 (point.x >= minX) && (point.x < maxX) && (point.y >= minY) && (point.y < maxY);
}
 

kojack

  • Sr. Member
  • ****
  • Posts: 343
  • C++/C# game dev teacher.
    • View Profile
Re: sf::Rect
« Reply #1 on: February 04, 2024, 10:13:36 am »
I would guess it's there to make sure the type is T to match the min and max signature.
For integer datatypes, the type of the result of a + is not always the type of the two operands. If you have a Rect<short>, then left and width are shorts, but left+width is an int.
(From cppreference.com: "In particular, arithmetic operators do not accept types smaller than int as arguments")

Garwin

  • Jr. Member
  • **
  • Posts: 59
    • View Profile
Re: sf::Rect
« Reply #2 on: February 05, 2024, 05:29:14 pm »
I would guess it's there to make sure the type is T to match the min and max signature.
For integer datatypes, the type of the result of a + is not always the type of the two operands. If you have a Rect<short>, then left and width are shorts, but left+width is an int.
(From cppreference.com: "In particular, arithmetic operators do not accept types smaller than int as arguments")
Thanks, forgot about this specifiation.

kojack

  • Sr. Member
  • ****
  • Posts: 343
  • C++/C# game dev teacher.
    • View Profile
Re: sf::Rect
« Reply #3 on: February 05, 2024, 10:44:21 pm »
I'd forgotten too, had a suspicion and had to google around to verify. :)

I assume without the static cast it would just give some warnings during the build about having to truncate ints to smaller types (if a Rect<short or char> was used) but would otherwise work. Floats or doubles wouldn't need the cast.

Or maybe the template would get confused. I should test it, I'm curious now.

Garwin

  • Jr. Member
  • **
  • Posts: 59
    • View Profile
Re: sf::Rect
« Reply #4 on: February 10, 2024, 12:16:00 pm »
Good, there is static_cast to show an intention.

However, a much more difficult area is floating point math and comparison of floating points. Mostly, you want the warning as it is unintentional but there are cases in which you want to compare floating points for equality and there is no way to tell the compiler to ignore this case and not issue a warning.