]> git.cworth.org Git - vogl/blob - src/voglcore/vogl_fixed_array.h
Initial vogl checkin
[vogl] / src / voglcore / vogl_fixed_array.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_fixed_array.h
28 #pragma once
29
30 #include "vogl_core.h"
31
32 namespace vogl
33 {
34     template <typename T, uint N>
35     class fixed_array
36     {
37     public:
38         typedef T element_type;
39         enum
40         {
41             cMaxElements = N
42         };
43
44         inline fixed_array()
45         {
46             VOGL_ASSUME(N > 0);
47         }
48
49         inline uint size() const
50         {
51             return N;
52         }
53
54         inline uint size_in_bytes() const
55         {
56             return sizeof(T) * N;
57         }
58
59         inline const T &operator[](uint i) const
60         {
61             VOGL_ASSERT(i < N);
62             return m[i];
63         }
64         inline T &operator[](uint i)
65         {
66             VOGL_ASSERT(i < N);
67             return m[i];
68         }
69
70         inline const T &front() const
71         {
72             return m[0];
73         }
74         inline T &front()
75         {
76             return m[0];
77         }
78
79         inline const T &back() const
80         {
81             return m[N - 1];
82         }
83         inline T &back()
84         {
85             return m[N - 1];
86         }
87
88         inline const T *begin() const
89         {
90             return m;
91         }
92         inline T *begin()
93         {
94             return m;
95         }
96
97         inline const T *end() const
98         {
99             return &m[N];
100         }
101         inline T *end()
102         {
103             return &m[N];
104         }
105
106         inline const T *get_ptr() const
107         {
108             return m;
109         }
110         inline T *get_ptr()
111         {
112             return m;
113         }
114
115         inline void set_all(const T &val)
116         {
117             for (uint i = 0; i < N; i++)
118                 m[i] = val;
119         }
120
121         inline void bitwise_zero(void)
122         {
123             utils::zero_this(this);
124         }
125
126         inline void sort(void)
127         {
128             //std::sort(begin(), end());
129             introsort(begin(), end());
130         }
131
132     private:
133         T m[N];
134     };
135
136     template <typename T, uint W, uint H>
137     class fixed_array2D
138     {
139     public:
140         enum
141         {
142             total_elements = W * H,
143             array_width = W,
144             array_height = H
145         };
146
147         typedef T value_type;
148         typedef T &reference;
149         typedef const T &const_reference;
150         typedef T *pointer;
151         typedef const T *const_pointer;
152
153         inline fixed_array2D()
154         {
155             set_all(T());
156         }
157
158         inline fixed_array2D(const fixed_array2D &other)
159         {
160             *this = other;
161         }
162
163         inline fixed_array2D &operator=(const fixed_array2D &rhs)
164         {
165             if (this == &rhs)
166                 return *this;
167
168             for (uint i = 0; i < total_elements; i++)
169                 m_vec[i] = rhs.m_vec[i];
170
171             return *this;
172         }
173
174         inline void clear()
175         {
176             set_all(T());
177         }
178
179         void resize(uint width, uint height, bool preserve = true)
180         {
181             (void)width, (void)height, (void)preserve;
182             // blindly ignoring resize for compat with vector2D
183         }
184
185         inline uint width() const
186         {
187             return array_width;
188         }
189         inline uint height() const
190         {
191             return array_height;
192         }
193         inline uint size() const
194         {
195             return total_elements;
196         }
197
198         inline uint size_in_bytes() const
199         {
200             return total_elements * sizeof(T);
201         }
202
203         inline const T *get_ptr() const
204         {
205             return m_vec;
206         }
207         inline T *get_ptr()
208         {
209             return m_vec;
210         }
211
212         inline const T &operator[](uint i) const
213         {
214             return m_vec[math::open_range_check(i, total_elements)];
215         }
216         inline T &operator[](uint i)
217         {
218             return m_vec[math::open_range_check(i, total_elements)];
219         }
220
221         inline const T &operator()(uint x, uint y) const
222         {
223             VOGL_ASSERT((x < array_width) && (y < array_height));
224             return m_vec[x + y * array_width];
225         }
226
227         inline T &operator()(uint x, uint y)
228         {
229             VOGL_ASSERT((x < array_width) && (y < array_height));
230             return m_vec[x + y * array_width];
231         }
232
233         inline const T &at(uint x, uint y) const
234         {
235             if ((x >= array_width) || (y >= array_height))
236             {
237                 VOGL_ASSERT_ALWAYS;
238                 return m_vec[0];
239             }
240             return m_vec[x + y * array_width];
241         }
242
243         inline T &at(uint x, uint y)
244         {
245             if ((x >= array_width) || (y >= array_height))
246             {
247                 VOGL_ASSERT_ALWAYS;
248                 return m_vec[0];
249             }
250             return m_vec[x + y * array_width];
251         }
252
253         inline const T &at_clamped(int x, int y) const
254         {
255             x = math::clamp<int>(x, 0, array_width - 1);
256             y = math::clamp<int>(y, 0, array_height - 1);
257             return m_vec[x + y * array_width];
258         }
259
260         inline T &at_clamped(int x, int y)
261         {
262             x = math::clamp<int>(x, 0, array_width - 1);
263             y = math::clamp<int>(y, 0, array_height - 1);
264             return m_vec[x + y * array_width];
265         }
266
267         inline const T &at_wrapped(int x, int y) const
268         {
269             x = math::posmod(x, array_width);
270             y = math::posmod(y, array_height);
271             return m_vec[x + y * array_width];
272         }
273
274         inline T &at_wrapped(int x, int y)
275         {
276             x = math::posmod(x, array_width);
277             y = math::posmod(y, array_height);
278             return m_vec[x + y * array_width];
279         }
280
281         inline void swap(fixed_array2D &other)
282         {
283             m_vec.swap(other.m_vec);
284             std::swap(array_width, other.array_width);
285             std::swap(array_height, other.array_height);
286         }
287
288         inline void set_all(const T &x)
289         {
290             for (uint i = 0; i < total_elements; i++)
291                 m_vec[i] = x;
292         }
293
294         inline void bitwise_zero(void)
295         {
296             utils::zero_this(this);
297         }
298
299         inline void extract_block_clamped(fixed_array2D &dst, uint dst_x, uint dst_y, int src_x, int src_y, uint w, uint h) const
300         {
301             for (uint y = 0; y < h; y++)
302                 for (uint x = 0; x < w; x++)
303                     dst.at(dst_x + x, dst_y + y) = at_clamped(src_x + x, src_y + y);
304         }
305
306         inline void extract_block_wrapped(fixed_array2D &dst, uint dst_x, uint dst_y, int src_x, int src_y, uint w, uint h) const
307         {
308             for (uint y = 0; y < h; y++)
309                 for (uint x = 0; x < w; x++)
310                     dst.at(dst_x + x, dst_y + y) = at_wrapped(src_x + x, src_y + y);
311         }
312
313         inline bool operator==(const fixed_array2D &rhs) const
314         {
315             for (uint i = 0; i < total_elements; i++)
316                 if (m_vec[i] != rhs.m_vec[i])
317                     return false;
318             return true;
319         }
320
321     private:
322         T m_vec[W * H];
323     };
324
325 } // namespace vogl