]> git.cworth.org Git - vogl/blob - src/voglcore/vogl_vector2d.h
Initial vogl checkin
[vogl] / src / voglcore / vogl_vector2d.h
1 /**************************************************************************
2  *
3  * Copyright 2013-2014 RAD Game Tools and Valve Software
4  * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
5  * All Rights Reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  *
25  **************************************************************************/
26
27 // File: vogl_vector2d.h
28 #pragma once
29
30 #include "vogl_core.h"
31
32 namespace vogl
33 {
34     template <typename T>
35     class vector2D
36     {
37     public:
38         typedef vogl::vector<T> vector_type;
39         typedef T value_type;
40         typedef T &reference;
41         typedef const T &const_reference;
42         typedef T *pointer;
43         typedef const T *const_pointer;
44
45         inline vector2D(uint width = 0, uint height = 0, const T &def = T())
46             : m_width(width),
47               m_height(height),
48               m_vec(width * height),
49               m_def(def)
50         {
51         }
52
53         inline vector2D(const vector2D &other)
54             : m_width(other.m_width),
55               m_height(other.m_height),
56               m_vec(other.m_vec),
57               m_def(other.m_def)
58         {
59         }
60
61         inline vector2D &operator=(const vector2D &rhs)
62         {
63             if (this == &rhs)
64                 return *this;
65
66             m_width = rhs.m_width;
67             m_height = rhs.m_height;
68             m_vec = rhs.m_vec;
69
70             return *this;
71         }
72
73         bool try_resize(uint width, uint height, bool preserve = true)
74         {
75             if ((width == m_width) && (height == m_height))
76                 return true;
77
78             vector_type new_vec;
79             if (!new_vec.try_resize(width * height))
80                 return false;
81
82             if (preserve)
83             {
84                 const uint nx = math::minimum(width, m_width);
85                 const uint ny = math::minimum(height, m_height);
86
87                 for (uint y = 0; y < ny; y++)
88                 {
89                     const T *pSrc = &m_vec[y * m_width];
90                     T *pDst = &new_vec[y * width];
91                     if (VOGL_IS_BITWISE_COPYABLE_OR_MOVABLE(T))
92                         memcpy(pDst, pSrc, nx * sizeof(T));
93                     else
94                     {
95                         for (uint x = 0; x < nx; x++)
96                             *pDst++ = *pSrc++;
97                     }
98                 }
99             }
100
101             m_width = width;
102             m_height = height;
103             m_vec.swap(new_vec);
104
105             return true;
106         }
107
108         void resize(uint width, uint height, bool preserve = true)
109         {
110             if (!try_resize(width, height, preserve))
111             {
112                 VOGL_FAIL("vector2D::resize: Out of memory");
113             }
114         }
115
116         inline void clear()
117         {
118             m_vec.clear();
119             m_width = 0;
120             m_height = 0;
121         }
122
123         inline uint width() const
124         {
125             return m_width;
126         }
127         inline uint height() const
128         {
129             return m_height;
130         }
131         inline uint size() const
132         {
133             return m_vec.size();
134         }
135
136         inline uint size_in_bytes() const
137         {
138             return m_vec.size() * sizeof(T);
139         }
140
141         const vector_type &get_vec() const
142         {
143             return m_vec;
144         }
145         vector_type &get_vec()
146         {
147             return m_vec;
148         }
149
150         inline const T *get_ptr() const
151         {
152             return m_vec.get_ptr();
153         }
154         inline T *get_ptr()
155         {
156             return m_vec.get_ptr();
157         }
158
159         inline const T &operator[](uint i) const
160         {
161             return m_vec[i];
162         }
163         inline T &operator[](uint i)
164         {
165             return m_vec[i];
166         }
167
168         inline const T &operator()(uint x, uint y) const
169         {
170             VOGL_ASSERT((x < m_width) && (y < m_height));
171             return m_vec[x + y * m_width];
172         }
173
174         inline T &operator()(uint x, uint y)
175         {
176             VOGL_ASSERT((x < m_width) && (y < m_height));
177             return m_vec[x + y * m_width];
178         }
179
180         inline const T &at(uint x, uint y) const
181         {
182             if ((x >= m_width) || (y >= m_height))
183                 return m_def;
184             return m_vec[x + y * m_width];
185         }
186
187         inline T &at(uint x, uint y)
188         {
189             if ((x >= m_width) || (y >= m_height))
190                 return m_def;
191             return m_vec[x + y * m_width];
192         }
193
194         inline const T &at_clamped(int x, int y) const
195         {
196             x = math::clamp<int>(x, 0, m_width - 1);
197             y = math::clamp<int>(y, 0, m_height - 1);
198             return m_vec[x + y * m_width];
199         }
200
201         inline T &at_clamped(int x, int y)
202         {
203             x = math::clamp<int>(x, 0, m_width - 1);
204             y = math::clamp<int>(y, 0, m_height - 1);
205             return m_vec[x + y * m_width];
206         }
207
208         inline const T &at_wrapped(int x, int y) const
209         {
210             x = math::posmod(x, m_width);
211             y = math::posmod(y, m_height);
212             return m_vec[x + y * m_width];
213         }
214
215         inline T &at_wrapped(int x, int y)
216         {
217             x = math::posmod(x, m_width);
218             y = math::posmod(y, m_height);
219             return m_vec[x + y * m_width];
220         }
221
222         inline void swap(vector2D &other)
223         {
224             m_vec.swap(other.m_vec);
225             std::swap(m_width, other.m_width);
226             std::swap(m_height, other.m_height);
227             std::swap(m_def, other.m_def);
228         }
229
230         inline void set_all(const T &x)
231         {
232             m_vec.set_all(x);
233         }
234
235         inline void extract_block_clamped(vector2D &dst, uint dst_x, uint dst_y, int src_x, int src_y, uint w, uint h) const
236         {
237             for (uint y = 0; y < h; y++)
238                 for (uint x = 0; x < w; x++)
239                     dst.at(dst_x + x, dst_y + y) = at_clamped(src_x + x, src_y + y);
240         }
241
242         inline void extract_block_wrapped(vector2D &dst, uint dst_x, uint dst_y, int src_x, int src_y, uint w, uint h) const
243         {
244             for (uint y = 0; y < h; y++)
245                 for (uint x = 0; x < w; x++)
246                     dst.at(dst_x + x, dst_y + y) = at_wrapped(src_x + x, src_y + y);
247         }
248
249         // Doesn't compare the default object
250         inline bool operator==(const vector2D &rhs) const
251         {
252             return (m_width == rhs.m_width) && (m_height == rhs.m_height) && (m_vec == rhs.m_vec);
253         }
254
255         inline bool operator!=(const vector2D &rhs) const
256         {
257             return !(*this == rhs);
258         }
259
260     private:
261         uint m_width;
262         uint m_height;
263         vector_type m_vec;
264         T m_def;
265     };
266
267 } // namespace vogl