dune-grid  2.2.0
geometrygrid/entitypointer.hh
Go to the documentation of this file.
00001 #ifndef DUNE_GEOGRID_ENTITYPOINTER_HH
00002 #define DUNE_GEOGRID_ENTITYPOINTER_HH
00003 
00004 #include <dune/grid/common/grid.hh>
00005 
00006 #include <dune/grid/geometrygrid/declaration.hh>
00007 #include <dune/grid/geometrygrid/capabilities.hh>
00008 #include <dune/grid/geometrygrid/entityseed.hh>
00009 
00010 namespace Dune
00011 {
00012 
00013   namespace GeoGrid
00014   {
00015 
00016     // External Forward Declarations
00017     // -----------------------------
00018 
00019     template< int, int, class >
00020     class Entity;
00021 
00022     template< class, class >
00023     struct ExportParams;
00024     
00025 
00026 
00027 
00028     // Internal Forward Declarations
00029     // -----------------------------
00030 
00031     template< int codim, class Grid >
00032     struct EntityPointerTraits;
00033 
00034     template< class Traits, bool fake = Traits::fake >
00035     class EntityPointer;
00036 
00037 
00038 
00039     // EntityPointerTraits
00040     // -------------------
00041     
00042     template< int codim, class Grid >
00043     struct EntityPointerTraits;
00044 
00046     template< int codim, class Grid >
00047     struct EntityPointerTraits< codim, const Grid >
00048     : public EntityPointerTraits< codim, Grid >
00049     {};
00052     template< int codim, class HostGrid, class CoordFunction, class Allocator >
00053     struct EntityPointerTraits< codim, GeometryGrid< HostGrid, CoordFunction, Allocator > >
00054     : public ExportParams< HostGrid, CoordFunction >
00055     {
00056       typedef Dune::GeometryGrid< HostGrid, CoordFunction, Allocator > Grid;
00057 
00058       static const bool fake = !Capabilities::hasHostEntity< Grid, codim >::v;
00059 
00060       typedef typename HostGrid::ctype ctype;
00061 
00062       static const int dimension = HostGrid::dimension;
00063       static const int codimension = codim;
00064 
00065       typedef Dune::Entity< codimension, dimension, const Grid, GeoGrid::Entity > Entity;
00066       typedef GeoGrid::EntitySeed< codimension, const Grid > EntitySeed;
00067               
00068       typedef typename HostGrid::template Codim< codim >::Entity HostEntity;
00069       typedef typename HostGrid::template Codim< codim >::EntityPointer HostEntityPointer;
00070       typedef HostEntityPointer HostEntityIterator;
00071       
00072       typedef typename HostGrid::template Codim< 0 >::Entity HostElement;
00073       typedef typename HostGrid::template Codim< 0 >::EntityPointer HostElementIterator;
00074     };
00075 
00076 
00077 
00078     // EntityPointer (real)
00079     // --------------------
00080 
00081     template< class Traits >
00082     class EntityPointer< Traits, false >
00083     {
00084       typedef EntityPointer< Traits, false > This;
00085 
00086       typedef typename Traits::Grid Grid;
00087     
00088       typedef EntityPointerTraits< Traits::codimension, const Grid > BaseTraits;
00089       friend class EntityPointer< BaseTraits, false >;
00090 
00091     public:
00092       static const int dimension = Traits::dimension;
00093       static const int codimension = Traits::codimension;
00094    
00095       typedef typename Traits::Entity Entity;
00096 
00097       static const bool fake = Traits::fake;
00098      
00099       typedef EntityPointer< BaseTraits, fake > EntityPointerImp;
00100 
00101     protected:
00102       typedef typename Traits::HostEntityPointer HostEntityPointer;
00103       typedef typename Traits::HostEntityIterator HostEntityIterator;
00104       typedef typename Traits::HostElement HostElement;
00105 
00106       typedef typename Traits::EntitySeed EntitySeed;
00107 
00108       typedef GeoGrid::Entity< codimension, dimension, const Grid > EntityImpl;
00109       typedef typename EntityImpl::GeometryImpl GeometryImpl;
00110 
00111     public:
00112       EntityPointer ( const GeometryImpl &geo, const HostEntityIterator &hostEntityIterator )
00113       : entity_( EntityImpl( geo ) ),
00114         hostEntityIterator_( hostEntityIterator )
00115       {}
00116 
00117       EntityPointer ( const Grid &grid, const HostEntityIterator &hostEntityIterator )
00118       : entity_( EntityImpl( grid ) ),
00119         hostEntityIterator_( hostEntityIterator )
00120       {}
00121 
00122       EntityPointer ( const Grid &grid, const HostElement &hostElement, int subEntity )
00123       : entity_( EntityImpl( grid ) ),
00124         hostEntityIterator_( hostElement.template subEntity< codimension >( subEntity ) )
00125       {}
00126 
00127       EntityPointer ( const Grid &grid, const EntitySeed &seed )
00128       : entity_( EntityImpl( grid ) ),
00129         hostEntityIterator_( grid.hostGrid().entityPointer( seed.hostEntitySeed() ) )
00130       {}
00131 
00132       explicit EntityPointer ( const EntityImpl &entity )
00133       : entity_( entity ),
00134         hostEntityIterator_( entity.hostEntity() )
00135       {}
00136 
00137       EntityPointer ( const This &other )
00138       : entity_( other.entityImpl() ),
00139         hostEntityIterator_( other.hostEntityIterator_ )
00140       {}
00141 
00142       template< class T >
00143       explicit EntityPointer ( const EntityPointer< T, fake > &other )
00144       : entity_( other.entityImpl() ),
00145         hostEntityIterator_( other.hostEntityIterator_ )
00146       {}
00147       
00148       const This &operator= ( const This &other )
00149       {
00150         entityImpl() = other.entityImpl();
00151         hostEntityIterator_ = other.hostEntityIterator_;
00152         return *this;
00153       }
00154 
00155       operator const EntityPointerImp & () const
00156       {
00157         return reinterpret_cast< const EntityPointerImp & >( *this );
00158       }
00159 
00160       template< class T >
00161       const This &operator= ( const EntityPointer< T, fake > &other )
00162       {
00163         entityImpl() = other.entityImpl();
00164         hostEntityIterator_ = other.hostEntityIterator_;
00165         return *this;
00166       }
00167 
00168       template< class T >
00169       bool equals ( const EntityPointer< T, fake > &other ) const
00170       {
00171         return (hostIterator() == other.hostIterator());
00172       }
00173       
00174       Entity &dereference () const
00175       {
00176         if( !entityImpl() )
00177           entityImpl().initialize( *hostIterator() );
00178         return entity_;
00179       }
00180       
00181       int level () const { return hostIterator().level(); }
00182 
00183       const HostEntityIterator &hostIterator() const { return hostEntityIterator_; }
00184 
00185       const Grid &grid () const { return entityImpl().grid(); }
00186 
00187     protected:
00188       EntityImpl &entityImpl () const
00189       {
00190         return Grid::getRealImplementation( entity_ );
00191       }
00192 
00193     private:
00194       mutable Entity entity_;
00195 
00196     protected:
00197       HostEntityIterator hostEntityIterator_;
00198     };
00199 
00200 
00201 
00202     // EntityPointer (fake)
00203     // --------------------
00204 
00205     template< class Traits >
00206     class EntityPointer< Traits, true >
00207     {
00208       typedef EntityPointer< Traits, true > This;
00209       
00210       typedef typename Traits::Grid Grid;
00211 
00212       typedef EntityPointerTraits< Traits::codimension, const Grid > BaseTraits;
00213       friend class EntityPointer< BaseTraits, true >;
00214 
00215     public:
00216       static const int dimension = Traits::dimension;
00217       static const int codimension = Traits::codimension;
00218    
00219       typedef typename Traits::Entity Entity;
00220 
00221       static const bool fake = Traits::fake;
00222 
00223       typedef EntityPointer< BaseTraits, fake > EntityPointerImp;
00224 
00225     protected:
00226       typedef typename Traits::HostEntityPointer HostEntityPointer;
00227       typedef typename Traits::HostElementIterator HostElementIterator;
00228       typedef typename Traits::HostElement HostElement;
00229 
00230       typedef typename Traits::EntitySeed EntitySeed;
00231 
00232       typedef GeoGrid::Entity< codimension, dimension, const Grid > EntityImpl;
00233       typedef typename EntityImpl::GeometryImpl GeometryImpl;
00234 
00235     public:
00236       EntityPointer ( const GeometryImpl &geo, const HostElementIterator &hostElementIterator, int subEntity )
00237       : entity_( EntityImpl( geo, subEntity ) ),
00238         hostElementIterator_( hostElementIterator )
00239       {}
00240 
00241       EntityPointer ( const Grid &grid, const HostElementIterator &hostElementIterator, int subEntity )
00242       : entity_( EntityImpl( grid, subEntity ) ),
00243         hostElementIterator_( hostElementIterator )
00244       {}
00245 
00246       EntityPointer ( const Grid &grid, const HostElement &hostElement, int subEntity )
00247       : entity_( EntityImpl( grid, subEntity ) ),
00248         hostElementIterator_( hostElement )
00249       {}
00250 
00251       EntityPointer ( const Grid &grid, const EntitySeed &seed )
00252       : entity_( EntityImpl( grid, seed.subEntity() ) ),
00253         hostElementIterator_( grid.hostGrid().entityPointer( seed.hostElementSeed() ) )
00254       {}
00255 
00256       explicit EntityPointer ( const EntityImpl &entity )
00257       : entity_( entity ),
00258         hostElementIterator_( entity.hostElement() )
00259       {}
00260 
00261       EntityPointer ( const This &other )
00262       : entity_( other.entityImpl() ),
00263         hostElementIterator_( other.hostElementIterator_ )
00264       {}
00265 
00266       template< class T >
00267       explicit EntityPointer ( const EntityPointer< T, fake > &other )
00268       : entity_( other.entityImpl() ),
00269         hostElementIterator_( other.hostElementIterator_ )
00270       {}
00271 
00272       const This &operator= ( const This &other )
00273       {
00274         entityImpl() = other.entityImpl();
00275         hostElementIterator_ = other.hostElementIterator_;
00276         return *this;
00277       }
00278 
00279       operator const EntityPointerImp & () const
00280       {
00281         return reinterpret_cast< const EntityPointerImp & >( *this );
00282       }
00283 
00284       template< class T >
00285       const This &operator= ( const EntityPointer< T, fake > &other )
00286       {
00287         entityImpl() = other.entityImpl();
00288         hostElementIterator_ = other.hostElementIterator_;
00289         return *this;
00290       }
00291 
00292       template< class T >
00293       bool equals ( const EntityPointer< T, fake > &other ) const
00294       {
00295         const bool thisEnd = (subEntity() < 0);
00296         const bool otherEnd = (other.subEntity() < 0);
00297         if( thisEnd || otherEnd )
00298           return thisEnd && otherEnd;
00299 
00300         const int lvl = level();
00301         if( lvl != other.level() )
00302           return false;
00303 
00304         const typename Traits::HostGrid::Traits::LevelIndexSet &indexSet
00305           = grid().hostGrid().levelIndexSet( lvl );
00306 
00307         const HostElement &thisElement = *hostElementIterator();
00308         assert( indexSet.contains( thisElement ) );
00309         const HostElement &otherElement = *(other.hostElementIterator());
00310         assert( indexSet.contains( otherElement ) );
00311 
00312         const int thisIndex = indexSet.subIndex( thisElement, subEntity(), codimension );
00313         const int otherIndex = indexSet.subIndex( otherElement, other.subEntity(), codimension );
00314         return (thisIndex == otherIndex);
00315       }
00316       
00317       Entity &dereference () const
00318       {
00319         if( !entityImpl() )
00320           entityImpl().initialize( *hostElementIterator() );
00321         return entity_;
00322       }
00323       
00324       int level () const { return hostElementIterator().level(); }
00325 
00326       const Grid &grid () const { return entityImpl().grid(); }
00327       int subEntity () const { return entityImpl().subEntity(); }
00328 
00329     protected:
00330       EntityImpl &entityImpl () const
00331       {
00332         return Grid::getRealImplementation( entity_ );
00333       }
00334 
00335       const HostElementIterator &hostElementIterator () const
00336       {
00337         return hostElementIterator_;
00338       }
00339 
00340     private:
00341       mutable Entity entity_;
00342 
00343     protected:
00344       HostElementIterator hostElementIterator_;
00345     };
00346 
00347   } // namespace GeoGrid
00348 
00349 } // namespace Dune
00350 
00351 #endif // #ifndef DUNE_GEOGRID_ENTITYPOINTER_HH