diff --git a/SDL2pp/Point.hh b/SDL2pp/Point.hh index 87123c1..3b9c693 100644 --- a/SDL2pp/Point.hh +++ b/SDL2pp/Point.hh @@ -23,6 +23,7 @@ #define SDL2PP_POINT_HH #include +#include #include @@ -471,4 +472,25 @@ bool operator<(const SDL2pp::Point& a, const SDL2pp::Point& b); //////////////////////////////////////////////////////////// std::ostream& operator<<(std::ostream& stream, const SDL2pp::Point& point); +namespace std { + +//////////////////////////////////////////////////////////// +/// \brief Hash function for SDL2pp::Point +/// +/// \param[in] p Input Point +/// +/// \returns Hash value +/// +//////////////////////////////////////////////////////////// +template<> +struct hash { + size_t operator()(const SDL2pp::Point& p) const { + size_t seed = std::hash()(p.x); + seed ^= std::hash()(p.y) + 0x9e3779b9 + (seed<<6) + (seed>>2); + return seed; + } +}; + +} + #endif diff --git a/SDL2pp/Rect.hh b/SDL2pp/Rect.hh index 0d1252d..4efeb2d 100644 --- a/SDL2pp/Rect.hh +++ b/SDL2pp/Rect.hh @@ -22,6 +22,8 @@ #ifndef SDL2PP_RECT_HH #define SDL2PP_RECT_HH +#include + #include #include @@ -545,4 +547,27 @@ bool operator<(const SDL2pp::Rect& a, const SDL2pp::Rect& b); //////////////////////////////////////////////////////////// std::ostream& operator<<(std::ostream& stream, const SDL2pp::Rect& rect); +namespace std { + +//////////////////////////////////////////////////////////// +/// \brief Hash function for SDL2pp::Rect +/// +/// \param[in] r Input Rect +/// +/// \returns Hash value +/// +//////////////////////////////////////////////////////////// +template<> +struct hash { + size_t operator()(const SDL2pp::Rect& r) const { + size_t seed = std::hash()(r.x); + seed ^= std::hash()(r.y) + 0x9e3779b9 + (seed<<6) + (seed>>2); + seed ^= std::hash()(r.w) + 0x9e3779b9 + (seed<<6) + (seed>>2); + seed ^= std::hash()(r.h) + 0x9e3779b9 + (seed<<6) + (seed>>2); + return seed; + } +}; + +} + #endif diff --git a/tests/test_pointrect.cc b/tests/test_pointrect.cc index e11cc08..1d7dc66 100644 --- a/tests/test_pointrect.cc +++ b/tests/test_pointrect.cc @@ -91,6 +91,12 @@ BEGIN_TEST() EXPECT_TRUE(!(Point(1, 1) < Point(0, 1))); EXPECT_TRUE(!(Point(0, 1) < Point(0, 0))); EXPECT_TRUE(!(Point(1, 1) < Point(1, 1))); + + // Hashes + EXPECT_TRUE(std::hash()(Point(123, 456)) == std::hash()(Point(123, 456))); + EXPECT_TRUE(std::hash()(Point(0, 0)) != std::hash()(Point(0, 1))); + EXPECT_TRUE(std::hash()(Point(0, 0)) != std::hash()(Point(1, 0))); + EXPECT_TRUE(std::hash()(Point(1, 0)) != std::hash()(Point(0, 1))); } { @@ -331,6 +337,13 @@ BEGIN_TEST() EXPECT_TRUE(!(Rect(1, 0, 0, 0) < Rect(1, 0, 0, 0))); } + { + // Hashes + EXPECT_TRUE(std::hash()(Rect(1, 2, 3, 4)) == std::hash()(Rect(1, 2, 3, 4))); + EXPECT_TRUE(std::hash()(Rect(1, 2, 3, 4)) != std::hash()(Rect(2, 1, 3, 4))); + EXPECT_TRUE(std::hash()(Rect(1, 2, 3, 4)) != std::hash()(Rect(1, 2, 4, 3))); + } + { // Construction from and comparison with SDL objects SDL_Rect sdlrect = { 1, 2, 3, 4 };