-
Notifications
You must be signed in to change notification settings - Fork 0
/
Rectangle.hpp
78 lines (66 loc) · 2.34 KB
/
Rectangle.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#pragma once
#include "Vector.hpp"
namespace MathsCPP {
template<typename T, typename = std::enable_if_t<std::is_arithmetic_v<T>>>
class Rectangle {
public:
constexpr Rectangle() = default;
constexpr Rectangle(T x, T y, T w = 0, T h = 0) : x(x), y(y), w(w), h(h) {}
template<typename T1>
constexpr Rectangle(const Rectangle<T1> &r) : x(r.x), y(r.y), w(r.w), h(r.h) {}
template<typename T1, typename T2>
constexpr Rectangle(const Vector<T1, 2> &xy, const Vector<T2, 2> &wh) : x(xy.x), y(xy.y), w(wh.x), h(wh.y) {}
template<typename T1>
constexpr Rectangle &operator=(const Rectangle<T1> &r) {
x = r.x, y = r.y, w = r.w, h = r.h;
return *this;
}
template<typename T1>
constexpr friend auto operator+(const Rectangle &lhs, const Rectangle<T1> &rhs) {
Rectangle<decltype(lhs.x + rhs.x)> result;
result.x = lhs.x + rhs.x;
result.y = lhs.y + rhs.y;
result.w = lhs.w;
result.h = rhs.h;
return result;
}
template<typename T1>
constexpr friend auto operator*(const Rectangle &lhs, const Rectangle<T1> &rhs) {
Rectangle<decltype(lhs.x + rhs.x)> result;
result.x = lhs.x + rhs.x;
result.y = lhs.y + rhs.y;
result.w = std::min(lhs.w, rhs.w - lhs.x);
result.h = std::min(lhs.h, rhs.h - lhs.y);
return result;
}
template<typename T1>
constexpr friend auto operator+=(Rectangle &lhs, const Rectangle<T1> &rhs) {
return lhs = lhs + rhs;
}
template<typename T1>
constexpr friend auto operator*=(Rectangle &lhs, const Rectangle<T1> &rhs) {
return lhs = lhs * rhs;
}
constexpr const Vector<T, 2> &xy() const { return *reinterpret_cast<const Vector<T, 2> *>(this); }
constexpr Vector<T, 2> &xy() { return *reinterpret_cast<Vector<T, 2> *>(this); }
constexpr const Vector<T, 2> &wh() const { return *reinterpret_cast<const Vector<T, 2> *>(this + (2 * sizeof(T))); }
constexpr Vector<T, 2> &wh() { return *reinterpret_cast<Vector<T, 2> *>(this + (2 * sizeof(T))); }
T x{}, y{};
T w{}, h{};
};
using Rectanglef = Rectangle<float>;
using Rectangled = Rectangle<double>;
using Rectanglei = Rectangle<int32_t>;
using Rectangleui = Rectangle<uint32_t>;
}
namespace std {
template<typename T>
struct hash<MathsCPP::Rectangle<T>> {
size_t operator()(const MathsCPP::Rectangle<T> &rectangle) const noexcept {
size_t seed = 0;
MathsCPP::Maths::HashCombine(seed, rectangle.xy());
MathsCPP::Maths::HashCombine(seed, rectangle.wh());
return seed;
}
};
}