Add std::hash support for Point and Rect

This commit is contained in:
Dmitry Marakasov 2015-11-26 13:42:16 +03:00
parent a63cdde38f
commit fa3cb7bcd9
3 changed files with 60 additions and 0 deletions

View File

@ -23,6 +23,7 @@
#define SDL2PP_POINT_HH
#include <iostream>
#include <functional>
#include <SDL2/SDL_rect.h>
@ -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<SDL2pp::Point> {
size_t operator()(const SDL2pp::Point& p) const {
size_t seed = std::hash<int>()(p.x);
seed ^= std::hash<int>()(p.y) + 0x9e3779b9 + (seed<<6) + (seed>>2);
return seed;
}
};
}
#endif

View File

@ -22,6 +22,8 @@
#ifndef SDL2PP_RECT_HH
#define SDL2PP_RECT_HH
#include <functional>
#include <SDL2/SDL_rect.h>
#include <SDL2pp/Optional.hh>
@ -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<SDL2pp::Rect> {
size_t operator()(const SDL2pp::Rect& r) const {
size_t seed = std::hash<int>()(r.x);
seed ^= std::hash<int>()(r.y) + 0x9e3779b9 + (seed<<6) + (seed>>2);
seed ^= std::hash<int>()(r.w) + 0x9e3779b9 + (seed<<6) + (seed>>2);
seed ^= std::hash<int>()(r.h) + 0x9e3779b9 + (seed<<6) + (seed>>2);
return seed;
}
};
}
#endif

View File

@ -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>()(Point(123, 456)) == std::hash<Point>()(Point(123, 456)));
EXPECT_TRUE(std::hash<Point>()(Point(0, 0)) != std::hash<Point>()(Point(0, 1)));
EXPECT_TRUE(std::hash<Point>()(Point(0, 0)) != std::hash<Point>()(Point(1, 0)));
EXPECT_TRUE(std::hash<Point>()(Point(1, 0)) != std::hash<Point>()(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>()(Rect(1, 2, 3, 4)) == std::hash<Rect>()(Rect(1, 2, 3, 4)));
EXPECT_TRUE(std::hash<Rect>()(Rect(1, 2, 3, 4)) != std::hash<Rect>()(Rect(2, 1, 3, 4)));
EXPECT_TRUE(std::hash<Rect>()(Rect(1, 2, 3, 4)) != std::hash<Rect>()(Rect(1, 2, 4, 3)));
}
{
// Construction from and comparison with SDL objects
SDL_Rect sdlrect = { 1, 2, 3, 4 };