propertymap.hh
00001
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 KeyTyoe;
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
00318 template<typename T, typename C>
00319 struct PropertyMapTypeSelector
00320 {
00324 typedef T Tag;
00329 typedef C Container;
00330 };
00331
00332 }
00333
00334 #endif