00001 // Software License for MTL 00002 // 00003 // Copyright (c) 2007 The Trustees of Indiana University. 00004 // 2008 Dresden University of Technology and the Trustees of Indiana University. 00005 // All rights reserved. 00006 // Authors: Peter Gottschling and Andrew Lumsdaine 00007 // 00008 // This file is part of the Matrix Template Library 00009 // 00010 // See also license.mtl.txt in the distribution. 00011 00012 #ifndef MTL_PROPERTY_MAP_IMPL_INCLUDE 00013 #define MTL_PROPERTY_MAP_IMPL_INCLUDE 00014 00015 00016 namespace mtl { namespace detail { 00017 00018 // functor with matrix reference to access rows 00019 template <class Matrix> struct indexer_row_ref 00020 { 00021 typedef Matrix matrix_type; 00022 typedef typename Matrix::key_type key_type; 00023 indexer_row_ref(const matrix_type& ma) : ma(ma) {} 00024 00025 typename Matrix::size_type operator() (key_type const& key) const 00026 { 00027 return ma.indexer.row(ma, key); 00028 } 00029 const matrix_type& ma; 00030 }; 00031 00032 00033 // functor to access rows using the key itself 00034 template <class Matrix> struct row_in_key 00035 { 00036 typedef Matrix matrix_type; 00037 typedef typename Matrix::key_type key_type; 00038 row_in_key(const matrix_type&) {} 00039 00040 typename Matrix::size_type operator() (key_type const& key) const 00041 { 00042 return key.row(); 00043 } 00044 }; 00045 00046 00047 // functor access the major dimension in key itself 00048 template <class Matrix> struct major_in_key 00049 { 00050 typedef Matrix matrix_type; 00051 typedef typename Matrix::key_type key_type; 00052 major_in_key(const matrix_type&) {} 00053 00054 typename Matrix::size_type operator() (key_type const& key) const 00055 { 00056 return key.major; 00057 } 00058 }; 00059 00060 00061 template <class Matrix> struct indexer_minor_ref 00062 { 00063 typedef Matrix matrix_type; 00064 typedef typename Matrix::key_type key_type; 00065 indexer_minor_ref(const matrix_type& ma) : ma(ma) {} 00066 00067 typename Matrix::size_type operator() (key_type const& key) const 00068 { 00069 return ma.indexer.minor_from_offset(ma, key.offset); 00070 } 00071 const matrix_type& ma; 00072 }; 00073 00074 00075 template <class Matrix> struct indexer_col_ref 00076 { 00077 typedef Matrix matrix_type; 00078 typedef typename Matrix::key_type key_type; 00079 indexer_col_ref(const matrix_type& ma) : ma(ma) {} 00080 00081 typename Matrix::size_type operator() (key_type const& key) const 00082 { 00083 return ma.indexer.col(ma, key); 00084 } 00085 const matrix_type& ma; 00086 }; 00087 00088 00089 template <class Matrix> struct col_in_key 00090 { 00091 typedef Matrix matrix_type; 00092 typedef typename Matrix::key_type key_type; 00093 col_in_key(const matrix_type&) {} 00094 00095 typename Matrix::size_type operator() (key_type const& key) const 00096 { 00097 return key.col(); 00098 } 00099 }; 00100 00101 // Collection must be derived from contiguous_memory_block 00102 // key must contain pointer 00103 template <class Collection> struct index_from_offset 00104 { 00105 typedef Collection collection_type; 00106 00107 index_from_offset(const collection_type& coll) : coll(coll) {} 00108 00109 template <typename Key> 00110 typename Collection::size_type operator() (Key const& key) const 00111 { 00112 return coll.offset(&*key); 00113 } 00114 private: 00115 const collection_type& coll; 00116 }; 00117 00118 template <typename Matrix> 00119 struct const_value_from_other 00120 { 00121 typedef typename Matrix::other other; 00122 typedef typename other::key_type key_type; 00123 typedef typename other::value_type value_type; 00124 00125 explicit const_value_from_other(Matrix const& matrix) 00126 : its_const_value(matrix.ref) {} 00127 00128 const value_type operator() (key_type const& key) const 00129 { 00130 return its_const_value(key); 00131 } 00132 00133 protected: 00134 typename traits::const_value<typename boost::remove_const<other>::type>::type its_const_value; 00135 }; 00136 00137 00138 00139 00140 template <typename Matrix> 00141 struct value_from_other 00142 { 00143 typedef typename Matrix::other other; 00144 typedef typename other::key_type key_type; 00145 typedef typename other::value_type value_type; 00146 00147 explicit value_from_other(Matrix const& matrix) 00148 : its_value(matrix.ref) {} 00149 00150 const value_type operator() (key_type const& key) const 00151 { 00152 return its_value(key); 00153 } 00154 00155 void operator() (key_type const& key, value_type value) const 00156 { 00157 its_value(key, value); 00158 } 00159 00160 protected: 00161 typename traits::value<other>::type its_value; 00162 }; 00163 00164 00165 // property map to read value if key is referring to value, e.g. pointer 00166 template <class Matrix> struct direct_const_value 00167 { 00168 direct_const_value(const Matrix&) {} // for compatibility 00169 typename Matrix::value_type const operator() (const typename Matrix::key_type key) const 00170 { 00171 return *key; 00172 } 00173 }; 00174 00175 00176 // same with writing 00177 template <class Matrix> struct direct_value 00178 : public direct_const_value<Matrix> 00179 { 00180 typedef typename Matrix::value_type value_type; 00181 00182 direct_value(const Matrix& ma) 00183 : direct_const_value<Matrix>(ma) 00184 {} // for compatibility 00185 00186 // May be to be replaced by inserter 00187 void operator() (typename Matrix::key_type const& key, value_type value) 00188 { 00189 * const_cast<value_type *>(key) = value; 00190 } 00191 00192 // should be inherited 00193 typename Matrix::value_type operator() (typename Matrix::key_type const& key) const 00194 { 00195 return *key; 00196 } 00197 }; 00198 00199 00200 template <class Matrix> struct matrix_const_value_ref 00201 { 00202 typedef Matrix matrix_type; 00203 typedef typename Matrix::key_type key_type; 00204 matrix_const_value_ref(const matrix_type& ma) : ma(ma) {} 00205 00206 typename Matrix::value_type operator() (key_type const& key) const 00207 { 00208 return ma(key); 00209 } 00210 const matrix_type& ma; 00211 }; 00212 00213 00214 template <class Matrix> struct matrix_value_ref 00215 { 00216 typedef Matrix matrix_type; 00217 typedef typename Matrix::key_type key_type; 00218 typedef typename Matrix::value_type value_type; 00219 matrix_value_ref(matrix_type& ma) : ma(ma) {} 00220 00221 typename Matrix::value_type operator() (key_type const& key) const 00222 { 00223 return ma(key); 00224 } 00225 00226 // Much better with inserters 00227 void operator() (typename Matrix::key_type const& key, value_type const& value) 00228 { 00229 ma(key, value); 00230 } 00231 00232 matrix_type& ma; 00233 }; 00234 00235 00236 template <class Matrix> struct matrix_offset_const_value 00237 { 00238 typedef Matrix matrix_type; 00239 typedef typename Matrix::key_type key_type; 00240 matrix_offset_const_value(const matrix_type& ma) : ma(ma) {} 00241 00242 typename Matrix::value_type operator() (key_type const& key) const 00243 { 00244 return ma.value_from_offset(key.offset); 00245 } 00246 const matrix_type& ma; 00247 }; 00248 00249 00250 template <class Matrix> struct matrix_offset_value 00251 { 00252 typedef Matrix matrix_type; 00253 typedef typename Matrix::key_type key_type; 00254 typedef typename Matrix::value_type value_type; 00255 matrix_offset_value(matrix_type& ma) : ma(ma) {} 00256 00257 typename Matrix::value_type operator() (key_type const& key) const 00258 { 00259 return ma.value_from_offset(key.offset); 00260 } 00261 00262 // Much better with inserters 00263 void operator() (typename Matrix::key_type const& key, value_type const& value) 00264 { 00265 ma.value_from_offset(key.offset) = value; 00266 } 00267 00268 matrix_type& ma; 00269 }; 00270 00271 template <class Matrix> struct offset_from_key 00272 { 00273 typedef Matrix matrix_type; 00274 typedef typename Matrix::key_type key_type; 00275 typedef typename Matrix::size_type size_type; 00276 offset_from_key(const matrix_type& ) {} 00277 00278 size_type operator() (key_type const& key) const 00279 { 00280 return key.offset; 00281 } 00282 }; 00283 00284 00285 }} // namespace mtl::detail 00286 00287 00288 #endif // MTL_PROPERTY_MAP_IMPL_INCLUDE 00289 00290