1 /* -*- C++ -*- ------------------------------------------------------------
3 Copyright (c) 2007 Jesse Anders and Demian Nave http://cmldev.net/
5 The Configurable Math Library (CML) is distributed under the terms of the
6 Boost Software License, v1.0 (see cml/LICENSE for details).
8 *-----------------------------------------------------------------------*/
12 * Defines the fixed-size and runtime-sized external 2D arrays.
14 * @todo Would casting get better performance in the external_2D<> element
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>
30 /** Fixed-size external 2D array.
32 * Both the memory and the size are fixed at compile time, and cannot be
35 template<typename Element
, int Rows
, int Cols
, typename Layout
>
40 /* Require Rows > 0, Cols > 0: */
41 CML_STATIC_REQUIRE((Rows
> 0) && (Cols
> 0));
43 /* Record the generator: */
44 typedef external
<Rows
,Cols
> generator_type
;
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
;
53 /* For matching by memory layout: */
54 typedef Layout layout
;
56 /* For matching by memory type: */
57 typedef external_memory_tag memory_tag
;
59 /* For matching by size type: */
60 typedef fixed_size_tag size_tag
;
62 /* For matching by resizability: */
63 typedef not_resizable_tag resizing_tag
;
65 /* For matching by dimensions: */
66 typedef twod_tag dimension_tag
;
68 /* To simplify the matrix transpose operator: */
69 typedef fixed_2D
<Element
,Cols
,Rows
,Layout
> transposed_type
;
70 /* Note: the transposed type must be fixed_2D, since an external array
71 * cannot be specified without a corresponding memory location.
74 /* To simplify the matrix row and column operators: */
75 typedef fixed_1D
<Element
,Rows
> row_array_type
;
76 typedef fixed_1D
<Element
,Cols
> col_array_type
;
77 /* Note: the row types must be fixed_1D, since external arrays cannot be
78 * specified without a memory location.
84 enum { array_rows
= Rows
, array_cols
= Cols
};
89 /** Construct an external array from a pointer. */
90 external_2D(value_type
const ptr
[Rows
][Cols
])
91 : m_data(const_cast<pointer
>(&ptr
[0][0])) {}
93 /** Construct an external array from a pointer. */
94 external_2D(value_type
* const ptr
) : m_data(ptr
) {}
99 /** Return the number of rows in the array. */
100 size_t rows() const { return size_t(array_rows
); }
102 /** Return the number of cols in the array. */
103 size_t cols() const { return size_t(array_cols
); }
108 /** Access element (row,col) of the matrix.
110 * @param row row of element.
111 * @param col column of element.
112 * @returns mutable reference.
114 * @note This function does not range-check the arguments.
116 reference
operator()(size_t row
, size_t col
) {
117 /* Dispatch to the right function based on layout: */
118 return get_element(row
,col
,layout());
121 /** Const access element (row,col) of the matrix.
123 * @param row row of element.
124 * @param col column of element.
125 * @returns const reference.
127 * @note This function does not range-check the arguments.
129 const_reference
operator()(size_t row
, size_t col
) const {
130 /* Dispatch to the right function based on layout: */
131 return get_element(row
,col
,layout());
134 /** Return access to the data as a raw pointer. */
135 pointer
data() { return m_data
; }
137 /** Return access to the data as a raw pointer. */
138 const_pointer
data() const { return m_data
; }
143 /* XXX May be able to cast to get better performance? */
144 reference
get_element(size_t row
, size_t col
, row_major
) {
145 return m_data
[row
*Cols
+ col
];
148 const_reference
get_element(size_t row
, size_t col
, row_major
) const {
149 return m_data
[row
*Cols
+ col
];
152 reference
get_element(size_t row
, size_t col
, col_major
) {
153 return m_data
[col
*Rows
+ row
];
156 const_reference
get_element(size_t row
, size_t col
, col_major
) const {
157 return m_data
[col
*Rows
+ row
];
163 /* Declare the data array: */
164 pointer
const m_data
;
167 /** Run-time sized external 2D array.
169 * Both the memory and the size are fixed at run-time, but cannot be changed.
170 * This is a specialization for the case that Rows and Cols are not specified
171 * (i.e. given as the default of -1,-1).
173 template<typename Element
, typename Layout
>
174 class external_2D
<Element
,-1,-1,Layout
>
178 /* Record the generator. Note: this is *not* unique, as it is the same
179 * generator used by external_1D. However, external_1D is used only by
180 * vector<> classes, so this is not a problem.
182 typedef external
<> generator_type
;
185 typedef Element value_type
;
186 typedef Element
* pointer
;
187 typedef Element
& reference
;
188 typedef const Element
& const_reference
;
189 typedef const Element
* const_pointer
;
191 /* For matching by memory layout: */
192 typedef Layout layout
;
194 /* For matching by memory type: */
195 typedef external_memory_tag memory_tag
;
197 /* For matching by size type: */
198 typedef dynamic_size_tag size_tag
;
200 /* For matching by resizability: */
201 typedef not_resizable_tag resizing_tag
;
203 /* For matching by dimensions: */
204 typedef twod_tag dimension_tag
;
206 /* To simplify the matrix transpose operator: */
207 typedef dynamic_2D
<Element
,Layout
, CML_DEFAULT_ARRAY_ALLOC
>
210 /* To simplify the matrix row and column operators: */
211 typedef dynamic_1D
<Element
, CML_DEFAULT_ARRAY_ALLOC
> row_array_type
;
212 typedef dynamic_1D
<Element
, CML_DEFAULT_ARRAY_ALLOC
> col_array_type
;
217 enum { array_rows
= -1, array_cols
= -1 };
222 /** Construct an external array with no size. */
223 external_2D(pointer
const ptr
, size_t rows
, size_t cols
)
224 : m_data(ptr
), m_rows(rows
), m_cols(cols
) {}
229 /** Return the number of rows in the array. */
230 size_t rows() const { return m_rows
; }
232 /** Return the number of cols in the array. */
233 size_t cols() const { return m_cols
; }
238 /** Access element (row,col) of the matrix.
240 * @param row row of element.
241 * @param col column of element.
242 * @returns mutable reference.
244 * @note This function does not range-check the arguments.
246 reference
operator()(size_t row
, size_t col
) {
247 /* Dispatch to the right function based on layout: */
248 return get_element(row
,col
,layout());
251 /** Const access element (row,col) of the matrix.
253 * @param row row of element.
254 * @param col column of element.
255 * @returns const reference.
257 * @note This function does not range-check the arguments.
259 const_reference
operator()(size_t row
, size_t col
) const {
260 /* Dispatch to the right function based on layout: */
261 return get_element(row
,col
,layout());
264 /** Return access to the data as a raw pointer. */
265 pointer
data() { return m_data
; }
267 /** Return access to the data as a raw pointer. */
268 const_pointer
data() const { return m_data
; }
273 /* XXX May be able to cast to get better performance? */
274 reference
get_element(size_t row
, size_t col
, row_major
) {
275 return m_data
[row
*m_cols
+ col
];
278 const_reference
get_element(size_t row
, size_t col
, row_major
) const {
279 return m_data
[row
*m_cols
+ col
];
282 reference
get_element(size_t row
, size_t col
, col_major
) {
283 return m_data
[col
*m_rows
+ row
];
286 const_reference
get_element(size_t row
, size_t col
, col_major
) const {
287 return m_data
[col
*m_rows
+ row
];
293 /* Declare the data array: */
294 value_type
* const m_data
;
303 // -------------------------------------------------------------------------