From 115308456cfa45cf83958487040b01697d8b7b30 Mon Sep 17 00:00:00 2001
From: Timo Koch <timo.koch@iws.uni-stuttgart.de>
Date: Thu, 1 Jul 2021 21:04:13 +0200
Subject: [PATCH] [entity] Cleanup hierarchic iterator

---
 dune/foamgrid/foamgrid/foamgridentity.hh      | 36 +--------
 .../foamgrid/foamgridhierarchiciterator.hh    | 75 ++++++++++++-------
 2 files changed, 51 insertions(+), 60 deletions(-)

diff --git a/dune/foamgrid/foamgrid/foamgridentity.hh b/dune/foamgrid/foamgrid/foamgridentity.hh
index 53ef4a9..e72ed34 100644
--- a/dune/foamgrid/foamgrid/foamgridentity.hh
+++ b/dune/foamgrid/foamgrid/foamgridentity.hh
@@ -453,26 +453,12 @@ class FoamGridEntity<0, 2, GridImp> :
         * Returns iterator to first son.
         */
         FoamGridHierarchicIterator<GridImp> hbegin (int maxLevel) const
-        {
-            FoamGridHierarchicIterator<GridImp> it(maxLevel);
-
-            // Load sons of old target onto the iterator stack
-            if (level()<=maxLevel && !isLeaf())
-                for (std::size_t i=0; i<target_->nSons(); i++)
-                    it.elemStack.push(target_->sons_[i]);
-
-            it.virtualEntity_.impl().setToTarget((it.elemStack.empty())
-                                          ? nullptr : it.elemStack.top());
-
-            return it;
-        }
+        { return { target_, maxLevel }; }
 
 
         //! Returns iterator to one past the last son
         FoamGridHierarchicIterator<GridImp> hend (int maxLevel) const
-        {
-            return FoamGridHierarchicIterator<const GridImp>(maxLevel);
-        }
+        { return { maxLevel }; }
 
 
         // /////////////////////////////////////////
@@ -758,26 +744,12 @@ class FoamGridEntity<0, 1, GridImp> :
         * Returns iterator to first son.
         */
         FoamGridHierarchicIterator<GridImp> hbegin (int maxLevel) const
-        {
-            FoamGridHierarchicIterator<GridImp> it(maxLevel);
-
-            // Load sons of old target onto the iterator stack
-            if (level()<=maxLevel && !isLeaf())
-                for (std::size_t i=0; i<target_->nSons(); i++)
-                    it.elemStack.push(target_->sons_[i]);
-
-            it.virtualEntity_.impl().setToTarget((it.elemStack.empty())
-                                          ? nullptr : it.elemStack.top());
-
-            return it;
-        }
+        { return { target_, maxLevel }; }
 
 
         //! Returns iterator to one past the last son
         FoamGridHierarchicIterator<GridImp> hend (int maxLevel) const
-        {
-            return FoamGridHierarchicIterator<const GridImp>(maxLevel);
-        }
+        { return { maxLevel }; }
 
 
         // /////////////////////////////////////////
diff --git a/dune/foamgrid/foamgrid/foamgridhierarchiciterator.hh b/dune/foamgrid/foamgrid/foamgridhierarchiciterator.hh
index ae1bb8d..0bb3a4b 100644
--- a/dune/foamgrid/foamgrid/foamgridhierarchiciterator.hh
+++ b/dune/foamgrid/foamgrid/foamgridhierarchiciterator.hh
@@ -22,12 +22,12 @@ starting from a given entity.
 template<class GridImp>
 class FoamGridHierarchicIterator
 {
-    enum {dimworld = GridImp::dimensionworld};
-    enum {dimgrid  = GridImp::dimension};
+    static constexpr int dimworld = GridImp::dimensionworld;
+    static constexpr int dimgrid = GridImp::dimension;
 
-    friend class FoamGridEntity<0, dimgrid,GridImp>;
-
-    using StackEntry = const FoamGridEntityImp<dimgrid, dimgrid, dimworld, typename GridImp::ctype>*;
+    using EntityImpPointer = const FoamGridEntityImp<
+        dimgrid, dimgrid, dimworld, typename GridImp::ctype
+    >*;
 
 public:
     using Entity = typename GridImp::template Codim<0>::Entity;
@@ -35,52 +35,71 @@ public:
     //! We only iterate over elements with this iterator
     enum { codimension = 0 };
 
-    //! Constructor
-    FoamGridHierarchicIterator(int maxlevel)
-    : maxlevel_(maxlevel)
+    //! Constructor with element impl (begin iterator)
+    FoamGridHierarchicIterator(EntityImpPointer target, int maxLevel)
+    : maxLevel_(maxLevel)
     {
-        virtualEntity_.impl().setToTarget(nullptr);
+        // Load sons of target onto the iterator stack
+        stackChildren_(target);
+
+        // Set entity target to the next child if exists
+        resetEntity_();
+    }
+
+    //! Constructor without valid element (end iterator)
+    FoamGridHierarchicIterator(int maxLevel)
+    : maxLevel_(maxLevel)
+    {
+        resetEntity_();
     }
 
     //! \todo Please doc me !
     void increment()
     {
-        if (elemStack.empty())
+        if (elemStack_.empty())
             return;
 
-        StackEntry old_target = elemStack.top();
-        elemStack.pop();
-
-        // Traverse the tree no deeper than maxlevel
-        if (old_target->level_ < maxlevel_) {
+        auto target = elemStack_.top();
+        elemStack_.pop();
 
-            // Load sons of old target onto the iterator stack
-            if (!old_target->isLeaf())
-                for (size_t i=0; i<old_target->nSons(); i++)
-                    elemStack.push(old_target->sons_[i]);
-        }
+        // Load sons of previous target onto the iterator stack
+        stackChildren_(target);
 
-        virtualEntity_.impl().setToTarget(elemStack.empty() ?
-                                          nullptr : elemStack.top());
+        // Set entity target to the next stacked element if exists
+        resetEntity_();
     }
 
     //! dereferencing
     const Entity& dereference() const { return virtualEntity_; }
 
     //! equality
-    bool equals(const FoamGridHierarchicIterator<GridImp>& other) const {
-      return virtualEntity_ == other.virtualEntity_;
-    }
+    bool equals(const FoamGridHierarchicIterator<GridImp>& other) const
+    { return virtualEntity_ == other.virtualEntity_; }
 
 private:
+    void stackChildren_(EntityImpPointer target)
+    {
+        // Load sons of target onto the iterator stack
+        if (target->level() < maxLevel_ && !target->isLeaf())
+            for (std::size_t i = 0; i < target->nSons(); i++)
+                elemStack_.push(target->sons_[i]);
+    }
+
+    void resetEntity_()
+    {
+        virtualEntity_.impl().setToTarget(
+            elemStack_.empty() ? nullptr : elemStack_.top()
+        );
+    }
+
     //! The entity that the iterator is pointing to
     Entity virtualEntity_;
 
-    //! max level to go down
-    int maxlevel_;
+    //! max level to iterate over
+    int maxLevel_;
 
     /** \brief For depth-first search */
-    std::stack<StackEntry> elemStack;
+    std::stack<EntityImpPointer> elemStack_;
 };
 
 
-- 
GitLab