00001
00002 #ifndef DUNE_PROPERTYMAP_HH
00003 #define DUNE_PROPERTYMAP_HH
00004
00005 #include<cstddef>
00006 #include"helpertemplates.hh"
00007 #include"typetraits.hh"
00008
00009 namespace Dune
00010 {
00011
00012 template<class PM>
00013 struct PropertyMapTraits
00014 {
00018 typedef typename PM::KeyType KeyType;
00022 typedef typename PM::ValueType ValueType;
00026 typedef typename PM::Reference Reference;
00030 typedef typename PM::Category Category;
00031 };
00032
00034 struct ReadablePropertyMapTag
00035 {};
00036
00038 struct WritablePropertyMapTag
00039 {};
00040
00045 struct ReadWritePropertyMapTag
00046 : public ReadablePropertyMapTag, public WritablePropertyMapTag
00047 {};
00048
00052 struct LvaluePropertyMapTag
00053 : public ReadWritePropertyMapTag
00054 {};
00055
00056 template<class T>
00057 struct PropertyMapTraits<T*>
00058 {
00059 typedef T ValueType;
00060 typedef ValueType& Reference;
00061 typedef std::ptrdiff_t KeyType;
00062 typedef LvaluePropertyMapTag Category;
00063 };
00064
00065
00066 template<class T>
00067 struct PropertyMapTraits<const T*>
00068 {
00069 typedef T ValueType;
00070 typedef const ValueType& Reference;
00071 typedef std::ptrdiff_t KeyTyoe;
00072 typedef LvaluePropertyMapTag Category;
00073 };
00074
00075 template<class Reference, class PropertyMap>
00076 struct RAPropertyMapHelper
00077 {};
00078
00079 template<class Reference, class PropertyMap, class Key>
00080 inline Reference
00081 get(const RAPropertyMapHelper<Reference,PropertyMap>& pmap,
00082 const Key& key)
00083 {
00084 return static_cast<const PropertyMap&>(pmap)[key];
00085 }
00086
00087 template<class Reference, class PropertyMap, class Key, class Value>
00088 inline void
00089 put(const RAPropertyMapHelper<Reference,PropertyMap>& pmap,
00090 const Key& key, const Value& value)
00091 {
00092 IsTrue<Conversion<typename PropertyMap::Category,WritablePropertyMapTag>
00093 ::exists>::yes();
00094 static_cast<const PropertyMap&>(pmap)[key] = value;
00095 }
00096
00100 template<class RAI, class IM,
00101 class T = typename std::iterator_traits<RAI>::value_type,
00102 class R = typename std::iterator_traits<RAI>::reference>
00103 class IteratorPropertyMap
00104 : public RAPropertyMapHelper<R,IteratorPropertyMap<RAI,IM,T,R> >
00105 {
00106 public:
00110 typedef RAI RandomAccessIterator;
00111
00117 typedef IM IndexMap;
00118
00122 typedef typename IndexMap::KeyType KeyType;
00123
00127 typedef T ValueType;
00128
00132 typedef R Reference;
00133
00137 typedef LvaluePropertyMapTag Category;
00138
00146 inline IteratorPropertyMap(RandomAccessIterator iter,
00147 const IndexMap& im)
00148 :iter_(iter), indexMap_(im)
00149 {}
00150
00152 inline IteratorPropertyMap()
00153 : iter_(), indexMap_()
00154 {}
00155
00157 inline Reference operator[](KeyType key) const
00158 {
00159 return *(iter_ + get(indexMap_, key));
00160 }
00161
00162 private:
00164 RandomAccessIterator iter_;
00166 IndexMap indexMap_;
00167 };
00168
00173 template<typename T>
00174 class AssociativePropertyMap
00175 : RAPropertyMapHelper<typename T::value_type::second_type&,
00176 AssociativePropertyMap<T> >
00177 {
00181 typedef T UniqueAssociativeContainer;
00182
00186 typedef typename UniqueAssociativeContainer::value_type::first_type
00187 KeyType;
00188
00192 typedef typename UniqueAssociativeContainer::value_type::second_type
00193 ValueType;
00194
00198 typedef ValueType& Reference;
00199
00203 typedef LvaluePropertyMapTag Category;
00204
00206 inline AssociativePropertyMap()
00207 : map_(0)
00208 {}
00209
00211 inline AssociativePropertyMap(UniqueAssociativeContainer& map)
00212 : map_(&map)
00213 {}
00214
00219 inline Reference operator[](KeyType key)const
00220 {
00221 return map_->find(key)->second;
00222 }
00223 private:
00224 UniqueAssociativeContainer* map_;
00225 };
00226
00231 template<typename T>
00232 class ConstAssociativePropertyMap
00233 : RAPropertyMapHelper<const typename T::value_type::second_type&,
00234 ConstAssociativePropertyMap<T> >
00235 {
00239 typedef T UniqueAssociativeContainer;
00240
00244 typedef typename UniqueAssociativeContainer::value_type::first_type
00245 KeyType;
00246
00250 typedef typename UniqueAssociativeContainer::value_type::second_type
00251 ValueType;
00252
00256 typedef const ValueType& Reference;
00257
00261 typedef LvaluePropertyMapTag Category;
00262
00264 inline ConstAssociativePropertyMap()
00265 : map_(0)
00266 {}
00267
00269 inline ConstAssociativePropertyMap(const UniqueAssociativeContainer& map)
00270 : map_(&map)
00271 {}
00272
00277 inline Reference operator[](KeyType key)const
00278 {
00279 return map_->find(key)->second;
00280 }
00281 private:
00282 const UniqueAssociativeContainer* map_;
00283 };
00284
00288 struct IdentityMap
00289 : public RAPropertyMapHelper<std::size_t, IdentityMap>
00290 {
00292 typedef std::size_t KeyType;
00293
00295 typedef std::size_t ValueType;
00296
00298 typedef std::size_t Reference;
00299
00301 typedef ReadablePropertyMapTag Category;
00302
00303 inline ValueType operator[](const KeyType& key) const
00304 {
00305 return key;
00306 }
00307 };
00308
00309
00316 template<typename T, typename C>
00317 struct PropertyMapTypeSelector
00318 {
00322 typedef T Tag;
00327 typedef C Container;
00328 };
00329
00330 }
00331
00332 #endif