external_2D.h

Go to the documentation of this file.
00001 /* -*- C++ -*- ------------------------------------------------------------
00002  
00003 Copyright (c) 2007 Jesse Anders and Demian Nave http://cmldev.net/
00004 
00005 The Configurable Math Library (CML) is distributed under the terms of the
00006 Boost Software License, v1.0 (see cml/LICENSE for details).
00007 
00008  *-----------------------------------------------------------------------*/
00018 #ifndef external_2D_h
00019 #define external_2D_h
00020 
00021 #include <cml/core/common.h>
00022 #include <cml/core/fixed_1D.h>
00023 #include <cml/core/fixed_2D.h>
00024 #include <cml/core/dynamic_1D.h>
00025 #include <cml/core/dynamic_2D.h>
00026 #include <cml/external.h>
00027 
00028 namespace cml {
00029 
00035 template<typename Element, int Rows, int Cols, typename Layout>
00036 class external_2D
00037 {
00038   public:
00039 
00040     /* Require Rows > 0, Cols > 0: */
00041     CML_STATIC_REQUIRE((Rows > 0) && (Cols > 0));
00042 
00043     /* Record the generator: */
00044     typedef external<Rows,Cols> generator_type;
00045 
00046     /* Standard: */
00047     typedef Element value_type;
00048     typedef Element* pointer;
00049     typedef Element& reference;
00050     typedef const Element& const_reference;
00051     typedef const Element* const_pointer;
00052 
00053     /* For matching by memory layout: */
00054     typedef Layout layout;
00055 
00056     /* For matching by memory type: */
00057     typedef external_memory_tag memory_tag;
00058 
00059     /* For matching by size type: */
00060     typedef fixed_size_tag size_tag;
00061 
00062     /* For matching by resizability: */
00063     typedef not_resizable_tag resizing_tag;
00064 
00065     /* For matching by dimensions: */
00066     typedef twod_tag dimension_tag;
00067 
00068     /* To simplify the matrix transpose operator: */
00069     typedef fixed_2D<Element,Cols,Rows,Layout> transposed_type;
00070     /* Note: the transposed type must be fixed_2D, since an external array
00071      * cannot be specified without a corresponding memory location.
00072      */
00073 
00074     /* To simplify the matrix row and column operators: */
00075     typedef fixed_1D<Element,Rows> row_array_type;
00076     typedef fixed_1D<Element,Cols> col_array_type;
00077     /* Note: the row types must be fixed_1D, since external arrays cannot be
00078      * specified without a memory location.
00079      */
00080 
00081 
00082   public:
00083 
00084     enum { array_rows = Rows, array_cols = Cols };
00085 
00086 
00087   public:
00088 
00090     external_2D(value_type const ptr[Rows][Cols])
00091         : m_data(const_cast<pointer>(&ptr[0][0])) {}
00092 
00094     external_2D(value_type* const ptr) : m_data(ptr) {}
00095 
00096 
00097   public:
00098 
00100     size_t rows() const { return size_t(array_rows); }
00101 
00103     size_t cols() const { return size_t(array_cols); }
00104 
00105 
00106   public:
00107 
00116     reference operator()(size_t row, size_t col) {
00117         /* Dispatch to the right function based on layout: */
00118         return get_element(row,col,layout());
00119     }
00120 
00129     const_reference operator()(size_t row, size_t col) const {
00130         /* Dispatch to the right function based on layout: */
00131         return get_element(row,col,layout());
00132     }
00133 
00135     pointer data() { return m_data; }
00136 
00138     const_pointer data() const { return m_data; }
00139 
00140 
00141   protected:
00142 
00143     /* XXX May be able to cast to get better performance? */
00144     reference get_element(size_t row, size_t col, row_major) {
00145         return m_data[row*Cols + col];
00146     }
00147 
00148     const_reference get_element(size_t row, size_t col, row_major) const {
00149         return m_data[row*Cols + col];
00150     }
00151 
00152     reference get_element(size_t row, size_t col, col_major) {
00153         return m_data[col*Rows + row];
00154     }
00155 
00156     const_reference get_element(size_t row, size_t col, col_major) const {
00157         return m_data[col*Rows + row];
00158     }
00159 
00160 
00161   protected:
00162 
00163     /* Declare the data array: */
00164     pointer const               m_data;
00165 };
00166 
00173 template<typename Element, typename Layout>
00174 class external_2D<Element,-1,-1,Layout>
00175 {
00176   public:
00177 
00178     /* Record the generator.  Note: this is *not* unique, as it is the same
00179      * generator used by external_1D.  However, external_1D is used only by
00180      * vector<> classes, so this is not a problem.
00181      */
00182     typedef external<> generator_type;
00183 
00184     /* Standard: */
00185     typedef Element value_type;
00186     typedef Element* pointer;
00187     typedef Element& reference;
00188     typedef const Element& const_reference;
00189     typedef const Element* const_pointer;
00190 
00191     /* For matching by memory layout: */
00192     typedef Layout layout;
00193 
00194     /* For matching by memory type: */
00195     typedef external_memory_tag memory_tag;
00196 
00197     /* For matching by size type: */
00198     typedef dynamic_size_tag size_tag;
00199 
00200     /* For matching by resizability: */
00201     typedef not_resizable_tag resizing_tag;
00202 
00203     /* For matching by dimensions: */
00204     typedef twod_tag dimension_tag;
00205 
00206     /* To simplify the matrix transpose operator: */
00207     typedef dynamic_2D<Element,Layout, CML_DEFAULT_ARRAY_ALLOC>
00208         transposed_type;
00209 
00210     /* To simplify the matrix row and column operators: */
00211     typedef dynamic_1D<Element, CML_DEFAULT_ARRAY_ALLOC> row_array_type;
00212     typedef dynamic_1D<Element, CML_DEFAULT_ARRAY_ALLOC> col_array_type;
00213 
00214 
00215   public:
00216 
00217     enum { array_rows = -1, array_cols = -1 };
00218 
00219 
00220   public:
00221 
00223     external_2D(pointer const ptr, size_t rows, size_t cols)
00224         : m_data(ptr), m_rows(rows), m_cols(cols) {}
00225 
00226 
00227   public:
00228 
00230     size_t rows() const { return m_rows; }
00231 
00233     size_t cols() const { return m_cols; }
00234 
00235 
00236   public:
00237 
00246     reference operator()(size_t row, size_t col) {
00247         /* Dispatch to the right function based on layout: */
00248         return get_element(row,col,layout());
00249     }
00250 
00259     const_reference operator()(size_t row, size_t col) const {
00260         /* Dispatch to the right function based on layout: */
00261         return get_element(row,col,layout());
00262     }
00263 
00265     pointer data() { return m_data; }
00266 
00268     const_pointer data() const { return m_data; }
00269 
00270 
00271   protected:
00272 
00273     /* XXX May be able to cast to get better performance? */
00274     reference get_element(size_t row, size_t col, row_major) {
00275         return m_data[row*m_cols + col];
00276     }
00277 
00278     const_reference get_element(size_t row, size_t col, row_major) const {
00279         return m_data[row*m_cols + col];
00280     }
00281 
00282     reference get_element(size_t row, size_t col, col_major) {
00283         return m_data[col*m_rows + row];
00284     }
00285 
00286     const_reference get_element(size_t row, size_t col, col_major) const {
00287         return m_data[col*m_rows + row];
00288     }
00289 
00290 
00291   protected:
00292 
00293     /* Declare the data array: */
00294     value_type* const           m_data;
00295     const size_t                m_rows;
00296     const size_t                m_cols;
00297 };
00298 
00299 } // namespace cml
00300 
00301 #endif
00302 
00303 // -------------------------------------------------------------------------
00304 // vim:ft=cpp

Generated on Sat Jul 18 19:35:20 2009 for CML 1.0 by  doxygen 1.5.9