dune-common  2.2.0
propertymap.hh
Go to the documentation of this file.
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