]> git.localhorst.tv Git - space.git/blob - src/graphics/Vector.h
Vector<int> : SDL_Point optimization
[space.git] / src / graphics / Vector.h
1 #ifndef SPACE_VECTOR_H_
2 #define SPACE_VECTOR_H_
3
4 #include <algorithm>
5 #include <ostream>
6 #include <SDL.h>
7
8
9 namespace space {
10
11 template<class Scalar>
12 class Vector {
13
14 public:
15         constexpr Vector() : x(0), y(0) { }
16         constexpr Vector(Scalar x, Scalar y) : x(x), y(y) { }
17
18         template<class Other>
19         constexpr Vector(Vector<Other> other) : x(other.x), y(other.y) { }
20
21 public:
22         Vector<Scalar> &operator +=(Vector<Scalar> other) {
23                 x += other.x;
24                 y += other.y;
25                 return *this;
26         }
27         Vector<Scalar> &operator -=(Vector<Scalar> other) {
28                 x -= other.x;
29                 y -= other.y;
30                 return *this;
31         }
32
33         SDL_Point ToPoint() const {
34                 SDL_Point p;
35                 p.x = x;
36                 p.y = y;
37                 return p;
38         }
39
40 public:
41         Scalar x;
42         Scalar y;
43
44 };
45
46 /// specialization with same layout as SDL_Point
47 template<>
48 class Vector<int>
49 : public SDL_Point {
50
51 public:
52         constexpr Vector() : SDL_Point({0, 0}) { }
53         constexpr Vector(int x, int y) : SDL_Point({x, y}) { }
54
55         template<class Other>
56         constexpr Vector(Vector<Other> other)
57         : SDL_Point({int(other.x), int(other.y)}) { }
58
59 public:
60         Vector<int> &operator +=(Vector<int> other) {
61                 x += other.x;
62                 y += other.y;
63                 return *this;
64         }
65         Vector<int> &operator -=(Vector<int> other) {
66                 x -= other.x;
67                 y -= other.y;
68                 return *this;
69         }
70
71         SDL_Point ToPoint() const {
72                 return *this;
73         }
74
75 };
76
77
78 template<class Scalar>
79 constexpr Vector<Scalar> operator -(Vector<Scalar> v) {
80         return Vector<Scalar>(-v.x, -v.y);
81 }
82
83
84 template<class Scalar>
85 constexpr Vector<Scalar> operator +(Vector<Scalar> lhs, Vector<Scalar> rhs) {
86         return Vector<Scalar>(lhs.x + rhs.x, lhs.y + rhs.y);
87 }
88
89 template<class Scalar>
90 constexpr Vector<Scalar> operator -(Vector<Scalar> lhs, Vector<Scalar> rhs) {
91         return Vector<Scalar>(lhs.x - rhs.x, lhs.y - rhs.y);
92 }
93
94
95 template<class Scalar>
96 constexpr Vector<Scalar> operator *(Vector<Scalar> lhs, Scalar rhs) {
97         return Vector<Scalar>(lhs.x * rhs, lhs.y * rhs);
98 }
99
100 template<class Scalar>
101 constexpr Vector<Scalar> operator *(Scalar lhs, Vector<Scalar> rhs) {
102         return rhs * lhs;
103 }
104 template<class Scalar>
105 constexpr Vector<Scalar> operator *(Vector<Scalar> lhs, Vector<Scalar> rhs) {
106         return Vector<Scalar>(lhs.x * rhs.x, lhs.y * rhs.y);
107 }
108
109
110 template<class Scalar>
111 constexpr Vector<Scalar> operator /(Vector<Scalar> lhs, Scalar rhs) {
112         return Vector<Scalar>(lhs.x / rhs, lhs.y / rhs);
113 }
114
115 template<class Scalar>
116 constexpr Vector<Scalar> operator /(Scalar lhs, Vector<Scalar> rhs) {
117         return rhs / lhs;
118 }
119 template<class Scalar>
120 constexpr Vector<Scalar> operator /(Vector<Scalar> lhs, Vector<Scalar> rhs) {
121         return Vector<Scalar>(lhs.x / rhs.x, lhs.y / rhs.y);
122 }
123
124
125 template<class Scalar>
126 constexpr bool operator ==(Vector<Scalar> lhs, Vector<Scalar> rhs) {
127         return lhs.x == rhs.x && lhs.y == rhs.y;
128 }
129 template<class Scalar>
130 constexpr bool operator !=(Vector<Scalar> lhs, Vector<Scalar> rhs) {
131         return lhs.x != rhs.x && lhs.y != rhs.y;
132 }
133
134
135 template<class Scalar>
136 inline std::ostream &operator <<(std::ostream &out, Vector<Scalar> v) {
137         return out << '<' << v.x << ',' << v.y << '>';
138 }
139
140 }
141
142
143 namespace std {
144
145 template<class Scalar>
146 constexpr space::Vector<Scalar> min(
147                 space::Vector<Scalar> lhs,
148                 space::Vector<Scalar> rhs
149 ) {
150         return space::Vector<Scalar>(
151                 min(lhs.x, rhs.x),
152                 min(lhs.y, rhs.y)
153         );
154 }
155
156 template<class Scalar>
157 constexpr space::Vector<Scalar> max(
158                 space::Vector<Scalar> lhs,
159                 space::Vector<Scalar> rhs
160 ) {
161         return space::Vector<Scalar>(
162                 max(lhs.x, rhs.x),
163                 max(lhs.y, rhs.y)
164         );
165 }
166
167 }
168
169 #endif