[geos-commits] [SCM] GEOS branch master updated. 4f9c3d9f42a1c7eb920c3bc7c4270c60a4807bc8

git at osgeo.org git at osgeo.org
Thu Feb 13 10:34:39 PST 2020


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GEOS".

The branch, master has been updated
       via  4f9c3d9f42a1c7eb920c3bc7c4270c60a4807bc8 (commit)
       via  86e943e609f0833d319fc9222908cad0306ab570 (commit)
      from  7e0d548fed76e75beb1c39b725f0b558d4a302e2 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 4f9c3d9f42a1c7eb920c3bc7c4270c60a4807bc8
Merge: 7e0d548 86e943e
Author: Dan Baston <dbaston at gmail.com>
Date:   Thu Feb 13 13:34:24 2020 -0500

    Merge remote-tracking branch 'rouault/down_cast'


commit 86e943e609f0833d319fc9222908cad0306ab570
Author: Even Rouault <even.rouault at spatialys.com>
Date:   Thu Feb 13 16:51:36 2020 +0100

    Add a geos::detail::down_cast<To>(From*) function
    
    (Ported from what has been used since a few years in GDAL, which was
    added per https://trac.osgeo.org/gdal/ticket/6720)
    
    This function can be used to replace most patterns where a static_cast
    or dynamic_cast is done, and we are sure that the result is of the target
    type (except programming bugs)
    
    In particular, the following common pattern
    ```
    assert(dynamic_cast<Target*>(foo));
    Target* t = static_cast<Target*>(foo);
    ```
    can now been replaced equivalently by
    ```
    Target* t = detail::down_cast<Target*>(foo);
    ```
    The assertion is only done in GEOS_DEBUG mode by down_cast.
    
    This is even safer as it avoids the risk of potentially side effect,
    in the assert() as was found in RelateComputer.cpp that had
    ```
                assert(dynamic_cast<RelateNode*>(nodes.addNode(ei.coord)));
                RelateNode* n = static_cast<RelateNode*>(nodes.addNode(ei.coord));
    ```

diff --git a/include/geos/util.h b/include/geos/util.h
index 2af350f..40d51dd 100644
--- a/include/geos/util.h
+++ b/include/geos/util.h
@@ -32,6 +32,7 @@
 //#include <geos/util/math.h>
 
 #include <memory>
+#include <type_traits>
 
 //
 // Private macros definition
@@ -81,8 +82,29 @@ typename _Unique_if<T>::_Known_bound
 make_unique(Args &&...) = delete;
 
 #endif
-}
 
+/** Use detail::down_cast<Derived*>(pointer_to_base) as equivalent of
+ * static_cast<Derived*>(pointer_to_base) with safe checking in debug
+ * mode.
+ *
+ * Only works if no virtual inheritance is involved.
+ *
+ * @param f pointer to a base class
+ * @return pointer to a derived class
+ */
+template<typename To, typename From> inline To down_cast(From* f)
+{
+    static_assert(
+        (std::is_base_of<From,
+                        typename std::remove_pointer<To>::type>::value),
+        "target type not derived from source type");
+#if GEOS_DEBUG
+    assert(f == nullptr || dynamic_cast<To>(f) != nullptr);
+#endif
+    return static_cast<To>(f);
 }
 
+} // namespace detail
+} // namespace geos
+
 #endif // GEOS_UTIL_H
diff --git a/src/geomgraph/DirectedEdgeStar.cpp b/src/geomgraph/DirectedEdgeStar.cpp
index c0ff38d..323028b 100644
--- a/src/geomgraph/DirectedEdgeStar.cpp
+++ b/src/geomgraph/DirectedEdgeStar.cpp
@@ -28,6 +28,7 @@
 #include <geos/geomgraph/Quadrant.h>
 #include <geos/geom/Location.h>
 #include <geos/util/TopologyException.h>
+#include <geos/util.h>
 
 #include <cassert>
 #include <string>
@@ -48,8 +49,7 @@ void
 DirectedEdgeStar::insert(EdgeEnd* ee)
 {
     assert(ee);
-    assert(dynamic_cast<DirectedEdge*>(ee));
-    DirectedEdge* de = static_cast<DirectedEdge*>(ee);
+    DirectedEdge* de = detail::down_cast<DirectedEdge*>(ee);
     insertEdgeEnd(de);
 }
 
