Fix MSYS2 issues
[xonotic/netradiant.git] / libs / generic / vector.h
1
2 #if !defined( INCLUDED_VECTOR_H )
3 #define INCLUDED_VECTOR_H
4
5 #include <cstddef>
6
7 template <typename Element>
8 class BasicVector2
9 {
10 Element m_elements[2];
11 public:
12 BasicVector2(){
13 }
14 BasicVector2( const Element& x_, const Element& y_ ){
15         x() = x_;
16         y() = y_;
17 }
18
19 Element& x(){
20         return m_elements[0];
21 }
22 const Element& x() const {
23         return m_elements[0];
24 }
25 Element& y(){
26         return m_elements[1];
27 }
28 const Element& y() const {
29         return m_elements[1];
30 }
31
32 const Element& operator[]( std::size_t i ) const {
33         return m_elements[i];
34 }
35 Element& operator[]( std::size_t i ){
36         return m_elements[i];
37 }
38
39 Element* data(){
40         return m_elements;
41 }
42 const Element* data() const {
43         return m_elements;
44 }
45 };
46
47 /// \brief A 3-element vector.
48 template<typename Element>
49 class BasicVector3
50 {
51 Element m_elements[3];
52 public:
53
54 BasicVector3(){
55 }
56 template<typename OtherElement>
57 BasicVector3( const BasicVector3<OtherElement>& other ){
58         x() = static_cast<Element>( other.x() );
59         y() = static_cast<Element>( other.y() );
60         z() = static_cast<Element>( other.z() );
61 }
62 BasicVector3( const Element& x_, const Element& y_, const Element& z_ ){
63         x() = x_;
64         y() = y_;
65         z() = z_;
66 }
67
68 Element& x(){
69         return m_elements[0];
70 }
71 const Element& x() const {
72         return m_elements[0];
73 }
74 Element& y(){
75         return m_elements[1];
76 }
77 const Element& y() const {
78         return m_elements[1];
79 }
80 Element& z(){
81         return m_elements[2];
82 }
83 const Element& z() const {
84         return m_elements[2];
85 }
86
87 const Element& operator[]( std::size_t i ) const {
88         return m_elements[i];
89 }
90 Element& operator[]( std::size_t i ){
91         return m_elements[i];
92 }
93
94 Element* data(){
95         return m_elements;
96 }
97 const Element* data() const {
98         return m_elements;
99 }
100 };
101
102 /// \brief A 4-element vector.
103 template<typename Element>
104 class BasicVector4
105 {
106 Element m_elements[4];
107 public:
108
109 BasicVector4(){
110 }
111 BasicVector4( Element x_, Element y_, Element z_, Element w_ ){
112         x() = x_;
113         y() = y_;
114         z() = z_;
115         w() = w_;
116 }
117 BasicVector4( const BasicVector3<Element>& self, Element w_ ){
118         x() = self.x();
119         y() = self.y();
120         z() = self.z();
121         w() = w_;
122 }
123
124 Element& x(){
125         return m_elements[0];
126 }
127 const Element& x() const {
128         return m_elements[0];
129 }
130 Element& y(){
131         return m_elements[1];
132 }
133 const Element& y() const {
134         return m_elements[1];
135 }
136 Element& z(){
137         return m_elements[2];
138 }
139 const Element& z() const {
140         return m_elements[2];
141 }
142 Element& w(){
143         return m_elements[3];
144 }
145 const Element& w() const {
146         return m_elements[3];
147 }
148
149 Element index( std::size_t i ) const {
150         return m_elements[i];
151 }
152 Element& index( std::size_t i ){
153         return m_elements[i];
154 }
155 Element operator[]( std::size_t i ) const {
156         return m_elements[i];
157 }
158 Element& operator[]( std::size_t i ){
159         return m_elements[i];
160 }
161
162 Element* data(){
163         return m_elements;
164 }
165 const Element* data() const {
166         return m_elements;
167 }
168 };
169
170 template<typename Element>
171 inline BasicVector3<Element> vector3_from_array( const Element* array ){
172         return BasicVector3<Element>( array[0], array[1], array[2] );
173 }
174
175 template<typename Element>
176 inline Element* vector3_to_array( BasicVector3<Element>& self ){
177         return self.data();
178 }
179 template<typename Element>
180 inline const Element* vector3_to_array( const BasicVector3<Element>& self ){
181         return self.data();
182 }
183
184 template<typename Element>
185 inline Element* vector4_to_array( BasicVector4<Element>& self ){
186         return self.data();
187 }
188 template<typename Element>
189 inline const Element* vector4_to_array( const BasicVector4<Element>& self ){
190         return self.data();
191 }
192
193 template<typename Element>
194 inline BasicVector3<Element>& vector4_to_vector3( BasicVector4<Element>& self ){
195         return *reinterpret_cast<BasicVector3<Element>*>( vector4_to_array( self ) );
196 }
197 template<typename Element>
198 inline const BasicVector3<Element>& vector4_to_vector3( const BasicVector4<Element>& self ){
199         return *reinterpret_cast<const BasicVector3<Element>*>( vector4_to_array( self ) );
200 }
201
202 /// \brief A 2-element vector stored in single-precision floating-point.
203 typedef BasicVector2<float> Vector2;
204
205 /// \brief A 3-element vector stored in single-precision floating-point.
206 typedef BasicVector3<float> Vector3;
207
208 /// \brief A 4-element vector stored in single-precision floating-point.
209 typedef BasicVector4<float> Vector4;
210
211
212 #endif