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
<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.
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.
85 enum { array_rows
= Rows
, array_cols
= Cols
};
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])) {}
94 /** Construct an external array from a pointer. */
95 external_2D(value_type
* const ptr
) : m_data(ptr
) {}
100 /** Return the number of rows in the array. */
101 size_t rows() const { return size_t(array_rows
); }
103 /** Return the number of cols in the array. */
104 size_t cols() const { return size_t(array_cols
); }
109 /** Access element (row,col) of the matrix.
111 * @param row row of element.
112 * @param col column of element.
113 * @returns mutable reference.
115 * @note This function does not range-check the arguments.
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());
122 /** Const access element (row,col) of the matrix.
124 * @param row row of element.
125 * @param col column of element.
126 * @returns const reference.
128 * @note This function does not range-check the arguments.
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());
135 /** Return access to the data as a raw pointer. */
136 pointer
data() { return m_data
; }
138 /** Return access to the data as a raw pointer. */
139 const_pointer
data() const { return m_data
; }
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
];
149 const_reference
get_element(size_t row
, size_t col
, row_major
) const {
150 return m_data
[row
*Cols
+ col
];
153 reference
get_element(size_t row
, size_t col
, col_major
) {
154 return m_data
[col
*Rows
+ row
];
157 const_reference
get_element(size_t row
, size_t col
, col_major
) const {
158 return m_data
[col
*Rows
+ row
];
164 /* Declare the data array: */
165 pointer
const m_data
;
168 /** Run-time sized external 2D array.
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).
174 template<typename Element
, typename Layout
>
175 class external_2D
<Element
,-1,-1,Layout
>
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.
183 typedef external
<> generator_type
;
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
;
192 /* For matching by memory layout: */
193 typedef Layout layout
;
195 /* For matching by memory type: */
196 typedef external_memory_tag memory_tag
;
198 /* For matching by size type: */
199 typedef dynamic_size_tag size_tag
;
201 /* For matching by resizability: */
202 typedef not_resizable_tag resizing_tag
;
204 /* For matching by dimensions: */
205 typedef twod_tag dimension_tag
;
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
;
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
;
218 enum { array_rows
= -1, array_cols
= -1 };
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
) {}
230 /** Return the number of rows in the array. */
231 size_t rows() const { return m_rows
; }
233 /** Return the number of cols in the array. */
234 size_t cols() const { return m_cols
; }
239 /** Access element (row,col) of the matrix.
241 * @param row row of element.
242 * @param col column of element.
243 * @returns mutable reference.
245 * @note This function does not range-check the arguments.
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());
252 /** Const access element (row,col) of the matrix.
254 * @param row row of element.
255 * @param col column of element.
256 * @returns const reference.
258 * @note This function does not range-check the arguments.
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());
265 /** Return access to the data as a raw pointer. */
266 pointer
data() { return m_data
; }
268 /** Return access to the data as a raw pointer. */
269 const_pointer
data() const { return m_data
; }
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
];
279 const_reference
get_element(size_t row
, size_t col
, row_major
) const {
280 return m_data
[row
*m_cols
+ col
];
283 reference
get_element(size_t row
, size_t col
, col_major
) {
284 return m_data
[col
*m_rows
+ row
];
287 const_reference
get_element(size_t row
, size_t col
, col_major
) const {
288 return m_data
[col
*m_rows
+ row
];
294 /* Declare the data array: */
295 value_type
* const m_data
;
304 // -------------------------------------------------------------------------