propertymap.hh

00001 // $Id: propertymap.hh 3355 2005-11-08 21:03:56Z mblatt $
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

Generated on 12 Dec 2007 with Doxygen (ver 1.5.1)