00001
00002
00003 #ifndef DUNE_PROPERTYMAP_HH
00004 #define DUNE_PROPERTYMAP_HH
00005
00006 #include <cstddef>
00007 #include <iterator>
00008 #include <type_traits>
00009
00010 namespace Dune
00011 {
00012
00013 template<class PM>
00014 struct PropertyMapTraits
00015 {
00019 typedef typename PM::KeyType KeyType;
00023 typedef typename PM::ValueType ValueType;
00027 typedef typename PM::Reference Reference;
00031 typedef typename PM::Category Category;
00032 };
00033
00035 struct ReadablePropertyMapTag
00036 {};
00037
00039 struct WritablePropertyMapTag
00040 {};
00041
00046 struct ReadWritePropertyMapTag
00047 : public ReadablePropertyMapTag, public WritablePropertyMapTag
00048 {};
00049
00053 struct LvaluePropertyMapTag
00054 : public ReadWritePropertyMapTag
00055 {};
00056
00057 template<class T>
00058 struct PropertyMapTraits<T*>
00059 {
00060 typedef T ValueType;
00061 typedef ValueType& Reference;
00062 typedef std::ptrdiff_t KeyType;
00063 typedef LvaluePropertyMapTag Category;
00064 };
00065
00066
00067 template<class T>
00068 struct PropertyMapTraits<const T*>
00069 {
00070 typedef T ValueType;
00071 typedef const ValueType& Reference;
00072 typedef std::ptrdiff_t KeyType;
00073 typedef LvaluePropertyMapTag Category;
00074 };
00075
00076 template<class Reference, class PropertyMap>
00077 struct RAPropertyMapHelper
00078 {};
00079
00080 template<class Reference, class PropertyMap, class Key>
00081 inline Reference
00082 get(const RAPropertyMapHelper<Reference,PropertyMap>& pmap,
00083 const Key& key)
00084 {
00085 return static_cast<const PropertyMap&>(pmap)[key];
00086 }
00087
00088 template<class Reference, class PropertyMap, class Key, class Value>
00089 inline void
00090 put(const RAPropertyMapHelper<Reference,PropertyMap>& pmap,
00091 const Key& key, const Value& value)
00092 {
00093 static_assert(std::is_convertible<typename PropertyMap::Category,WritablePropertyMapTag>::value,
00094 "WritablePropertyMapTag required!");
00095 static_cast<const PropertyMap&>(pmap)[key] = value;
00096 }
00097
00101 template<class RAI, class IM,
00102 class T = typename std::iterator_traits<RAI>::value_type,
00103 class R = typename std::iterator_traits<RAI>::reference>
00104 class IteratorPropertyMap
00105 : public RAPropertyMapHelper<R,IteratorPropertyMap<RAI,IM,T,R> >
00106 {
00107 public:
00111 typedef RAI RandomAccessIterator;
00112
00118 typedef IM IndexMap;
00119
00123 typedef typename IndexMap::KeyType KeyType;
00124
00128 typedef T ValueType;
00129
00133 typedef R Reference;
00134
00138 typedef LvaluePropertyMapTag Category;
00139
00147 inline IteratorPropertyMap(RandomAccessIterator iter,
00148 const IndexMap& im=IndexMap())
00149 : iter_(iter), indexMap_(im)
00150 {}
00151
00153 inline IteratorPropertyMap()
00154 : iter_(), indexMap_()
00155 {}
00156
00158 inline Reference operator[](KeyType key) const
00159 {
00160 return *(iter_ + get(indexMap_, key));
00161 }
00162
00163 private:
00165 RandomAccessIterator iter_;
00167 IndexMap indexMap_;
00168 };
00169
00174 template<typename T>
00175 class AssociativePropertyMap
00176 : RAPropertyMapHelper<typename T::value_type::second_type&,
00177 AssociativePropertyMap<T> >
00178 {
00182 typedef T UniqueAssociativeContainer;
00183
00187 typedef typename UniqueAssociativeContainer::value_type::first_type
00188 KeyType;
00189
00193 typedef typename UniqueAssociativeContainer::value_type::second_type
00194 ValueType;
00195
00199 typedef ValueType& Reference;
00200
00204 typedef LvaluePropertyMapTag Category;
00205
00207 inline AssociativePropertyMap()
00208 : map_(0)
00209 {}
00210
00212 inline AssociativePropertyMap(UniqueAssociativeContainer& map)
00213 : map_(&map)
00214 {}
00215
00220 inline Reference operator[](KeyType key) const
00221 {
00222 return map_->find(key)->second;
00223 }
00224 private:
00225 UniqueAssociativeContainer* map_;
00226 };
00227
00232 template<typename T>
00233 class ConstAssociativePropertyMap
00234 : RAPropertyMapHelper<const typename T::value_type::second_type&,
00235 ConstAssociativePropertyMap<T> >
00236 {
00240 typedef T UniqueAssociativeContainer;
00241
00245 typedef typename UniqueAssociativeContainer::value_type::first_type
00246 KeyType;
00247
00251 typedef typename UniqueAssociativeContainer::value_type::second_type
00252 ValueType;
00253
00257 typedef const ValueType& Reference;
00258
00262 typedef LvaluePropertyMapTag Category;
00263
00265 inline ConstAssociativePropertyMap()
00266 : map_(0)
00267 {}
00268
00270 inline ConstAssociativePropertyMap(const UniqueAssociativeContainer& map)
00271 : map_(&map)
00272 {}
00273
00278 inline Reference operator[](KeyType key) const
00279 {
00280 return map_->find(key)->second;
00281 }
00282 private:
00283 const UniqueAssociativeContainer* map_;
00284 };
00285
00289 struct IdentityMap
00290 : public RAPropertyMapHelper<std::size_t, IdentityMap>
00291 {
00293 typedef std::size_t KeyType;
00294
00296 typedef std::size_t ValueType;
00297
00299 typedef std::size_t Reference;
00300
00302 typedef ReadablePropertyMapTag Category;
00303
00304 inline ValueType operator[](const KeyType& key) const
00305 {
00306 return key;
00307 }
00308 };
00309
00310
00316 template<typename T, typename C>
00317 struct PropertyMapTypeSelector
00318 {
00322 typedef T Tag;
00327 typedef C Container;
00328 };
00329
00330 }
00331
00332 #endif