From 241a51778bd4841ee4d8fa87d108a644225b335e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Robert=20Kl=C3=B6fkorn?= <robertk@dune-project.org>
Date: Tue, 18 Jan 2005 16:12:57 +0000
Subject: [PATCH] example implementation for const grid iterators. example here
 LevelIterator.

[[Imported from SVN: r1372]]
---
 grid/albertagrid.hh               | 103 +++++++++++++++++++--
 grid/albertagrid/albertagrid.cc   |  89 +++++++++++++++---
 grid/common/constgriditerators.hh | 145 ++++++++++++++++++++++++++++++
 grid/common/grid.hh               |   1 +
 4 files changed, 320 insertions(+), 18 deletions(-)
 create mode 100644 grid/common/constgriditerators.hh

diff --git a/grid/albertagrid.hh b/grid/albertagrid.hh
index e01c052aa..fe78bf2cd 100644
--- a/grid/albertagrid.hh
+++ b/grid/albertagrid.hh
@@ -312,10 +312,10 @@ namespace Dune
     //! return the global unique index in grid
     int global_index() const ;
 
-    AlbertaGridEntity(AlbertaGrid<dim,dimworld> &grid, int level,
+    AlbertaGridEntity(const AlbertaGrid<dim,dimworld> &grid, int level,
                       ALBERTA TRAVERSE_STACK * travStack);
 
-    AlbertaGridEntity(AlbertaGrid<dim,dimworld> &grid, int level);
+    AlbertaGridEntity(const AlbertaGrid<dim,dimworld> &grid, int level);
 
     //! geometry of this entity
     AlbertaGridElement<dim-codim,dimworld>& geometry () const;
@@ -344,7 +344,7 @@ namespace Dune
     // private Methods
     void makeDescription();
 
-    AlbertaGrid<dim,dimworld> &grid_;
+    const AlbertaGrid<dim,dimworld> &grid_;
 
     // private Members
     ALBERTA EL_INFO *elInfo_;
@@ -550,7 +550,7 @@ namespace Dune
     void makeDescription();
 
     //! the corresponding grid
-    AlbertaGrid<dim,dimworld> &grid_;
+    AlbertaGrid<dim,dimworld> & grid_;
 
     //! the level of the entity
     int level_;
@@ -879,11 +879,17 @@ namespace Dune
     bool operator!= (const AlbertaGridLevelIteratorType & i) const;
 
     //! dereferencing
-    AlbertaGridEntity<codim,dim,dimworld>& operator*() ;
+    AlbertaGridEntity<codim,dim,dimworld>& operator *() ;
 
     //! arrow
     AlbertaGridEntity<codim,dim,dimworld>* operator->() ;
 
+    //! dereferencing
+    const AlbertaGridEntity<codim,dim,dimworld>& operator *() const ;
+
+    //! arrow
+    const AlbertaGridEntity<codim,dim,dimworld>* operator->() const ;
+
     //! ask for level of entity
     int level () const;
 
@@ -915,7 +921,7 @@ namespace Dune
     ALBERTA MACRO_EL * nextGhostMacro(ALBERTA MACRO_EL *mel);
 
     //! the grid were it all comes from
-    AlbertaGrid<dim,dimworld> &grid_;
+    AlbertaGrid<dim,dimworld> & grid_;
 
     //! level :)
     int level_;
@@ -953,6 +959,7 @@ namespace Dune
   //**********************************************************************
   //
   // --AlbertaGrid
+  // --Grid
   //
   //**********************************************************************
 
@@ -989,6 +996,56 @@ namespace Dune
     // The Interface Methods
     //**********************************************************
   public:
+    //! remember the types of template parameters
+    template <int codim>
+    struct Traits
+    {
+      //! Please doc me!
+      typedef albertCtype CoordType;
+
+      //! Please doc me!
+      typedef AlbertaGrid<dim,dimworld>           ImpGrid;
+
+      //! Please doc me!
+      typedef AlbertaGridLevelIterator<codim,dim,dimworld,All_Partition>  LevelIterator;
+
+      //! Please doc me!
+      typedef AlbertaGridLevelIterator<codim,dim,dimworld,Interior_Partition>        InteriorLevelIterator;
+
+      //! Please doc me!
+      typedef AlbertaGridLevelIterator<codim,dim,dimworld,InteriorBorder_Partition>  InteriorBorderLevelIterator;
+
+      //! Please doc me!
+      typedef AlbertaGridLevelIterator<codim,dim,dimworld,Overlap_Partition>         OverlapLevelIterator;
+
+      //! Please doc me!
+      typedef AlbertaGridLevelIterator<codim,dim,dimworld,OverlapFront_Partition>    OverlapFrontLevelIterator;
+
+      //! Please doc me!
+      typedef AlbertaGridLevelIterator<codim,dim,dimworld,Ghost_Partition>           GhostLevelIterator;
+
+      //! Please doc me!
+      typedef ConstLevelIteratorWrapper<AlbertaGridLevelIterator<codim,dim,dimworld,All_Partition> >  ConstLevelIterator;
+
+      //! Please doc me!
+      typedef ConstLevelIteratorWrapper<AlbertaGridLevelIterator<codim,dim,dimworld,Interior_Partition> > ConstInteriorLevelIterator;
+
+      //! Please doc me!
+      typedef ConstLevelIteratorWrapper<AlbertaGridLevelIterator<codim,dim,dimworld,InteriorBorder_Partition> > ConstInteriorBorderLevelIterator;
+
+      //! Please doc me!
+      typedef ConstLevelIteratorWrapper<AlbertaGridLevelIterator<codim,dim,dimworld,Overlap_Partition> > ConstOverlapLevelIterator;
+
+      //! Please doc me!
+      typedef ConstLevelIteratorWrapper<AlbertaGridLevelIterator<codim,dim,dimworld,OverlapFront_Partition> > ConstOverlapFrontLevelIterator;
+
+      //! Please doc me!
+      typedef ConstLevelIteratorWrapper<AlbertaGridLevelIterator<codim,dim,dimworld,Ghost_Partition> > ConstGhostLevelIterator;
+
+      //! Please doc me!
+      typedef AlbertaGridEntity<codim,dim,dimworld>         Entity;
+    };
+
     typedef AlbertaGridLevelIterator<0,dim,dimworld,All_Partition> LeafIterator;
     typedef AlbertaGridReferenceElement<dim> ReferenceElement;
 
@@ -996,6 +1053,16 @@ namespace Dune
     typedef std::pair < ObjectStreamType * ,
         AlbertaGridEntity<0,dim,dimworld>  * > DataCollectorParamType;
 
+    template<int codim, PartitionIteratorType pitype>
+    struct ConstAlbertaGridLevelIterator
+    {
+      typedef ConstLevelIteratorWrapper<
+          AlbertaGridLevelIterator<codim,dim,dimworld,pitype> > IteratorType;
+    };
+
+    typedef typename ConstAlbertaGridLevelIterator<0,All_Partition> :: IteratorType Const0LevelIteratorType;
+    typedef typename ConstAlbertaGridLevelIterator<dim,All_Partition> :: IteratorType ConstDimLevelIteratorType;
+
     //! we always have dim+1 codimensions since we use only simplices
     enum { numCodim = dim+1 };
 
@@ -1043,6 +1110,28 @@ namespace Dune
     template<int codim> AlbertaGridLevelIterator<codim,dim,dimworld,All_Partition>
     lend (int level, int proc = -1 );
 
+    // the const versions
+
+    //! Iterator to first entity of given codim on level
+    template<int codim, PartitionIteratorType pitype>
+    typename ConstAlbertaGridLevelIterator <codim,pitype> :: IteratorType
+    lbegin (int level, int proc = -1 ) const;
+
+    //! one past the end on this level
+    template<int codim, PartitionIteratorType pitype>
+    typename ConstAlbertaGridLevelIterator <codim,pitype> :: IteratorType
+    lend (int level, int proc = -1 ) const;
+
+    //! Iterator to first entity of given codim on level
+    template<int codim>
+    typename ConstAlbertaGridLevelIterator <codim,All_Partition> :: IteratorType
+    lbegin (int level, int proc = -1 ) const;
+
+    //! one past the end on this level
+    template<int codim>
+    typename ConstAlbertaGridLevelIterator <codim,All_Partition> :: IteratorType
+    lend (int level, int proc = -1 ) const;
+
     /** \brief Number of grid entities per level and codim
      * because lbegin and lend are none const, and we need this methods
      * counting the entities on each level, you know.
@@ -1183,7 +1272,7 @@ namespace Dune
 
     //! map the global index from the Albert Mesh to the local index on Level
     template <int codim>
-    int indexOnLevel(int globalIndex, int level ) ;
+    int indexOnLevel(int globalIndex, int level ) const ;
 
     // pointer to the real number of elements or vertices
     // i.e. points to mesh->n_hier_elements or mesh->n_vertices
diff --git a/grid/albertagrid/albertagrid.cc b/grid/albertagrid/albertagrid.cc
index 43b170500..184c63185 100644
--- a/grid/albertagrid/albertagrid.cc
+++ b/grid/albertagrid/albertagrid.cc
@@ -839,7 +839,7 @@ namespace Dune
 
   template<int codim, int dim, int dimworld>
   inline AlbertaGridEntity < codim, dim ,dimworld >::
-  AlbertaGridEntity(AlbertaGrid<dim,dimworld> &grid, int level,
+  AlbertaGridEntity(const AlbertaGrid<dim,dimworld> &grid, int level,
                     ALBERTA TRAVERSE_STACK * travStack) : grid_(grid)
                                                           , level_ ( level )
                                                           , geo_ (false)
@@ -858,7 +858,7 @@ namespace Dune
 
   template<int codim, int dim, int dimworld>
   inline AlbertaGridEntity < codim, dim ,dimworld >::
-  AlbertaGridEntity(AlbertaGrid<dim,dimworld> &grid, int level) :
+  AlbertaGridEntity(const AlbertaGrid<dim,dimworld> &grid, int level) :
     grid_(grid)
     , level_ (level)
     , geo_ ( false )
@@ -898,6 +898,7 @@ namespace Dune
   inline int AlbertaGridEntity < codim, dim ,dimworld >::
   index() const
   {
+    assert(elNum_ >= 0);
     return elNum_;
   }
 
@@ -1107,12 +1108,13 @@ namespace Dune
 
   template< int dim, int dimworld>
   inline AlbertaGridEntity < 0, dim ,dimworld >::
-  AlbertaGridEntity(AlbertaGrid<dim,dimworld> &grid, int level) : grid_(grid)
-                                                                  , level_ (level)
-                                                                  , vxEntity_ ( grid_ , -1, 0, 0, 0, 0, 0)
-                                                                  , travStack_ (0) , elInfo_ (0)
-                                                                  , geo_(false)
-                                                                  , builtgeometry_ (false)
+  AlbertaGridEntity(AlbertaGrid<dim,dimworld> &grid, int level)
+    : grid_(grid)
+      , level_ (level)
+      , vxEntity_ ( grid_ , -1, 0, 0, 0, 0, 0)
+      , travStack_ (0) , elInfo_ (0)
+      , geo_(false)
+      , builtgeometry_ (false)
   {}
 
   //*****************************************************************8
@@ -2122,7 +2124,8 @@ namespace Dune
   inline AlbertaGridLevelIterator<codim,dim,dimworld,pitype>::
   AlbertaGridLevelIterator(AlbertaGrid<dim,dimworld> &grid, int travLevel,
                            int proc, bool leafIt ) :
-    grid_(grid), level_ (travLevel) ,  virtualEntity_(grid,travLevel)
+    grid_(grid), level_ (travLevel) ,
+    virtualEntity_(grid,travLevel)
     ,leafIt_(leafIt) , proc_(proc)
   {
     makeIterator();
@@ -2133,7 +2136,8 @@ namespace Dune
   inline AlbertaGridLevelIterator<codim,dim,dimworld,pitype>::
   AlbertaGridLevelIterator(AlbertaGrid<dim,dimworld> &grid, int level,
                            ALBERTA EL_INFO *elInfo,int elNum,int face,int edge,int vertex) :
-    grid_(grid), level_ (level) , virtualEntity_(grid,level) , elNum_ ( elNum ) , face_ ( face ) ,
+    grid_(grid), level_ (level)
+    , virtualEntity_(grid,level) , elNum_ ( elNum ) , face_ ( face ) ,
     edge_ ( edge ), vertex_ ( vertex ) , leafIt_(false) ,
     proc_(-1)
   {
@@ -2292,6 +2296,22 @@ namespace Dune
     return &virtualEntity_;
   }
 
+  template<int codim, int dim, int dimworld,PartitionIteratorType pitype>
+  inline const AlbertaGridEntity<codim,dim,dimworld> &
+  AlbertaGridLevelIterator<codim,dim,dimworld,pitype>::operator *() const
+  {
+    assert(virtualEntity_.getElInfo() != 0);
+    return virtualEntity_;
+  }
+
+  template<int codim, int dim, int dimworld,PartitionIteratorType pitype>
+  inline const AlbertaGridEntity< codim,dim,dimworld >*
+  AlbertaGridLevelIterator<codim,dim,dimworld,pitype>::operator ->() const
+  {
+    assert(virtualEntity_.getElInfo() != 0);
+    return &virtualEntity_;
+  }
+
 
   template<int codim, int dim, int dimworld,PartitionIteratorType pitype>
   inline ALBERTA EL_INFO * AlbertaGridLevelIterator<codim,dim,dimworld,pitype>::
@@ -3197,6 +3217,53 @@ namespace Dune
     return it;
   }
 
+  //**********************************************
+  // the const versions of LevelIterator
+  //**********************************************
+  template < int dim, int dimworld > template<int codim, PartitionIteratorType pitype>
+  inline typename AlbertaGrid < dim, dimworld > :: template ConstAlbertaGridLevelIterator<codim,pitype> :: IteratorType
+  AlbertaGrid < dim, dimworld >::lbegin (int level, int proc) const
+  {
+    // const_cast ok, because constness of object is preserved via const iterator
+    AlbertaGrid<dim,dimworld> & mygrid = const_cast<AlbertaGrid<dim,dimworld> &> (*this);
+    AlbertaGridLevelIterator<codim,dim,dimworld,pitype> it( mygrid ,vertexMarker_,level,proc);
+    typename ConstAlbertaGridLevelIterator<codim,pitype> :: IteratorType cit ( it );
+    return cit;
+  }
+
+  template < int dim, int dimworld > template<int codim, PartitionIteratorType pitype>
+  inline typename AlbertaGrid < dim, dimworld >::template ConstAlbertaGridLevelIterator<codim,pitype> :: IteratorType
+  AlbertaGrid < dim, dimworld >::lend (int level, int proc ) const
+  {
+    // const_cast ok, because constness of object is preserved via const iterator
+    AlbertaGrid<dim,dimworld> & mygrid = const_cast<AlbertaGrid<dim,dimworld> &> (*this);
+    AlbertaGridLevelIterator<codim,dim,dimworld,pitype> it( mygrid ,level,proc);
+    typename ConstAlbertaGridLevelIterator<codim,pitype> :: IteratorType cit ( it );
+    return cit;
+  }
+
+  template < int dim, int dimworld > template<int codim>
+  inline typename AlbertaGrid < dim, dimworld >:: template ConstAlbertaGridLevelIterator<codim,All_Partition> :: IteratorType
+  AlbertaGrid < dim, dimworld >::lbegin (int level, int proc) const
+  {
+    // const_cast ok, because constness of object is preserved via const iterator
+    AlbertaGrid<dim,dimworld> & mygrid = const_cast<AlbertaGrid<dim,dimworld> &> (*this);
+    AlbertaGridLevelIterator<codim,dim,dimworld,All_Partition> it( mygrid ,vertexMarker_,level,proc);
+    typename ConstAlbertaGridLevelIterator<codim,All_Partition> :: IteratorType cit ( it );
+    return cit;
+  }
+
+  template < int dim, int dimworld > template<int codim>
+  inline typename AlbertaGrid < dim, dimworld >:: template ConstAlbertaGridLevelIterator<codim,All_Partition> :: IteratorType
+  AlbertaGrid < dim, dimworld >::lend (int level, int proc ) const
+  {
+    // const_cast ok, because constness of object is preserved via const iterator
+    AlbertaGrid<dim,dimworld> & mygrid = const_cast<AlbertaGrid<dim,dimworld> &> (*this);
+    AlbertaGridLevelIterator<codim,dim,dimworld,All_Partition> it( mygrid ,level,proc);
+    typename ConstAlbertaGridLevelIterator<codim,All_Partition> :: IteratorType cit ( it );
+    return cit;
+  }
+
   //*****************************************************************
   template < int dim, int dimworld >
   inline AlbertaGridLevelIterator<0,dim,dimworld,All_Partition>
@@ -3617,7 +3684,7 @@ namespace Dune
 
   template < int dim, int dimworld > template <int codim>
   inline int AlbertaGrid < dim, dimworld >::
-  indexOnLevel(int globalIndex, int level)
+  indexOnLevel(int globalIndex, int level) const
   {
     assert(hasLevelIndex_ == true);
     // level = 0 is not interesting for this implementation
diff --git a/grid/common/constgriditerators.hh b/grid/common/constgriditerators.hh
new file mode 100644
index 000000000..84736d8cb
--- /dev/null
+++ b/grid/common/constgriditerators.hh
@@ -0,0 +1,145 @@
+// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+// vi: set et ts=4 sw=2 sts=2:
+#ifndef __DUNE_CONSTGRIDITERATORS_HH__
+#define __DUNE_CONSTGRIDITERATORS_HH__
+
+#include <string>
+#include <dune/common/matvec.hh>
+#include <dune/common/exceptions.hh>
+
+namespace Dune {
+
+  /** @defgroup GridCommon Grid Interface
+
+     These Iterators define wrapper for const versions
+     of all interface grid iterators.
+
+     @{
+   */
+
+  //************************************************************************
+  // C O N S T  L E V E L I T E R A T O R
+  //************************************************************************
+
+  /** \brief Enables iteration over all entities of a given codimension and level of a grid.
+   */
+  template <class LevelIteratorImp>
+  class ConstLevelIteratorWrapper
+  {
+    typedef ConstLevelIteratorWrapper<LevelIteratorImp> ConstLevelIteratorType;
+  public:
+    struct Traits
+    {
+      /** \todo Please doc me! */
+      typedef typename LevelIteratorImp:: Traits :: CoordType CoordType;
+
+      /** \todo Please doc me! */
+      typedef const typename LevelIteratorImp :: Traits :: Entity Entity;
+
+      //! Please doc me!
+      typedef const typename LevelIteratorImp :: Traits :: LevelIterator LevelIterator;
+
+      //! Please doc me!
+      typedef const typename LevelIteratorImp :: Traits :: InteriorLevelIterator InteriorLevelIterator;
+
+      //! Please doc me!
+      typedef const typename LevelIteratorImp :: Traits :: InteriorBorderLevelIterator InteriorBorderLevelIterator;
+
+      //! Please doc me!
+      typedef const typename LevelIteratorImp :: Traits :: OverlapLevelIterator OverlapLevelIterator;
+
+      //! Please doc me!
+      typedef const typename LevelIteratorImp :: Traits :: OverlapFrontLevelIterator OverlapFrontLevelIterator;
+
+      //! Please doc me!
+      typedef const typename LevelIteratorImp :: Traits :: GhostLevelIterator GhostLevelIterator;
+    };
+
+    //! know your own codimension
+    enum { codimension    = LevelIteratorImp :: codimension };
+
+    //! know your own dimension
+    enum { dimension      = LevelIteratorImp :: dimension };
+
+    //! know your own dimension of world
+    enum { dimensionworld = LevelIteratorImp :: dimensionworld };
+
+    //! copy the normal LevelIterator, this is ok because the normal
+    //! interface method lbegin uses copy aswell
+    ConstLevelIteratorWrapper ( LevelIteratorImp & lit);
+
+    //! prefix increment
+    ConstLevelIteratorType & operator ++ ();
+
+    //! equality
+    bool operator== (const ConstLevelIteratorType & i) const;
+
+    //! inequality
+    bool operator!= (const ConstLevelIteratorType & i) const;
+
+    //! dereferencing
+    typename Traits :: Entity & operator*() const;
+
+    //! arrow
+    typename Traits :: Entity * operator->() const;
+
+    //! ask for level of entity
+    int level () const;
+  protected:
+    LevelIteratorImp it_;
+
+  };
+
+  template <class LevelIteratorImp>
+  inline ConstLevelIteratorWrapper<LevelIteratorImp> ::
+  ConstLevelIteratorWrapper( LevelIteratorImp & lit ) : it_ ( lit ) {}
+
+  template <class LevelIteratorImp>
+  inline ConstLevelIteratorWrapper<LevelIteratorImp> &
+  ConstLevelIteratorWrapper<LevelIteratorImp> :: operator++()
+  {
+    ++it_;
+    return (*this);
+  }
+
+  template <class LevelIteratorImp>
+  inline bool ConstLevelIteratorWrapper<LevelIteratorImp> ::
+  operator == ( const ConstLevelIteratorWrapper<LevelIteratorImp> & i) const
+  {
+    return it_ == i.it_;
+  }
+
+  template <class LevelIteratorImp>
+  inline bool ConstLevelIteratorWrapper<LevelIteratorImp> ::
+  operator != ( const ConstLevelIteratorWrapper<LevelIteratorImp> & i) const
+  {
+    return it_ != i.it_;
+  }
+
+  template <class LevelIteratorImp>
+  inline typename ConstLevelIteratorWrapper<LevelIteratorImp> :: Traits :: Entity &
+  ConstLevelIteratorWrapper<LevelIteratorImp> :: operator * () const
+  {
+    return *it_;
+  }
+
+  template <class LevelIteratorImp>
+  inline typename ConstLevelIteratorWrapper<LevelIteratorImp> :: Traits :: Entity *
+  ConstLevelIteratorWrapper<LevelIteratorImp> :: operator -> () const
+  {
+    return it_.operator -> ();
+  }
+
+  template <class LevelIteratorImp>
+  inline int ConstLevelIteratorWrapper<LevelIteratorImp> ::
+  level () const
+  {
+    return it_.level();
+  }
+
+  /** @} */
+
+}
+
+
+#endif
diff --git a/grid/common/grid.hh b/grid/common/grid.hh
index 7d903b20d..ad6c2bb01 100644
--- a/grid/common/grid.hh
+++ b/grid/common/grid.hh
@@ -1591,5 +1591,6 @@ namespace Dune {
 }
 
 #include "grid.cc"
+#include "constgriditerators.hh"
 
 #endif
-- 
GitLab