@@ -61,8 +61,7 @@ DirectedEdgeStar::getOutgoingDegree()
     EdgeEndStar::iterator endIt = end();
     for(EdgeEndStar::iterator it = begin(); it != endIt; ++it) {
         assert(*it);
-        assert(dynamic_cast<DirectedEdge*>(*it));
-        DirectedEdge* de = static_cast<DirectedEdge*>(*it);
+        DirectedEdge* de = detail::down_cast<DirectedEdge*>(*it);
         if(de->isInResult()) {
             ++degree;
         }
@@ -78,8 +77,7 @@ DirectedEdgeStar::getOutgoingDegree(EdgeRing* er)
     EdgeEndStar::iterator endIt = end();
     for(EdgeEndStar::iterator it = begin(); it != endIt; ++it) {
         assert(*it);
-        assert(dynamic_cast<DirectedEdge*>(*it));
-        DirectedEdge* de = static_cast<DirectedEdge*>(*it);
+        DirectedEdge* de = detail::down_cast<DirectedEdge*>(*it);
         if(de->getEdgeRing() == er) {
             ++degree;
         }
@@ -97,8 +95,7 @@ DirectedEdgeStar::getRightmostEdge()
     }
 
     assert(*it);
-    assert(dynamic_cast<DirectedEdge*>(*it));
-    DirectedEdge* de0 = static_cast<DirectedEdge*>(*it);
+    DirectedEdge* de0 = detail::down_cast<DirectedEdge*>(*it);
     ++it;
     if(it == end()) {
         return de0;
@@ -108,8 +105,7 @@ DirectedEdgeStar::getRightmostEdge()
     --it;
 
     assert(*it);
-    assert(dynamic_cast<DirectedEdge*>(*it));
-    DirectedEdge* deLast = static_cast<DirectedEdge*>(*it);
+    DirectedEdge* deLast = detail::down_cast<DirectedEdge*>(*it);
 
     assert(de0);
     int quad0 = de0->getQuadrant();
@@ -170,8 +166,7 @@ DirectedEdgeStar::mergeSymLabels()
     EdgeEndStar::iterator endIt = end();
     for(EdgeEndStar::iterator it = begin(); it != endIt; ++it) {
         assert(*it);
-        assert(dynamic_cast<DirectedEdge*>(*it));
-        DirectedEdge* de = static_cast<DirectedEdge*>(*it);
+        DirectedEdge* de = detail::down_cast<DirectedEdge*>(*it);
         Label& deLabel = de->getLabel();
 
         DirectedEdge* deSym = de->getSym();
@@ -189,8 +184,8 @@ DirectedEdgeStar::updateLabelling(const Label& nodeLabel)
 {
     EdgeEndStar::iterator endIt = end();
     for(EdgeEndStar::iterator it = begin(); it != endIt; ++it) {
-        DirectedEdge* de = dynamic_cast<DirectedEdge*>(*it);
-        assert(de);
+        assert(*it);
+        DirectedEdge* de = detail::down_cast<DirectedEdge*>(*it);
         Label& deLabel = de->getLabel();
         deLabel.setAllLocationsIfNull(0, nodeLabel.getLocation(0));
         deLabel.setAllLocationsIfNull(1, nodeLabel.getLocation(1));
@@ -208,8 +203,7 @@ DirectedEdgeStar::getResultAreaEdges()
     EdgeEndStar::iterator endIt = end();
     for(EdgeEndStar::iterator it = begin(); it != endIt; ++it) {
         assert(*it);
-        assert(dynamic_cast<DirectedEdge*>(*it));
-        DirectedEdge* de = static_cast<DirectedEdge*>(*it);
+        DirectedEdge* de = detail::down_cast<DirectedEdge*>(*it);
         if(de->isInResult() || de->getSym()->isInResult()) {
             resultAreaEdgeList.push_back(de);
         }
@@ -340,8 +334,7 @@ DirectedEdgeStar::linkAllDirectedEdges()
     EdgeEndStar::reverse_iterator rendIt = rend();
     for(EdgeEndStar::reverse_iterator it = rbeginIt; it != rendIt; ++it) {
         assert(*it);
-        assert(dynamic_cast<DirectedEdge*>(*it));
-        DirectedEdge* nextOut = static_cast<DirectedEdge*>(*it);
+        DirectedEdge* nextOut = detail::down_cast<DirectedEdge*>(*it);
 
         DirectedEdge* nextIn = nextOut->getSym();
         assert(nextIn);
@@ -378,8 +371,7 @@ DirectedEdgeStar::findCoveredLineEdges()
     EdgeEndStar::iterator endIt = end();
     for(EdgeEndStar::iterator it = begin(); it != endIt; ++it) {
         assert(*it);
-        assert(dynamic_cast<DirectedEdge*>(*it));
-        DirectedEdge* nextOut = static_cast<DirectedEdge*>(*it);
+        DirectedEdge* nextOut = detail::down_cast<DirectedEdge*>(*it);
 
         DirectedEdge* nextIn = nextOut->getSym();
         assert(nextIn);
@@ -409,8 +401,7 @@ DirectedEdgeStar::findCoveredLineEdges()
     Location currLoc = startLoc;
     for(EdgeEndStar::iterator it = begin(); it != endIt; ++it) {
         assert(*it);
-        assert(dynamic_cast<DirectedEdge*>(*it));
-        DirectedEdge* nextOut = static_cast<DirectedEdge*>(*it);
+        DirectedEdge* nextOut = detail::down_cast<DirectedEdge*>(*it);
 
         DirectedEdge* nextIn = nextOut->getSym();
         assert(nextIn);
@@ -461,8 +452,7 @@ DirectedEdgeStar::computeDepths(EdgeEndStar::iterator startIt,
     int currDepth = startDepth;
     for(EdgeEndStar::iterator it = startIt; it != endIt; ++it) {
         assert(*it);
-        assert(dynamic_cast<DirectedEdge*>(*it));
-        DirectedEdge* nextDe = static_cast<DirectedEdge*>(*it);
+        DirectedEdge* nextDe = detail::down_cast<DirectedEdge*>(*it);
 
         nextDe->setEdgeDepths(Position::RIGHT, currDepth);
         currDepth = nextDe->getDepth(Position::LEFT);
@@ -479,8 +469,7 @@ DirectedEdgeStar::print() const
     EdgeEndStar::iterator endIt = end();
     for(EdgeEndStar::iterator it = begin(); it != endIt; ++it) {
         assert(*it);
-        assert(dynamic_cast<DirectedEdge*>(*it));
-        DirectedEdge* de = static_cast<DirectedEdge*>(*it);
+        DirectedEdge* de = detail::down_cast<DirectedEdge*>(*it);
         assert(de);
         out += "out ";
         out += de->print();
diff --git a/src/geomgraph/EdgeRing.cpp b/src/geomgraph/EdgeRing.cpp
index f99b661..2e4077a 100644
--- a/src/geomgraph/EdgeRing.cpp
+++ b/src/geomgraph/EdgeRing.cpp
@@ -243,8 +243,7 @@ EdgeRing::computeMaxNodeDegree()
     do {
         Node* node = de->getNode();
         EdgeEndStar* ees = node->getEdges();
-        assert(dynamic_cast<DirectedEdgeStar*>(ees));
-        DirectedEdgeStar* des = static_cast<DirectedEdgeStar*>(ees);
+        DirectedEdgeStar* des = detail::down_cast<DirectedEdgeStar*>(ees);
         int degree = des->getOutgoingDegree(this);
         if(degree > maxNodeDegree) {
             maxNodeDegree = degree;
diff --git a/src/geomgraph/Node.cpp b/src/geomgraph/Node.cpp
index fcd8a21..f1f6478 100644
--- a/src/geomgraph/Node.cpp
+++ b/src/geomgraph/Node.cpp
@@ -26,6 +26,7 @@
 #include <geos/geomgraph/DirectedEdge.h>
 #include <geos/geom/Location.h>
 #include <geos/util/IllegalArgumentException.h>
+#include <geos/util.h>
 
 #include <cmath>
 #include <string>
@@ -123,8 +124,7 @@ Node::isIncidentEdgeInResult() const
     EdgeEndStar::iterator endIt = edges->end();
     for(; it != endIt; ++it) {
         assert(*it);
-        assert(dynamic_cast<DirectedEdge*>(*it));
-        DirectedEdge* de = static_cast<DirectedEdge*>(*it);
+        DirectedEdge* de = detail::down_cast<DirectedEdge*>(*it);
         if(de->getEdge()->isInResult()) {
             return true;
         }
diff --git a/src/geomgraph/PlanarGraph.cpp b/src/geomgraph/PlanarGraph.cpp
index 3ad84c7..fed2a4c 100644
--- a/src/geomgraph/PlanarGraph.cpp
+++ b/src/geomgraph/PlanarGraph.cpp
@@ -240,8 +240,7 @@ PlanarGraph::linkResultDirectedEdges()
 
         EdgeEndStar* ees = node->getEdges();
         assert(ees);
-        assert(dynamic_cast<DirectedEdgeStar*>(ees));
-        DirectedEdgeStar* des = static_cast<DirectedEdgeStar*>(ees);
+        DirectedEdgeStar* des = detail::down_cast<DirectedEdgeStar*>(ees);
 
         // this might throw an exception
         des->linkResultDirectedEdges();
@@ -268,8 +267,7 @@ PlanarGraph::linkAllDirectedEdges()
         assert(ees);
 
         // Unespected non-DirectedEdgeStar in node
-        assert(dynamic_cast<DirectedEdgeStar*>(ees));
-        DirectedEdgeStar* des = static_cast<DirectedEdgeStar*>(ees);
+        DirectedEdgeStar* des = detail::down_cast<DirectedEdgeStar*>(ees);
 
         des->linkAllDirectedEdges();
     }
diff --git a/src/noding/IntersectionAdder.cpp b/src/noding/IntersectionAdder.cpp
index 8bf3988..91b560b 100644
--- a/src/noding/IntersectionAdder.cpp
+++ b/src/noding/IntersectionAdder.cpp
@@ -21,6 +21,7 @@
 #include <geos/noding/NodedSegmentString.h>
 #include <geos/algorithm/LineIntersector.h>
 #include <geos/geom/Coordinate.h>
+#include <geos/util.h>
 
 using namespace geos::geom;
 
@@ -99,9 +100,8 @@ IntersectionAdder::processIntersections(
     if(! isTrivialIntersection(e0, segIndex0, e1, segIndex1)) {
         hasIntersectionVar = true;
 
-        NodedSegmentString* ee0 = dynamic_cast<NodedSegmentString*>(e0);
-        NodedSegmentString* ee1 = dynamic_cast<NodedSegmentString*>(e1);
-        assert(ee0 && ee1);
+        NodedSegmentString* ee0 = detail::down_cast<NodedSegmentString*>(e0);
+        NodedSegmentString* ee1 = detail::down_cast<NodedSegmentString*>(e1);
         ee0->addIntersections(&li, segIndex0, 0);
         ee1->addIntersections(&li, segIndex1, 1);
 
diff --git a/src/noding/IntersectionFinderAdder.cpp b/src/noding/IntersectionFinderAdder.cpp
index 3235119..7efa694 100644
--- a/src/noding/IntersectionFinderAdder.cpp
+++ b/src/noding/IntersectionFinderAdder.cpp
@@ -23,6 +23,7 @@
 #include <geos/noding/NodedSegmentString.h>
 #include <geos/algorithm/LineIntersector.h>
 #include <geos/geom/Coordinate.h>
+#include <geos/util.h>
 
 using namespace geos::geom;
 
@@ -53,9 +54,8 @@ IntersectionFinderAdder::processIntersections(
                 interiorIntersections.push_back(li.getIntersection(intIndex));
             }
 
-            NodedSegmentString* ee0 = dynamic_cast<NodedSegmentString*>(e0);
-            NodedSegmentString* ee1 = dynamic_cast<NodedSegmentString*>(e1);
-            assert(ee0 && ee1);
+            NodedSegmentString* ee0 = detail::down_cast<NodedSegmentString*>(e0);
+            NodedSegmentString* ee1 = detail::down_cast<NodedSegmentString*>(e1);
             ee0->addIntersections(&li, segIndex0, 0);
             ee1->addIntersections(&li, segIndex1, 1);
         }
diff --git a/src/noding/snapround/SimpleSnapRounder.cpp b/src/noding/snapround/SimpleSnapRounder.cpp
index 723aa90..fa6caca 100644
--- a/src/noding/snapround/SimpleSnapRounder.cpp
+++ b/src/noding/snapround/SimpleSnapRounder.cpp
@@ -26,6 +26,7 @@
 #include <geos/geom/Coordinate.h>
 #include <geos/geom/CoordinateSequence.h>
 #include <geos/algorithm/LineIntersector.h>
+#include <geos/util.h>
 
 #include <vector>
 #include <exception>
@@ -116,7 +117,7 @@ SimpleSnapRounder::computeSnaps(const SegmentString::NonConstVect& segStrings,
     for(SegmentString::NonConstVect::const_iterator
             i = segStrings.begin(), iEnd = segStrings.end();
             i != iEnd; ++i) {
-        NodedSegmentString* ss = dynamic_cast<NodedSegmentString*>(*i);
+        NodedSegmentString* ss = detail::down_cast<NodedSegmentString*>(*i);
 
         computeSnaps(ss, snapPts);
     }
@@ -171,13 +172,11 @@ SimpleSnapRounder::computeVertexSnaps(const SegmentString::NonConstVect& edges)
     for(SegmentString::NonConstVect::const_iterator
             i0 = edges.begin(), i0End = edges.end();
             i0 != i0End; ++i0) {
-        NodedSegmentString* edge0 = dynamic_cast<NodedSegmentString*>(*i0);
-        assert(edge0);
+        NodedSegmentString* edge0 = detail::down_cast<NodedSegmentString*>(*i0);
         for(SegmentString::NonConstVect::const_iterator
                 i1 = edges.begin(), i1End = edges.end();
                 i1 != i1End; ++i1) {
-            NodedSegmentString* edge1 = dynamic_cast<NodedSegmentString*>(*i1);
-            assert(edge1);
+            NodedSegmentString* edge1 = detail::down_cast<NodedSegmentString*>(*i1);
             computeVertexSnaps(edge0, edge1);
         }
     }
diff --git a/src/operation/buffer/BufferSubgraph.cpp b/src/operation/buffer/BufferSubgraph.cpp
index b2ca203..2602a39 100644
--- a/src/operation/buffer/BufferSubgraph.cpp
+++ b/src/operation/buffer/BufferSubgraph.cpp
@@ -27,6 +27,7 @@
 #include <geos/geomgraph/DirectedEdgeStar.h>
 #include <geos/geomgraph/EdgeEndStar.h>
 #include <geos/geomgraph/Position.h>
+#include <geos/util.h>
 
 #include <cassert>
 #include <vector>
@@ -103,8 +104,7 @@ BufferSubgraph::add(Node* node, vector<Node*>* nodeStack)
     EdgeEndStar::iterator it = ees->begin();
     EdgeEndStar::iterator endIt = ees->end();
     for(; it != endIt; ++it) {
-        assert(dynamic_cast<DirectedEdge*>(*it));
-        DirectedEdge* de = static_cast<DirectedEdge*>(*it);
+        DirectedEdge* de = detail::down_cast<DirectedEdge*>(*it);
         dirEdgeList.push_back(de);
         DirectedEdge* sym = de->getSym();
         Node* symNode = sym->getNode();
@@ -157,15 +157,13 @@ BufferSubgraph::computeNodeDepth(Node* n)
     // find a visited dirEdge to start at
     DirectedEdge* startEdge = nullptr;
 
-    assert(dynamic_cast<DirectedEdgeStar*>(n->getEdges()));
-    DirectedEdgeStar* ees = static_cast<DirectedEdgeStar*>(n->getEdges());
+    DirectedEdgeStar* ees = detail::down_cast<DirectedEdgeStar*>(n->getEdges());
 
     EdgeEndStar::iterator endIt = ees->end();
 
     EdgeEndStar::iterator it = ees->begin();
     for(; it != endIt; ++it) {
-        assert(dynamic_cast<DirectedEdge*>(*it));
-        DirectedEdge* de = static_cast<DirectedEdge*>(*it);
+        DirectedEdge* de = detail::down_cast<DirectedEdge*>(*it);
         if(de->isVisited() || de->getSym()->isVisited()) {
             startEdge = de;
             break;
@@ -185,8 +183,7 @@ BufferSubgraph::computeNodeDepth(Node* n)
 
     // copy depths to sym edges
     for(it = ees->begin(); it != endIt; ++it) {
-        assert(dynamic_cast<DirectedEdge*>(*it));
-        DirectedEdge* de = static_cast<DirectedEdge*>(*it);
+        DirectedEdge* de = detail::down_cast<DirectedEdge*>(*it);
         de->setVisited(true);
         copySymDepths(de);
     }
@@ -284,8 +281,7 @@ BufferSubgraph::computeDepths(DirectedEdge* startEdge)
         EdgeEndStar::iterator endIt = ees->end();
         EdgeEndStar::iterator it = ees->begin();
         for(; it != endIt; ++it) {
-            assert(dynamic_cast<DirectedEdge*>(*it));
-            DirectedEdge* de = static_cast<DirectedEdge*>(*it);
+            DirectedEdge* de = detail::down_cast<DirectedEdge*>(*it);
             DirectedEdge* sym = de->getSym();
             if(sym->isVisited()) {
                 continue;
diff --git a/src/operation/buffer/OffsetCurveSetBuilder.cpp b/src/operation/buffer/OffsetCurveSetBuilder.cpp
index d23c899..e2c3804 100644
--- a/src/operation/buffer/OffsetCurveSetBuilder.cpp
+++ b/src/operation/buffer/OffsetCurveSetBuilder.cpp
@@ -39,6 +39,7 @@
 #include <geos/geomgraph/Position.h>
 #include <geos/geomgraph/Label.h>
 #include <geos/noding/NodedSegmentString.h>
+#include <geos/util.h>
 
 #include <algorithm> // for min
 #include <cmath>
@@ -254,8 +255,7 @@ OffsetCurveSetBuilder::addPolygon(const Polygon* p)
 
     for(size_t i = 0, n = p->getNumInteriorRing(); i < n; ++i) {
         const LineString* hls = p->getInteriorRingN(i);
-        assert(dynamic_cast<const LinearRing*>(hls));
-        const LinearRing* hole = static_cast<const LinearRing*>(hls);
+        const LinearRing* hole = detail::down_cast<const LinearRing*>(hls);
 
         // optimization - don't bother computing buffer for this hole
         // if the hole would be completely covered
diff --git a/src/operation/buffer/RightmostEdgeFinder.cpp b/src/operation/buffer/RightmostEdgeFinder.cpp
index 02b4741..57765c3 100644
--- a/src/operation/buffer/RightmostEdgeFinder.cpp
+++ b/src/operation/buffer/RightmostEdgeFinder.cpp
@@ -25,6 +25,7 @@
 #include <geos/geomgraph/Node.h>
 #include <geos/geomgraph/Edge.h>
 #include <geos/util/TopologyException.h>
+#include <geos/util.h>
 
 #include <vector>
 #include <cassert>
@@ -120,8 +121,7 @@ RightmostEdgeFinder::findRightmostEdgeAtNode()
     Node* node = minDe->getNode();
     assert(node);
 
-    assert(dynamic_cast<DirectedEdgeStar*>(node->getEdges()));
-    DirectedEdgeStar* star = static_cast<DirectedEdgeStar*>(node->getEdges());
+    DirectedEdgeStar* star = detail::down_cast<DirectedEdgeStar*>(node->getEdges());
 
     // Warning! NULL could be returned if the star is empty!
     minDe = star->getRightmostEdge();
diff --git a/src/operation/linemerge/EdgeString.cpp b/src/operation/linemerge/EdgeString.cpp
index 8c7ad8b..4b152f4 100644
--- a/src/operation/linemerge/EdgeString.cpp
+++ b/src/operation/linemerge/EdgeString.cpp
@@ -26,6 +26,7 @@
 #include <geos/geom/CoordinateSequence.h>
 #include <geos/geom/CoordinateArraySequence.h>
 #include <geos/geom/LineString.h>
+#include <geos/util.h>
 
 #include <vector>
 #include <cassert>
@@ -73,8 +74,7 @@ EdgeString::getCoordinates()
                 reverseDirectedEdges++;
             }
 
-            assert(dynamic_cast<LineMergeEdge*>(directedEdge->getEdge()));
-            LineMergeEdge* lme = static_cast<LineMergeEdge*>(directedEdge->getEdge());
+            LineMergeEdge* lme = detail::down_cast<LineMergeEdge*>(directedEdge->getEdge());
 
             coordinates->add(lme->getLine()->getCoordinatesRO(),
                              false,
diff --git a/src/operation/linemerge/LineMerger.cpp b/src/operation/linemerge/LineMerger.cpp
index ec680f3..af7c4ca 100644
--- a/src/operation/linemerge/LineMerger.cpp
+++ b/src/operation/linemerge/LineMerger.cpp
@@ -200,9 +200,8 @@ LineMerger::buildEdgeStringsStartingAt(Node* node)
     vector<planargraph::DirectedEdge*>& edges = node->getOutEdges()->getEdges();
     size_t size = edges.size();
     for(size_t i = 0; i < size; i++) {
-        assert(dynamic_cast<LineMergeDirectedEdge*>(edges[i]));
-        LineMergeDirectedEdge* directedEdge = \
-                                              static_cast<LineMergeDirectedEdge*>(edges[i]);
+        LineMergeDirectedEdge* directedEdge =
+                            detail::down_cast<LineMergeDirectedEdge*>(edges[i]);
         if(directedEdge->getEdge()->isMarked()) {
             continue;
         }
diff --git a/src/operation/linemerge/LineSequencer.cpp b/src/operation/linemerge/LineSequencer.cpp
index f4e6edb..3739d7a 100644
--- a/src/operation/linemerge/LineSequencer.cpp
+++ b/src/operation/linemerge/LineSequencer.cpp
@@ -30,6 +30,7 @@
 #include <geos/planargraph/Subgraph.h>
 #include <geos/planargraph/algorithm/ConnectedSubgraphFinder.h>
 #include <geos/util/Assert.h>
+#include <geos/util.h>
 
 #include <cassert>
 #include <limits>
@@ -206,8 +207,7 @@ LineSequencer::buildSequencedGeometry(const Sequences& sequences)
         for(planargraph::DirectedEdge::NonConstList::iterator i2 = seq.begin(),
                 i2End = seq.end(); i2 != i2End; ++i2) {
             const planargraph::DirectedEdge* de = *i2;
-            assert(dynamic_cast<LineMergeEdge* >(de->getEdge()));
-            LineMergeEdge* e = static_cast<LineMergeEdge* >(de->getEdge());
+            LineMergeEdge* e = detail::down_cast<LineMergeEdge* >(de->getEdge());
             const LineString* line = e->getLine();
 
             // lineToAdd will be a *copy* of input things
@@ -218,8 +218,7 @@ LineSequencer::buildSequencedGeometry(const Sequences& sequences)
             }
             else {
                 Geometry* lineClone = line->clone().release();
-                lineToAdd = dynamic_cast<LineString*>(lineClone);
-                assert(lineToAdd);
+                lineToAdd = detail::down_cast<LineString*>(lineClone);
             }
 
             lines->push_back(lineToAdd);
diff --git a/src/operation/overlay/LineBuilder.cpp b/src/operation/overlay/LineBuilder.cpp
index 487577b..c3d64ef 100644
--- a/src/operation/overlay/LineBuilder.cpp
+++ b/src/operation/overlay/LineBuilder.cpp
@@ -25,6 +25,7 @@
 #include <geos/geomgraph/Edge.h>
 #include <geos/geomgraph/DirectedEdge.h>
 #include <geos/geomgraph/DirectedEdgeStar.h>
+#include <geos/util.h>
 
 #include <map>
 #include <vector>
@@ -85,8 +86,7 @@ LineBuilder::findCoveredLineEdges()
     for(auto& entry : nodeMap) {
         Node* node = entry.second;
         //node.print(System.out);
-        assert(dynamic_cast<DirectedEdgeStar*>(node->getEdges()));
-        DirectedEdgeStar* des = static_cast<DirectedEdgeStar*>(node->getEdges());
+        DirectedEdgeStar* des = detail::down_cast<DirectedEdgeStar*>(node->getEdges());
         des->findCoveredLineEdges();
         //((DirectedEdgeStar*)node->getEdges())->findCoveredLineEdges();
     }
@@ -97,8 +97,7 @@ LineBuilder::findCoveredLineEdges()
      */
     vector<EdgeEnd*>* ee = op->getGraph().getEdgeEnds();
     for(size_t i = 0, s = ee->size(); i < s; ++i) {
-        assert(dynamic_cast<DirectedEdge*>((*ee)[i]));
-        DirectedEdge* de = static_cast<DirectedEdge*>((*ee)[i]);
+        DirectedEdge* de = detail::down_cast<DirectedEdge*>((*ee)[i]);
         Edge* e = de->getEdge();
         if(de->isLineEdge() && !e->isCoveredSet()) {
             bool isCovered = op->isCoveredByA(de->getCoordinate());
@@ -112,8 +111,7 @@ LineBuilder::collectLines(OverlayOp::OpCode opCode)
 {
     vector<EdgeEnd*>* ee = op->getGraph().getEdgeEnds();
     for(size_t i = 0, s = ee->size(); i < s; ++i) {
-        assert(dynamic_cast<DirectedEdge*>((*ee)[i]));
-        DirectedEdge* de = static_cast<DirectedEdge*>((*ee)[i]);
+        DirectedEdge* de = detail::down_cast<DirectedEdge*>((*ee)[i]);
         collectLineEdge(de, opCode, &lineEdgesList);
         collectBoundaryTouchEdge(de, opCode, &lineEdgesList);
     }
diff --git a/src/operation/overlay/MaximalEdgeRing.cpp b/src/operation/overlay/MaximalEdgeRing.cpp
index f8f73f8..5f5e4c8 100644
--- a/src/operation/overlay/MaximalEdgeRing.cpp
+++ b/src/operation/overlay/MaximalEdgeRing.cpp
@@ -24,6 +24,7 @@
 #include <geos/geomgraph/Node.h>
 #include <geos/geomgraph/EdgeEndStar.h>
 #include <geos/geomgraph/DirectedEdgeStar.h>
+#include <geos/util.h>
 
 #include <cassert>
 #include <vector>
@@ -81,8 +82,7 @@ MaximalEdgeRing::linkDirectedEdgesForMinimalEdgeRings()
         Node* node = de->getNode();
         EdgeEndStar* ees = node->getEdges();
 
-        assert(dynamic_cast<DirectedEdgeStar*>(ees));
-        DirectedEdgeStar* des = static_cast<DirectedEdgeStar*>(ees);
+        DirectedEdgeStar* des = detail::down_cast<DirectedEdgeStar*>(ees);
 
         des->linkMinimalDirectedEdges(this);
 
diff --git a/src/operation/overlay/OverlayOp.cpp b/src/operation/overlay/OverlayOp.cpp
index df1e654..7959c7c 100644
--- a/src/operation/overlay/OverlayOp.cpp
+++ b/src/operation/overlay/OverlayOp.cpp
@@ -44,6 +44,7 @@
 #include <geos/util/Interrupt.h>
 #include <geos/util/TopologyException.h>
 #include <geos/geomgraph/EdgeNodingValidator.h>
+#include <geos/util.h>
 
 #include <cassert>
 #include <cmath>
@@ -319,8 +320,7 @@ OverlayOp::mergeSymLabels()
             it != itEnd; ++it) {
         Node* node = it->second;
         EdgeEndStar* ees = node->getEdges();
-        assert(dynamic_cast<DirectedEdgeStar*>(ees));
-        static_cast<DirectedEdgeStar*>(ees)->mergeSymLabels();
+        detail::down_cast<DirectedEdgeStar*>(ees)->mergeSymLabels();
         //((DirectedEdgeStar*)node->getEdges())->mergeSymLabels();
 #if GEOS_DEBUG
         cerr << "     " << node->print() << endl;
@@ -349,8 +349,7 @@ OverlayOp::updateNodeLabelling()
             it != itEnd; ++it) {
         Node* node = it->second;
         EdgeEndStar* ees = node->getEdges();
-        assert(dynamic_cast<DirectedEdgeStar*>(ees));
-        DirectedEdgeStar* des = static_cast<DirectedEdgeStar*>(ees);
+        DirectedEdgeStar* des = detail::down_cast<DirectedEdgeStar*>(ees);
         Label& lbl = des->getLabel();
         node->getLabel().merge(lbl);
 #if GEOS_DEBUG
@@ -383,8 +382,7 @@ OverlayOp::labelIncompleteNodes()
         }
         // now update the labelling for the DirectedEdges incident on this node
         EdgeEndStar* ees = n->getEdges();
-        assert(dynamic_cast<DirectedEdgeStar*>(ees));
-        DirectedEdgeStar* des = static_cast<DirectedEdgeStar*>(ees);
+        DirectedEdgeStar* des = detail::down_cast<DirectedEdgeStar*>(ees);
 
         des->updateLabelling(label);
         //((DirectedEdgeStar*)n->getEdges())->updateLabelling(label);
diff --git a/src/operation/overlay/PolygonBuilder.cpp b/src/operation/overlay/PolygonBuilder.cpp
index 90d12ca..0069edc 100644
--- a/src/operation/overlay/PolygonBuilder.cpp
+++ b/src/operation/overlay/PolygonBuilder.cpp
@@ -81,8 +81,7 @@ PolygonBuilder::add(PlanarGraph* graph)
 
     vector<DirectedEdge*> dirEdges(eeSize);
     for(size_t i = 0; i < eeSize; ++i) {
-        assert(dynamic_cast<DirectedEdge*>(ee[i]));
-        DirectedEdge* de = static_cast<DirectedEdge*>(ee[i]);
+        DirectedEdge* de = detail::down_cast<DirectedEdge*>(ee[i]);
         dirEdges[i] = de;
     }
 
diff --git a/src/operation/polygonize/PolygonizeGraph.cpp b/src/operation/polygonize/PolygonizeGraph.cpp
index 3bafb0f..84354ba 100644
--- a/src/operation/polygonize/PolygonizeGraph.cpp
+++ b/src/operation/polygonize/PolygonizeGraph.cpp
@@ -27,6 +27,7 @@
 #include <geos/planargraph/DirectedEdge.h>
 #include <geos/geom/CoordinateSequence.h>
 #include <geos/geom/LineString.h>
+#include <geos/util.h>
 
 #include <cassert>
 #include <vector>
@@ -62,7 +63,7 @@ PolygonizeGraph::getDegree(Node* node, long label)
     auto edges = node->getOutEdges()->getEdges();
     int degree = 0;
     for(const auto& de : edges) {
-        auto pde = dynamic_cast<PolygonizeDirectedEdge*>(de);
+        auto pde = detail::down_cast<PolygonizeDirectedEdge*>(de);
         if(pde->getLabel() == label) {
             ++degree;
         }
@@ -235,7 +236,7 @@ PolygonizeGraph::getEdgeRings(std::vector<EdgeRing*>& edgeRingList)
 
     // find all edgerings
     for(DirectedEdge* de : dirEdges) {
-        auto pde = dynamic_cast<PolygonizeDirectedEdge*>(de);
+        auto pde = detail::down_cast<PolygonizeDirectedEdge*>(de);
         if(pde->isMarked()) {
             continue;
         }
@@ -255,7 +256,7 @@ PolygonizeGraph::findLabeledEdgeRings(std::vector<DirectedEdge*>& dirEdges,
     // label the edge rings formed
     long currLabel = 1;
     for(DirectedEdge* de : dirEdges) {
-        auto pde = dynamic_cast<PolygonizeDirectedEdge*>(de);
+        auto pde = detail::down_cast<PolygonizeDirectedEdge*>(de);
 
         if(pde->isMarked()) {
             continue;
@@ -291,20 +292,20 @@ PolygonizeGraph::deleteCutEdges(std::vector<const LineString*>& cutLines)
      * Delete them, and record them
      */
     for(DirectedEdge* de : dirEdges) {
-        auto pde = dynamic_cast<PolygonizeDirectedEdge*>(de);
+        auto pde = detail::down_cast<PolygonizeDirectedEdge*>(de);
 
         if(de->isMarked()) {
             continue;
         }
 
-        auto sym = dynamic_cast<PolygonizeDirectedEdge*>(de->getSym());
+        auto sym = detail::down_cast<PolygonizeDirectedEdge*>(de->getSym());
 
         if(pde->getLabel() == sym->getLabel()) {
             de->setMarked(true);
             sym->setMarked(true);
 
             // save the line as a cut edge
-            auto e = dynamic_cast<PolygonizeEdge*>(de->getEdge());
+            auto e = detail::down_cast<PolygonizeEdge*>(de->getEdge());
 
             cutLines.push_back(e->getLine());
         }
@@ -323,7 +324,7 @@ void
 PolygonizeGraph::label(std::vector<DirectedEdge*>& dirEdges, long label)
 {
     for(auto& de : dirEdges) {
-        auto pde = dynamic_cast<PolygonizeDirectedEdge*>(de);
+        auto pde = detail::down_cast<PolygonizeDirectedEdge*>(de);
         pde->setLabel(label);
     }
 }
@@ -338,7 +339,7 @@ PolygonizeGraph::computeNextCWEdges(Node* node)
     // the edges are stored in CCW order around the star
     std::vector<DirectedEdge*>& pde = deStar->getEdges();
     for(DirectedEdge* de : pde) {
-        auto outDE = dynamic_cast<PolygonizeDirectedEdge*>(de);
+        auto outDE = detail::down_cast<PolygonizeDirectedEdge*>(de);
         if(outDE->isMarked()) {
             continue;
         }
@@ -346,13 +347,13 @@ PolygonizeGraph::computeNextCWEdges(Node* node)
             startDE = outDE;
         }
         if(prevDE != nullptr) {
-            auto sym = dynamic_cast<PolygonizeDirectedEdge*>(prevDE->getSym());
+            auto sym = detail::down_cast<PolygonizeDirectedEdge*>(prevDE->getSym());
             sym->setNext(outDE);
         }
         prevDE = outDE;
     }
     if(prevDE != nullptr) {
-        auto sym = dynamic_cast<PolygonizeDirectedEdge*>(prevDE->getSym());
+        auto sym = detail::down_cast<PolygonizeDirectedEdge*>(prevDE->getSym());
         sym->setNext(startDE);
     }
 }
@@ -374,8 +375,8 @@ PolygonizeGraph::computeNextCCWEdges(Node* node, long label)
     std::vector<DirectedEdge*>& edges = deStar->getEdges();
 
     for(auto i = edges.size(); i > 0; --i) {
-        PolygonizeDirectedEdge* de = dynamic_cast<PolygonizeDirectedEdge*>(edges[i - 1]);
-        PolygonizeDirectedEdge* sym = dynamic_cast<PolygonizeDirectedEdge*>(de->getSym());
+        PolygonizeDirectedEdge* de = detail::down_cast<PolygonizeDirectedEdge*>(edges[i - 1]);
+        PolygonizeDirectedEdge* sym = detail::down_cast<PolygonizeDirectedEdge*>(de->getSym());
         PolygonizeDirectedEdge* outDE = nullptr;
         if(de->getLabel() == label) {
             outDE = de;
@@ -446,7 +447,7 @@ PolygonizeGraph::deleteDangles(std::vector<const LineString*>& dangleLines)
                 sym->setMarked(true);
             }
             // save the line as a dangle
-            auto e = dynamic_cast<PolygonizeEdge*>(de->getEdge());
+            auto e = detail::down_cast<PolygonizeEdge*>(de->getEdge());
             const LineString* ls = e->getLine();
             if(uniqueDangles.insert(ls).second) {
                 dangleLines.push_back(ls);
diff --git a/src/operation/relate/RelateComputer.cpp b/src/operation/relate/RelateComputer.cpp
index 9d1f136..2c8d149 100644
--- a/src/operation/relate/RelateComputer.cpp
+++ b/src/operation/relate/RelateComputer.cpp
@@ -37,6 +37,7 @@
 #include <geos/geomgraph/EdgeIntersection.h>
 
 #include <geos/util/Interrupt.h>
+#include <geos/util.h>
 
 #include <vector>
 #include <cassert>
@@ -339,8 +340,7 @@ RelateComputer::computeIntersectionNodes(int argIndex)
         Location eLoc = e->getLabel().getLocation(argIndex);
         EdgeIntersectionList& eiL = e->getEdgeIntersectionList();
         for(const EdgeIntersection & ei : eiL) {
-            assert(dynamic_cast<RelateNode*>(nodes.addNode(ei.coord)));
-            RelateNode* n = static_cast<RelateNode*>(nodes.addNode(ei.coord));
+            RelateNode* n = detail::down_cast<RelateNode*>(nodes.addNode(ei.coord));
             if(eLoc == Location::BOUNDARY) {
                 n->setLabelBoundary(argIndex);
             }
@@ -405,8 +405,7 @@ RelateComputer::labelNodeEdges()
 {
     auto& nMap = nodes.nodeMap;
     for(auto& entry : nMap) {
-        assert(dynamic_cast<RelateNode*>(entry.second));
-        RelateNode* node = static_cast<RelateNode*>(entry.second);
+        RelateNode* node = detail::down_cast<RelateNode*>(entry.second);
 #if GEOS_DEBUG
         std::cerr << "RelateComputer::labelNodeEdges: "
                   << "node edges: " << *(node->getEdges())
diff --git a/src/operation/relate/RelateNode.cpp b/src/operation/relate/RelateNode.cpp
index 5ea1b85..161dbde 100644
--- a/src/operation/relate/RelateNode.cpp
+++ b/src/operation/relate/RelateNode.cpp
@@ -22,6 +22,7 @@
 #include <geos/geom/IntersectionMatrix.h>
 #include <geos/geomgraph/Label.h>
 #include <geos/geomgraph/Node.h>
+#include <geos/util.h>
 
 #include <cassert>
 
@@ -49,8 +50,7 @@ RelateNode::computeIM(IntersectionMatrix& im)
 void
 RelateNode::updateIMFromEdges(IntersectionMatrix& im)
 {
-    assert(dynamic_cast<EdgeEndBundleStar*>(edges));
-    EdgeEndBundleStar* eebs = static_cast<EdgeEndBundleStar*>(edges);
+    EdgeEndBundleStar* eebs = detail::down_cast<EdgeEndBundleStar*>(edges);
 
     eebs->updateIM(im);
 }
diff --git a/src/operation/valid/ConnectedInteriorTester.cpp b/src/operation/valid/ConnectedInteriorTester.cpp
index a2770f3..6cda789 100644
--- a/src/operation/valid/ConnectedInteriorTester.cpp
+++ b/src/operation/valid/ConnectedInteriorTester.cpp
@@ -43,6 +43,7 @@
 #include <geos/geomgraph/DirectedEdge.h>
 #include <geos/geomgraph/Position.h>
 #include <geos/geomgraph/Label.h>
+#include <geos/util.h>
 
 #include <vector>
 #include <cassert>
@@ -52,8 +53,6 @@
 #define GEOS_DEBUG 0
 #endif
 
-//#define GEOS_CAST_PARANOIA 1
-
 #if GEOS_DEBUG
 #include <iostream>
 #endif
@@ -174,8 +173,7 @@ ConnectedInteriorTester::setInteriorEdgesInResult(PlanarGraph& graph)
     std::vector<EdgeEnd*>* ee = graph.getEdgeEnds();
     for(size_t i = 0, n = ee->size(); i < n; ++i) {
         // Unexpected non DirectedEdge in graphEdgeEnds
-        assert(dynamic_cast<DirectedEdge*>((*ee)[i]));
-        DirectedEdge* de = static_cast<DirectedEdge*>((*ee)[i]);
+        DirectedEdge* de = detail::down_cast<DirectedEdge*>((*ee)[i]);
         if(de->getLabel().getLocation(0, Position::RIGHT) == Location::INTERIOR) {
             de->setInResult(true);
         }
@@ -195,10 +193,7 @@ ConnectedInteriorTester::buildEdgeRings(std::vector<EdgeEnd*>* dirEdges,
 
     //std::vector<MinimalEdgeRing*> minEdgeRings;
     for(EdgeEnds::size_type i = 0, n = dirEdges->size(); i < n; ++i) {
-#ifdef GEOS_CAST_PARANOIA
-        assert(dynamic_cast<DirectedEdge*>((*dirEdges)[i]));
-#endif
-        DirectedEdge* de = static_cast<DirectedEdge*>((*dirEdges)[i]);
+        DirectedEdge* de = detail::down_cast<DirectedEdge*>((*dirEdges)[i]);
 
 #if GEOS_DEBUG
         cerr << "DirectedEdge " << i << ": " << de->print() << endl;
diff --git a/src/operation/valid/ConsistentAreaTester.cpp b/src/operation/valid/ConsistentAreaTester.cpp
index 325aae3..9ebefb2 100644
--- a/src/operation/valid/ConsistentAreaTester.cpp
+++ b/src/operation/valid/ConsistentAreaTester.cpp
@@ -28,6 +28,7 @@
 #include <geos/operation/relate/RelateNodeGraph.h>
 #include <geos/operation/relate/RelateNode.h>
 #include <geos/operation/relate/EdgeEndBundle.h>
+#include <geos/util.h>
 
 #include <memory> // unique_ptr
 #include <cassert>
@@ -100,13 +101,11 @@ ConsistentAreaTester::hasDuplicateRings()
 {
     auto& nMap = nodeGraph.getNodeMap();
     for(auto& entry : nMap) {
-        assert(dynamic_cast<relate::RelateNode*>(entry.second));
-        relate::RelateNode* node = static_cast<relate::RelateNode*>(entry.second);
+        relate::RelateNode* node = detail::down_cast<relate::RelateNode*>(entry.second);
         EdgeEndStar* ees = node->getEdges();
         EdgeEndStar::iterator endIt = ees->end();
         for(EdgeEndStar::iterator it = ees->begin(); it != endIt; ++it) {
-            assert(dynamic_cast<relate::EdgeEndBundle*>(*it));
-            relate::EdgeEndBundle* eeb = static_cast<relate::EdgeEndBundle*>(*it);
+            relate::EdgeEndBundle* eeb = detail::down_cast<relate::EdgeEndBundle*>(*it);
             if(eeb->getEdgeEnds().size() > 1) {
                 invalidPoint = eeb->getEdge()->getCoordinate(0);
                 return true;

-----------------------------------------------------------------------

Summary of changes:
 include/geos/util.h                             | 24 ++++++++++++++-
 src/geomgraph/DirectedEdgeStar.cpp              | 41 +++++++++----------------
 src/geomgraph/EdgeRing.cpp                      |  3 +-
 src/geomgraph/Node.cpp                          |  4 +--
 src/geomgraph/PlanarGraph.cpp                   |  6 ++--
 src/noding/IntersectionAdder.cpp                |  6 ++--
 src/noding/IntersectionFinderAdder.cpp          |  6 ++--
 src/noding/snapround/SimpleSnapRounder.cpp      |  9 +++---
 src/operation/buffer/BufferSubgraph.cpp         | 16 ++++------
 src/operation/buffer/OffsetCurveSetBuilder.cpp  |  4 +--
 src/operation/buffer/RightmostEdgeFinder.cpp    |  4 +--
 src/operation/linemerge/EdgeString.cpp          |  4 +--
 src/operation/linemerge/LineMerger.cpp          |  5 ++-
 src/operation/linemerge/LineSequencer.cpp       |  7 ++---
 src/operation/overlay/LineBuilder.cpp           | 10 +++---
 src/operation/overlay/MaximalEdgeRing.cpp       |  4 +--
 src/operation/overlay/OverlayOp.cpp             | 10 +++---
 src/operation/overlay/PolygonBuilder.cpp        |  3 +-
 src/operation/polygonize/PolygonizeGraph.cpp    | 27 ++++++++--------
 src/operation/relate/RelateComputer.cpp         |  7 ++---
 src/operation/relate/RelateNode.cpp             |  4 +--
 src/operation/valid/ConnectedInteriorTester.cpp | 11 ++-----
 src/operation/valid/ConsistentAreaTester.cpp    |  7 ++---
 23 files changed, 106 insertions(+), 116 deletions(-)


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list