dune-common 2.1.1
|
00001 // $Id: propertymap.hh 6003 2010-05-14 09:12:39Z sander $ 00002 #ifndef DUNE_PROPERTYMAP_HH 00003 #define DUNE_PROPERTYMAP_HH 00004 00005 #include <cstddef> 00006 #include <iterator> 00007 00008 #include"static_assert.hh" 00009 #include"typetraits.hh" 00010 00011 namespace Dune 00012 { 00013 00014 template<class PM> 00015 struct PropertyMapTraits 00016 { 00020 typedef typename PM::KeyType KeyType; 00024 typedef typename PM::ValueType ValueType; 00028 typedef typename PM::Reference Reference; 00032 typedef typename PM::Category Category; 00033 }; 00034 00036 struct ReadablePropertyMapTag 00037 {}; 00038 00040 struct WritablePropertyMapTag 00041 {}; 00042 00047 struct ReadWritePropertyMapTag 00048 : public ReadablePropertyMapTag, public WritablePropertyMapTag 00049 {}; 00050 00054 struct LvaluePropertyMapTag 00055 : public ReadWritePropertyMapTag 00056 {}; 00057 00058 template<class T> 00059 struct PropertyMapTraits<T*> 00060 { 00061 typedef T ValueType; 00062 typedef ValueType& Reference; 00063 typedef std::ptrdiff_t KeyType; 00064 typedef LvaluePropertyMapTag Category; 00065 }; 00066 00067 00068 template<class T> 00069 struct PropertyMapTraits<const T*> 00070 { 00071 typedef T ValueType; 00072 typedef const ValueType& Reference; 00073 typedef std::ptrdiff_t KeyType; 00074 typedef LvaluePropertyMapTag Category; 00075 }; 00076 00077 template<class Reference, class PropertyMap> 00078 struct RAPropertyMapHelper 00079 {}; 00080 00081 template<class Reference, class PropertyMap, class Key> 00082 inline Reference 00083 get(const RAPropertyMapHelper<Reference,PropertyMap>& pmap, 00084 const Key& key) 00085 { 00086 return static_cast<const PropertyMap&>(pmap)[key]; 00087 } 00088 00089 template<class Reference, class PropertyMap, class Key, class Value> 00090 inline void 00091 put(const RAPropertyMapHelper<Reference,PropertyMap>& pmap, 00092 const Key& key, const Value& value) 00093 { 00094 dune_static_assert((Conversion<typename PropertyMap::Category,WritablePropertyMapTag> 00095 ::exists), "WritablePropertyMapTag required!"); 00096 static_cast<const PropertyMap&>(pmap)[key] = value; 00097 } 00098 00102 template<class RAI, class IM, 00103 class T = typename std::iterator_traits<RAI>::value_type, 00104 class R = typename std::iterator_traits<RAI>::reference> 00105 class IteratorPropertyMap 00106 : public RAPropertyMapHelper<R,IteratorPropertyMap<RAI,IM,T,R> > 00107 { 00108 public: 00112 typedef RAI RandomAccessIterator; 00113 00119 typedef IM IndexMap; 00120 00124 typedef typename IndexMap::KeyType KeyType; 00125 00129 typedef T ValueType; 00130 00134 typedef R Reference; 00135 00139 typedef LvaluePropertyMapTag Category; 00140 00148 inline IteratorPropertyMap(RandomAccessIterator iter, 00149 const IndexMap& im=IndexMap()) 00150 :iter_(iter), indexMap_(im) 00151 {} 00152 00154 inline IteratorPropertyMap() 00155 : iter_(), indexMap_() 00156 {} 00157 00159 inline Reference operator[](KeyType key) const 00160 { 00161 return *(iter_ + get(indexMap_, key)); 00162 } 00163 00164 private: 00166 RandomAccessIterator iter_; 00168 IndexMap indexMap_; 00169 }; 00170 00175 template<typename T> 00176 class AssociativePropertyMap 00177 : RAPropertyMapHelper<typename T::value_type::second_type&, 00178 AssociativePropertyMap<T> > 00179 { 00183 typedef T UniqueAssociativeContainer; 00184 00188 typedef typename UniqueAssociativeContainer::value_type::first_type 00189 KeyType; 00190 00194 typedef typename UniqueAssociativeContainer::value_type::second_type 00195 ValueType; 00196 00200 typedef ValueType& Reference; 00201 00205 typedef LvaluePropertyMapTag Category; 00206 00208 inline AssociativePropertyMap() 00209 : map_(0) 00210 {} 00211 00213 inline AssociativePropertyMap(UniqueAssociativeContainer& map) 00214 : map_(&map) 00215 {} 00216 00221 inline Reference operator[](KeyType key)const 00222 { 00223 return map_->find(key)->second; 00224 } 00225 private: 00226 UniqueAssociativeContainer* map_; 00227 }; 00228 00233 template<typename T> 00234 class ConstAssociativePropertyMap 00235 : RAPropertyMapHelper<const typename T::value_type::second_type&, 00236 ConstAssociativePropertyMap<T> > 00237 { 00241 typedef T UniqueAssociativeContainer; 00242 00246 typedef typename UniqueAssociativeContainer::value_type::first_type 00247 KeyType; 00248 00252 typedef typename UniqueAssociativeContainer::value_type::second_type 00253 ValueType; 00254 00258 typedef const ValueType& Reference; 00259 00263 typedef LvaluePropertyMapTag Category; 00264 00266 inline ConstAssociativePropertyMap() 00267 : map_(0) 00268 {} 00269 00271 inline ConstAssociativePropertyMap(const UniqueAssociativeContainer& map) 00272 : map_(&map) 00273 {} 00274 00279 inline Reference operator[](KeyType key)const 00280 { 00281 return map_->find(key)->second; 00282 } 00283 private: 00284 const UniqueAssociativeContainer* map_; 00285 }; 00286 00290 struct IdentityMap 00291 : public RAPropertyMapHelper<std::size_t, IdentityMap> 00292 { 00294 typedef std::size_t KeyType; 00295 00297 typedef std::size_t ValueType; 00298 00300 typedef std::size_t Reference; 00301 00303 typedef ReadablePropertyMapTag Category; 00304 00305 inline ValueType operator[](const KeyType& key) const 00306 { 00307 return key; 00308 } 00309 }; 00310 00311 00317 template<typename T, typename C> 00318 struct PropertyMapTypeSelector 00319 { 00323 typedef T Tag; 00328 typedef C Container; 00329 }; 00330 00331 } 00332 00333 #endif