]> Dogcows Code - chaz/yoink/blob - src/Moof/cml/core/external_2D.h
version bump cml to version 1.0.2
[chaz/yoink] / src / Moof / cml / core / external_2D.h
1 /* -*- C++ -*- ------------------------------------------------------------
2
3 Copyright (c) 2007 Jesse Anders and Demian Nave http://cmldev.net/
4
5 The Configurable Math Library (CML) is distributed under the terms of the
6 Boost Software License, v1.0 (see cml/LICENSE for details).
7
8 *-----------------------------------------------------------------------*/
9 /** @file
10 * @brief
11 *
12 * Defines the fixed-size and runtime-sized external 2D arrays.
13 *
14 * @todo Would casting get better performance in the external_2D<> element
15 * access methods?
16 */
17
18 #ifndef external_2D_h
19 #define external_2D_h
20
21 #include <cml/core/common.h>
22 #include <cml/core/fixed_1D.h>
23 #include <cml/core/fixed_2D.h>
24 #include <cml/core/dynamic_1D.h>
25 #include <cml/core/dynamic_2D.h>
26 #include <cml/external.h>
27
28 namespace cml {
29
30 /** Fixed-size external 2D array.
31 *
32 * Both the memory and the size are fixed at compile time, and cannot be
33 * changed.
34 */
35 template<typename Element, int Rows, int Cols, typename Layout>
36 class external_2D
37 {
38 public:
39
40 /* Require Rows > 0, Cols > 0: */
41 CML_STATIC_REQUIRE((Rows > 0) && (Cols > 0));
42
43 /* Record the generator: */
44 typedef external<Rows,Cols> generator_type;
45
46 /* Standard: */
47 typedef Element value_type;
48 typedef Element* pointer;
49 typedef Element& reference;
50 typedef const Element& const_reference;
51 typedef const Element* const_pointer;
52
53 /* For matching by memory layout: */
54 typedef Layout layout;
55
56 /* For matching by memory type: */
57 typedef external_memory_tag memory_tag;
58
59 /* For matching by size type: */
60 typedef fixed_size_tag size_tag;
61
62 /* For matching by resizability: */
63 typedef not_resizable_tag resizing_tag;
64
65 /* For matching by dimensions: */
66 typedef twod_tag dimension_tag;
67
68 /* To simplify the matrix transpose operator: */
69 typedef fixed_2D<typename cml::remove_const<Element>::type,
70 Cols,Rows,Layout> transposed_type;
71 /* Note: the transposed type must be fixed_2D, since an external array
72 * cannot be specified without a corresponding memory location.
73 */
74
75 /* To simplify the matrix row and column operators: */
76 typedef fixed_1D<Element,Rows> row_array_type;
77 typedef fixed_1D<Element,Cols> col_array_type;
78 /* Note: the row types must be fixed_1D, since external arrays cannot be
79 * specified without a memory location.
80 */
81
82
83 public:
84
85 enum { array_rows = Rows, array_cols = Cols };
86
87
88 public:
89
90 /** Construct an external array from a pointer. */
91 external_2D(value_type const ptr[Rows][Cols])
92 : m_data(const_cast<pointer>(&ptr[0][0])) {}
93
94 /** Construct an external array from a pointer. */
95 external_2D(value_type* const ptr) : m_data(ptr) {}
96
97
98 public:
99
100 /** Return the number of rows in the array. */
101 size_t rows() const { return size_t(array_rows); }
102
103 /** Return the number of cols in the array. */
104 size_t cols() const { return size_t(array_cols); }
105
106
107 public:
108
109 /** Access element (row,col) of the matrix.
110 *
111 * @param row row of element.
112 * @param col column of element.
113 * @returns mutable reference.
114 *
115 * @note This function does not range-check the arguments.
116 */
117 reference operator()(size_t row, size_t col) {
118 /* Dispatch to the right function based on layout: */
119 return get_element(row,col,layout());
120 }
121
122 /** Const access element (row,col) of the matrix.
123 *
124 * @param row row of element.
125 * @param col column of element.
126 * @returns const reference.
127 *
128 * @note This function does not range-check the arguments.
129 */
130 const_reference operator()(size_t row, size_t col) const {
131 /* Dispatch to the right function based on layout: */
132 return get_element(row,col,layout());
133 }
134
135 /** Return access to the data as a raw pointer. */
136 pointer data() { return m_data; }
137
138 /** Return access to the data as a raw pointer. */
139 const_pointer data() const { return m_data; }
140
141
142 protected:
143
144 /* XXX May be able to cast to get better performance? */
145 reference get_element(size_t row, size_t col, row_major) {
146 return m_data[row*Cols + col];
147 }
148
149 const_reference get_element(size_t row, size_t col, row_major) const {
150 return m_data[row*Cols + col];
151 }
152
153 reference get_element(size_t row, size_t col, col_major) {
154 return m_data[col*Rows + row];
155 }
156
157 const_reference get_element(size_t row, size_t col, col_major) const {
158 return m_data[col*Rows + row];
159 }
160
161
162 protected:
163
164 /* Declare the data array: */
165 pointer const m_data;
166 };
167
168 /** Run-time sized external 2D array.
169 *
170 * Both the memory and the size are fixed at run-time, but cannot be changed.
171 * This is a specialization for the case that Rows and Cols are not specified
172 * (i.e. given as the default of -1,-1).
173 */
174 template<typename Element, typename Layout>
175 class external_2D<Element,-1,-1,Layout>
176 {
177 public:
178
179 /* Record the generator. Note: this is *not* unique, as it is the same
180 * generator used by external_1D. However, external_1D is used only by
181 * vector<> classes, so this is not a problem.
182 */
183 typedef external<> generator_type;
184
185 /* Standard: */
186 typedef Element value_type;
187 typedef Element* pointer;
188 typedef Element& reference;
189 typedef const Element& const_reference;
190 typedef const Element* const_pointer;
191
192 /* For matching by memory layout: */
193 typedef Layout layout;
194
195 /* For matching by memory type: */
196 typedef external_memory_tag memory_tag;
197
198 /* For matching by size type: */
199 typedef dynamic_size_tag size_tag;
200
201 /* For matching by resizability: */
202 typedef not_resizable_tag resizing_tag;
203
204 /* For matching by dimensions: */
205 typedef twod_tag dimension_tag;
206
207 /* To simplify the matrix transpose operator: */
208 typedef dynamic_2D<typename cml::remove_const<Element>::type,
209 Layout, CML_DEFAULT_ARRAY_ALLOC> transposed_type;
210
211 /* To simplify the matrix row and column operators: */
212 typedef dynamic_1D<Element, CML_DEFAULT_ARRAY_ALLOC> row_array_type;
213 typedef dynamic_1D<Element, CML_DEFAULT_ARRAY_ALLOC> col_array_type;
214
215
216 public:
217
218 enum { array_rows = -1, array_cols = -1 };
219
220
221 public:
222
223 /** Construct an external array with no size. */
224 external_2D(pointer const ptr, size_t rows, size_t cols)
225 : m_data(ptr), m_rows(rows), m_cols(cols) {}
226
227
228 public:
229
230 /** Return the number of rows in the array. */
231 size_t rows() const { return m_rows; }
232
233 /** Return the number of cols in the array. */
234 size_t cols() const { return m_cols; }
235
236
237 public:
238
239 /** Access element (row,col) of the matrix.
240 *
241 * @param row row of element.
242 * @param col column of element.
243 * @returns mutable reference.
244 *
245 * @note This function does not range-check the arguments.
246 */
247 reference operator()(size_t row, size_t col) {
248 /* Dispatch to the right function based on layout: */
249 return get_element(row,col,layout());
250 }
251
252 /** Const access element (row,col) of the matrix.
253 *
254 * @param row row of element.
255 * @param col column of element.
256 * @returns const reference.
257 *
258 * @note This function does not range-check the arguments.
259 */
260 const_reference operator()(size_t row, size_t col) const {
261 /* Dispatch to the right function based on layout: */
262 return get_element(row,col,layout());
263 }
264
265 /** Return access to the data as a raw pointer. */
266 pointer data() { return m_data; }
267
268 /** Return access to the data as a raw pointer. */
269 const_pointer data() const { return m_data; }
270
271
272 protected:
273
274 /* XXX May be able to cast to get better performance? */
275 reference get_element(size_t row, size_t col, row_major) {
276 return m_data[row*m_cols + col];
277 }
278
279 const_reference get_element(size_t row, size_t col, row_major) const {
280 return m_data[row*m_cols + col];
281 }
282
283 reference get_element(size_t row, size_t col, col_major) {
284 return m_data[col*m_rows + row];
285 }
286
287 const_reference get_element(size_t row, size_t col, col_major) const {
288 return m_data[col*m_rows + row];
289 }
290
291
292 protected:
293
294 /* Declare the data array: */
295 value_type* const m_data;
296 const size_t m_rows;
297 const size_t m_cols;
298 };
299
300 } // namespace cml
301
302 #endif
303
304 // -------------------------------------------------------------------------
305 // vim:ft=cpp
This page took 0.043041 seconds and 4 git commands to generate.