[geos-commits] [SCM] GEOS branch master updated. 030ee891c8bf571f37174b51084e76c01d738950

git at osgeo.org git at osgeo.org
Mon Sep 23 13:49:33 PDT 2019


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  030ee891c8bf571f37174b51084e76c01d738950 (commit)
       via  6e683329a7ff127868fc1133d8d94fe696a35e78 (commit)
       via  dcebb66a97190f42e6e79f8a0b4e5a19418ab657 (commit)
       via  0bdececf28d9bdae945913c9fbeff914d0444399 (commit)
       via  4175971f36e3505fc9b4434d83e393757cd5368e (commit)
       via  274427a99096336af4a1b69de968638c6de20b01 (commit)
       via  ca835cfe60b58aa21d5b56612f1ac374cb4d3c4f (commit)
       via  d6e2882de805e05212407eed155455d92b0a7ff0 (commit)
       via  e8680b4a58b9e0d87c08ba35c303eb3e3ae30357 (commit)
       via  9926c5036ea8708fa3e9dedf969c8592adc1e463 (commit)
       via  ba6340e26fc9e28d39121e035f207e66618b0abd (commit)
       via  f578e6c4ceca6d4fde50ad0566df279d0c57df5d (commit)
       via  e1fd59f2c826e8b5ca3490416ed7461003bd2529 (commit)
       via  dc76a5989a492dfce2ff76ab78c7760fe8a0b7e0 (commit)
       via  3d280950490a7d7d64b90e1b3b9dbc09fe3e36fc (commit)
       via  660038c330599635cf224b199248c690ac92dd1f (commit)
       via  de653e0113298557ebb8d1e65949fce1614475f7 (commit)
       via  4c28ade0dc9c413a3003507db61b5579d2b822c4 (commit)
       via  692f90fa62da867e58b0d7bface9d99483aae670 (commit)
       via  86d19e41441df9c2ee9683dbca3140541a3456d6 (commit)
       via  6b0bde06d048af58ec549747516505de6148caf5 (commit)
       via  7102aa84d20a9694fba8f8ca0bd96072892bbde0 (commit)
       via  b73adc0bce3da17018508994e6bfa65b54c0aad4 (commit)
       via  4f68a684f037f5967fca105202bfc608eb9c9d9c (commit)
       via  81a3952b0340788252a5e483eeb35c867df61d0c (commit)
       via  f47a5fe78c839f797298528b5c96085f136b6276 (commit)
       via  73524c36f1bbe3547615d4d29929cb4f03c41b68 (commit)
      from  a79ba9904d1cc1d52d1d248b71579bf1b82711b8 (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 030ee891c8bf571f37174b51084e76c01d738950
Author: Daniel Baston <dbaston at gmail.com>
Date:   Mon Sep 23 14:21:43 2019 -0400

    Use array instead of vector in SegmentIntersector

diff --git a/include/geos/geom/Coordinate.h b/include/geos/geom/Coordinate.h
index eb8ca72..c6b5877 100644
--- a/include/geos/geom/Coordinate.h
+++ b/include/geos/geom/Coordinate.h
@@ -115,7 +115,7 @@ public:
 
     double distanceSquared(const Coordinate& p) const;
 
-    struct HashCode {
+    struct GEOS_DLL HashCode {
         size_t operator()(const Coordinate & c) const;
     };
 
diff --git a/include/geos/geomgraph/index/SegmentIntersector.h b/include/geos/geomgraph/index/SegmentIntersector.h
index 774d368..2584cd4 100644
--- a/include/geos/geomgraph/index/SegmentIntersector.h
+++ b/include/geos/geomgraph/index/SegmentIntersector.h
@@ -17,6 +17,7 @@
 #define GEOS_GEOMGRAPH_INDEX_SEGMENTINTERSECTOR_H
 
 #include <geos/export.h>
+#include <array>
 #include <vector>
 
 #include <geos/geom/Coordinate.h> // for composition
@@ -76,12 +77,12 @@ private:
     int numIntersections;
 
     /// Elements are externally owned
-    std::vector<std::vector<Node*>*> bdyNodes;
+    std::array<std::vector<Node*>*, 2> bdyNodes;
 
     bool isTrivialIntersection(Edge* e0, size_t segIndex0, Edge* e1, size_t segIndex1);
 
     bool isBoundaryPoint(algorithm::LineIntersector* li,
-                         std::vector<std::vector<Node*>*>& tstBdyNodes);
+                         std::array<std::vector<Node*>*, 2>& tstBdyNodes);
 
     bool isBoundaryPoint(algorithm::LineIntersector* li,
                          std::vector<Node*>* tstBdyNodes);
@@ -110,7 +111,7 @@ public:
         includeProper(newIncludeProper),
         recordIsolated(newRecordIsolated),
         numIntersections(0),
-        bdyNodes(2),
+        bdyNodes{nullptr, nullptr},
         numTests(0)
     {}
 
diff --git a/include/geos/geomgraph/index/SegmentIntersector.inl b/include/geos/geomgraph/index/SegmentIntersector.inl
index eb7b5be..bdec37b 100644
--- a/include/geos/geomgraph/index/SegmentIntersector.inl
+++ b/include/geos/geomgraph/index/SegmentIntersector.inl
@@ -88,7 +88,7 @@ SegmentIntersector::hasProperInteriorIntersection()
 /*private*/
 INLINE bool
 SegmentIntersector::isBoundaryPoint(algorithm::LineIntersector* p_li,
-                                    std::vector<std::vector<Node*>*>& tstBdyNodes)
+                                    std::array<std::vector<Node*>*, 2>& tstBdyNodes)
 {
     return isBoundaryPoint(p_li, tstBdyNodes[0]) || isBoundaryPoint(p_li, tstBdyNodes[1]);
 }
diff --git a/include/geos/noding/OrientedCoordinateArray.h b/include/geos/noding/OrientedCoordinateArray.h
index 08caf76..7b648ec 100644
--- a/include/geos/noding/OrientedCoordinateArray.h
+++ b/include/geos/noding/OrientedCoordinateArray.h
@@ -71,7 +71,7 @@ public:
 
     bool operator==(const OrientedCoordinateArray& other) const;
 
-    struct HashCode {
+    struct GEOS_DLL HashCode {
         size_t operator()(const OrientedCoordinateArray & oca) const;
     };
 

commit 6e683329a7ff127868fc1133d8d94fe696a35e78
Author: Daniel Baston <dbaston at gmail.com>
Date:   Mon Sep 23 14:16:09 2019 -0400

    Inline short methods of SegmentIntersector

diff --git a/include/geos/geomgraph/index/Makefile.am b/include/geos/geomgraph/index/Makefile.am
index 6501b6a..280fde3 100644
--- a/include/geos/geomgraph/index/Makefile.am
+++ b/include/geos/geomgraph/index/Makefile.am
@@ -13,6 +13,7 @@ geos_HEADERS = \
     MonotoneChainEdge.h \
     MonotoneChainIndexer.h \
     SegmentIntersector.h \
+    SegmentIntersector.inl \
     SimpleEdgeSetIntersector.h \
     SimpleMCSweepLineIntersector.h \
     SimpleSweepLineIntersector.h \
diff --git a/include/geos/geomgraph/index/SegmentIntersector.h b/include/geos/geomgraph/index/SegmentIntersector.h
index 5c1aec9..774d368 100644
--- a/include/geos/geomgraph/index/SegmentIntersector.h
+++ b/include/geos/geomgraph/index/SegmentIntersector.h
@@ -140,6 +140,10 @@ public:
 } // namespace geos.geomgraph
 } // namespace geos
 
+#ifdef GEOS_INLINE
+#include <geos/geomgraph/index/SegmentIntersector.inl>
+#endif
+
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
diff --git a/include/geos/geomgraph/index/SegmentIntersector.inl b/include/geos/geomgraph/index/SegmentIntersector.inl
new file mode 100644
index 0000000..eb7b5be
--- /dev/null
+++ b/include/geos/geomgraph/index/SegmentIntersector.inl
@@ -0,0 +1,101 @@
+/**********************************************************************
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.osgeo.org
+ *
+ * Copyright (C) 2001-2002 Vivid Solutions Inc.
+ * Copyright (C) 2005 Refractions Research Inc.
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU Lesser General Public Licence as published
+ * by the Free Software Foundation.
+ * See the COPYING file for more information.
+ *
+ **********************************************************************/
+
+#ifndef GEOS_GEOMGRAPH_INDEX_SEGMENTINTERSECTOR_INL
+#define GEOS_GEOMGRAPH_INDEX_SEGMENTINTERSECTOR_INL
+
+namespace geos {
+namespace geomgraph {
+namespace index {
+
+INLINE bool
+SegmentIntersector::isAdjacentSegments(size_t i1, size_t i2)
+{
+    return (i1 > i2 ? i1 - i2 : i2 - i1) == 1;
+}
+
+INLINE void
+SegmentIntersector::setBoundaryNodes(std::vector<Node*>* bdyNodes0,
+                                     std::vector<Node*>* bdyNodes1)
+{
+    bdyNodes[0] = bdyNodes0;
+    bdyNodes[1] = bdyNodes1;
+}
+
+/*
+* @return the proper intersection point, or <code>null</code>
+* if none was found
+*/
+INLINE geom::Coordinate&
+SegmentIntersector::getProperIntersectionPoint()
+{
+    return properIntersectionPoint;
+}
+
+INLINE bool
+SegmentIntersector::hasIntersection()
+{
+    return hasIntersectionVar;
+}
+
+INLINE void
+SegmentIntersector::setIsDoneIfProperInt(bool idwpi)
+{
+    isDoneWhenProperInt = idwpi;
+}
+
+INLINE bool
+SegmentIntersector::getIsDone()
+{
+    return isDone;
+}
+
+/*
+ * A proper intersection is an intersection which is interior to at least two
+ * line segments.  Note that a proper intersection is not necessarily
+ * in the interior of the entire Geometry, since another edge may have
+ * an endpoint equal to the intersection, which according to SFS semantics
+ * can result in the point being on the Boundary of the Geometry.
+ */
+INLINE bool
+SegmentIntersector::hasProperIntersection()
+{
+    return hasProper;
+}
+
+/*
+ * A proper interior intersection is a proper intersection which is <b>not</b>
+ * contained in the set of boundary nodes set for this SegmentIntersector.
+ */
+INLINE bool
+SegmentIntersector::hasProperInteriorIntersection()
+{
+    return hasProperInterior;
+}
+
+/*private*/
+INLINE bool
+SegmentIntersector::isBoundaryPoint(algorithm::LineIntersector* p_li,
+                                    std::vector<std::vector<Node*>*>& tstBdyNodes)
+{
+    return isBoundaryPoint(p_li, tstBdyNodes[0]) || isBoundaryPoint(p_li, tstBdyNodes[1]);
+}
+
+
+}
+}
+}
+
+#endif
diff --git a/src/geomgraph/index/SegmentIntersector.cpp b/src/geomgraph/index/SegmentIntersector.cpp
index f3d5c78..7cc61f1 100644
--- a/src/geomgraph/index/SegmentIntersector.cpp
+++ b/src/geomgraph/index/SegmentIntersector.cpp
@@ -34,7 +34,6 @@
 #include <iostream>
 #endif
 
-using namespace std;
 using namespace geos::geom;
 
 namespace geos {
@@ -43,71 +42,6 @@ namespace index { // geos.geomgraph.index
 
 using namespace geos::algorithm;
 
-bool
-SegmentIntersector::isAdjacentSegments(size_t i1, size_t i2)
-{
-    return (i1 > i2 ? i1 - i2 : i2 - i1) == 1;
-}
-
-void
-SegmentIntersector::setBoundaryNodes(vector<Node*>* bdyNodes0,
-                                     vector<Node*>* bdyNodes1)
-{
-    bdyNodes[0] = bdyNodes0;
-    bdyNodes[1] = bdyNodes1;
-}
-
-/*
- * @return the proper intersection point, or <code>null</code>
- * if none was found
- */
-Coordinate&
-SegmentIntersector::getProperIntersectionPoint()
-{
-    return properIntersectionPoint;
-}
-
-bool
-SegmentIntersector::hasIntersection()
-{
-    return hasIntersectionVar;
-}
-
-void
-SegmentIntersector::setIsDoneIfProperInt(bool idwpi)
-{
-    isDoneWhenProperInt = idwpi;
-}
-
-bool
-SegmentIntersector::getIsDone()
-{
-    return isDone;
-}
-
-/*
- * A proper intersection is an intersection which is interior to at least two
- * line segments.  Note that a proper intersection is not necessarily
- * in the interior of the entire Geometry, since another edge may have
- * an endpoint equal to the intersection, which according to SFS semantics
- * can result in the point being on the Boundary of the Geometry.
- */
-bool
-SegmentIntersector::hasProperIntersection()
-{
-    return hasProper;
-}
-
-/*
- * A proper interior intersection is a proper intersection which is <b>not</b>
- * contained in the set of boundary nodes set for this SegmentIntersector.
- */
-bool
-SegmentIntersector::hasProperInteriorIntersection()
-{
-    return hasProperInterior;
-}
-
 /*
  * A trivial intersection is an apparent self-intersection which in fact
  * is simply the point shared by adjacent line segments.
@@ -216,13 +150,13 @@ SegmentIntersector::addIntersections(Edge* e0, size_t segIndex0, Edge* e1, size_
 /*private*/
 bool
 SegmentIntersector::isBoundaryPoint(LineIntersector* p_li,
-                                    vector<Node*>* tstBdyNodes)
+                                    std::vector<Node*>* tstBdyNodes)
 {
     if(! tstBdyNodes) {
         return false;
     }
 
-    for(vector<Node*>::iterator i = tstBdyNodes->begin(); i < tstBdyNodes->end(); i++) {
+    for(std::vector<Node*>::iterator i = tstBdyNodes->begin(); i < tstBdyNodes->end(); i++) {
         Node* node = *i;
         const Coordinate& pt = node->getCoordinate();
         if(p_li->isIntersection(pt)) {
@@ -233,20 +167,6 @@ SegmentIntersector::isBoundaryPoint(LineIntersector* p_li,
 }
 
 
-/*private*/
-bool
-SegmentIntersector::isBoundaryPoint(LineIntersector* p_li,
-                                    vector<vector<Node*>*>& tstBdyNodes)
-{
-    if(isBoundaryPoint(p_li, tstBdyNodes[0])) {
-        return true;
-    }
-    if(isBoundaryPoint(p_li, tstBdyNodes[1])) {
-        return true;
-    }
-    return false;
-}
-
 } // namespace geos.geomgraph.index
 } // namespace geos.geomgraph
 } // namespace geos
diff --git a/src/inlines.cpp b/src/inlines.cpp
index 444b2af..8f9d462 100644
--- a/src/inlines.cpp
+++ b/src/inlines.cpp
@@ -60,6 +60,7 @@
 #include <geos/geomgraph/Label.inl>
 #include <geos/geomgraph/Quadrant.inl>
 #include <geos/geomgraph/TopologyLocation.inl>
+#include <geos/geomgraph/index/SegmentIntersector.inl>
 #include <geos/noding/snapround/HotPixel.inl>
 #include <geos/noding/BasicSegmentString.inl>
 #include <geos/noding/MCIndexNoder.inl>

commit dcebb66a97190f42e6e79f8a0b4e5a19418ab657
Author: Daniel Baston <dbaston at gmail.com>
Date:   Mon Sep 23 13:51:35 2019 -0400

    Inline simple methods of BasicSegmentString

diff --git a/include/geos/noding/BasicSegmentString.h b/include/geos/noding/BasicSegmentString.h
index f5a5342..15226d7 100644
--- a/include/geos/noding/BasicSegmentString.h
+++ b/include/geos/noding/BasicSegmentString.h
@@ -28,11 +28,6 @@
 #include <vector>
 
 // Forward declarations
-namespace geos {
-namespace algorithm {
-//class LineIntersector;
-}
-}
 
 namespace geos {
 namespace noding { // geos.noding
@@ -102,5 +97,8 @@ private:
 } // namespace geos.noding
 } // namespace geos
 
-#endif // ndef GEOS_NODING_BASICSEGMENTSTRING_H
+#ifdef GEOS_INLINE
+#include <geos/noding/BasicSegmentString.inl>
+#endif
 
+#endif // ndef GEOS_NODING_BASICSEGMENTSTRING_H
diff --git a/src/noding/BasicSegmentString.cpp b/include/geos/noding/BasicSegmentString.inl
similarity index 65%
copy from src/noding/BasicSegmentString.cpp
copy to include/geos/noding/BasicSegmentString.inl
index 5c98203..449ddca 100644
--- a/src/noding/BasicSegmentString.cpp
+++ b/include/geos/noding/BasicSegmentString.inl
@@ -16,30 +16,19 @@
  *
  **********************************************************************/
 
-#include <geos/noding/BasicSegmentString.h>
-#include <geos/geom/Coordinate.h>
-#include <geos/geom/CoordinateSequence.h>
-#include <geos/util/IllegalArgumentException.h>
-#include <geos/noding/Octant.h>
-//#include <geos/profiler.h>
-
-#ifndef GEOS_DEBUG
-#define GEOS_DEBUG 0
-#endif
+#ifndef GEOS_NODING_BASICSEGMENTSTRING_INL
+#define GEOS_NODING_BASICSEGMENTSTRING_INL
 
-#include <iostream>
-#include <sstream>
+#include <cstddef>
 
-using namespace geos::algorithm;
-using namespace geos::geom;
+#include <geos/noding/BasicSegmentString.h>
+#include <geos/noding/Octant.h>
 
 namespace geos {
-namespace noding { // geos.noding
-
-
+namespace noding {
 
 /*public*/
-int
+INLINE int
 BasicSegmentString::getSegmentOctant(size_t index) const
 {
     if(index >= size() - 1) {
@@ -49,37 +38,27 @@ BasicSegmentString::getSegmentOctant(size_t index) const
 }
 
 /* virtual public */
-const geom::Coordinate&
+INLINE const geom::Coordinate&
 BasicSegmentString::getCoordinate(size_t i) const
 {
     return pts->getAt(i);
 }
 
 /* virtual public */
-geom::CoordinateSequence*
+INLINE geom::CoordinateSequence*
 BasicSegmentString::getCoordinates() const
 {
     return pts;
 }
 
 /* virtual public */
-bool
+INLINE bool
 BasicSegmentString::isClosed() const
 {
     return pts->getAt(0) == pts->getAt(size() - 1);
 }
 
-/* public virtual */
-std::ostream&
-BasicSegmentString::print(std::ostream& os) const
-{
-    os << "BasicSegmentString: " << std::endl;
-    os << " LINESTRING" << *(pts) << ";" << std::endl;
-
-    return os;
+}
 }
 
-
-} // namespace geos.noding
-} // namespace geos
-
+#endif
diff --git a/include/geos/noding/Makefile.am b/include/geos/noding/Makefile.am
index 30cf761..1b7d389 100644
--- a/include/geos/noding/Makefile.am
+++ b/include/geos/noding/Makefile.am
@@ -9,6 +9,7 @@ geosdir = $(includedir)/geos/noding
 
 geos_HEADERS = \
 	BasicSegmentString.h \
+	BasicSegmentString.inl \
 	FastNodingValidator.h \
 	FastSegmentSetIntersectionFinder.h \
 	GeometryNoder.h \
diff --git a/src/inlines.cpp b/src/inlines.cpp
index e4d18b0..444b2af 100644
--- a/src/inlines.cpp
+++ b/src/inlines.cpp
@@ -61,6 +61,7 @@
 #include <geos/geomgraph/Quadrant.inl>
 #include <geos/geomgraph/TopologyLocation.inl>
 #include <geos/noding/snapround/HotPixel.inl>
+#include <geos/noding/BasicSegmentString.inl>
 #include <geos/noding/MCIndexNoder.inl>
 
 #endif // defined __CYGWIN__
diff --git a/src/noding/BasicSegmentString.cpp b/src/noding/BasicSegmentString.cpp
index 5c98203..ad826b2 100644
--- a/src/noding/BasicSegmentString.cpp
+++ b/src/noding/BasicSegmentString.cpp
@@ -17,11 +17,7 @@
  **********************************************************************/
 
 #include <geos/noding/BasicSegmentString.h>
-#include <geos/geom/Coordinate.h>
 #include <geos/geom/CoordinateSequence.h>
-#include <geos/util/IllegalArgumentException.h>
-#include <geos/noding/Octant.h>
-//#include <geos/profiler.h>
 
 #ifndef GEOS_DEBUG
 #define GEOS_DEBUG 0
@@ -36,39 +32,6 @@ using namespace geos::geom;
 namespace geos {
 namespace noding { // geos.noding
 
-
-
-/*public*/
-int
-BasicSegmentString::getSegmentOctant(size_t index) const
-{
-    if(index >= size() - 1) {
-        return -1;
-    }
-    return Octant::octant(getCoordinate(index), getCoordinate(index + 1));
-}
-
-/* virtual public */
-const geom::Coordinate&
-BasicSegmentString::getCoordinate(size_t i) const
-{
-    return pts->getAt(i);
-}
-
-/* virtual public */
-geom::CoordinateSequence*
-BasicSegmentString::getCoordinates() const
-{
-    return pts;
-}
-
-/* virtual public */
-bool
-BasicSegmentString::isClosed() const
-{
-    return pts->getAt(0) == pts->getAt(size() - 1);
-}
-
 /* public virtual */
 std::ostream&
 BasicSegmentString::print(std::ostream& os) const

commit 0bdececf28d9bdae945913c9fbeff914d0444399
Author: Daniel Baston <dbaston at gmail.com>
Date:   Mon Sep 23 12:23:56 2019 -0400

    Avoid heap alloc in DirectedEdgeStar

diff --git a/benchmarks/ClassSizes.cpp b/benchmarks/ClassSizes.cpp
index 33fb7e1..015be21 100644
--- a/benchmarks/ClassSizes.cpp
+++ b/benchmarks/ClassSizes.cpp
@@ -52,6 +52,7 @@ main()
 {
     check(geomgraph::Depth);
     check(geomgraph::DirectedEdge);
+    check(geomgraph::DirectedEdgeStar);
     check(geomgraph::Edge);
     check(geomgraph::EdgeEnd);
     check(geomgraph::PlanarGraph);
diff --git a/include/geos/geomgraph/DirectedEdgeStar.h b/include/geos/geomgraph/DirectedEdgeStar.h
index bbdd24a..0c773b5 100644
--- a/include/geos/geomgraph/DirectedEdgeStar.h
+++ b/include/geos/geomgraph/DirectedEdgeStar.h
@@ -59,14 +59,11 @@ public:
     DirectedEdgeStar()
         :
         EdgeEndStar(),
-        resultAreaEdgeList(nullptr),
-        label()
+        label(),
+        resultAreaEdgesComputed(false)
     {}
 
-    ~DirectedEdgeStar() override
-    {
-        delete resultAreaEdgeList;
-    }
+    ~DirectedEdgeStar() override = default;
 
     /// Insert a directed edge in the list
     void insert(EdgeEnd* ee) override;
@@ -140,14 +137,17 @@ private:
     /**
      * A list of all outgoing edges in the result, in CCW order
      */
-    std::vector<DirectedEdge*>* resultAreaEdgeList;
+    std::vector<DirectedEdge*> resultAreaEdgeList;
 
     Label label;
 
+    bool resultAreaEdgesComputed;
+
     /// \brief
-    /// Returned vector is onwed by DirectedEdgeStar object, but
+    /// Returned vector is owned by DirectedEdgeStar object, but
     /// lazily created
-    std::vector<DirectedEdge*>* getResultAreaEdges();
+    const std::vector<DirectedEdge*>& getResultAreaEdges();
+
 
     /// States for linResultDirectedEdges
     enum {
diff --git a/src/geomgraph/DirectedEdgeStar.cpp b/src/geomgraph/DirectedEdgeStar.cpp
index e4c7827..6929582 100644
--- a/src/geomgraph/DirectedEdgeStar.cpp
+++ b/src/geomgraph/DirectedEdgeStar.cpp
@@ -198,24 +198,24 @@ DirectedEdgeStar::updateLabelling(const Label& nodeLabel)
 }
 
 /*private*/
-std::vector<DirectedEdge*>*
+const std::vector<DirectedEdge*>&
 DirectedEdgeStar::getResultAreaEdges()
 {
-    if(resultAreaEdgeList != nullptr) {
+    if(resultAreaEdgesComputed) {
         return resultAreaEdgeList;
     }
 
-    resultAreaEdgeList = new std::vector<DirectedEdge*>();
-
     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);
         if(de->isInResult() || de->getSym()->isInResult()) {
-            resultAreaEdgeList->push_back(de);
+            resultAreaEdgeList.push_back(de);
         }
     }
+
+    resultAreaEdgesComputed = true;
     return resultAreaEdgeList;
 }
 
@@ -231,11 +231,7 @@ DirectedEdgeStar::linkResultDirectedEdges()
     DirectedEdge* incoming = nullptr;
     int state = SCANNING_FOR_INCOMING;
     // link edges in CCW order
-    for(std::vector<DirectedEdge*>::iterator
-            i = resultAreaEdgeList->begin(), iEnd = resultAreaEdgeList->end();
-            i != iEnd;
-            ++i) {
-        DirectedEdge* nextOut = *i;
+    for(DirectedEdge* nextOut : resultAreaEdgeList) {
         assert(nextOut);
 
         // skip de's that we're not interested in
@@ -290,10 +286,9 @@ DirectedEdgeStar::linkMinimalDirectedEdges(EdgeRing* er)
 
     // link edges in CW order
     for(std::vector<DirectedEdge*>::reverse_iterator
-            i = resultAreaEdgeList->rbegin(), iEnd = resultAreaEdgeList->rend();
+            i = resultAreaEdgeList.rbegin(), iEnd = resultAreaEdgeList.rend();
             i != iEnd;
             ++i) {
-        //DirectedEdge *nextOut=(*resultAreaEdgeList)[i];
         DirectedEdge* nextOut = *i;
         assert(nextOut);
 

commit 4175971f36e3505fc9b4434d83e393757cd5368e
Author: Daniel Baston <dbaston at gmail.com>
Date:   Mon Sep 23 12:10:59 2019 -0400

    Remove heap alloc in EdgeEndBundle

diff --git a/include/geos/operation/relate/EdgeEndBundle.h b/include/geos/operation/relate/EdgeEndBundle.h
index 95dc021..bc573b8 100644
--- a/include/geos/operation/relate/EdgeEndBundle.h
+++ b/include/geos/operation/relate/EdgeEndBundle.h
@@ -48,7 +48,7 @@ class GEOS_DLL EdgeEndBundle: public geomgraph::EdgeEnd {
 public:
     EdgeEndBundle(geomgraph::EdgeEnd* e);
     ~EdgeEndBundle() override;
-    std::vector<geomgraph::EdgeEnd*>* getEdgeEnds();
+    const std::vector<geomgraph::EdgeEnd*>& getEdgeEnds();
     void insert(geomgraph::EdgeEnd* e);
 
     void computeLabel(const algorithm::BoundaryNodeRule& bnr) override;
@@ -62,7 +62,7 @@ public:
 
     std::string print() const override;
 protected:
-    std::vector<geomgraph::EdgeEnd*>* edgeEnds;
+    std::vector<geomgraph::EdgeEnd*> edgeEnds;
 
     /**
      * Compute the overall ON location for the list of EdgeStubs.
diff --git a/src/operation/relate/EdgeEndBundle.cpp b/src/operation/relate/EdgeEndBundle.cpp
index 3f458d8..fce941b 100644
--- a/src/operation/relate/EdgeEndBundle.cpp
+++ b/src/operation/relate/EdgeEndBundle.cpp
@@ -40,22 +40,20 @@ EdgeEndBundle::EdgeEndBundle(EdgeEnd* e):
             e->getDirectedCoordinate(),
             e->getLabel())
 {
-    edgeEnds = new vector<EdgeEnd*>();
     insert(e);
 }
 
 EdgeEndBundle::~EdgeEndBundle()
 {
-    for(size_t i = 0, n = edgeEnds->size(); i < n; i++) {
-        delete(*edgeEnds)[i];
+    for(size_t i = 0, n = edgeEnds.size(); i < n; i++) {
+        delete edgeEnds[i];
     }
-    delete edgeEnds;
 }
 
 //Not needed
 //public Iterator iterator() { return edgeEnds.iterator(); }
 
-vector<EdgeEnd*>*
+const vector<EdgeEnd*>&
 EdgeEndBundle::getEdgeEnds()
 {
     return edgeEnds;
@@ -66,7 +64,7 @@ EdgeEndBundle::insert(EdgeEnd* e)
 {
     // Assert: start point is the same
     // Assert: direction is the same
-    edgeEnds->push_back(e);
+    edgeEnds.push_back(e);
 }
 
 
@@ -83,7 +81,7 @@ EdgeEndBundle::computeLabel(
     // the label must be an area label
     bool isArea = false;
 
-    for(vector<EdgeEnd*>::iterator it = edgeEnds->begin(), itEnd = edgeEnds->end();
+    for(vector<EdgeEnd*>::iterator it = edgeEnds.begin(), itEnd = edgeEnds.end();
             it != itEnd; it++) {
         EdgeEnd* e = *it;
         if(e->getLabel().isArea()) {
@@ -113,7 +111,7 @@ EdgeEndBundle::computeLabelOn(int geomIndex, const algorithm::BoundaryNodeRule&
     int boundaryCount = 0;
     bool foundInterior = false;
 
-    for(vector<EdgeEnd*>::iterator it = edgeEnds->begin(); it < edgeEnds->end(); it++) {
+    for(vector<EdgeEnd*>::iterator it = edgeEnds.begin(); it < edgeEnds.end(); it++) {
         EdgeEnd* e = *it;
         Location loc = e->getLabel().getLocation(geomIndex);
         if(loc == Location::BOUNDARY) {
@@ -162,7 +160,7 @@ EdgeEndBundle::computeLabelSides(int geomIndex)
 void
 EdgeEndBundle::computeLabelSide(int geomIndex, int side)
 {
-    for(vector<EdgeEnd*>::iterator it = edgeEnds->begin(); it < edgeEnds->end(); it++) {
+    for(vector<EdgeEnd*>::iterator it = edgeEnds.begin(); it < edgeEnds.end(); it++) {
         EdgeEnd* e = *it;
         if(e->getLabel().isArea()) {
             Location loc = e->getLabel().getLocation(geomIndex, side);
@@ -187,8 +185,7 @@ string
 EdgeEndBundle::print() const
 {
     string out = "EdgeEndBundle--> Label: " + label.toString() + "\n";
-    for(vector<EdgeEnd*>::iterator it = edgeEnds->begin(); it < edgeEnds->end(); it++) {
-        EdgeEnd* e = *it;
+    for(auto& e : edgeEnds) {
         out += e->print();
         out += "\n";
     }
diff --git a/src/operation/valid/ConsistentAreaTester.cpp b/src/operation/valid/ConsistentAreaTester.cpp
index 0b7280a..445add1 100644
--- a/src/operation/valid/ConsistentAreaTester.cpp
+++ b/src/operation/valid/ConsistentAreaTester.cpp
@@ -107,7 +107,7 @@ ConsistentAreaTester::hasDuplicateRings()
         for(EdgeEndStar::iterator it = ees->begin(); it != endIt; ++it) {
             assert(dynamic_cast<relate::EdgeEndBundle*>(*it));
             relate::EdgeEndBundle* eeb = static_cast<relate::EdgeEndBundle*>(*it);
-            if(eeb->getEdgeEnds()->size() > 1) {
+            if(eeb->getEdgeEnds().size() > 1) {
                 invalidPoint = eeb->getEdge()->getCoordinate(0);
                 return true;
             }

commit 274427a99096336af4a1b69de968638c6de20b01
Author: Daniel Baston <dbaston at gmail.com>
Date:   Mon Sep 23 10:59:15 2019 -0400

    Reuse vector between iterations of MCIndexNoder::intersectChains()

diff --git a/src/noding/MCIndexNoder.cpp b/src/noding/MCIndexNoder.cpp
index 74827f1..8b6bb52 100644
--- a/src/noding/MCIndexNoder.cpp
+++ b/src/noding/MCIndexNoder.cpp
@@ -64,22 +64,15 @@ MCIndexNoder::intersectChains()
 
     SegmentOverlapAction overlapAction(*segInt);
 
-    for(vector<MonotoneChain*>::iterator
-            i = monoChains.begin(), iEnd = monoChains.end();
-            i != iEnd;
-            ++i) {
-
+    vector<void*> overlapChains;
+    for(MonotoneChain* queryChain : monoChains) {
         GEOS_CHECK_FOR_INTERRUPTS();
 
-        MonotoneChain* queryChain = *i;
         assert(queryChain);
-        vector<void*> overlapChains;
+        overlapChains.clear();
         index.query(&(queryChain->getEnvelope()), overlapChains);
-        for(vector<void*>::iterator
-                j = overlapChains.begin(), jEnd = overlapChains.end();
-                j != jEnd;
-                ++j) {
-            MonotoneChain* testChain = static_cast<MonotoneChain*>(*j);
+        for(void* hit : overlapChains) {
+            MonotoneChain* testChain = static_cast<MonotoneChain*>(hit);
             assert(testChain);
 
             /**

commit ca835cfe60b58aa21d5b56612f1ac374cb4d3c4f
Author: Daniel Baston <dbaston at gmail.com>
Date:   Mon Sep 23 10:34:22 2019 -0400

    Optimize LineString::computeEnvelopeInternal
    
    CoordinateSequence can calculate its own envlope faster that we can through getAt()

diff --git a/src/geom/LineString.cpp b/src/geom/LineString.cpp
index 590c893..cfcbb2b 100644
--- a/src/geom/LineString.cpp
+++ b/src/geom/LineString.cpp
@@ -253,25 +253,7 @@ LineString::computeEnvelopeInternal() const
         return Envelope::Ptr(new Envelope());
     }
 
-    assert(points.get());
-    const Coordinate& c = points->getAt(0);
-    double minx = c.x;
-    double miny = c.y;
-    double maxx = c.x;
-    double maxy = c.y;
-    std::size_t npts = points->getSize();
-    for(std::size_t i = 1; i < npts; i++) {
-        const Coordinate& c1 = points->getAt(i);
-        minx = minx < c1.x ? minx : c1.x;
-        maxx = maxx > c1.x ? maxx : c1.x;
-        miny = miny < c1.y ? miny : c1.y;
-        maxy = maxy > c1.y ? maxy : c1.y;
-    }
-
-    // caller expects a newly allocated Envelope.
-    // this function won't be called twice, unless
-    // cached Envelope is invalidated (set to NULL)
-    return Envelope::Ptr(new Envelope(minx, maxx, miny, maxy));
+    return detail::make_unique<Envelope>(points->getEnvelope());
 }
 
 bool

commit d6e2882de805e05212407eed155455d92b0a7ff0
Author: Daniel Baston <dbaston at gmail.com>
Date:   Sun Sep 22 16:33:16 2019 -0400

    Inline small methods of Depth

diff --git a/include/geos/geomgraph/Depth.h b/include/geos/geomgraph/Depth.h
index 095affd..829e1c5 100644
--- a/include/geos/geomgraph/Depth.h
+++ b/include/geos/geomgraph/Depth.h
@@ -63,4 +63,8 @@ private:
 } // namespace geos.geomgraph
 } // namespace geos
 
+#ifdef GEOS_INLINE
+# include "geos/geomgraph/Depth.inl"
+#endif
+
 #endif // ifndef GEOS_GEOMGRAPH_DEPTH_H
diff --git a/include/geos/geomgraph/Depth.inl b/include/geos/geomgraph/Depth.inl
new file mode 100644
index 0000000..6025c17
--- /dev/null
+++ b/include/geos/geomgraph/Depth.inl
@@ -0,0 +1,119 @@
+/**********************************************************************
+ *
+ * GEOS - Geometry Engine Open Source
+ * http://geos.osgeo.org
+ *
+ * Copyright (C) 2001-2002 Vivid Solutions Inc.
+ * Copyright (C) 2005 Refractions Research Inc.
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU Lesser General Public Licence as published
+ * by the Free Software Foundation.
+ * See the COPYING file for more information.
+ *
+ **********************************************************************
+ *
+ * Last port: geomgraph/Depth.java rev. 1.4 (JTS-1.10)
+ *
+ **********************************************************************/
+
+#ifndef GEOS_GEOMGRAPH_DEPTH_INL
+#define GEOS_GEOMGRAPH_DEPTH_INL
+
+#include <geos/geomgraph/Depth.h>
+#include <geos/geomgraph/Position.h>
+#include <geos/geom/Location.h>
+
+namespace geos {
+namespace geomgraph {
+
+INLINE
+Depth::Depth()
+{
+    // initialize depth array to a sentinel value
+    for(int i = 0; i < 2; i++) {
+        for(int j = 0; j < 3; j++) {
+            depth[i][j] = NULL_VALUE;
+        }
+    }
+}
+
+INLINE int
+Depth::getDepth(int geomIndex, int posIndex) const
+{
+    return depth[geomIndex][posIndex];
+}
+
+INLINE void
+Depth::setDepth(int geomIndex, int posIndex, int depthValue)
+{
+    depth[geomIndex][posIndex] = depthValue;
+}
+
+INLINE geom::Location
+Depth::getLocation(int geomIndex, int posIndex) const
+{
+    if(depth[geomIndex][posIndex] <= 0) {
+        return geom::Location::EXTERIOR;
+    }
+    return geom::Location::INTERIOR;
+}
+
+INLINE void
+Depth::add(int geomIndex, int posIndex, geom::Location location)
+{
+    if(location == geom::Location::INTERIOR) {
+        depth[geomIndex][posIndex]++;
+    }
+}
+
+INLINE int
+Depth::depthAtLocation(geom::Location location)
+{
+    if(location == geom::Location::EXTERIOR) {
+        return 0;
+    }
+    if(location == geom::Location::INTERIOR) {
+        return 1;
+    }
+    return NULL_VALUE;
+}
+
+/**
+ * A Depth object is null (has never been initialized) if all depths are null.
+ */
+INLINE bool
+Depth::isNull() const
+{
+    for(int i = 0; i < 2; i++) {
+        for(int j = 0; j < 3; j++) {
+            if(depth[i][j] != NULL_VALUE) {
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
+INLINE bool
+Depth::isNull(int geomIndex) const
+{
+    return depth[geomIndex][1] == NULL_VALUE;
+}
+
+INLINE bool
+Depth::isNull(int geomIndex, int posIndex) const
+{
+    return depth[geomIndex][posIndex] == NULL_VALUE;
+}
+
+INLINE int
+Depth::getDelta(int geomIndex) const
+{
+    return depth[geomIndex][Position::RIGHT] - depth[geomIndex][Position::LEFT];
+}
+
+}
+}
+
+#endif
\ No newline at end of file
diff --git a/include/geos/geomgraph/Makefile.am b/include/geos/geomgraph/Makefile.am
index 3d4c97a..0f4d9d2 100644
--- a/include/geos/geomgraph/Makefile.am
+++ b/include/geos/geomgraph/Makefile.am
@@ -9,6 +9,7 @@ geosdir = $(includedir)/geos/geomgraph
 
 geos_HEADERS = \
     Depth.h \
+    Depth.inl \
     DirectedEdge.h \
     DirectedEdge.inl \
     DirectedEdgeStar.h \
diff --git a/src/geomgraph/Depth.cpp b/src/geomgraph/Depth.cpp
index 1050fbf..a7fb7c8 100644
--- a/src/geomgraph/Depth.cpp
+++ b/src/geomgraph/Depth.cpp
@@ -25,99 +25,11 @@
 #include <geos/geomgraph/Position.h>
 #include <geos/geom/Location.h>
 
-#define NULL_VALUE -1
-
-using namespace std;
 using namespace geos::geom;
 
 namespace geos {
 namespace geomgraph { // geos.geomgraph
 
-int
-Depth::depthAtLocation(geom::Location location)
-{
-    if(location == Location::EXTERIOR) {
-        return 0;
-    }
-    if(location == Location::INTERIOR) {
-        return 1;
-    }
-    return NULL_VALUE;
-}
-
-Depth::Depth()
-{
-    // initialize depth array to a sentinel value
-    for(int i = 0; i < 2; i++) {
-        for(int j = 0; j < 3; j++) {
-            depth[i][j] = NULL_VALUE;
-        }
-    }
-}
-
-int
-Depth::getDepth(int geomIndex, int posIndex) const
-{
-    return depth[geomIndex][posIndex];
-}
-
-void
-Depth::setDepth(int geomIndex, int posIndex, int depthValue)
-{
-    depth[geomIndex][posIndex] = depthValue;
-}
-
-Location
-Depth::getLocation(int geomIndex, int posIndex) const
-{
-    if(depth[geomIndex][posIndex] <= 0) {
-        return Location::EXTERIOR;
-    }
-    return Location::INTERIOR;
-}
-
-void
-Depth::add(int geomIndex, int posIndex, Location location)
-{
-    if(location == Location::INTERIOR) {
-        depth[geomIndex][posIndex]++;
-    }
-}
-
-/**
- * A Depth object is null (has never been initialized) if all depths are null.
- */
-bool
-Depth::isNull() const
-{
-    for(int i = 0; i < 2; i++) {
-        for(int j = 0; j < 3; j++) {
-            if(depth[i][j] != NULL_VALUE) {
-                return false;
-            }
-        }
-    }
-    return true;
-}
-
-bool
-Depth::isNull(int geomIndex) const
-{
-    return depth[geomIndex][1] == NULL_VALUE;
-}
-
-bool
-Depth::isNull(int geomIndex, int posIndex) const
-{
-    return depth[geomIndex][posIndex] == NULL_VALUE;
-}
-
-int
-Depth::getDelta(int geomIndex) const
-{
-    return depth[geomIndex][Position::RIGHT] - depth[geomIndex][Position::LEFT];
-}
-
 /**
  * Normalize the depths for each geometry, if they are non-null.
  * A normalized depth
@@ -169,10 +81,10 @@ Depth::add(const Label& lbl)
     }
 }
 
-string
+std::string
 Depth::toString() const
 {
-    ostringstream s;
+    std::ostringstream s;
     s << "A:" << depth[0][1] << "," << depth[0][2] << " ";
     s << "B:" << depth[1][1] << "," << depth[1][2] << "]";
     return s.str();
diff --git a/src/inlines.cpp b/src/inlines.cpp
index eb660f4..e4d18b0 100644
--- a/src/inlines.cpp
+++ b/src/inlines.cpp
@@ -56,6 +56,7 @@
 #include <geos/geom/MultiLineString.inl>
 #include <geos/geom/MultiPolygon.inl>
 #include <geos/geom/CoordinateArraySequenceFactory.inl>
+#include <geos/geomgraph/Depth.inl>
 #include <geos/geomgraph/Label.inl>
 #include <geos/geomgraph/Quadrant.inl>
 #include <geos/geomgraph/TopologyLocation.inl>

commit e8680b4a58b9e0d87c08ba35c303eb3e3ae30357
Author: Daniel Baston <dbaston at gmail.com>
Date:   Sun Sep 22 16:24:38 2019 -0400

    Inline CoordinateArraySequence destructor

diff --git a/include/geos/geom/CoordinateArraySequence.h b/include/geos/geom/CoordinateArraySequence.h
index b2b3a36..e8e04a6 100644
--- a/include/geos/geom/CoordinateArraySequence.h
+++ b/include/geos/geom/CoordinateArraySequence.h
@@ -67,7 +67,7 @@ public:
     /// Construct sequence allocating space for n coordinates
     CoordinateArraySequence(std::size_t n, std::size_t dimension = 0);
 
-    ~CoordinateArraySequence() override;
+    ~CoordinateArraySequence() override = default;
 
     bool
     isEmpty() const override
diff --git a/src/geom/CoordinateArraySequence.cpp b/src/geom/CoordinateArraySequence.cpp
index be9ee1a..f7015e2 100644
--- a/src/geom/CoordinateArraySequence.cpp
+++ b/src/geom/CoordinateArraySequence.cpp
@@ -204,8 +204,6 @@ CoordinateArraySequence::setAt(const Coordinate& c, size_t pos)
     vect[pos] = c;
 }
 
-CoordinateArraySequence::~CoordinateArraySequence() = default;
-
 void
 CoordinateArraySequence::expandEnvelope(Envelope& env) const
 {

commit 9926c5036ea8708fa3e9dedf969c8592adc1e463
Author: Daniel Baston <dbaston at gmail.com>
Date:   Sun Sep 22 16:13:17 2019 -0400

    Eagerly calculate Envelope in Edge and MonotoneChain
    
    We always end up needing it, so avoid the heap allocation associated
    with lazy computation.

diff --git a/include/geos/geomgraph/Edge.h b/include/geos/geomgraph/Edge.h
index bfb8a67..bdf1a87 100644
--- a/include/geos/geomgraph/Edge.h
+++ b/include/geos/geomgraph/Edge.h
@@ -30,6 +30,7 @@
 #include <geos/geomgraph/Depth.h> // for member
 #include <geos/geomgraph/EdgeIntersectionList.h> // for composition
 #include <geos/geom/CoordinateSequence.h> // for inlines
+#include <geos/geom/Envelope.h>
 
 #include <geos/inline.h>
 
@@ -41,7 +42,6 @@
 // Forward declarations
 namespace geos {
 namespace geom {
-class Envelope;
 class IntersectionMatrix;
 class Coordinate;
 }
@@ -71,8 +71,7 @@ private:
     /// Lazily-created, owned by Edge.
     std::unique_ptr<index::MonotoneChainEdge> mce;
 
-    /// Lazily-created, owned by Edge.
-    std::unique_ptr<geom::Envelope> env;
+    geom::Envelope env;
 
     Depth depth;
 
diff --git a/include/geos/index/chain/MonotoneChain.h b/include/geos/index/chain/MonotoneChain.h
index c6ac23b..3d23b35 100644
--- a/include/geos/index/chain/MonotoneChain.h
+++ b/include/geos/index/chain/MonotoneChain.h
@@ -27,7 +27,6 @@
 // Forward declarations
 namespace geos {
 namespace geom {
-class Envelope;
 class LineSegment;
 class CoordinateSequence;
 }
@@ -172,8 +171,8 @@ private:
     /// Externally owned
     const geom::CoordinateSequence& pts;
 
-    /// Owned by this class, lazely created
-    mutable std::unique_ptr<geom::Envelope> env;
+    /// Owned by this class
+    geom::Envelope env;
 
     /// user-defined information
     void* context;
diff --git a/src/geomgraph/Edge.cpp b/src/geomgraph/Edge.cpp
index 6c25b80..cb013fd 100644
--- a/src/geomgraph/Edge.cpp
+++ b/src/geomgraph/Edge.cpp
@@ -85,7 +85,7 @@ Edge::Edge(CoordinateSequence* newPts, const Label& newLabel)
     :
     GraphComponent(newLabel),
     mce(nullptr),
-    env(nullptr),
+    env(newPts->getEnvelope()),
     depth(),
     depthDelta(0),
     isIsolatedVar(true),
@@ -100,7 +100,7 @@ Edge::Edge(CoordinateSequence* newPts)
     :
     GraphComponent(),
     mce(nullptr),
-    env(nullptr),
+    env(newPts->getEnvelope()),
     depth(),
     depthDelta(0),
     isIsolatedVar(true),
@@ -299,13 +299,7 @@ Edge::printReverse() const
 const Envelope*
 Edge::getEnvelope()
 {
-    // compute envelope lazily
-    if(env == nullptr) {
-        env = detail::make_unique<Envelope>();
-        pts->expandEnvelope(*env);
-    }
-    testInvariant();
-    return env.get();
+    return &env;
 }
 
 std::ostream&
diff --git a/src/index/chain/MonotoneChain.cpp b/src/index/chain/MonotoneChain.cpp
index 69360ea..82b0602 100644
--- a/src/index/chain/MonotoneChain.cpp
+++ b/src/index/chain/MonotoneChain.cpp
@@ -35,7 +35,7 @@ MonotoneChain::MonotoneChain(const geom::CoordinateSequence& newPts,
                              size_t nstart, size_t nend, void* nContext)
     :
     pts(newPts),
-    env(nullptr),
+    env(newPts[nstart], newPts[nend]),
     context(nContext),
     start(nstart),
     end(nend),
@@ -46,12 +46,7 @@ MonotoneChain::MonotoneChain(const geom::CoordinateSequence& newPts,
 const Envelope&
 MonotoneChain::getEnvelope() const
 {
-    if(nullptr == env) {
-        const Coordinate& p0 = pts[start];
-        const Coordinate& p1 = pts[end];
-        env = detail::make_unique<Envelope>(p0, p1);
-    }
-    return *env;
+    return env;
 }
 
 void

commit ba6340e26fc9e28d39121e035f207e66618b0abd
Author: Daniel Baston <dbaston at gmail.com>
Date:   Sun Sep 22 16:06:50 2019 -0400

    Optimize Edge Envelope calculation
    
    A CoordinateSequence can more efficiently calculate its own envelope,
    because it has optimal access to the underlying coordinates.

diff --git a/include/geos/geom/CoordinateSequence.h b/include/geos/geom/CoordinateSequence.h
index 9e135fd..0b4297e 100644
--- a/include/geos/geom/CoordinateSequence.h
+++ b/include/geos/geom/CoordinateSequence.h
@@ -103,6 +103,8 @@ public:
         return getAt(i);
     }
 
+    virtual Envelope getEnvelope() const;
+
     /** \brief
      * Write Coordinate at position i to given Coordinate.
      */
diff --git a/include/geos/geomgraph/Edge.h b/include/geos/geomgraph/Edge.h
index 87bfdde..bfb8a67 100644
--- a/include/geos/geomgraph/Edge.h
+++ b/include/geos/geomgraph/Edge.h
@@ -259,7 +259,7 @@ public:
         return equals(*e);
     }
 
-    virtual geom::Envelope* getEnvelope();
+    virtual const geom::Envelope* getEnvelope();
 };
 
 
diff --git a/src/geom/CoordinateSequence.cpp b/src/geom/CoordinateSequence.cpp
index 4af566a..2f6ed6e 100644
--- a/src/geom/CoordinateSequence.cpp
+++ b/src/geom/CoordinateSequence.cpp
@@ -204,6 +204,13 @@ CoordinateSequence::expandEnvelope(Envelope& env) const
     }
 }
 
+Envelope
+CoordinateSequence::getEnvelope() const {
+    Envelope e;
+    expandEnvelope(e);
+    return e;
+}
+
 std::ostream&
 operator<< (std::ostream& os, const CoordinateSequence& cs)
 {
diff --git a/src/geomgraph/Edge.cpp b/src/geomgraph/Edge.cpp
index 3b3a17e..6c25b80 100644
--- a/src/geomgraph/Edge.cpp
+++ b/src/geomgraph/Edge.cpp
@@ -296,16 +296,13 @@ Edge::printReverse() const
     return os.str();
 }
 
-Envelope*
+const Envelope*
 Edge::getEnvelope()
 {
     // compute envelope lazily
     if(env == nullptr) {
         env = detail::make_unique<Envelope>();
-        auto npts = getNumPoints();
-        for(size_t i = 0; i < npts; ++i) {
-            env->expandToInclude(pts->getAt(i));
-        }
+        pts->expandEnvelope(*env);
     }
     testInvariant();
     return env.get();

commit f578e6c4ceca6d4fde50ad0566df279d0c57df5d
Author: Daniel Baston <dbaston at gmail.com>
Date:   Sun Sep 22 15:53:33 2019 -0400

    Inline many methods of Envelope

diff --git a/include/geos/geom/Envelope.h b/include/geos/geom/Envelope.h
index f63847c..7f7da87 100644
--- a/include/geos/geom/Envelope.h
+++ b/include/geos/geom/Envelope.h
@@ -66,7 +66,7 @@ public:
     /** \brief
      * Creates a null Envelope.
      */
-    Envelope(void);
+    Envelope();
 
     /** \brief
      * Creates an Envelope for a region defined by maximum and minimum values.
diff --git a/include/geos/geom/Envelope.inl b/include/geos/geom/Envelope.inl
index fa66133..30599f0 100644
--- a/include/geos/geom/Envelope.inl
+++ b/include/geos/geom/Envelope.inl
@@ -27,6 +27,90 @@ namespace geos {
 namespace geom { // geos::geom
 
 /*public*/
+INLINE
+Envelope::Envelope()
+{
+    init();
+}
+
+/*public*/
+INLINE
+Envelope::Envelope(double x1, double x2, double y1, double y2)
+{
+    init(x1, x2, y1, y2);
+}
+/*public*/
+INLINE
+Envelope::Envelope(const Coordinate& p1, const Coordinate& p2)
+{
+    init(p1, p2);
+}
+
+/*public*/
+INLINE
+Envelope::Envelope(const Coordinate& p)
+{
+    init(p);
+}
+
+/*public*/
+INLINE
+Envelope::Envelope(const Envelope& env)
+        :
+        minx(env.minx),
+        maxx(env.maxx),
+        miny(env.miny),
+        maxy(env.maxy)
+{
+#if GEOS_DEBUG
+    std::cerr << "Envelope copy" << std::endl;
+#endif
+    //init(env.minx, env.maxx, env.miny, env.maxy);
+}
+
+/*public*/
+INLINE double
+Envelope::distance(double x0, double y0, double x1, double y1)
+{
+    double dx = x1 - x0;
+    double dy = y1 - y0;
+    return std::sqrt(dx * dx + dy * dy);
+}
+
+/*public*/
+INLINE void
+Envelope::expandToInclude(const Coordinate& p)
+{
+    expandToInclude(p.x, p.y);
+}
+
+/*public*/
+INLINE void
+Envelope::expandToInclude(double x, double y)
+{
+    if(isNull()) {
+        minx = x;
+        maxx = x;
+        miny = y;
+        maxy = y;
+    }
+    else {
+        if(x < minx) {
+            minx = x;
+        }
+        if(x > maxx) {
+            maxx = x;
+        }
+        if(y < miny) {
+            miny = y;
+        }
+        if(y > maxy) {
+            maxy = y;
+        }
+    }
+}
+
+/*public*/
 INLINE double
 Envelope::getMaxY() const
 {
@@ -55,6 +139,69 @@ Envelope::getMinX() const
 }
 
 /*public*/
+INLINE double
+Envelope::getWidth() const
+{
+    if(isNull()) {
+        return 0;
+    }
+    return maxx - minx;
+}
+
+/*public*/
+INLINE double
+Envelope::getHeight() const
+{
+    if(isNull()) {
+        return 0;
+    }
+    return maxy - miny;
+}
+
+/*public*/
+INLINE void
+Envelope::init()
+{
+    setToNull();
+}
+
+/*public*/
+INLINE void
+Envelope::init(double x1, double x2, double y1, double y2)
+{
+    if(x1 < x2) {
+        minx = x1;
+        maxx = x2;
+    }
+    else {
+        minx = x2;
+        maxx = x1;
+    }
+    if(y1 < y2) {
+        miny = y1;
+        maxy = y2;
+    }
+    else {
+        miny = y2;
+        maxy = y1;
+    }
+}
+
+/*public*/
+INLINE void
+Envelope::init(const Coordinate& p1, const Coordinate& p2)
+{
+    init(p1.x, p2.x, p1.y, p2.y);
+}
+
+/*public*/
+INLINE void
+Envelope::init(const Coordinate& p)
+{
+    init(p.x, p.x, p.y, p.y);
+}
+
+/*public*/
 INLINE bool
 Envelope::intersects(const Coordinate& other) const
 {
@@ -105,6 +252,16 @@ Envelope::covers(const Coordinate* p) const
     return covers(p->x, p->y);
 }
 
+/*public*/
+INLINE void
+Envelope::setToNull()
+{
+    minx = 0;
+    maxx = -1;
+    miny = 0;
+    maxy = -1;
+}
+
 } // namespace geos::geom
 } // namespace geos
 
diff --git a/src/geom/Envelope.cpp b/src/geom/Envelope.cpp
index e90fa78..2c8cc69 100644
--- a/src/geom/Envelope.cpp
+++ b/src/geom/Envelope.cpp
@@ -112,53 +112,6 @@ Envelope::intersects(const Coordinate& a, const Coordinate& b) const
 }
 
 /*public*/
-double
-Envelope::distance(double x0, double y0, double x1, double y1)
-{
-    double dx = x1 - x0;
-    double dy = y1 - y0;
-    return sqrt(dx * dx + dy * dy);
-}
-
-/*public*/
-Envelope::Envelope(void)
-{
-    init();
-}
-
-/*public*/
-Envelope::Envelope(double x1, double x2, double y1, double y2)
-{
-    init(x1, x2, y1, y2);
-}
-
-/*public*/
-Envelope::Envelope(const Coordinate& p1, const Coordinate& p2)
-{
-    init(p1, p2);
-}
-
-/*public*/
-Envelope::Envelope(const Coordinate& p)
-{
-    init(p);
-}
-
-/*public*/
-Envelope::Envelope(const Envelope& env)
-    :
-    minx(env.minx),
-    maxx(env.maxx),
-    miny(env.miny),
-    maxy(env.maxy)
-{
-#if GEOS_DEBUG
-    std::cerr << "Envelope copy" << std::endl;
-#endif
-    //init(env.minx, env.maxx, env.miny, env.maxy);
-}
-
-/*public*/
 Envelope::Envelope(const string& str)
 {
     // The string should be in the format:
@@ -178,49 +131,6 @@ Envelope::Envelope(const string& str)
          strtod(values[3].c_str(), nullptr));
 }
 
-/*public*/
-void
-Envelope::init()
-{
-    setToNull();
-}
-
-/*public*/
-void
-Envelope::init(double x1, double x2, double y1, double y2)
-{
-    if(x1 < x2) {
-        minx = x1;
-        maxx = x2;
-    }
-    else {
-        minx = x2;
-        maxx = x1;
-    }
-    if(y1 < y2) {
-        miny = y1;
-        maxy = y2;
-    }
-    else {
-        miny = y2;
-        maxy = y1;
-    }
-}
-
-/*public*/
-void
-Envelope::init(const Coordinate& p1, const Coordinate& p2)
-{
-    init(p1.x, p2.x, p1.y, p2.y);
-}
-
-/*public*/
-void
-Envelope::init(const Coordinate& p)
-{
-    init(p.x, p.x, p.y, p.y);
-}
-
 #if 0
 /**
  *  Initialize an <code>Envelope</code> from an existing Envelope.
@@ -236,69 +146,6 @@ Envelope::init(Envelope env)
 
 /*public*/
 void
-Envelope::setToNull()
-{
-    minx = 0;
-    maxx = -1;
-    miny = 0;
-    maxy = -1;
-}
-
-/*public*/
-double
-Envelope::getWidth() const
-{
-    if(isNull()) {
-        return 0;
-    }
-    return maxx - minx;
-}
-
-/*public*/
-double
-Envelope::getHeight() const
-{
-    if(isNull()) {
-        return 0;
-    }
-    return maxy - miny;
-}
-
-/*public*/
-void
-Envelope::expandToInclude(const Coordinate& p)
-{
-    expandToInclude(p.x, p.y);
-}
-
-/*public*/
-void
-Envelope::expandToInclude(double x, double y)
-{
-    if(isNull()) {
-        minx = x;
-        maxx = x;
-        miny = y;
-        maxy = y;
-    }
-    else {
-        if(x < minx) {
-            minx = x;
-        }
-        if(x > maxx) {
-            maxx = x;
-        }
-        if(y < miny) {
-            miny = y;
-        }
-        if(y > maxy) {
-            maxy = y;
-        }
-    }
-}
-
-/*public*/
-void
 Envelope::expandToInclude(const Envelope* other)
 {
     if(other->isNull()) {
@@ -355,9 +202,6 @@ Envelope::covers(const Envelope& other) const
         other.getMaxY() <= maxy;
 }
 
-
-
-
 /*public*/
 bool
 Envelope::equals(const Envelope* other) const

commit e1fd59f2c826e8b5ca3490416ed7461003bd2529
Author: Daniel Baston <dbaston at gmail.com>
Date:   Sun Sep 22 15:33:52 2019 -0400

    Reduce CoordinateSequence::getAt calls in MonotoneChainBuilder

diff --git a/src/index/chain/MonotoneChainBuilder.cpp b/src/index/chain/MonotoneChainBuilder.cpp
index db5cc20..be5836a 100644
--- a/src/index/chain/MonotoneChainBuilder.cpp
+++ b/src/index/chain/MonotoneChainBuilder.cpp
@@ -97,17 +97,22 @@ MonotoneChainBuilder::findChainEnd(const CoordinateSequence& pts, std::size_t st
     int chainQuad = Quadrant::quadrant(pts[safeStart],
                                        pts[safeStart + 1]);
     std::size_t last = start + 1;
+
+    const Coordinate* prev = &pts[last-1]; // avoid repeated coordinate access by index (virtual call)
+    const Coordinate* curr = &pts[last];
+
     while(last < npts) {
         // skip zero-length segments, but include them in the chain
-        if(! pts[last - 1].equals2D(pts[last])) {
+        if(!prev->equals2D(*curr)) {
             // compute quadrant for next possible segment in chain
-            int quad = Quadrant::quadrant(pts[last - 1],
-                                          pts[last]);
+            int quad = Quadrant::quadrant(*prev, *curr);
             if(quad != chainQuad) {
                 break;
             }
         }
         ++last;
+        prev = curr;
+        curr = &pts[last];
     }
 #if GEOS_DEBUG
     std::cerr << "MonotoneChainBuilder::findChainEnd() returning" << std::endl;

commit dc76a5989a492dfce2ff76ab78c7760fe8a0b7e0
Author: Daniel Baston <dbaston at gmail.com>
Date:   Sun Sep 22 15:18:30 2019 -0400

    Remove unused Edge::name

diff --git a/include/geos/geomgraph/Edge.h b/include/geos/geomgraph/Edge.h
index 3a6a0ff..87bfdde 100644
--- a/include/geos/geomgraph/Edge.h
+++ b/include/geos/geomgraph/Edge.h
@@ -68,8 +68,6 @@ class GEOS_DLL Edge: public GraphComponent {
 
 private:
 
-    std::string name;
-
     /// Lazily-created, owned by Edge.
     std::unique_ptr<index::MonotoneChainEdge> mce;
 
@@ -114,12 +112,6 @@ public:
         return pts->getSize();
     }
 
-    virtual void
-    setName(const std::string& newName)
-    {
-        name = newName;
-    }
-
     virtual const geom::CoordinateSequence*
     getCoordinates() const
     {
diff --git a/src/geomgraph/Edge.cpp b/src/geomgraph/Edge.cpp
index 1aa22e2..3b3a17e 100644
--- a/src/geomgraph/Edge.cpp
+++ b/src/geomgraph/Edge.cpp
@@ -279,9 +279,6 @@ Edge::printReverse() const
     stringstream os;
 
     os << "EDGE (rev)";
-    if(name != "") {
-        os << " name:" << name;
-    }
 
     os << " label:" << label
        << " depthDelta:" << depthDelta
@@ -318,9 +315,6 @@ std::ostream&
 operator<< (std::ostream& os, const Edge& e)
 {
     os << "edge";
-    if(e.name != "") {
-        os << " " << e.name;
-    }
 
     os
             << "  LINESTRING"

commit 3d280950490a7d7d64b90e1b3b9dbc09fe3e36fc
Author: Daniel Baston <dbaston at gmail.com>
Date:   Sun Sep 22 14:57:13 2019 -0400

    Reduce heap allocations in SimpleMCSweepLineIntersector
    
    Improves performance of intersection benchmark by ~7%.

diff --git a/include/geos/geomgraph/index/SimpleMCSweepLineIntersector.h b/include/geos/geomgraph/index/SimpleMCSweepLineIntersector.h
index 62baf16..cfdaf2f 100644
--- a/include/geos/geomgraph/index/SimpleMCSweepLineIntersector.h
+++ b/include/geos/geomgraph/index/SimpleMCSweepLineIntersector.h
@@ -22,6 +22,7 @@
 
 #include <geos/geomgraph/index/EdgeSetIntersector.h> // for inheritance
 #include <geos/geomgraph/index/SegmentIntersector.h>
+#include <geos/geomgraph/index/SweepLineEvent.h>
 #include <geos/geomgraph/index/MonotoneChain.h>
 
 #ifdef _MSC_VER
@@ -33,10 +34,6 @@
 namespace geos {
 namespace geomgraph {
 class Edge;
-namespace index {
-// class SegmentIntersector;
-class SweepLineEvent;
-}
 }
 }
 
@@ -57,7 +54,7 @@ class GEOS_DLL SimpleMCSweepLineIntersector: public EdgeSetIntersector {
 
 public:
 
-    SimpleMCSweepLineIntersector();
+    SimpleMCSweepLineIntersector() = default;
 
     ~SimpleMCSweepLineIntersector() override = default;
 
@@ -70,8 +67,15 @@ public:
 
 protected:
 
-    std::vector<std::unique_ptr<SweepLineEvent>> events;
-    std::vector<std::unique_ptr<MonotoneChain>> chains;
+    // SweepLineEvents need to refer to each other, and to MonotoneChains.
+    // To avoid individually heap-allocating all of these, we store them
+    // in deques so that subsequent inserts preserve addresses. However,
+    // we also need to sort the SweepLineEvents after they have all been
+    // inserted, so we keep a pointer to each event in a separate vector,
+    // which can be freely reordered without breaking linkages.
+    std::vector<SweepLineEvent*> events;
+    std::deque<SweepLineEvent> eventStore;
+    std::deque<MonotoneChain> chains;
 
     // statistics information
     int nOverlaps;
diff --git a/src/geomgraph/index/SimpleMCSweepLineIntersector.cpp b/src/geomgraph/index/SimpleMCSweepLineIntersector.cpp
index 4edd712..b635ad7 100644
--- a/src/geomgraph/index/SimpleMCSweepLineIntersector.cpp
+++ b/src/geomgraph/index/SimpleMCSweepLineIntersector.cpp
@@ -23,18 +23,12 @@
 #include <geos/geomgraph/Edge.h>
 #include <geos/util/Interrupt.h>
 
-using namespace std;
-
 namespace geos {
 namespace geomgraph { // geos.geomgraph
 namespace index { // geos.geomgraph.index
 
-SimpleMCSweepLineIntersector::SimpleMCSweepLineIntersector()
-{
-}
-
 void
-SimpleMCSweepLineIntersector::computeIntersections(vector<Edge*>* edges,
+SimpleMCSweepLineIntersector::computeIntersections(std::vector<Edge*>* edges,
         SegmentIntersector* si, bool testAllSegments)
 {
     if(testAllSegments) {
@@ -47,8 +41,8 @@ SimpleMCSweepLineIntersector::computeIntersections(vector<Edge*>* edges,
 }
 
 void
-SimpleMCSweepLineIntersector::computeIntersections(vector<Edge*>* edges0,
-        vector<Edge*>* edges1, SegmentIntersector* si)
+SimpleMCSweepLineIntersector::computeIntersections(std::vector<Edge*>* edges0,
+        std::vector<Edge*>* edges1, SegmentIntersector* si)
 {
     add(edges0, edges0);
     add(edges1, edges1);
@@ -56,7 +50,7 @@ SimpleMCSweepLineIntersector::computeIntersections(vector<Edge*>* edges0,
 }
 
 void
-SimpleMCSweepLineIntersector::add(vector<Edge*>* edges)
+SimpleMCSweepLineIntersector::add(std::vector<Edge*>* edges)
 {
     for(size_t i = 0; i < edges->size(); ++i) {
         Edge* edge = (*edges)[i];
@@ -66,7 +60,7 @@ SimpleMCSweepLineIntersector::add(vector<Edge*>* edges)
 }
 
 void
-SimpleMCSweepLineIntersector::add(vector<Edge*>* edges, void* edgeSet)
+SimpleMCSweepLineIntersector::add(std::vector<Edge*>* edges, void* edgeSet)
 {
     for(size_t i = 0; i < edges->size(); ++i) {
         Edge* edge = (*edges)[i];
@@ -83,11 +77,13 @@ SimpleMCSweepLineIntersector::add(Edge* edge, void* edgeSet)
 
     for(size_t i = 0; i < n; ++i) {
         GEOS_CHECK_FOR_INTERRUPTS();
-        MonotoneChain* mc = new MonotoneChain(mce, i);
-        chains.emplace_back(mc);
-        SweepLineEvent* insertEvent = new SweepLineEvent(edgeSet, mce->getMinX(i), nullptr, mc);
-        events.emplace_back(insertEvent);
-        events.emplace_back(new SweepLineEvent(edgeSet, mce->getMaxX(i), insertEvent, mc));
+        chains.emplace_back(mce, i);
+        MonotoneChain* mc = &chains.back();
+
+        eventStore.emplace_back(edgeSet, mce->getMinX(i), nullptr, mc);
+        SweepLineEvent* insertEvent = &eventStore.back();
+
+        eventStore.emplace_back(edgeSet, mce->getMaxX(i), insertEvent, mc);
     }
 }
 
@@ -99,6 +95,12 @@ SimpleMCSweepLineIntersector::add(Edge* edge, void* edgeSet)
 void
 SimpleMCSweepLineIntersector::prepareEvents()
 {
+    events.clear();
+    events.reserve(eventStore.size());
+    for (auto& e : eventStore) {
+        events.push_back(&e);
+    }
+
     sort(events.begin(), events.end(), SweepLineEventLessThen());
     for(size_t i = 0; i < events.size(); ++i) {
         GEOS_CHECK_FOR_INTERRUPTS();
@@ -118,7 +120,7 @@ SimpleMCSweepLineIntersector::computeIntersections(SegmentIntersector* si)
         GEOS_CHECK_FOR_INTERRUPTS();
         auto& ev = events[i];
         if(ev->isInsert()) {
-            processOverlaps(i, ev->getDeleteEventIndex(), ev.get(), si);
+            processOverlaps(i, ev->getDeleteEventIndex(), ev, si);
         }
         if(si->getIsDone()) {
             break;

commit 660038c330599635cf224b199248c690ac92dd1f
Author: Daniel Baston <dbaston at gmail.com>
Date:   Sun Sep 22 14:55:57 2019 -0400

    Reduce size of SweepLineEvent
    
    - declare class to be final and remove virtual destructor. This removes
    storage for the vtable.
    - avoid storing trivially computed event type

diff --git a/benchmarks/ClassSizes.cpp b/benchmarks/ClassSizes.cpp
index 8a78c67..33fb7e1 100644
--- a/benchmarks/ClassSizes.cpp
+++ b/benchmarks/ClassSizes.cpp
@@ -39,6 +39,7 @@
 #include <geos/profiler.h>
 #include <geos/constants.h>
 #include <iostream>
+#include <geos/geomgraph/index/SweepLineEvent.h>
 
 using namespace std;
 using namespace geos;
@@ -55,6 +56,7 @@ main()
     check(geomgraph::EdgeEnd);
     check(geomgraph::PlanarGraph);
     check(geomgraph::TopologyLocation);
+    check(geomgraph::index::SweepLineEvent);
     check(noding::NodedSegmentString);
     check(geom::Geometry);
     check(geom::Point);
diff --git a/include/geos/geomgraph/index/SweepLineEvent.h b/include/geos/geomgraph/index/SweepLineEvent.h
index 34abb30..7386d6e 100644
--- a/include/geos/geomgraph/index/SweepLineEvent.h
+++ b/include/geos/geomgraph/index/SweepLineEvent.h
@@ -35,7 +35,7 @@ namespace index { // geos::geomgraph::index
 
 //class SweepLineEventLessThen; // needed ??
 
-class GEOS_DLL SweepLineEvent {
+class GEOS_DLL SweepLineEvent final {
     friend class SweepLineEventLessThen;
 
 public:
@@ -49,7 +49,7 @@ public:
                    SweepLineEvent* newInsertEvent,
                    SweepLineEventOBJ* newObj);
 
-    virtual ~SweepLineEvent() = default;
+    ~SweepLineEvent() = default;
 
     bool
     isInsert()
@@ -63,6 +63,12 @@ public:
         return insertEvent != nullptr;
     }
 
+    int
+    eventType()
+    {
+        return insertEvent == nullptr ? INSERT_EVENT : DELETE_EVENT;
+    }
+
     SweepLineEvent*
     getInsertEvent()
     {
@@ -101,8 +107,6 @@ private:
 
     double xValue;
 
-    int eventType;
-
     SweepLineEvent* insertEvent; // null if this is an INSERT_EVENT event
 
     size_t deleteEventIndex;
@@ -120,7 +124,7 @@ public:
         if(f->xValue > s->xValue) {
             return false;
         }
-        if(f->eventType < s->eventType) {
+        if(f->eventType() < s->eventType()) {
             return true;
         }
         return false;
diff --git a/src/geomgraph/index/SweepLineEvent.cpp b/src/geomgraph/index/SweepLineEvent.cpp
index 4a30ebc..d6e9889 100644
--- a/src/geomgraph/index/SweepLineEvent.cpp
+++ b/src/geomgraph/index/SweepLineEvent.cpp
@@ -18,8 +18,6 @@
 #include <geos/geomgraph/index/SweepLineEvent.h>
 #include <geos/geomgraph/index/SweepLineEventObj.h>
 
-using namespace std;
-
 namespace geos {
 namespace geomgraph { // geos.geomgraph
 namespace index { // geos.geomgraph.index
@@ -32,12 +30,6 @@ SweepLineEvent::SweepLineEvent(void* newEdgeSet, double x,
     insertEvent(newInsertEvent),
     deleteEventIndex(0)
 {
-    if(insertEvent != nullptr) {
-        eventType = DELETE_EVENT;
-    }
-    else {
-        eventType = INSERT_EVENT;
-    }
 }
 
 /**
@@ -56,24 +48,24 @@ SweepLineEvent::compareTo(SweepLineEvent* sle)
     if(xValue > sle->xValue) {
         return 1;
     }
-    if(eventType < sle->eventType) {
+    if(eventType() < sle->eventType()) {
         return -1;
     }
-    if(eventType > sle->eventType) {
+    if(eventType() > sle->eventType()) {
         return 1;
     }
     return 0;
 }
 
-string
+std::string
 SweepLineEvent::print()
 {
-    ostringstream s;
+    std::ostringstream s;
 
     s << "SweepLineEvent:";
     s << " xValue=" << xValue << " deleteEventIndex=" << deleteEventIndex;
-    s << ((eventType == INSERT_EVENT) ? " INSERT_EVENT" : " DELETE_EVENT");
-    s << endl << "\tinsertEvent=";
+    s << ((eventType() == INSERT_EVENT) ? " INSERT_EVENT" : " DELETE_EVENT");
+    s << std::endl << "\tinsertEvent=";
     if(insertEvent) {
         s << insertEvent->print();
     }

commit de653e0113298557ebb8d1e65949fce1614475f7
Author: Daniel Baston <dbaston at gmail.com>
Date:   Sun Sep 22 13:27:07 2019 -0400

    Avoid dynamic_cast in STRtree
    
    This increases performance of tree operations. The addition of a
    isLeaf() method to the Boundable interface isn't a great fit, but the
    Boundable interface is really more of a TreeNode interface anyway.

diff --git a/include/geos/index/strtree/AbstractNode.h b/include/geos/index/strtree/AbstractNode.h
index a93d44a..2f0228e 100644
--- a/include/geos/index/strtree/AbstractNode.h
+++ b/include/geos/index/strtree/AbstractNode.h
@@ -110,6 +110,10 @@ public:
         childBoundables.push_back(childBoundable);
     }
 
+    bool isLeaf() const override {
+        return false;
+    }
+
 protected:
 
     virtual void* computeBounds() const = 0;
diff --git a/include/geos/index/strtree/AbstractSTRtree.h b/include/geos/index/strtree/AbstractSTRtree.h
index d9dcf24..b2e10bc 100644
--- a/include/geos/index/strtree/AbstractSTRtree.h
+++ b/include/geos/index/strtree/AbstractSTRtree.h
@@ -42,7 +42,6 @@ namespace strtree { // geos::index::strtree
 
 /// A list of boundables. TODO: use a list
 typedef std::vector<Boundable*> BoundableList;
-//typedef std::list<Boundable*> BoundableList;
 
 /// list contains boundables or lists of boundables. The lists are owned by
 /// this class, the plain boundables are held by reference only.
@@ -223,16 +222,6 @@ protected:
     ///  Also builds the tree, if necessary.
     void query(const void* searchBounds, std::vector<void*>& foundItems);
 
-#if 0
-    ///  Also builds the tree, if necessary.
-    std::vector<void*>*
-    query(const void* searchBounds)
-    {
-        vector<void*>* matches = new vector<void*>();
-        query(searchBounds, *matches);
-        return matches;
-    }
-#endif
     ///  Also builds the tree, if necessary.
     void query(const void* searchBounds, ItemVisitor& visitor);
 
diff --git a/include/geos/index/strtree/Boundable.h b/include/geos/index/strtree/Boundable.h
index 2a0ee4a..e8c34fb 100644
--- a/include/geos/index/strtree/Boundable.h
+++ b/include/geos/index/strtree/Boundable.h
@@ -38,6 +38,8 @@ public:
      * @see AbstractSTRtree::IntersectsOp
      */
     virtual const void* getBounds() const = 0;
+
+    virtual bool isLeaf() const = 0;
     virtual
     ~Boundable() {}
 };
diff --git a/include/geos/index/strtree/ItemBoundable.h b/include/geos/index/strtree/ItemBoundable.h
index 1e1af25..263f19d 100644
--- a/include/geos/index/strtree/ItemBoundable.h
+++ b/include/geos/index/strtree/ItemBoundable.h
@@ -35,6 +35,10 @@ public:
     ItemBoundable(const void* newBounds, void* newItem) : bounds(newBounds), item(newItem) {}
     ~ItemBoundable() override = default;
 
+    bool isLeaf() const override {
+        return true;
+    }
+
     const void* getBounds() const override {
         return bounds;
     }
diff --git a/src/index/strtree/AbstractSTRtree.cpp b/src/index/strtree/AbstractSTRtree.cpp
index ffbf349..fd04cad 100644
--- a/src/index/strtree/AbstractSTRtree.cpp
+++ b/src/index/strtree/AbstractSTRtree.cpp
@@ -167,14 +167,10 @@ AbstractSTRtree::query(const void* searchBounds, const AbstractNode& node,
             continue;
         }
 
-        if(const AbstractNode* an = dynamic_cast<const AbstractNode*>(childBoundable)) {
-            query(searchBounds, *an, visitor);
-        }
-        else if(const ItemBoundable* ib = dynamic_cast<const ItemBoundable*>(childBoundable)) {
-            visitor.visitItem(ib->getItem());
-        }
-        else {
-            assert(0); // unsupported childBoundable type
+        if (childBoundable->isLeaf()) {
+            visitor.visitItem(static_cast<const ItemBoundable*>(childBoundable)->getItem());
+        } else {
+            query(searchBounds, *static_cast<const AbstractNode*>(childBoundable), visitor);
         }
     }
 }
@@ -207,14 +203,15 @@ AbstractSTRtree::remove(const void* searchBounds, AbstractNode& node, void* item
     BoundableList& boundables = *(node.getChildBoundables());
 
     // next try removing item from lower nodes
-    for(BoundableList::iterator i = boundables.begin(), e = boundables.end();
-            i != e; i++) {
+    for(auto i = boundables.begin(), e = boundables.end(); i != e; i++) {
         Boundable* childBoundable = *i;
         if(!getIntersectsOp()->intersects(childBoundable->getBounds(), searchBounds)) {
             continue;
         }
 
-        if(AbstractNode* an = dynamic_cast<AbstractNode*>(childBoundable)) {
+        if(!childBoundable->isLeaf()) {
+           AbstractNode* an = static_cast<AbstractNode*>(childBoundable);
+
             // if found, record child for pruning and exit
             if(remove(searchBounds, *an, item)) {
                 if(an->getChildBoundables()->empty()) {
@@ -236,16 +233,16 @@ AbstractSTRtree::removeItem(AbstractNode& node, void* item)
 
     BoundableList::iterator childToRemove = boundables.end();
 
-    for(BoundableList::iterator i = boundables.begin(),
-            e = boundables.end();
-            i != e; i++) {
+    for(auto i = boundables.begin(), e = boundables.end(); i != e; i++) {
         Boundable* childBoundable = *i;
-        if(ItemBoundable* ib = dynamic_cast<ItemBoundable*>(childBoundable)) {
+        if (childBoundable->isLeaf()) {
+            ItemBoundable* ib = static_cast<ItemBoundable*>(childBoundable);
             if(ib->getItem() == item) {
                 childToRemove = i;
             }
         }
     }
+
     if(childToRemove != boundables.end()) {
         boundables.erase(childToRemove);
         return true;
@@ -264,25 +261,17 @@ AbstractSTRtree::query(const void* searchBounds,
 
     const BoundableList& vb = *(node->getChildBoundables());
 
-
     IntersectsOp* io = getIntersectsOp();
-    //std::size_t vbsize=vb.size();
-    //cerr<<"AbstractSTRtree::query: childBoundables: "<<vbsize<<endl;
-    for(BoundableList::const_iterator i = vb.begin(), e = vb.end();
-            i != e; ++i) {
-        const Boundable* childBoundable = *i;
+
+    for(const Boundable* childBoundable : vb) {
         if(!io->intersects(childBoundable->getBounds(), searchBounds)) {
             continue;
         }
 
-        if(const AbstractNode* an = dynamic_cast<const AbstractNode*>(childBoundable)) {
-            query(searchBounds, an, matches);
-        }
-        else if(const ItemBoundable* ib = dynamic_cast<const ItemBoundable*>(childBoundable)) {
-            matches->push_back(ib->getItem());
-        }
-        else {
-            assert(0); // unsupported childBoundable type
+        if (childBoundable->isLeaf()) {
+            matches->push_back(static_cast<const ItemBoundable*>(childBoundable)->getItem());
+        } else {
+            query(searchBounds, static_cast<const AbstractNode*>(childBoundable), matches);
         }
     }
 }
@@ -290,12 +279,9 @@ AbstractSTRtree::query(const void* searchBounds,
 void
 AbstractSTRtree::iterate(ItemVisitor& visitor)
 {
-    for(BoundableList::const_iterator i = itemBoundables->begin(), e = itemBoundables->end();
-            i != e; i++) {
-        const Boundable* boundable = *i;
-        if(const ItemBoundable* ib = dynamic_cast<const ItemBoundable*>(boundable)) {
-            visitor.visitItem(ib->getItem());
-        }
+    for(const Boundable* boundable : *itemBoundables) {
+        const ItemBoundable* ib = static_cast<const ItemBoundable*>(boundable);
+        visitor.visitItem(ib->getItem());
     }
 }
 
@@ -323,18 +309,17 @@ AbstractSTRtree::boundablesAtLevel(int level, AbstractNode* top,
 
     const BoundableList& vb = *(top->getChildBoundables());
 
-    for(BoundableList::const_iterator i = vb.begin(), e = vb.end();
-            i != e; ++i) {
-        Boundable* boundable = *i;
-        if(typeid(*boundable) == typeid(AbstractNode)) {
-            boundablesAtLevel(level, (AbstractNode*)boundable,
-                              boundables);
-        }
-        else {
+    for(Boundable* boundable : vb) {
+        if(boundable->isLeaf()) {
             assert(typeid(*boundable) == typeid(ItemBoundable));
             if(level == -1) {
                 boundables->push_back(boundable);
             }
+        } else {
+            assert(typeid(*boundable) == typeid(AbstractNode));
+            boundablesAtLevel(level,
+                              static_cast<AbstractNode*>(boundable),
+                              boundables);
         }
     }
     return;
@@ -345,25 +330,18 @@ AbstractSTRtree::itemsTree(AbstractNode* node)
 {
     std::unique_ptr<ItemsList> valuesTreeForNode(new ItemsList());
 
-    BoundableList::iterator end = node->getChildBoundables()->end();
-    for(BoundableList::iterator i = node->getChildBoundables()->begin();
-            i != end; ++i) {
-        Boundable* childBoundable = *i;
-        if(dynamic_cast<AbstractNode*>(childBoundable)) {
+    for(Boundable* childBoundable : *node->getChildBoundables()) {
+        if (childBoundable->isLeaf()) {
+            valuesTreeForNode->push_back(
+                    static_cast<ItemBoundable*>(childBoundable)->getItem());
+        } else {
             ItemsList* valuesTreeForChild =
-                itemsTree(static_cast<AbstractNode*>(childBoundable));
+                    itemsTree(static_cast<AbstractNode*>(childBoundable));
             // only add if not null (which indicates an item somewhere in this tree
             if(valuesTreeForChild != nullptr) {
                 valuesTreeForNode->push_back_owned(valuesTreeForChild);
             }
         }
-        else if(dynamic_cast<ItemBoundable*>(childBoundable)) {
-            valuesTreeForNode->push_back(
-                static_cast<ItemBoundable*>(childBoundable)->getItem());
-        }
-        else {
-            assert(!static_cast<bool>("should never be reached"));
-        }
     }
     if(valuesTreeForNode->empty()) {
         return nullptr;

commit 4c28ade0dc9c413a3003507db61b5579d2b822c4
Author: Daniel Baston <dbaston at gmail.com>
Date:   Sat Sep 21 22:05:00 2019 -0400

    Avoid repeated call to CoordinateSequence::getSize()

diff --git a/src/geomgraph/index/MonotoneChainIndexer.cpp b/src/geomgraph/index/MonotoneChainIndexer.cpp
index b53d7df..8867176 100644
--- a/src/geomgraph/index/MonotoneChainIndexer.cpp
+++ b/src/geomgraph/index/MonotoneChainIndexer.cpp
@@ -55,7 +55,8 @@ MonotoneChainIndexer::findChainEnd(const CoordinateSequence* pts, size_t start)
     // determine quadrant for chain
     auto chainQuad = Quadrant::quadrant(pts->getAt(start), pts->getAt(start + 1));
     auto last = start + 1;
-    while(last < pts->size()) {
+    auto sz = pts->size(); // virtual call, doesn't inline
+    while(last < sz) {
         // compute quadrant for next possible segment in chain
         auto quad = Quadrant::quadrant(pts->getAt(last - 1), pts->getAt(last));
         if(quad != chainQuad) {

commit 692f90fa62da867e58b0d7bface9d99483aae670
Author: Daniel Baston <dbaston at gmail.com>
Date:   Sat Sep 21 21:54:54 2019 -0400

    Inline many methods of Quadrant

diff --git a/include/geos/geomgraph/Makefile.am b/include/geos/geomgraph/Makefile.am
index 50dcf8a..3d4c97a 100644
--- a/include/geos/geomgraph/Makefile.am
+++ b/include/geos/geomgraph/Makefile.am
@@ -31,5 +31,6 @@ geos_HEADERS = \
     PlanarGraph.h \
     Position.h \
     Quadrant.h \
+    Quadrant.inl \
     TopologyLocation.h \
     TopologyLocation.inl
diff --git a/include/geos/geomgraph/Quadrant.h b/include/geos/geomgraph/Quadrant.h
index 8ed8a9c..0bc9bf3 100644
--- a/include/geos/geomgraph/Quadrant.h
+++ b/include/geos/geomgraph/Quadrant.h
@@ -99,5 +99,9 @@ public:
 } // namespace geos.geomgraph
 } // namespace geos
 
+#ifdef GEOS_INLINE
+# include "geos/geomgraph/Quadrant.inl"
+#endif
+
 #endif // ifndef GEOS_GEOMGRAPH_QUADRANT_H
 
diff --git a/src/geomgraph/Quadrant.cpp b/include/geos/geomgraph/Quadrant.inl
similarity index 62%
copy from src/geomgraph/Quadrant.cpp
copy to include/geos/geomgraph/Quadrant.inl
index a668279..124e1f0 100644
--- a/src/geomgraph/Quadrant.cpp
+++ b/include/geos/geomgraph/Quadrant.inl
@@ -3,6 +3,7 @@
  * GEOS - Geometry Engine Open Source
  * http://geos.osgeo.org
  *
+ * Copyright (C) 2005-2006 Refractions Research Inc.
  * Copyright (C) 2001-2002 Vivid Solutions Inc.
  *
  * This is free software; you can redistribute and/or modify it under
@@ -16,27 +17,26 @@
  *
  **********************************************************************/
 
-#include <sstream>
+#ifndef GEOS_GEOMGRAPH_QUADRANT_INL
+#define GEOS_GEOMGRAPH_QUADRANT_INL
 
 #include <geos/geomgraph/Quadrant.h>
-#include <geos/util/IllegalArgumentException.h>
-
 #include <geos/geom/Coordinate.h>
+#include <geos/util/IllegalArgumentException.h>
 
-using namespace std;
-using namespace geos::geom;
+#include <sstream>
 
 namespace geos {
-namespace geomgraph { // geos.geomgraph
+namespace geomgraph {
 
 /* public static */
-int
+INLINE int
 Quadrant::quadrant(double dx, double dy)
 {
     if(dx == 0.0 && dy == 0.0) {
-        ostringstream s;
+        std::ostringstream s;
         s << "Cannot compute the quadrant for point ";
-        s << "(" << dx << "," << dy << ")" << endl;
+        s << "(" << dx << "," << dy << ")" << std::endl;
         throw util::IllegalArgumentException(s.str());
     }
     if(dx >= 0) {
@@ -58,8 +58,8 @@ Quadrant::quadrant(double dx, double dy)
 }
 
 /* public static */
-int
-Quadrant::quadrant(const Coordinate& p0, const Coordinate& p1)
+INLINE int
+Quadrant::quadrant(const geom::Coordinate& p0, const geom::Coordinate& p1)
 {
     if(p1.x == p0.x && p1.y == p0.y) {
         throw util::IllegalArgumentException("Cannot compute the quadrant for two identical points " + p0.toString());
@@ -84,7 +84,7 @@ Quadrant::quadrant(const Coordinate& p0, const Coordinate& p1)
 }
 
 /* public static */
-bool
+INLINE bool
 Quadrant::isOpposite(int quad1, int quad2)
 {
     if(quad1 == quad2) {
@@ -99,48 +99,14 @@ Quadrant::isOpposite(int quad1, int quad2)
 }
 
 /* public static */
-int
-Quadrant::commonHalfPlane(int quad1, int quad2)
+INLINE bool
+Quadrant::isNorthern(int quad)
 {
-    // if quadrants are the same they do not determine a unique
-    // common halfplane.
-    // Simply return one of the two possibilities
-    if(quad1 == quad2) {
-        return quad1;
-    }
-    int diff = (quad1 - quad2 + 4) % 4;
-    // if quadrants are not adjacent, they do not share a common halfplane
-    if(diff == 2) {
-        return -1;
-    }
-    //
-    int min = (quad1 < quad2) ? quad1 : quad2;
-    int max = (quad1 > quad2) ? quad1 : quad2;
-    // for this one case, the righthand plane is NOT the minimum index;
-    if(min == 0 && max == 3) {
-        return 3;
-    }
-    // in general, the halfplane index is the minimum of the two
-    // adjacent quadrants
-    return min;
+    return quad == NE || quad == NW;
 }
 
-/* public static */
-bool
-Quadrant::isInHalfPlane(int quad, int halfPlane)
-{
-    if(halfPlane == SE) {
-        return quad == SE || quad == SW;
-    }
-    return quad == halfPlane || quad == halfPlane + 1;
 }
-
-/* public static */
-bool
-Quadrant::isNorthern(int quad)
-{
-    return quad == NE || quad == NW;
 }
 
-} // namespace geos.geomgraph
-} // namespace geos
+#endif
+
diff --git a/src/geomgraph/Quadrant.cpp b/src/geomgraph/Quadrant.cpp
index a668279..e45bfd0 100644
--- a/src/geomgraph/Quadrant.cpp
+++ b/src/geomgraph/Quadrant.cpp
@@ -16,14 +16,8 @@
  *
  **********************************************************************/
 
-#include <sstream>
-
 #include <geos/geomgraph/Quadrant.h>
-#include <geos/util/IllegalArgumentException.h>
-
-#include <geos/geom/Coordinate.h>
 
-using namespace std;
 using namespace geos::geom;
 
 namespace geos {
@@ -31,75 +25,6 @@ namespace geomgraph { // geos.geomgraph
 
 /* public static */
 int
-Quadrant::quadrant(double dx, double dy)
-{
-    if(dx == 0.0 && dy == 0.0) {
-        ostringstream s;
-        s << "Cannot compute the quadrant for point ";
-        s << "(" << dx << "," << dy << ")" << endl;
-        throw util::IllegalArgumentException(s.str());
-    }
-    if(dx >= 0) {
-        if(dy >= 0) {
-            return NE;
-        }
-        else {
-            return SE;
-        }
-    }
-    else {
-        if(dy >= 0) {
-            return NW;
-        }
-        else {
-            return SW;
-        }
-    }
-}
-
-/* public static */
-int
-Quadrant::quadrant(const Coordinate& p0, const Coordinate& p1)
-{
-    if(p1.x == p0.x && p1.y == p0.y) {
-        throw util::IllegalArgumentException("Cannot compute the quadrant for two identical points " + p0.toString());
-    }
-
-    if(p1.x >= p0.x) {
-        if(p1.y >= p0.y) {
-            return NE;
-        }
-        else {
-            return SE;
-        }
-    }
-    else {
-        if(p1.y >= p0.y) {
-            return NW;
-        }
-        else {
-            return SW;
-        }
-    }
-}
-
-/* public static */
-bool
-Quadrant::isOpposite(int quad1, int quad2)
-{
-    if(quad1 == quad2) {
-        return false;
-    }
-    int diff = (quad1 - quad2 + 4) % 4;
-    // if quadrants are not adjacent, they are opposite
-    if(diff == 2) {
-        return true;
-    }
-    return false;
-}
-
-/* public static */
-int
 Quadrant::commonHalfPlane(int quad1, int quad2)
 {
     // if quadrants are the same they do not determine a unique
@@ -135,12 +60,6 @@ Quadrant::isInHalfPlane(int quad, int halfPlane)
     return quad == halfPlane || quad == halfPlane + 1;
 }
 
-/* public static */
-bool
-Quadrant::isNorthern(int quad)
-{
-    return quad == NE || quad == NW;
-}
 
 } // namespace geos.geomgraph
 } // namespace geos
diff --git a/src/inlines.cpp b/src/inlines.cpp
index 514f7f6..eb660f4 100644
--- a/src/inlines.cpp
+++ b/src/inlines.cpp
@@ -57,6 +57,7 @@
 #include <geos/geom/MultiPolygon.inl>
 #include <geos/geom/CoordinateArraySequenceFactory.inl>
 #include <geos/geomgraph/Label.inl>
+#include <geos/geomgraph/Quadrant.inl>
 #include <geos/geomgraph/TopologyLocation.inl>
 #include <geos/noding/snapround/HotPixel.inl>
 #include <geos/noding/MCIndexNoder.inl>

commit 86d19e41441df9c2ee9683dbca3140541a3456d6
Author: Daniel Baston <dbaston at gmail.com>
Date:   Sat Sep 21 21:41:32 2019 -0400

    Store OrientedCoordinateArrays in unordered_map
    
    This improves performance by reducing the number of
    OrientedCoordinateArray comparisons needed with std::set.

diff --git a/include/geos/geom/Coordinate.h b/include/geos/geom/Coordinate.h
index 7a41c94..eb8ca72 100644
--- a/include/geos/geom/Coordinate.h
+++ b/include/geos/geom/Coordinate.h
@@ -115,13 +115,9 @@ public:
 
     double distanceSquared(const Coordinate& p) const;
 
-    int hashCode() const;
-
-    /**
-     * Returns a hash code for a double value, using the algorithm from
-     * Joshua Bloch's book <i>Effective Java</i>
-     */
-    static int hashCode(double d);
+    struct HashCode {
+        size_t operator()(const Coordinate & c) const;
+    };
 
 };
 
diff --git a/include/geos/geom/Coordinate.inl b/include/geos/geom/Coordinate.inl
index 74df6fd..7accf73 100644
--- a/include/geos/geom/Coordinate.inl
+++ b/include/geos/geom/Coordinate.inl
@@ -105,24 +105,6 @@ Coordinate::distanceSquared(const Coordinate& p) const
     return dx * dx + dy * dy;
 }
 
-INLINE int
-Coordinate::hashCode() const
-{
-    //Algorithm from Effective Java by Joshua Bloch [Jon Aquino]
-    int result = 17;
-    result = 37 * result + hashCode(x);
-    result = 37 * result + hashCode(y);
-    return result;
-}
-
-/*static*/
-INLINE int
-Coordinate::hashCode(double d)
-{
-    int64 f = (int64)(d);
-    return (int)(f ^ (f >> 32));
-}
-
 INLINE bool
 CoordinateLessThen::operator()(const Coordinate* a, const Coordinate* b) const
 {
@@ -157,6 +139,14 @@ operator!=(const Coordinate& a, const Coordinate& b)
     return ! a.equals2D(b);
 }
 
+INLINE size_t
+Coordinate::HashCode::operator()(const geos::geom::Coordinate &c) const {
+    size_t h = std::hash<double>{}(c.x);
+    h ^= std::hash<double>{}(c.y) << 1;
+    h ^= std::hash<double>{}(c.z) << 1;
+    return h;
+}
+
 } // namespace geos::geom
 } // namespace geos
 
diff --git a/include/geos/geom/Envelope.h b/include/geos/geom/Envelope.h
index 7308a16..f63847c 100644
--- a/include/geos/geom/Envelope.h
+++ b/include/geos/geom/Envelope.h
@@ -453,7 +453,7 @@ public:
      */
     double distance(const Envelope* env) const;
 
-    int hashCode() const;
+    size_t hashCode() const;
 
 private:
 
diff --git a/include/geos/geomgraph/Edge.h b/include/geos/geomgraph/Edge.h
index b6d6be9..3a6a0ff 100644
--- a/include/geos/geomgraph/Edge.h
+++ b/include/geos/geomgraph/Edge.h
@@ -91,7 +91,6 @@ public:
         assert(pts->size() > 1);
     }
 
-
     friend std::ostream& operator<< (std::ostream& os, const Edge& el);
 
     static void updateIM(const Label& lbl, geom::IntersectionMatrix& im);
@@ -101,8 +100,6 @@ public:
 
     EdgeIntersectionList eiList;
 
-    //Edge();
-
     /// Takes ownership of CoordinateSequence
     Edge(geom::CoordinateSequence* newPts, const Label& newLabel);
 
diff --git a/include/geos/geomgraph/EdgeList.h b/include/geos/geomgraph/EdgeList.h
index 8b4ca0e..77ad48e 100644
--- a/include/geos/geomgraph/EdgeList.h
+++ b/include/geos/geomgraph/EdgeList.h
@@ -23,7 +23,7 @@
 
 #include <geos/export.h>
 #include <vector>
-#include <map>
+#include <unordered_map>
 #include <string>
 #include <iostream>
 
@@ -73,13 +73,10 @@ private:
 
     /**
      * An index of the edges, for fast lookup.
-     *
-     * OrientedCoordinateArray objects are owned by us.
-     * TODO: optimize by dropping the OrientedCoordinateArray
-     *       construction as a whole, and use CoordinateSequence
-     *       directly instead..
      */
-    typedef std::map<noding::OrientedCoordinateArray*, Edge*, OcaCmp> EdgeMap;
+    typedef std::unordered_map<noding::OrientedCoordinateArray,
+                               Edge*,
+                               noding::OrientedCoordinateArray::HashCode> EdgeMap;
     EdgeMap ocaMap;
 
 public:
@@ -91,7 +88,7 @@ public:
         ocaMap()
     {}
 
-    virtual ~EdgeList();
+    virtual ~EdgeList() = default;
 
     /**
      * Insert an edge unless it is already in the list
@@ -106,11 +103,11 @@ public:
         return edges;
     }
 
-    Edge* findEqualEdge(Edge* e);
+    Edge* findEqualEdge(const Edge* e) const;
 
     Edge* get(int i);
 
-    int findEdgeIndex(Edge* e);
+    int findEdgeIndex(const Edge* e) const;
 
     std::string print();
 
diff --git a/include/geos/noding/OrientedCoordinateArray.h b/include/geos/noding/OrientedCoordinateArray.h
index dead361..08caf76 100644
--- a/include/geos/noding/OrientedCoordinateArray.h
+++ b/include/geos/noding/OrientedCoordinateArray.h
@@ -21,10 +21,7 @@
 
 #include <geos/export.h>
 
-//#include <vector>
-//#include <iostream>
-
-//#include <geos/inline.h>
+#include <cstddef>
 
 // Forward declarations
 namespace geos {
@@ -72,6 +69,11 @@ public:
      */
     int compareTo(const OrientedCoordinateArray& o1) const;
 
+    bool operator==(const OrientedCoordinateArray& other) const;
+
+    struct HashCode {
+        size_t operator()(const OrientedCoordinateArray & oca) const;
+    };
 
 private:
 
diff --git a/src/geom/Envelope.cpp b/src/geom/Envelope.cpp
index 284556a..e90fa78 100644
--- a/src/geom/Envelope.cpp
+++ b/src/geom/Envelope.cpp
@@ -438,15 +438,17 @@ operator==(const Envelope& a, const Envelope& b)
 }
 
 /*public*/
-int
+size_t
 Envelope::hashCode() const
 {
+    auto hash = std::hash<double>{};
+
     //Algorithm from Effective Java by Joshua Bloch [Jon Aquino]
-    int result = 17;
-    result = 37 * result + Coordinate::hashCode(minx);
-    result = 37 * result + Coordinate::hashCode(maxx);
-    result = 37 * result + Coordinate::hashCode(miny);
-    result = 37 * result + Coordinate::hashCode(maxy);
+    size_t result = 17;
+    result = 37 * result + hash(minx);
+    result = 37 * result + hash(maxx);
+    result = 37 * result + hash(miny);
+    result = 37 * result + hash(maxy);
     return result;
 }
 
diff --git a/src/geomgraph/EdgeList.cpp b/src/geomgraph/EdgeList.cpp
index 398438e..f865a86 100644
--- a/src/geomgraph/EdgeList.cpp
+++ b/src/geomgraph/EdgeList.cpp
@@ -29,7 +29,6 @@
 #define GEOS_DEBUG 0
 #endif
 
-using namespace std;
 using namespace geos::noding;
 
 namespace geos {
@@ -44,12 +43,12 @@ void
 EdgeList::add(Edge* e)
 {
     edges.push_back(e);
-    OrientedCoordinateArray* oca = new OrientedCoordinateArray(*(e->getCoordinates()));
+    OrientedCoordinateArray oca(*e->getCoordinates());
     ocaMap[oca] = e;
 }
 
 void
-EdgeList::addAll(const vector<Edge*>& edgeColl)
+EdgeList::addAll(const std::vector<Edge*>& edgeColl)
 {
     for(std::size_t i = 0, s = edgeColl.size(); i < s ; ++i) {
         add(edgeColl[i]);
@@ -63,7 +62,7 @@ EdgeList::addAll(const vector<Edge*>& edgeColl)
  *          null otherwise
  */
 Edge*
-EdgeList::findEqualEdge(Edge* e)
+EdgeList::findEqualEdge(const Edge* e) const
 {
 #if PROFILE
     static Profile* prof = profiler->get("EdgeList::findEqualEdge(Edge *e)");
@@ -72,7 +71,7 @@ EdgeList::findEqualEdge(Edge* e)
 
     OrientedCoordinateArray oca(*(e->getCoordinates()));
 
-    EdgeMap::iterator it = ocaMap.find(&oca);
+    auto it = ocaMap.find(oca);
 
 #if PROFILE
     prof->stop();
@@ -96,7 +95,7 @@ EdgeList::get(int i)
  *          -1 otherwise
  */
 int
-EdgeList::findEdgeIndex(Edge* e)
+EdgeList::findEdgeIndex(const Edge* e) const
 {
     for(int i = 0, s = (int)edges.size(); i < s; ++i) {
         if(edges[i]->equals(e)) {
@@ -106,10 +105,10 @@ EdgeList::findEdgeIndex(Edge* e)
     return -1;
 }
 
-string
+std::string
 EdgeList::print()
 {
-    ostringstream ss;
+    std::ostringstream ss;
     ss << *this;
     return ss.str();
 #if 0
@@ -147,12 +146,5 @@ operator<< (std::ostream& os, const EdgeList& el)
     return os;
 }
 
-EdgeList::~EdgeList()
-{
-    for(EdgeMap::iterator i = ocaMap.begin(), e = ocaMap.end(); i != e; ++i) {
-        delete i->first; // OrientedCoordinateArray
-    }
-}
-
 } // namespace geos.geomgraph
 } // namespace geos
diff --git a/src/noding/OrientedCoordinateArray.cpp b/src/noding/OrientedCoordinateArray.cpp
index b5be19a..0906286 100644
--- a/src/noding/OrientedCoordinateArray.cpp
+++ b/src/noding/OrientedCoordinateArray.cpp
@@ -21,12 +21,8 @@
 
 #include <geos/noding/OrientedCoordinateArray.h>
 
-//#include <geos/util/IllegalArgumentException.h>
-//#include <geos/noding/Octant.h>
-//#include <geos/geom/Coordinate.h>
 #include <geos/geom/CoordinateSequence.h>
 
-//using namespace std;
 using namespace geos::geom;
 
 #ifdef _MSC_VER
@@ -101,6 +97,53 @@ OrientedCoordinateArray::compareOriented(const geom::CoordinateSequence& pts1,
     }
 }
 
+bool
+OrientedCoordinateArray::operator==(const OrientedCoordinateArray& other) const {
+    auto sz1 = pts->size();
+    auto sz2 = other.pts->size();
+
+    if (sz1 != sz2) {
+        return false;
+    }
+
+    if (orientationVar == other.orientationVar) {
+        for (size_t i = 0; i < sz1; i++) {
+            if (pts->getAt(i) != other.pts->getAt(i)) {
+                return false;
+            }
+        }
+    } else {
+        for (size_t i = 0; i < sz1; i++) {
+            if (pts->getAt(i) != other.pts->getAt(sz2 - i - 1)) {
+                return false;
+            }
+        }
+    }
+
+    return true;
+}
+
+size_t
+OrientedCoordinateArray::HashCode::operator()(const geos::noding::OrientedCoordinateArray &oca) const {
+    Coordinate::HashCode coordHash;
+
+    auto sz = oca.pts->getSize();
+
+    size_t result = std::hash<size_t>{}(sz);
+
+    if (oca.orientationVar) {
+        for (size_t i = 0; i < sz; i++) {
+            result ^= coordHash(oca.pts->getAt(i));
+        }
+    } else {
+        for (size_t i = sz; i > 0; i--) {
+            result ^= coordHash(oca.pts->getAt(i-1));
+        }
+    }
+
+    return result;
+}
+
 } // namespace geos.noding
 } // namespace geos
 

commit 6b0bde06d048af58ec549747516505de6148caf5
Author: Daniel Baston <dbaston at gmail.com>
Date:   Sat Sep 21 14:27:57 2019 -0400

    Avoid heap alloc in EdgeIntersectionList::createSplitEdge

diff --git a/src/geomgraph/EdgeIntersectionList.cpp b/src/geomgraph/EdgeIntersectionList.cpp
index bd09ee8..d38eaa7 100644
--- a/src/geomgraph/EdgeIntersectionList.cpp
+++ b/src/geomgraph/EdgeIntersectionList.cpp
@@ -40,7 +40,6 @@
 #include <iostream>
 #endif
 
-using namespace std;
 using namespace geos::geom;
 
 namespace geos {
@@ -99,7 +98,7 @@ EdgeIntersectionList::addEndpoints()
 }
 
 void
-EdgeIntersectionList::addSplitEdges(vector<Edge*>* edgeList)
+EdgeIntersectionList::addSplitEdges(std::vector<Edge*>* edgeList)
 {
     // ensure that the list has entries for the first and last point
     // of the edge
@@ -146,29 +145,29 @@ EdgeIntersectionList::createSplitEdge(const EdgeIntersection* ei0,
     cerr << "    npts:" << npts << endl;
 #endif // GEOS_DEBUG
 
-    vector<Coordinate>* vc = new vector<Coordinate>();
-    vc->reserve(npts);
+    std::vector<Coordinate> vc;
+    vc.reserve(npts);
 
-    vc->push_back(ei0->coord);
+    vc.push_back(ei0->coord);
     for(auto i = ei0->segmentIndex + 1; i <= ei1->segmentIndex; ++i) {
         if(! useIntPt1 && ei1->segmentIndex == i) {
-            vc->push_back(ei1->coord);
+            vc.push_back(ei1->coord);
         }
         else {
-            vc->push_back(edge->pts->getAt(i));
+            vc.push_back(edge->pts->getAt(i));
         }
     }
 
     if(useIntPt1) {
-        vc->push_back(ei1->coord);
+        vc.push_back(ei1->coord);
     }
 
-    CoordinateSequence* pts = new CoordinateArraySequence(vc);
+    std::unique_ptr<CoordinateSequence> pts(new CoordinateArraySequence(std::move(vc)));
 
-    return new Edge(pts, edge->getLabel());
+    return new Edge(pts.release(), edge->getLabel());
 }
 
-string
+std::string
 EdgeIntersectionList::print() const
 {
     std::stringstream ss;
@@ -181,7 +180,7 @@ operator<< (std::ostream& os, const EdgeIntersectionList& e)
 {
     os << "Intersections:" << std::endl;
     for(const auto & ei : e) {
-        os << ei << endl;
+        os << ei << std::endl;
     }
     return os;
 }

commit 7102aa84d20a9694fba8f8ca0bd96072892bbde0
Author: Daniel Baston <dbaston at gmail.com>
Date:   Sat Sep 21 14:25:11 2019 -0400

    Back EdgeIntersectionList with std::vector
    
    This is substantially faster than std::set. We satisfy the uniqueness
    and sortedness conditions lazily, before iterating on the
    EdgeIntersections. This improves overall performance of the intersection
    benchmark by 10-15%.

diff --git a/include/geos/geomgraph/EdgeIntersection.h b/include/geos/geomgraph/EdgeIntersection.h
index 89163f3..050e8a8 100644
--- a/include/geos/geomgraph/EdgeIntersection.h
+++ b/include/geos/geomgraph/EdgeIntersection.h
@@ -92,6 +92,13 @@ public:
         return dist;
     }
 
+    bool operator==(const EdgeIntersection& other) const {
+        return segmentIndex == other.segmentIndex &&
+            dist == other.dist;
+
+        // We don't check the coordinate, consistent with operator<
+    }
+
 };
 
 /// Strict weak ordering operator for EdgeIntersection
diff --git a/include/geos/geomgraph/EdgeIntersectionList.h b/include/geos/geomgraph/EdgeIntersectionList.h
index 0966428..eed7641 100644
--- a/include/geos/geomgraph/EdgeIntersectionList.h
+++ b/include/geos/geomgraph/EdgeIntersectionList.h
@@ -23,8 +23,8 @@
 #define GEOS_GEOMGRAPH_EDGEINTERSECTIONLIST_H
 
 #include <geos/export.h>
+#include <algorithm>
 #include <vector>
-#include <set>
 #include <string>
 
 #include <geos/geomgraph/EdgeIntersection.h> // for EdgeIntersectionLessThen
@@ -58,17 +58,20 @@ namespace geomgraph { // geos.geomgraph
  */
 class GEOS_DLL EdgeIntersectionList {
 public:
-    typedef std::set<EdgeIntersection, EdgeIntersectionLessThen> container;
-    typedef container::iterator iterator;
-    typedef container::const_iterator const_iterator;
+    // Instead of storing edge intersections in a set, as JTS does, we store them
+    // in a vector and then sort the vector if needed before iterating among the
+    // edges. This is much faster.
+    using container = std::vector<EdgeIntersection>;
+    using const_iterator = container::const_iterator;
 
 private:
-    container nodeMap;
+    mutable container nodeMap;
+    mutable bool sorted;
 
 public:
 
-    Edge* edge;
-    EdgeIntersectionList(Edge* edge);
+    const Edge* edge;
+    EdgeIntersectionList(const Edge* edge);
     ~EdgeIntersectionList() = default;
 
     /*
@@ -76,22 +79,17 @@ public:
      * The input segmentIndex and dist are expected to be normalized.
      * @return the EdgeIntersection found or added
      */
-    const EdgeIntersection& add(const geom::Coordinate& coord,
-                          size_t segmentIndex, double dist);
+    void add(const geom::Coordinate& coord, size_t segmentIndex, double dist);
 
-    iterator
-    begin()
-    {
-        return nodeMap.begin();
-    }
-    iterator
-    end()
-    {
-        return nodeMap.end();
-    }
     const_iterator
     begin() const
     {
+        if (!sorted) {
+            std::sort(nodeMap.begin(), nodeMap.end());
+            nodeMap.erase(std::unique(nodeMap.begin(), nodeMap.end()), nodeMap.end());
+            sorted = true;
+        }
+
         return nodeMap.begin();
     }
     const_iterator
@@ -120,7 +118,6 @@ public:
 
     Edge* createSplitEdge(const EdgeIntersection* ei0, const EdgeIntersection* ei1);
     std::string print() const;
-
 };
 
 std::ostream& operator<< (std::ostream&, const EdgeIntersectionList&);
diff --git a/src/geomgraph/EdgeIntersectionList.cpp b/src/geomgraph/EdgeIntersectionList.cpp
index 7a3747c..bd09ee8 100644
--- a/src/geomgraph/EdgeIntersectionList.cpp
+++ b/src/geomgraph/EdgeIntersectionList.cpp
@@ -46,17 +46,31 @@ using namespace geos::geom;
 namespace geos {
 namespace geomgraph { // geos.geomgraph
 
-EdgeIntersectionList::EdgeIntersectionList(Edge* newEdge):
+EdgeIntersectionList::EdgeIntersectionList(const Edge* newEdge):
+    sorted(false),
     edge(newEdge)
 {
 }
 
-const EdgeIntersection&
+void
 EdgeIntersectionList::add(const Coordinate& coord,
                           size_t segmentIndex, double dist)
 {
-    pair<EdgeIntersectionList::iterator, bool> p = nodeMap.emplace(coord, segmentIndex, dist);
-    return *(p.first);
+    if (nodeMap.empty()) {
+        nodeMap.emplace_back(coord, segmentIndex, dist);
+        return;
+    }
+
+    if (nodeMap.back().segmentIndex == segmentIndex && nodeMap.back().dist == dist) {
+        return; // don't add duplicate
+    }
+
+    nodeMap.emplace_back(coord, segmentIndex, dist);
+    // Did our addition break the sortedness of the vector? If so, we'll have to
+    // sort before we iterate over the intersections again.
+    if (sorted && (!(nodeMap[nodeMap.size() - 2] < nodeMap[nodeMap.size() - 1]))) {
+        sorted = false;
+    }
 }
 
 bool
@@ -91,13 +105,13 @@ EdgeIntersectionList::addSplitEdges(vector<Edge*>* edgeList)
     // of the edge
     addEndpoints();
 
-    EdgeIntersectionList::iterator it = nodeMap.begin();
+    EdgeIntersectionList::const_iterator it = begin();
 
     // there should always be at least two entries in the list
     const EdgeIntersection* eiPrev = &*it;
     ++it;
 
-    while(it != nodeMap.end()) {
+    while(it != end()) {
         const EdgeIntersection* ei = &*it;
         Edge* newEdge = createSplitEdge(eiPrev, ei);
         edgeList->push_back(newEdge);
@@ -113,7 +127,7 @@ EdgeIntersectionList::createSplitEdge(const EdgeIntersection* ei0,
 #if GEOS_DEBUG
     cerr << "[" << this << "] EdgeIntersectionList::createSplitEdge()" << endl;
 #endif // GEOS_DEBUG
-    auto npts = ei1->segmentIndex - ei0->segmentIndex + 2;
+    auto npts = 2ul + ei1->segmentIndex - ei0->segmentIndex;
 
     const Coordinate& lastSegStartPt = edge->pts->getAt(ei1->segmentIndex);
 
diff --git a/src/operation/relate/EdgeEndBuilder.cpp b/src/operation/relate/EdgeEndBuilder.cpp
index 20207b0..af0c9bd 100644
--- a/src/operation/relate/EdgeEndBuilder.cpp
+++ b/src/operation/relate/EdgeEndBuilder.cpp
@@ -55,7 +55,7 @@ EdgeEndBuilder::computeEdgeEnds(Edge* edge, std::vector<EdgeEnd*>* l)
     // ensure that the list has entries for the first and last point of the edge
     eiList.addEndpoints();
 
-    EdgeIntersectionList::iterator it = eiList.begin();
+    EdgeIntersectionList::const_iterator it = eiList.begin();
     // no intersections, so there is nothing to do
     if(it == eiList.end()) {
         return;

commit b73adc0bce3da17018508994e6bfa65b54c0aad4
Author: Daniel Baston <dbaston at gmail.com>
Date:   Fri Sep 20 23:36:14 2019 -0400

    Reduce heap allocs in EdgeIntersectionList
    
    Possibly more performance could be obtained with an unordered_set, but
    at least some usages appear to require sorted iteration.

diff --git a/include/geos/geomgraph/EdgeIntersection.h b/include/geos/geomgraph/EdgeIntersection.h
index 61aa498..89163f3 100644
--- a/include/geos/geomgraph/EdgeIntersection.h
+++ b/include/geos/geomgraph/EdgeIntersection.h
@@ -123,6 +123,13 @@ struct GEOS_DLL  EdgeIntersectionLessThen {
     {
         return *ei1 < *ei2;
     }
+
+    bool
+    operator()(const EdgeIntersection& ei1,
+               const EdgeIntersection& ei2) const
+    {
+        return ei1 < ei2;
+    }
 };
 
 /// Output operator
diff --git a/include/geos/geomgraph/EdgeIntersectionList.h b/include/geos/geomgraph/EdgeIntersectionList.h
index 37a8c83..0966428 100644
--- a/include/geos/geomgraph/EdgeIntersectionList.h
+++ b/include/geos/geomgraph/EdgeIntersectionList.h
@@ -58,7 +58,7 @@ namespace geomgraph { // geos.geomgraph
  */
 class GEOS_DLL EdgeIntersectionList {
 public:
-    typedef std::set<EdgeIntersection*, EdgeIntersectionLessThen> container;
+    typedef std::set<EdgeIntersection, EdgeIntersectionLessThen> container;
     typedef container::iterator iterator;
     typedef container::const_iterator const_iterator;
 
@@ -69,14 +69,14 @@ public:
 
     Edge* edge;
     EdgeIntersectionList(Edge* edge);
-    ~EdgeIntersectionList();
+    ~EdgeIntersectionList() = default;
 
     /*
      * Adds an intersection into the list, if it isn't already there.
      * The input segmentIndex and dist are expected to be normalized.
      * @return the EdgeIntersection found or added
      */
-    EdgeIntersection* add(const geom::Coordinate& coord,
+    const EdgeIntersection& add(const geom::Coordinate& coord,
                           size_t segmentIndex, double dist);
 
     iterator
@@ -118,7 +118,7 @@ public:
      */
     void addSplitEdges(std::vector<Edge*>* edgeList);
 
-    Edge* createSplitEdge(EdgeIntersection* ei0, EdgeIntersection* ei1);
+    Edge* createSplitEdge(const EdgeIntersection* ei0, const EdgeIntersection* ei1);
     std::string print() const;
 
 };
diff --git a/include/geos/operation/relate/EdgeEndBuilder.h b/include/geos/operation/relate/EdgeEndBuilder.h
index c904a57..42538dc 100644
--- a/include/geos/operation/relate/EdgeEndBuilder.h
+++ b/include/geos/operation/relate/EdgeEndBuilder.h
@@ -56,13 +56,13 @@ protected:
 
     void createEdgeEndForPrev(geomgraph::Edge* edge,
                               std::vector<geomgraph::EdgeEnd*>* l,
-                              geomgraph::EdgeIntersection* eiCurr,
-                              geomgraph::EdgeIntersection* eiPrev);
+                              const geomgraph::EdgeIntersection* eiCurr,
+                              const geomgraph::EdgeIntersection* eiPrev);
 
     void createEdgeEndForNext(geomgraph::Edge* edge,
                               std::vector<geomgraph::EdgeEnd*>* l,
-                              geomgraph::EdgeIntersection* eiCurr,
-                              geomgraph::EdgeIntersection* eiNext);
+                              const geomgraph::EdgeIntersection* eiCurr,
+                              const geomgraph::EdgeIntersection* eiNext);
 };
 
 } // namespace geos:operation:relate
diff --git a/src/geomgraph/EdgeIntersectionList.cpp b/src/geomgraph/EdgeIntersectionList.cpp
index 9ee0776..7a3747c 100644
--- a/src/geomgraph/EdgeIntersectionList.cpp
+++ b/src/geomgraph/EdgeIntersectionList.cpp
@@ -51,29 +51,12 @@ EdgeIntersectionList::EdgeIntersectionList(Edge* newEdge):
 {
 }
 
-EdgeIntersectionList::~EdgeIntersectionList()
-{
-    for(EdgeIntersectionList::iterator it = nodeMap.begin(),
-            endIt = nodeMap.end();
-            it != endIt; ++it) {
-        delete *it;
-    }
-}
-
-EdgeIntersection*
+const EdgeIntersection&
 EdgeIntersectionList::add(const Coordinate& coord,
                           size_t segmentIndex, double dist)
 {
-    EdgeIntersection* eiNew = new EdgeIntersection(coord, segmentIndex, dist);
-
-    pair<EdgeIntersectionList::iterator, bool> p = nodeMap.insert(eiNew);
-    if(p.second) {    // new EdgeIntersection inserted
-        return eiNew;
-    }
-    else {
-        delete eiNew;
-        return *(p.first);
-    }
+    pair<EdgeIntersectionList::iterator, bool> p = nodeMap.emplace(coord, segmentIndex, dist);
+    return *(p.first);
 }
 
 bool
@@ -85,13 +68,8 @@ EdgeIntersectionList::isEmpty() const
 bool
 EdgeIntersectionList::isIntersection(const Coordinate& pt) const
 {
-    EdgeIntersectionList::const_iterator
-    it = nodeMap.begin(),
-    endIt = nodeMap.end();
-
-    for(; it != endIt; ++it) {
-        EdgeIntersection* ei = *it;
-        if(ei->coord == pt) {
+    for(const EdgeIntersection& ei : nodeMap) {
+        if(ei.coord == pt) {
             return true;
         }
     }
@@ -116,11 +94,11 @@ EdgeIntersectionList::addSplitEdges(vector<Edge*>* edgeList)
     EdgeIntersectionList::iterator it = nodeMap.begin();
 
     // there should always be at least two entries in the list
-    EdgeIntersection* eiPrev = *it;
+    const EdgeIntersection* eiPrev = &*it;
     ++it;
 
     while(it != nodeMap.end()) {
-        EdgeIntersection* ei = *it;
+        const EdgeIntersection* ei = &*it;
         Edge* newEdge = createSplitEdge(eiPrev, ei);
         edgeList->push_back(newEdge);
         eiPrev = ei;
@@ -129,8 +107,8 @@ EdgeIntersectionList::addSplitEdges(vector<Edge*>* edgeList)
 }
 
 Edge*
-EdgeIntersectionList::createSplitEdge(EdgeIntersection* ei0,
-                                      EdgeIntersection* ei1)
+EdgeIntersectionList::createSplitEdge(const EdgeIntersection* ei0,
+                                      const EdgeIntersection* ei1)
 {
 #if GEOS_DEBUG
     cerr << "[" << this << "] EdgeIntersectionList::createSplitEdge()" << endl;
@@ -188,10 +166,8 @@ std::ostream&
 operator<< (std::ostream& os, const EdgeIntersectionList& e)
 {
     os << "Intersections:" << std::endl;
-    EdgeIntersectionList::const_iterator it = e.begin(), endIt = e.end();
-    for(; it != endIt; ++it) {
-        EdgeIntersection* ei = *it;
-        os << *ei << endl;
+    for(const auto & ei : e) {
+        os << ei << endl;
     }
     return os;
 }
diff --git a/src/geomgraph/GeometryGraph.cpp b/src/geomgraph/GeometryGraph.cpp
index 9630379..7354953 100644
--- a/src/geomgraph/GeometryGraph.cpp
+++ b/src/geomgraph/GeometryGraph.cpp
@@ -483,11 +483,8 @@ GeometryGraph::addSelfIntersectionNodes(int p_argIndex)
         Edge* e = *i;
         Location eLoc = e->getLabel().getLocation(p_argIndex);
         EdgeIntersectionList& eiL = e->eiList;
-        for(EdgeIntersectionList::iterator
-                eiIt = eiL.begin(), eiEnd = eiL.end();
-                eiIt != eiEnd; ++eiIt) {
-            EdgeIntersection* ei = *eiIt;
-            addSelfIntersectionNode(p_argIndex, ei->coord, eLoc);
+        for(const EdgeIntersection& ei : eiL) {
+            addSelfIntersectionNode(p_argIndex, ei.coord, eLoc);
             GEOS_CHECK_FOR_INTERRUPTS();
         }
     }
diff --git a/src/geomgraph/index/SimpleMCSweepLineIntersector.cpp b/src/geomgraph/index/SimpleMCSweepLineIntersector.cpp
index fd57111..4edd712 100644
--- a/src/geomgraph/index/SimpleMCSweepLineIntersector.cpp
+++ b/src/geomgraph/index/SimpleMCSweepLineIntersector.cpp
@@ -80,8 +80,7 @@ SimpleMCSweepLineIntersector::add(Edge* edge, void* edgeSet)
     MonotoneChainEdge* mce = edge->getMonotoneChainEdge();
     auto& startIndex = mce->getStartIndexes();
     size_t n = startIndex.size() - 1;
-    events.reserve(events.size() + (n * 2));
-    chains.reserve(chains.size() + n);
+
     for(size_t i = 0; i < n; ++i) {
         GEOS_CHECK_FOR_INTERRUPTS();
         MonotoneChain* mc = new MonotoneChain(mce, i);
diff --git a/src/operation/IsSimpleOp.cpp b/src/operation/IsSimpleOp.cpp
index c808f8c..6526f97 100644
--- a/src/operation/IsSimpleOp.cpp
+++ b/src/operation/IsSimpleOp.cpp
@@ -207,12 +207,10 @@ IsSimpleOp::hasNonEndpointIntersection(GeometryGraph& graph)
         Edge* e = *i;
         auto maxSegmentIndex = e->getMaximumSegmentIndex();
         EdgeIntersectionList& eiL = e->getEdgeIntersectionList();
-        for(EdgeIntersectionList::iterator eiIt = eiL.begin(),
-                eiEnd = eiL.end(); eiIt != eiEnd; ++eiIt) {
-            EdgeIntersection* ei = *eiIt;
-            if(!ei->isEndPoint(maxSegmentIndex)) {
+        for(const EdgeIntersection& ei : eiL) {
+            if(!ei.isEndPoint(maxSegmentIndex)) {
                 nonSimpleLocation.reset(
-                    new Coordinate(ei->getCoordinate())
+                    new Coordinate(ei.getCoordinate())
                 );
                 return true;
             }
diff --git a/src/operation/relate/EdgeEndBuilder.cpp b/src/operation/relate/EdgeEndBuilder.cpp
index 28e8037..20207b0 100644
--- a/src/operation/relate/EdgeEndBuilder.cpp
+++ b/src/operation/relate/EdgeEndBuilder.cpp
@@ -61,17 +61,17 @@ EdgeEndBuilder::computeEdgeEnds(Edge* edge, std::vector<EdgeEnd*>* l)
         return;
     }
 
-    EdgeIntersection* eiPrev = nullptr;
-    EdgeIntersection* eiCurr = nullptr;
+    const EdgeIntersection* eiPrev = nullptr;
+    const EdgeIntersection* eiCurr = nullptr;
 
-    EdgeIntersection* eiNext = *it;
+    const EdgeIntersection* eiNext = &*it;
     it++;
     do {
         eiPrev = eiCurr;
         eiCurr = eiNext;
         eiNext = nullptr;
         if(it != eiList.end()) {
-            eiNext = *it;
+            eiNext = &*it;
             it++;
         }
         if(eiCurr != nullptr) {
@@ -92,7 +92,7 @@ EdgeEndBuilder::computeEdgeEnds(Edge* edge, std::vector<EdgeEnd*>* l)
  */
 void
 EdgeEndBuilder::createEdgeEndForPrev(Edge* edge, std::vector<EdgeEnd*>* l,
-                                     EdgeIntersection* eiCurr, EdgeIntersection* eiPrev)
+                                     const EdgeIntersection* eiCurr, const EdgeIntersection* eiPrev)
 {
     auto iPrev = eiCurr->segmentIndex;
     if(eiCurr->dist == 0.0) {
@@ -125,7 +125,7 @@ EdgeEndBuilder::createEdgeEndForPrev(Edge* edge, std::vector<EdgeEnd*>* l,
  */
 void
 EdgeEndBuilder::createEdgeEndForNext(Edge* edge, std::vector<EdgeEnd*>* l,
-                                     EdgeIntersection* eiCurr, EdgeIntersection* eiNext)
+                                     const EdgeIntersection* eiCurr, const EdgeIntersection* eiNext)
 {
     size_t iNext = eiCurr->segmentIndex + 1;
     // if there is no next edge there is nothing to do
diff --git a/src/operation/relate/RelateComputer.cpp b/src/operation/relate/RelateComputer.cpp
index 2b860a6..afae6f1 100644
--- a/src/operation/relate/RelateComputer.cpp
+++ b/src/operation/relate/RelateComputer.cpp
@@ -338,12 +338,9 @@ RelateComputer::computeIntersectionNodes(int argIndex)
         Edge* e = *i;
         Location eLoc = e->getLabel().getLocation(argIndex);
         EdgeIntersectionList& eiL = e->getEdgeIntersectionList();
-        EdgeIntersectionList::iterator it = eiL.begin();
-        EdgeIntersectionList::iterator end = eiL.end();
-        for(; it != end; ++it) {
-            EdgeIntersection* ei = *it;
-            assert(dynamic_cast<RelateNode*>(nodes.addNode(ei->coord)));
-            RelateNode* n = static_cast<RelateNode*>(nodes.addNode(ei->coord));
+        for(const EdgeIntersection & ei : eiL) {
+            assert(dynamic_cast<RelateNode*>(nodes.addNode(ei.coord)));
+            RelateNode* n = static_cast<RelateNode*>(nodes.addNode(ei.coord));
             if(eLoc == Location::BOUNDARY) {
                 n->setLabelBoundary(argIndex);
             }
@@ -371,12 +368,9 @@ RelateComputer::labelIntersectionNodes(int argIndex)
         Edge* e = *i;
         Location eLoc = e->getLabel().getLocation(argIndex);
         EdgeIntersectionList& eiL = e->getEdgeIntersectionList();
-        EdgeIntersectionList::iterator eiIt = eiL.begin();
-        EdgeIntersectionList::iterator eiEnd = eiL.end();
 
-        for(; eiIt != eiEnd; ++eiIt) {
-            EdgeIntersection* ei = *eiIt;
-            RelateNode* n = (RelateNode*) nodes.find(ei->coord);
+        for(const EdgeIntersection& ei : eiL) {
+            RelateNode* n = (RelateNode*) nodes.find(ei.coord);
             if(n->getLabel().isNull(argIndex)) {
                 if(eLoc == Location::BOUNDARY) {
                     n->setLabelBoundary(argIndex);
diff --git a/src/operation/relate/RelateNodeGraph.cpp b/src/operation/relate/RelateNodeGraph.cpp
index e4e8e0a..0477aaf 100644
--- a/src/operation/relate/RelateNodeGraph.cpp
+++ b/src/operation/relate/RelateNodeGraph.cpp
@@ -95,11 +95,8 @@ RelateNodeGraph::computeIntersectionNodes(GeometryGraph* geomGraph,
         Edge* e = *edgeIt;
         Location eLoc = e->getLabel().getLocation(argIndex);
         EdgeIntersectionList& eiL = e->getEdgeIntersectionList();
-        EdgeIntersectionList::iterator eiIt = eiL.begin();
-        EdgeIntersectionList::iterator eiEnd = eiL.end();
-        for(; eiIt != eiEnd; ++eiIt) {
-            EdgeIntersection* ei = *eiIt;
-            RelateNode* n = (RelateNode*) nodes->addNode(ei->coord);
+        for(const EdgeIntersection& ei : eiL) {
+            RelateNode* n = (RelateNode*) nodes->addNode(ei.coord);
             if(eLoc == Location::BOUNDARY) {
                 n->setLabelBoundary(argIndex);
             }
diff --git a/src/operation/valid/IsValidOp.cpp b/src/operation/valid/IsValidOp.cpp
index c6b705f..92b8504 100644
--- a/src/operation/valid/IsValidOp.cpp
+++ b/src/operation/valid/IsValidOp.cpp
@@ -405,22 +405,19 @@ IsValidOp::checkNoSelfIntersectingRing(EdgeIntersectionList& eiList)
 {
     set<const Coordinate*, CoordinateLessThen>nodeSet;
     bool isFirst = true;
-    EdgeIntersectionList::iterator it = eiList.begin();
-    EdgeIntersectionList::iterator end = eiList.end();
-    for(; it != end; ++it) {
-        EdgeIntersection* ei = *it;
+    for(const EdgeIntersection& ei : eiList) {
         if(isFirst) {
             isFirst = false;
             continue;
         }
-        if(nodeSet.find(&ei->coord) != nodeSet.end()) {
+        if(nodeSet.find(&ei.coord) != nodeSet.end()) {
             validErr = new TopologyValidationError(
                 TopologyValidationError::eRingSelfIntersection,
-                ei->coord);
+                ei.coord);
             return;
         }
         else {
-            nodeSet.insert(&ei->coord);
+            nodeSet.insert(&ei.coord);
         }
     }
 }

commit 4f68a684f037f5967fca105202bfc608eb9c9d9c
Author: Daniel Baston <dbaston at gmail.com>
Date:   Fri Sep 20 22:41:52 2019 -0400

    Inline AbstractNode and ItemBoundable

diff --git a/include/geos/index/strtree/AbstractNode.h b/include/geos/index/strtree/AbstractNode.h
index 4736b3f..a93d44a 100644
--- a/include/geos/index/strtree/AbstractNode.h
+++ b/include/geos/index/strtree/AbstractNode.h
@@ -15,6 +15,7 @@
 #ifndef GEOS_INDEX_STRTREE_ABSTRACTNODE_H
 #define GEOS_INDEX_STRTREE_ABSTRACTNODE_H
 
+#include <cassert>
 #include <cstddef>
 #include <geos/export.h>
 #include <geos/index/strtree/Boundable.h> // for inheritance
@@ -45,7 +46,16 @@ private:
     std::vector<Boundable*> childBoundables;
     int level;
 public:
-    AbstractNode(int newLevel, size_t capacity = 10);
+
+    /*
+     * Constructs an AbstractNode at the given level in the tree
+     * @param level 0 if this node is a leaf, 1 if a parent of a leaf, and so on;
+     * the root node will have the highest level
+     */
+    AbstractNode(int newLevel, size_t capacity = 10) : level(newLevel), bounds(nullptr) {
+        childBoundables.reserve(capacity);
+    }
+
     ~AbstractNode() override = default;
 
     // TODO: change signature to return by ref,
@@ -76,11 +86,29 @@ public:
      *
      * @see AbstractSTRtree::IntersectsOp
      */
-    const void* getBounds() const override;
+    const void* getBounds() const override {
+        if(bounds == nullptr) {
+            bounds = computeBounds();
+        }
+        return bounds;
+    }
 
-    int getLevel();
+    /**
+    * Returns 0 if this node is a leaf, 1 if a parent of a leaf, and so on; the
+    * root node will have the highest level
+    */
+    int getLevel() {
+        return level;
+    }
 
-    void addChildBoundable(Boundable* childBoundable);
+    /**
+     * Adds either an AbstractNode, or if this is a leaf node, a data object
+     * (wrapped in an ItemBoundable)
+     */
+    void addChildBoundable(Boundable* childBoundable) {
+        assert(bounds == nullptr);
+        childBoundables.push_back(childBoundable);
+    }
 
 protected:
 
diff --git a/include/geos/index/strtree/ItemBoundable.h b/include/geos/index/strtree/ItemBoundable.h
index bf7be99..1e1af25 100644
--- a/include/geos/index/strtree/ItemBoundable.h
+++ b/include/geos/index/strtree/ItemBoundable.h
@@ -32,11 +32,16 @@ namespace strtree { // geos::index::strtree
 class GEOS_DLL ItemBoundable: public Boundable {
 public:
 
-    ItemBoundable(const void* newBounds, void* newItem);
+    ItemBoundable(const void* newBounds, void* newItem) : bounds(newBounds), item(newItem) {}
     ~ItemBoundable() override = default;
 
-    const void* getBounds() const override;
-    void* getItem() const;
+    const void* getBounds() const override {
+        return bounds;
+    }
+
+    void* getItem() const {
+        return item;
+    }
 
 private:
 
diff --git a/src/index/strtree/AbstractNode.cpp b/src/index/strtree/AbstractNode.cpp
deleted file mode 100644
index fea79db..0000000
--- a/src/index/strtree/AbstractNode.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/**********************************************************************
- *
- * GEOS - Geometry Engine Open Source
- * http://geos.osgeo.org
- *
- * Copyright (C) 2006 Refractions Research Inc.
- * Copyright (C) 2001-2002 Vivid Solutions Inc.
- *
- * This is free software; you can redistribute and/or modify it under
- * the terms of the GNU Lesser General Public Licence as published
- * by the Free Software Foundation.
- * See the COPYING file for more information.
- *
- **********************************************************************/
-
-#include <geos/index/strtree/AbstractNode.h>
-
-#include <vector>
-#include <cstddef>
-#include <cassert>
-
-using namespace std;
-
-namespace geos {
-namespace index { // geos.index
-namespace strtree { // geos.index.strtree
-
-/*
- * Constructs an AbstractNode at the given level in the tree
- * @param level 0 if this node is a leaf, 1 if a parent of a leaf, and so on;
- * the root node will have the highest level
- */
-AbstractNode::AbstractNode(int newLevel, size_t capacity)
-{
-    childBoundables.reserve(capacity);
-    bounds = nullptr;
-    level = newLevel;
-}
-
-const void*
-AbstractNode::getBounds() const
-{
-    if(bounds == nullptr) {
-        bounds = computeBounds();
-    }
-    return bounds;
-}
-
-/**
-* Returns 0 if this node is a leaf, 1 if a parent of a leaf, and so on; the
-* root node will have the highest level
-*/
-int
-AbstractNode::getLevel()
-{
-    return level;
-}
-
-/**
- * Adds either an AbstractNode, or if this is a leaf node, a data object
- * (wrapped in an ItemBoundable)
- */
-void
-AbstractNode::addChildBoundable(Boundable* childBoundable)
-{
-    assert(bounds == nullptr);
-    childBoundables.push_back(childBoundable);
-}
-
-} // namespace geos.index.strtree
-} // namespace geos.index
-} // namespace geos
diff --git a/src/index/strtree/ItemBoundable.cpp b/src/index/strtree/ItemBoundable.cpp
deleted file mode 100644
index 4726625..0000000
--- a/src/index/strtree/ItemBoundable.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/**********************************************************************
- *
- * GEOS - Geometry Engine Open Source
- * http://geos.osgeo.org
- *
- * Copyright (C) 2006 Refractions Research Inc.
- * Copyright (C) 2001-2002 Vivid Solutions Inc.
- *
- * This is free software; you can redistribute and/or modify it under
- * the terms of the GNU Lesser General Public Licence as published
- * by the Free Software Foundation.
- * See the COPYING file for more information.
- *
- **********************************************************************/
-
-#include <geos/index/strtree/ItemBoundable.h>
-
-namespace geos {
-namespace index { // geos.index
-namespace strtree { // geos.index.strtree
-
-ItemBoundable::ItemBoundable(const void* newBounds, void* newItem) :
-    bounds(newBounds), item(newItem)
-{
-}
-
-const void*
-ItemBoundable::getBounds() const
-{
-    return bounds;
-}
-
-void*
-ItemBoundable::getItem() const
-{
-    return item;
-}
-
-} // namespace geos.index.strtree
-} // namespace geos.index
-} // namespace geos
-
diff --git a/src/index/strtree/Makefile.am b/src/index/strtree/Makefile.am
index d35d510..64227b5 100644
--- a/src/index/strtree/Makefile.am
+++ b/src/index/strtree/Makefile.am
@@ -6,13 +6,11 @@ noinst_LTLIBRARIES = libindexstrtree.la
 AM_CPPFLAGS = -I$(top_srcdir)/include
 
 libindexstrtree_la_SOURCES = \
-    AbstractNode.cpp \
     AbstractSTRtree.cpp \
     BoundablePair.cpp \
     EnvelopeUtil.cpp \
     GeometryItemDistance.cpp \
     Interval.cpp \
-    ItemBoundable.cpp \
     SIRtree.cpp \
     STRtree.cpp
 

commit 81a3952b0340788252a5e483eeb35c867df61d0c
Author: Daniel Baston <dbaston at gmail.com>
Date:   Fri Sep 20 22:41:37 2019 -0400

    Inline EdgeEnd::getCoordinate

diff --git a/include/geos/geomgraph/EdgeEnd.h b/include/geos/geomgraph/EdgeEnd.h
index af6e196..4c5f695 100644
--- a/include/geos/geomgraph/EdgeEnd.h
+++ b/include/geos/geomgraph/EdgeEnd.h
@@ -103,7 +103,9 @@ public:
         return label;
     }
 
-    virtual geom::Coordinate& getCoordinate();
+    virtual geom::Coordinate& getCoordinate() {
+        return p0;
+    }
 
     const geom::Coordinate&
     getCoordinate() const
diff --git a/src/geomgraph/EdgeEnd.cpp b/src/geomgraph/EdgeEnd.cpp
index 4ee7239..8332bf6 100644
--- a/src/geomgraph/EdgeEnd.cpp
+++ b/src/geomgraph/EdgeEnd.cpp
@@ -107,13 +107,6 @@ EdgeEnd::init(const Coordinate& newP0, const Coordinate& newP1)
 
 /*public*/
 Coordinate&
-EdgeEnd::getCoordinate()
-{
-    return p0;
-}
-
-/*public*/
-Coordinate&
 EdgeEnd::getDirectedCoordinate()
 {
     return p1;

commit f47a5fe78c839f797298528b5c96085f136b6276
Author: Daniel Baston <dbaston at gmail.com>
Date:   Fri Sep 20 22:21:19 2019 -0400

    Declare empty destructors as default in header
    
    Destructors declared in separate files cannot be inlined.

diff --git a/include/geos/algorithm/InteriorPointArea.h b/include/geos/algorithm/InteriorPointArea.h
index bc90f4c..1842f1b 100644
--- a/include/geos/algorithm/InteriorPointArea.h
+++ b/include/geos/algorithm/InteriorPointArea.h
@@ -88,8 +88,6 @@ public:
      */
     InteriorPointArea(const geom::Geometry* g);
 
-    ~InteriorPointArea();
-
     /**
      * Gets the computed interior point.
      *
diff --git a/include/geos/algorithm/InteriorPointLine.h b/include/geos/algorithm/InteriorPointLine.h
index ff43f64..e9d0e78 100644
--- a/include/geos/algorithm/InteriorPointLine.h
+++ b/include/geos/algorithm/InteriorPointLine.h
@@ -49,9 +49,6 @@ class GEOS_DLL InteriorPointLine {
 public:
 
     InteriorPointLine(const geom::Geometry* g);
-
-    ~InteriorPointLine();
-
     //Coordinate* getInteriorPoint() const;
 
     bool getInteriorPoint(geom::Coordinate& ret) const;
diff --git a/include/geos/algorithm/SimplePointInRing.h b/include/geos/algorithm/SimplePointInRing.h
index b5bd6a3..481b74a 100644
--- a/include/geos/algorithm/SimplePointInRing.h
+++ b/include/geos/algorithm/SimplePointInRing.h
@@ -34,7 +34,7 @@ namespace algorithm { // geos::algorithm
 class GEOS_DLL SimplePointInRing: public PointInRing {
 public:
     SimplePointInRing(geom::LinearRing* ring);
-    ~SimplePointInRing() override;
+    ~SimplePointInRing() override = default;
     bool isInside(const geom::Coordinate& pt) override;
 private:
     const geom::CoordinateSequence* pts;
diff --git a/include/geos/geom/CoordinateSequenceFactory.h b/include/geos/geom/CoordinateSequenceFactory.h
index daf2c30..7fb9e31 100644
--- a/include/geos/geom/CoordinateSequenceFactory.h
+++ b/include/geos/geom/CoordinateSequenceFactory.h
@@ -105,7 +105,7 @@ public:
      */
     virtual std::unique_ptr<CoordinateSequence> create(const CoordinateSequence& coordSeq) const = 0;
 
-    virtual ~CoordinateSequenceFactory();
+    virtual ~CoordinateSequenceFactory() = default;
 };
 
 } // namespace geos::geom
diff --git a/include/geos/geom/Envelope.h b/include/geos/geom/Envelope.h
index 8a09d05..7308a16 100644
--- a/include/geos/geom/Envelope.h
+++ b/include/geos/geom/Envelope.h
@@ -105,8 +105,6 @@ public:
      */
     Envelope(const std::string& str);
 
-    ~Envelope(void);
-
     /** \brief
      * Test the point `q` to see whether it intersects the Envelope
      * defined by `p1-p2`.
diff --git a/include/geos/geom/GeometryCollection.h b/include/geos/geom/GeometryCollection.h
index 516180f..fab1fba 100644
--- a/include/geos/geom/GeometryCollection.h
+++ b/include/geos/geom/GeometryCollection.h
@@ -77,7 +77,7 @@ public:
         return std::unique_ptr<Geometry>(new GeometryCollection(*this));
     }
 
-    ~GeometryCollection() override;
+    ~GeometryCollection() override = default;
 
     void setSRID(int) override;
 
diff --git a/include/geos/geom/LineString.h b/include/geos/geom/LineString.h
index 0316d62..6ed0348 100644
--- a/include/geos/geom/LineString.h
+++ b/include/geos/geom/LineString.h
@@ -74,7 +74,7 @@ public:
     /// A vector of const LineString pointers
     typedef std::vector<const LineString*> ConstVect;
 
-    ~LineString() override;
+    ~LineString() override = default;
 
     /**
      * \brief
diff --git a/include/geos/geom/LinearRing.h b/include/geos/geom/LinearRing.h
index 631e100..c474f3b 100644
--- a/include/geos/geom/LinearRing.h
+++ b/include/geos/geom/LinearRing.h
@@ -88,7 +88,7 @@ public:
         return std::unique_ptr<Geometry>(new LinearRing(*this));
     }
 
-    ~LinearRing() override;
+    ~LinearRing() override = default;
 
     /** \brief
      * Returns <code>Dimension.FALSE</code>, since by definition
diff --git a/include/geos/geom/MultiLineString.h b/include/geos/geom/MultiLineString.h
index 6faa43b..67c4238 100644
--- a/include/geos/geom/MultiLineString.h
+++ b/include/geos/geom/MultiLineString.h
@@ -54,7 +54,7 @@ public:
 
     friend class GeometryFactory;
 
-    ~MultiLineString() override;
+    ~MultiLineString() override = default;
 
     /// Returns line dimension (1)
     Dimension::DimensionType getDimension() const override;
diff --git a/include/geos/geom/MultiPoint.h b/include/geos/geom/MultiPoint.h
index 20ee0c7..2695907 100644
--- a/include/geos/geom/MultiPoint.h
+++ b/include/geos/geom/MultiPoint.h
@@ -56,7 +56,7 @@ public:
 
     friend class GeometryFactory;
 
-    ~MultiPoint() override;
+    ~MultiPoint() override = default;
 
     /// Returns point dimension (0)
     Dimension::DimensionType getDimension() const override;
diff --git a/include/geos/geom/Point.h b/include/geos/geom/Point.h
index e9fb358..a631e70 100644
--- a/include/geos/geom/Point.h
+++ b/include/geos/geom/Point.h
@@ -72,7 +72,7 @@ public:
     /// A vector of const Point pointers
     typedef std::vector<const Point*> ConstVect;
 
-    ~Point() override;
+    ~Point() override = default;
 
     /**
      * Creates and returns a full copy of this {@link Point} object.
diff --git a/include/geos/geom/Polygon.h b/include/geos/geom/Polygon.h
index d274c7b..abc1a99 100644
--- a/include/geos/geom/Polygon.h
+++ b/include/geos/geom/Polygon.h
@@ -70,7 +70,7 @@ public:
     /// A vector of const Polygon pointers
     typedef std::vector<const Polygon*> ConstVect;
 
-    ~Polygon() override;
+    ~Polygon() override = default;
 
     /**
      * Creates and returns a full copy of this {@link Polygon} object.
diff --git a/include/geos/geom/prep/BasicPreparedGeometry.h b/include/geos/geom/prep/BasicPreparedGeometry.h
index 1fcdfdb..d66bc1d 100644
--- a/include/geos/geom/prep/BasicPreparedGeometry.h
+++ b/include/geos/geom/prep/BasicPreparedGeometry.h
@@ -89,7 +89,7 @@ protected:
 public:
     BasicPreparedGeometry(const Geometry* geom);
 
-    ~BasicPreparedGeometry() override;
+    ~BasicPreparedGeometry() override = default;
 
     const geom::Geometry&
     getGeometry() const override
diff --git a/include/geos/geom/util/GeometryTransformer.h b/include/geos/geom/util/GeometryTransformer.h
index 410a22d..8641aa2 100644
--- a/include/geos/geom/util/GeometryTransformer.h
+++ b/include/geos/geom/util/GeometryTransformer.h
@@ -92,7 +92,7 @@ public:
 
     GeometryTransformer();
 
-    virtual ~GeometryTransformer();
+    virtual ~GeometryTransformer() = default;
 
     std::unique_ptr<Geometry> transform(const Geometry* nInputGeom);
 
diff --git a/include/geos/geomgraph/Depth.h b/include/geos/geomgraph/Depth.h
index 371b0a1..095affd 100644
--- a/include/geos/geomgraph/Depth.h
+++ b/include/geos/geomgraph/Depth.h
@@ -41,7 +41,7 @@ class GEOS_DLL Depth {
 public:
     static int depthAtLocation(geom::Location location);
     Depth();
-    virtual ~Depth(); // FIXME: shoudn't be virtual!
+    virtual ~Depth() = default; // FIXME: shoudn't be virtual!
     int getDepth(int geomIndex, int posIndex) const;
     void setDepth(int geomIndex, int posIndex, int depthValue);
     geom::Location getLocation(int geomIndex, int posIndex) const;
diff --git a/include/geos/geomgraph/EdgeRing.h b/include/geos/geomgraph/EdgeRing.h
index ff4cdeb..f38117a 100644
--- a/include/geos/geomgraph/EdgeRing.h
+++ b/include/geos/geomgraph/EdgeRing.h
@@ -24,6 +24,8 @@
 
 #include <geos/export.h>
 #include <geos/geomgraph/Label.h> // for composition
+#include <geos/geom/CoordinateArraySequence.h>
+#include <geos/geom/LinearRing.h>
 
 #include <geos/inline.h>
 
@@ -41,10 +43,8 @@
 namespace geos {
 namespace geom {
 class GeometryFactory;
-class LinearRing;
 class Polygon;
 class Coordinate;
-class CoordinateArraySequence;
 }
 namespace geomgraph {
 class DirectedEdge;
@@ -65,7 +65,7 @@ public:
     EdgeRing(DirectedEdge* newStart,
              const geom::GeometryFactory* newGeometryFactory);
 
-    virtual ~EdgeRing();
+    virtual ~EdgeRing() = default;
 
     bool isIsolated();
 
diff --git a/include/geos/geomgraph/GraphComponent.h b/include/geos/geomgraph/GraphComponent.h
index 73c190d..5891523 100644
--- a/include/geos/geomgraph/GraphComponent.h
+++ b/include/geos/geomgraph/GraphComponent.h
@@ -52,7 +52,8 @@ public:
      * GraphComponent copies the given Label.
      */
     GraphComponent(const Label& newLabel);
-    virtual ~GraphComponent();
+
+    virtual ~GraphComponent() = default;
 
     Label&
     getLabel()
diff --git a/include/geos/geomgraph/Label.h b/include/geos/geomgraph/Label.h
index 0582460..d0e1a00 100644
--- a/include/geos/geomgraph/Label.h
+++ b/include/geos/geomgraph/Label.h
@@ -169,9 +169,9 @@ std::ostream& operator<< (std::ostream&, const Label&);
 } // namespace geos
 
 
-//#ifdef GEOS_INLINE
-//# include "geos/geomgraph/Label.inl"
-//#endif
+#ifdef GEOS_INLINE
+# include "geos/geomgraph/Label.inl"
+#endif
 
 #endif // ifndef GEOS_GEOMGRAPH_LABEL_H
 
diff --git a/include/geos/geomgraph/TopologyLocation.h b/include/geos/geomgraph/TopologyLocation.h
index 14fcf78..0bf0854 100644
--- a/include/geos/geomgraph/TopologyLocation.h
+++ b/include/geos/geomgraph/TopologyLocation.h
@@ -63,9 +63,7 @@ public:
 
     friend std::ostream& operator<< (std::ostream&, const TopologyLocation&);
 
-    TopologyLocation();
-
-    ~TopologyLocation();
+    TopologyLocation() = default;
 
     /** \brief
      * Constructs a TopologyLocation specifying how points on, to the
@@ -140,9 +138,9 @@ std::ostream& operator<< (std::ostream&, const TopologyLocation&);
 } // namespace geos.geomgraph
 } // namespace geos
 
-//#ifdef GEOS_INLINE
-//# include "geos/geomgraph/TopologyLocation.inl"
-//#endif
+#ifdef GEOS_INLINE
+# include "geos/geomgraph/TopologyLocation.inl"
+#endif
 
 #ifdef _MSC_VER
 #pragma warning(pop)
diff --git a/include/geos/geomgraph/index/MonotoneChainEdge.h b/include/geos/geomgraph/index/MonotoneChainEdge.h
index 1805439..238338c 100644
--- a/include/geos/geomgraph/index/MonotoneChainEdge.h
+++ b/include/geos/geomgraph/index/MonotoneChainEdge.h
@@ -44,7 +44,7 @@ namespace index { // geos::geomgraph::index
 class GEOS_DLL MonotoneChainEdge {
 public:
     //MonotoneChainEdge();
-    ~MonotoneChainEdge();
+    ~MonotoneChainEdge() = default;
     MonotoneChainEdge(Edge* newE);
     const geom::CoordinateSequence* getCoordinates();
     std::vector<size_t>& getStartIndexes();
diff --git a/include/geos/geomgraph/index/SimpleMCSweepLineIntersector.h b/include/geos/geomgraph/index/SimpleMCSweepLineIntersector.h
index 55ef114..62baf16 100644
--- a/include/geos/geomgraph/index/SimpleMCSweepLineIntersector.h
+++ b/include/geos/geomgraph/index/SimpleMCSweepLineIntersector.h
@@ -59,7 +59,7 @@ public:
 
     SimpleMCSweepLineIntersector();
 
-    ~SimpleMCSweepLineIntersector() override;
+    ~SimpleMCSweepLineIntersector() override = default;
 
     void computeIntersections(std::vector<Edge*>* edges,
                               SegmentIntersector* si, bool testAllSegments) override;
diff --git a/include/geos/geomgraph/index/SweepLineEvent.h b/include/geos/geomgraph/index/SweepLineEvent.h
index f23b85c..34abb30 100644
--- a/include/geos/geomgraph/index/SweepLineEvent.h
+++ b/include/geos/geomgraph/index/SweepLineEvent.h
@@ -49,7 +49,7 @@ public:
                    SweepLineEvent* newInsertEvent,
                    SweepLineEventOBJ* newObj);
 
-    virtual ~SweepLineEvent();
+    virtual ~SweepLineEvent() = default;
 
     bool
     isInsert()
diff --git a/include/geos/geomgraph/index/SweepLineSegment.h b/include/geos/geomgraph/index/SweepLineSegment.h
index 5a91436..198081d 100644
--- a/include/geos/geomgraph/index/SweepLineSegment.h
+++ b/include/geos/geomgraph/index/SweepLineSegment.h
@@ -40,7 +40,7 @@ namespace index { // geos::geomgraph::index
 class GEOS_DLL SweepLineSegment: public SweepLineEventOBJ {
 public:
     SweepLineSegment(Edge* newEdge, size_t newPtIndex);
-    ~SweepLineSegment() override;
+    ~SweepLineSegment() override = default;
     double getMinX();
     double getMaxX();
     void computeIntersections(SweepLineSegment* ss, SegmentIntersector* si);
diff --git a/include/geos/index/bintree/Interval.h b/include/geos/index/bintree/Interval.h
index f3b717c..ada82d7 100644
--- a/include/geos/index/bintree/Interval.h
+++ b/include/geos/index/bintree/Interval.h
@@ -30,8 +30,6 @@ public:
 
     Interval();
 
-    ~Interval();
-
     Interval(double nmin, double nmax);
 
     /// TODO: drop this, rely on copy ctor
diff --git a/include/geos/index/chain/MonotoneChain.h b/include/geos/index/chain/MonotoneChain.h
index 13323af..c6ac23b 100644
--- a/include/geos/index/chain/MonotoneChain.h
+++ b/include/geos/index/chain/MonotoneChain.h
@@ -98,7 +98,7 @@ public:
     MonotoneChain(const geom::CoordinateSequence& pts,
                   std::size_t start, std::size_t end, void* context);
 
-    ~MonotoneChain();
+    ~MonotoneChain() = default;
 
     /// Returned envelope is owned by this class
     const geom::Envelope& getEnvelope() const;
diff --git a/include/geos/index/quadtree/Key.h b/include/geos/index/quadtree/Key.h
index f003864..fc6d6d3 100644
--- a/include/geos/index/quadtree/Key.h
+++ b/include/geos/index/quadtree/Key.h
@@ -49,7 +49,7 @@ public:
     Key(const geom::Envelope& itemEnv);
 
     // used to be virtual, but I don't see subclasses...
-    ~Key();
+    ~Key() = default;
 
     /// Returned object ownership retained by this class
     const geom::Coordinate& getPoint() const;
diff --git a/include/geos/index/strtree/AbstractNode.h b/include/geos/index/strtree/AbstractNode.h
index 97080db..4736b3f 100644
--- a/include/geos/index/strtree/AbstractNode.h
+++ b/include/geos/index/strtree/AbstractNode.h
@@ -46,7 +46,7 @@ private:
     int level;
 public:
     AbstractNode(int newLevel, size_t capacity = 10);
-    ~AbstractNode() override;
+    ~AbstractNode() override = default;
 
     // TODO: change signature to return by ref,
     // document ownership of the return
diff --git a/include/geos/index/strtree/STRtree.h b/include/geos/index/strtree/STRtree.h
index aaf5583..1ceddef 100644
--- a/include/geos/index/strtree/STRtree.h
+++ b/include/geos/index/strtree/STRtree.h
@@ -114,7 +114,7 @@ protected:
 
 public:
 
-    ~STRtree() override;
+    ~STRtree() override = default;
 
     /**
      * Constructs an STRtree with the given maximum number of child nodes that
diff --git a/include/geos/io/WKBWriter.h b/include/geos/io/WKBWriter.h
index 902f303..1ed424e 100644
--- a/include/geos/io/WKBWriter.h
+++ b/include/geos/io/WKBWriter.h
@@ -90,7 +90,7 @@ public:
      * \brief
      * Destructor.
      */
-    virtual ~WKBWriter();
+    virtual ~WKBWriter() = default;
 
     /*
      * \brief
diff --git a/include/geos/io/WKTWriter.h b/include/geos/io/WKTWriter.h
index ed05fc2..b501804 100644
--- a/include/geos/io/WKTWriter.h
+++ b/include/geos/io/WKTWriter.h
@@ -79,7 +79,7 @@ namespace io {
 class GEOS_DLL WKTWriter {
 public:
     WKTWriter();
-    ~WKTWriter();
+    ~WKTWriter() = default;
 
     //string(count, ch) can be used for this
     //static string stringOfChar(char ch, int count);
diff --git a/include/geos/io/Writer.h b/include/geos/io/Writer.h
index 9cfc344..17618b6 100644
--- a/include/geos/io/Writer.h
+++ b/include/geos/io/Writer.h
@@ -36,7 +36,7 @@ class GEOS_DLL Writer {
 public:
     Writer();
     void reserve(std::size_t capacity);
-    ~Writer();
+    ~Writer() = default;
     void write(const std::string& txt);
     const std::string& toString();
 private:
diff --git a/include/geos/operation/linemerge/EdgeString.h b/include/geos/operation/linemerge/EdgeString.h
index a79d17b..47fce19 100644
--- a/include/geos/operation/linemerge/EdgeString.h
+++ b/include/geos/operation/linemerge/EdgeString.h
@@ -67,7 +67,7 @@ public:
      */
     EdgeString(const geom::GeometryFactory* newFactory);
 
-    ~EdgeString();
+    ~EdgeString() = default;
 
     /**
     * Adds a directed edge which is known to form part of this line.
diff --git a/include/geos/operation/overlay/ElevationMatrix.h b/include/geos/operation/overlay/ElevationMatrix.h
index aa38cde..b0a6d4c 100644
--- a/include/geos/operation/overlay/ElevationMatrix.h
+++ b/include/geos/operation/overlay/ElevationMatrix.h
@@ -61,7 +61,7 @@ namespace overlay { // geos::operation::overlay
 class GEOS_DLL ElevationMatrixFilter: public geom::CoordinateFilter {
 public:
     ElevationMatrixFilter(ElevationMatrix& em);
-    ~ElevationMatrixFilter() override;
+    ~ElevationMatrixFilter() override = default;
     void filter_rw(geom::Coordinate* c) const override;
     void filter_ro(const geom::Coordinate* c) override;
 private:
@@ -81,7 +81,7 @@ class GEOS_DLL ElevationMatrix {
 public:
     ElevationMatrix(const geom::Envelope& extent, unsigned int rows,
                     unsigned int cols);
-    ~ElevationMatrix();
+    ~ElevationMatrix() = default;
     void add(const geom::Geometry* geom);
     void elevate(geom::Geometry* geom) const;
     // set Z value for each cell w/out one
diff --git a/include/geos/operation/overlay/ElevationMatrixCell.h b/include/geos/operation/overlay/ElevationMatrixCell.h
index d2235fa..0ef9772 100644
--- a/include/geos/operation/overlay/ElevationMatrixCell.h
+++ b/include/geos/operation/overlay/ElevationMatrixCell.h
@@ -43,7 +43,7 @@ namespace overlay { // geos::operation::overlay
 class GEOS_DLL ElevationMatrixCell {
 public:
     ElevationMatrixCell();
-    ~ElevationMatrixCell();
+    ~ElevationMatrixCell() = default;
     void add(const geom::Coordinate& c);
     void add(double z);
     double getAvg(void) const;
diff --git a/include/geos/operation/overlay/LineBuilder.h b/include/geos/operation/overlay/LineBuilder.h
index e08dc4c..0db0a66 100644
--- a/include/geos/operation/overlay/LineBuilder.h
+++ b/include/geos/operation/overlay/LineBuilder.h
@@ -68,7 +68,7 @@ public:
                 const geom::GeometryFactory* newGeometryFactory,
                 algorithm::PointLocator* newPtLocator);
 
-    ~LineBuilder();
+    ~LineBuilder() = default;
 
     /**
      * @return a list of the LineStrings in the result of the specified overlay operation
diff --git a/include/geos/operation/overlay/MaximalEdgeRing.h b/include/geos/operation/overlay/MaximalEdgeRing.h
index e3c3772..79d2d3b 100644
--- a/include/geos/operation/overlay/MaximalEdgeRing.h
+++ b/include/geos/operation/overlay/MaximalEdgeRing.h
@@ -71,7 +71,7 @@ public:
                     const geom::GeometryFactory* geometryFactory);
     // throw(const TopologyException &)
 
-    ~MaximalEdgeRing() override;
+    ~MaximalEdgeRing() override = default;
 
     geomgraph::DirectedEdge* getNext(geomgraph::DirectedEdge* de) override;
 
diff --git a/include/geos/operation/relate/RelateComputer.h b/include/geos/operation/relate/RelateComputer.h
index 66f91c5..f904510 100644
--- a/include/geos/operation/relate/RelateComputer.h
+++ b/include/geos/operation/relate/RelateComputer.h
@@ -75,7 +75,7 @@ namespace relate { // geos::operation::relate
 class GEOS_DLL RelateComputer {
 public:
     RelateComputer(std::vector<geomgraph::GeometryGraph*>* newArg);
-    ~RelateComputer();
+    ~RelateComputer() = default;
 
     std::unique_ptr<geom::IntersectionMatrix> computeIM();
 private:
diff --git a/include/geos/operation/relate/RelateNode.h b/include/geos/operation/relate/RelateNode.h
index 6c0fdcd..21595dd 100644
--- a/include/geos/operation/relate/RelateNode.h
+++ b/include/geos/operation/relate/RelateNode.h
@@ -49,7 +49,7 @@ public:
 
     RelateNode(const geom::Coordinate& coord, geomgraph::EdgeEndStar* edges);
 
-    ~RelateNode() override;
+    ~RelateNode() override = default;
 
     /**
      * Update the IM with the contribution for the EdgeEnds incident on this node.
diff --git a/include/geos/operation/relate/RelateOp.h b/include/geos/operation/relate/RelateOp.h
index ed46b08..3a9359d 100644
--- a/include/geos/operation/relate/RelateOp.h
+++ b/include/geos/operation/relate/RelateOp.h
@@ -112,7 +112,7 @@ public:
              const geom::Geometry* g1,
              const algorithm::BoundaryNodeRule& boundaryNodeRule);
 
-    ~RelateOp() override;
+    ~RelateOp() override = default;
 
     /** \brief
      * Gets the IntersectionMatrix for the spatial relationship
diff --git a/include/geos/operation/valid/ConnectedInteriorTester.h b/include/geos/operation/valid/ConnectedInteriorTester.h
index 4e101ba..574870a 100644
--- a/include/geos/operation/valid/ConnectedInteriorTester.h
+++ b/include/geos/operation/valid/ConnectedInteriorTester.h
@@ -71,7 +71,7 @@ namespace valid { // geos::operation::valid
 class GEOS_DLL ConnectedInteriorTester {
 public:
     ConnectedInteriorTester(geomgraph::GeometryGraph& newGeomGraph);
-    ~ConnectedInteriorTester();
+    ~ConnectedInteriorTester() = default;
     geom::Coordinate& getCoordinate();
     bool isInteriorsConnected();
     static const geom::Coordinate& findDifferentPoint(
diff --git a/include/geos/operation/valid/ConsistentAreaTester.h b/include/geos/operation/valid/ConsistentAreaTester.h
index d23dfa4..aa76035 100644
--- a/include/geos/operation/valid/ConsistentAreaTester.h
+++ b/include/geos/operation/valid/ConsistentAreaTester.h
@@ -95,7 +95,7 @@ public:
      */
     ConsistentAreaTester(geomgraph::GeometryGraph* newGeomGraph);
 
-    ~ConsistentAreaTester();
+    ~ConsistentAreaTester() = default;
 
     /**
      * @return the intersection point, or <code>null</code>
diff --git a/include/geos/planargraph/NodeMap.h b/include/geos/planargraph/NodeMap.h
index 2a67fe4..fcaf4f5 100644
--- a/include/geos/planargraph/NodeMap.h
+++ b/include/geos/planargraph/NodeMap.h
@@ -58,7 +58,7 @@ public:
 
     container& getNodeMap();
 
-    virtual ~NodeMap();
+    virtual ~NodeMap() = default;
 
     /**
      * \brief
diff --git a/include/geos/triangulate/VoronoiDiagramBuilder.h b/include/geos/triangulate/VoronoiDiagramBuilder.h
index 780d503..dc5c089 100644
--- a/include/geos/triangulate/VoronoiDiagramBuilder.h
+++ b/include/geos/triangulate/VoronoiDiagramBuilder.h
@@ -51,7 +51,7 @@ public:
      */
     VoronoiDiagramBuilder();
 
-    ~VoronoiDiagramBuilder();
+    ~VoronoiDiagramBuilder() = default;
 
     /** \brief
      * Sets the sites (point or vertices) which will be diagrammed.
diff --git a/include/geos/triangulate/quadedge/QuadEdgeLocator.h b/include/geos/triangulate/quadedge/QuadEdgeLocator.h
index 5d8dc68..cbdff34 100644
--- a/include/geos/triangulate/quadedge/QuadEdgeLocator.h
+++ b/include/geos/triangulate/quadedge/QuadEdgeLocator.h
@@ -38,7 +38,7 @@ class QuadEdge;
  */
 class QuadEdgeLocator {
 public:
-    virtual ~QuadEdgeLocator() = 0; //not implemented
+    virtual ~QuadEdgeLocator() = default;
     virtual QuadEdge* locate(const Vertex& v) = 0; //not implemented
 };
 
diff --git a/include/geos/triangulate/quadedge/TriangleVisitor.h b/include/geos/triangulate/quadedge/TriangleVisitor.h
index 966f8ca..48f4efb 100644
--- a/include/geos/triangulate/quadedge/TriangleVisitor.h
+++ b/include/geos/triangulate/quadedge/TriangleVisitor.h
@@ -39,7 +39,7 @@ public:
      * @param triEdges an array of the 3 quad edges in a triangle (in CCW order)
      */
     virtual void visit(QuadEdge* triEdges[3]) = 0;
-    virtual ~TriangleVisitor() = 0 ;
+    virtual ~TriangleVisitor() = default;
 private:
 } ;
 
diff --git a/src/algorithm/InteriorPointArea.cpp b/src/algorithm/InteriorPointArea.cpp
index 379083c..1ddddac 100644
--- a/src/algorithm/InteriorPointArea.cpp
+++ b/src/algorithm/InteriorPointArea.cpp
@@ -294,10 +294,6 @@ InteriorPointArea::InteriorPointArea(const Geometry* g)
     process(g);
 }
 
-InteriorPointArea::~InteriorPointArea()
-{
-}
-
 bool
 InteriorPointArea::getInteriorPoint(Coordinate& ret) const
 {
diff --git a/src/algorithm/InteriorPointLine.cpp b/src/algorithm/InteriorPointLine.cpp
index a36818b..4aa5ac1 100644
--- a/src/algorithm/InteriorPointLine.cpp
+++ b/src/algorithm/InteriorPointLine.cpp
@@ -53,10 +53,6 @@ InteriorPointLine::InteriorPointLine(const Geometry* g)
     }
 }
 
-InteriorPointLine::~InteriorPointLine()
-{
-}
-
 /* private
  *
  * Tests the interior vertices (if any)
diff --git a/src/algorithm/SimplePointInRing.cpp b/src/algorithm/SimplePointInRing.cpp
index a3fff70..7d0693b 100644
--- a/src/algorithm/SimplePointInRing.cpp
+++ b/src/algorithm/SimplePointInRing.cpp
@@ -32,10 +32,6 @@ SimplePointInRing::SimplePointInRing(geom::LinearRing* ring)
     pts = ring->getCoordinatesRO();
 }
 
-SimplePointInRing::~SimplePointInRing()
-{
-}
-
 bool
 SimplePointInRing::isInside(const geom::Coordinate& pt)
 {
diff --git a/src/geom/CoordinateSequenceFactory.cpp b/src/geom/CoordinateSequenceFactory.cpp
deleted file mode 100644
index 8760f23..0000000
--- a/src/geom/CoordinateSequenceFactory.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-/**********************************************************************
- *
- * GEOS - Geometry Engine Open Source
- * http://geos.osgeo.org
- *
- * Copyright (C) 2001-2002 Vivid Solutions Inc.
- *
- * This is free software; you can redistribute and/or modify it under
- * the terms of the GNU Lesser General Public Licence as published
- * by the Free Software Foundation.
- * See the COPYING file for more information.
- *
- **********************************************************************
- *
- * Last port: geom/CoordinateSequenceFactory.java r591 (JTS-1.12)
- *
- **********************************************************************/
-
-#include <geos/geom/CoordinateSequenceFactory.h>
-
-namespace geos {
-namespace geom { // geos::geom
-
-CoordinateSequenceFactory::~CoordinateSequenceFactory()
-{}
-
-} // namespace geos::geom
-}
diff --git a/src/geom/Envelope.cpp b/src/geom/Envelope.cpp
index 43bd73a..284556a 100644
--- a/src/geom/Envelope.cpp
+++ b/src/geom/Envelope.cpp
@@ -179,9 +179,6 @@ Envelope::Envelope(const string& str)
 }
 
 /*public*/
-Envelope::~Envelope(void) {}
-
-/*public*/
 void
 Envelope::init()
 {
diff --git a/src/geom/GeometryCollection.cpp b/src/geom/GeometryCollection.cpp
index 9751be0..60bfb02 100644
--- a/src/geom/GeometryCollection.cpp
+++ b/src/geom/GeometryCollection.cpp
@@ -372,8 +372,6 @@ GeometryCollection::apply_ro(CoordinateSequenceFilter& filter) const
     //if (filter.isGeometryChanged()) geometryChanged();
 }
 
-GeometryCollection::~GeometryCollection() = default;
-
 GeometryTypeId
 GeometryCollection::getGeometryTypeId() const
 {
diff --git a/src/geom/LineString.cpp b/src/geom/LineString.cpp
index cf52831..590c893 100644
--- a/src/geom/LineString.cpp
+++ b/src/geom/LineString.cpp
@@ -104,8 +104,6 @@ LineString::LineString(CoordinateSequence::Ptr && newCoords,
 }
 
 
-LineString::~LineString() = default;
-
 std::unique_ptr<CoordinateSequence>
 LineString::getCoordinates() const
 {
diff --git a/src/geom/LinearRing.cpp b/src/geom/LinearRing.cpp
index afd5dab..e437c53 100644
--- a/src/geom/LinearRing.cpp
+++ b/src/geom/LinearRing.cpp
@@ -74,13 +74,6 @@ LinearRing::validateConstruction()
     }
 }
 
-
-
-// superclass LineString will delete internal CoordinateSequence
-LinearRing::~LinearRing()
-{
-}
-
 int
 LinearRing::getBoundaryDimension() const
 {
diff --git a/src/geom/Makefile.am b/src/geom/Makefile.am
index 8a9dd5d..b9b7da3 100644
--- a/src/geom/Makefile.am
+++ b/src/geom/Makefile.am
@@ -13,7 +13,6 @@ AM_CPPFLAGS = -I$(top_srcdir)/include
 libgeom_la_SOURCES = \
     Coordinate.cpp \
     CoordinateSequence.cpp \
-    CoordinateSequenceFactory.cpp  \
     CoordinateArraySequence.cpp \
     CoordinateArraySequenceFactory.cpp \
     Dimension.cpp \
diff --git a/src/geom/MultiLineString.cpp b/src/geom/MultiLineString.cpp
index 2226dc0..592f38a 100644
--- a/src/geom/MultiLineString.cpp
+++ b/src/geom/MultiLineString.cpp
@@ -57,8 +57,6 @@ MultiLineString::MultiLineString(std::vector<std::unique_ptr<Geometry>> && newLi
         : GeometryCollection(std::move(newLines), factory)
 {}
 
-MultiLineString::~MultiLineString() {}
-
 Dimension::DimensionType
 MultiLineString::getDimension() const
 {
diff --git a/src/geom/MultiPoint.cpp b/src/geom/MultiPoint.cpp
index 0d22e99..3a2b0e7 100644
--- a/src/geom/MultiPoint.cpp
+++ b/src/geom/MultiPoint.cpp
@@ -49,8 +49,6 @@ MultiPoint::MultiPoint(std::vector<std::unique_ptr<Geometry>> && newPoints, cons
 
 }
 
-MultiPoint::~MultiPoint() {}
-
 Dimension::DimensionType
 MultiPoint::getDimension() const
 {
diff --git a/src/geom/Point.cpp b/src/geom/Point.cpp
index 921073e..0db6b30 100644
--- a/src/geom/Point.cpp
+++ b/src/geom/Point.cpp
@@ -274,11 +274,6 @@ Point::compareToSameClass(const Geometry* g) const
     return getCoordinate()->compareTo(*(p->getCoordinate()));
 }
 
-Point::~Point()
-{
-    //delete coordinates;
-}
-
 GeometryTypeId
 Point::getGeometryTypeId() const
 {
diff --git a/src/geom/Polygon.cpp b/src/geom/Polygon.cpp
index bb95902..3bdc917 100644
--- a/src/geom/Polygon.cpp
+++ b/src/geom/Polygon.cpp
@@ -452,8 +452,6 @@ Polygon::apply_ro(CoordinateSequenceFilter& filter) const
     //if (filter.isGeometryChanged()) geometryChanged();
 }
 
-Polygon::~Polygon() = default;
-
 GeometryTypeId
 Polygon::getGeometryTypeId() const
 {
diff --git a/src/geom/prep/BasicPreparedGeometry.cpp b/src/geom/prep/BasicPreparedGeometry.cpp
index 436b316..65fca75 100644
--- a/src/geom/prep/BasicPreparedGeometry.cpp
+++ b/src/geom/prep/BasicPreparedGeometry.cpp
@@ -65,11 +65,6 @@ BasicPreparedGeometry::BasicPreparedGeometry(const Geometry* geom)
     setGeometry(geom);
 }
 
-BasicPreparedGeometry::~BasicPreparedGeometry()
-{
-}
-
-
 bool
 BasicPreparedGeometry::isAnyTargetComponentInTest(const geom::Geometry* testGeom) const
 {
diff --git a/src/geom/util/GeometryTransformer.cpp b/src/geom/util/GeometryTransformer.cpp
index 67b9106..53c05b5 100644
--- a/src/geom/util/GeometryTransformer.cpp
+++ b/src/geom/util/GeometryTransformer.cpp
@@ -61,10 +61,6 @@ GeometryTransformer::GeometryTransformer()
     skipTransformedInvalidInteriorRings(false)
 {}
 
-GeometryTransformer::~GeometryTransformer()
-{
-}
-
 void
 GeometryTransformer::setSkipTransformedInvalidInteriorRings(bool b)
 {
diff --git a/src/geomgraph/Depth.cpp b/src/geomgraph/Depth.cpp
index 0e67a9c..1050fbf 100644
--- a/src/geomgraph/Depth.cpp
+++ b/src/geomgraph/Depth.cpp
@@ -55,8 +55,6 @@ Depth::Depth()
     }
 }
 
-Depth::~Depth() = default;
-
 int
 Depth::getDepth(int geomIndex, int posIndex) const
 {
diff --git a/src/geomgraph/EdgeRing.cpp b/src/geomgraph/EdgeRing.cpp
index 0b10d37..9e3c802 100644
--- a/src/geomgraph/EdgeRing.cpp
+++ b/src/geomgraph/EdgeRing.cpp
@@ -75,14 +75,6 @@ EdgeRing::EdgeRing(DirectedEdge* newStart,
     testInvariant();
 }
 
-EdgeRing::~EdgeRing()
-{
-    testInvariant();
-#ifdef GEOS_DEBUG
-    cerr << "EdgeRing[" << this << "] dtor" << endl;
-#endif
-}
-
 bool
 EdgeRing::isIsolated()
 {
diff --git a/src/geomgraph/GraphComponent.cpp b/src/geomgraph/GraphComponent.cpp
index f1993c2..7762108 100644
--- a/src/geomgraph/GraphComponent.cpp
+++ b/src/geomgraph/GraphComponent.cpp
@@ -47,10 +47,6 @@ GraphComponent::GraphComponent(const Label& newLabel):
 {
 }
 
-GraphComponent::~GraphComponent()
-{
-}
-
 void
 GraphComponent::setCovered(bool p_isCovered)
 {
diff --git a/src/geomgraph/index/MonotoneChainEdge.cpp b/src/geomgraph/index/MonotoneChainEdge.cpp
index d3dbcfa..cd57ac6 100644
--- a/src/geomgraph/index/MonotoneChainEdge.cpp
+++ b/src/geomgraph/index/MonotoneChainEdge.cpp
@@ -48,10 +48,6 @@ namespace index { // geos.geomgraph.index
  * @version 1.1
  */
 
-MonotoneChainEdge::~MonotoneChainEdge()
-{
-}
-
 MonotoneChainEdge::MonotoneChainEdge(Edge* newE):
     e(newE),
     pts(newE->getCoordinates())
diff --git a/src/geomgraph/index/SimpleMCSweepLineIntersector.cpp b/src/geomgraph/index/SimpleMCSweepLineIntersector.cpp
index 6e93ead..fd57111 100644
--- a/src/geomgraph/index/SimpleMCSweepLineIntersector.cpp
+++ b/src/geomgraph/index/SimpleMCSweepLineIntersector.cpp
@@ -33,8 +33,6 @@ SimpleMCSweepLineIntersector::SimpleMCSweepLineIntersector()
 {
 }
 
-SimpleMCSweepLineIntersector::~SimpleMCSweepLineIntersector() = default;
-
 void
 SimpleMCSweepLineIntersector::computeIntersections(vector<Edge*>* edges,
         SegmentIntersector* si, bool testAllSegments)
diff --git a/src/geomgraph/index/SweepLineEvent.cpp b/src/geomgraph/index/SweepLineEvent.cpp
index a8aacf5..4a30ebc 100644
--- a/src/geomgraph/index/SweepLineEvent.cpp
+++ b/src/geomgraph/index/SweepLineEvent.cpp
@@ -40,8 +40,6 @@ SweepLineEvent::SweepLineEvent(void* newEdgeSet, double x,
     }
 }
 
-SweepLineEvent::~SweepLineEvent() = default;
-
 /**
  * ProjectionEvents are ordered first by their x-value, and then by their
  * eventType.
diff --git a/src/geomgraph/index/SweepLineSegment.cpp b/src/geomgraph/index/SweepLineSegment.cpp
index 125fae7..6e662e1 100644
--- a/src/geomgraph/index/SweepLineSegment.cpp
+++ b/src/geomgraph/index/SweepLineSegment.cpp
@@ -35,10 +35,6 @@ SweepLineSegment::SweepLineSegment(Edge* newEdge, size_t newPtIndex):
     //ptIndex=newPtIndex;
 }
 
-SweepLineSegment::~SweepLineSegment()
-{
-}
-
 double
 SweepLineSegment::getMinX()
 {
diff --git a/src/index/bintree/Interval.cpp b/src/index/bintree/Interval.cpp
index 859ec79..c65f949 100644
--- a/src/index/bintree/Interval.cpp
+++ b/src/index/bintree/Interval.cpp
@@ -30,10 +30,6 @@ Interval::Interval(double nmin, double nmax)
     init(nmin, nmax);
 }
 
-Interval::~Interval()
-{
-}
-
 Interval::Interval(const Interval* interval)
 {
     init(interval->min, interval->max);
diff --git a/src/index/chain/MonotoneChain.cpp b/src/index/chain/MonotoneChain.cpp
index 8f2e13c..69360ea 100644
--- a/src/index/chain/MonotoneChain.cpp
+++ b/src/index/chain/MonotoneChain.cpp
@@ -43,8 +43,6 @@ MonotoneChain::MonotoneChain(const geom::CoordinateSequence& newPts,
 {
 }
 
-MonotoneChain::~MonotoneChain() = default;
-
 const Envelope&
 MonotoneChain::getEnvelope() const
 {
diff --git a/src/index/quadtree/Key.cpp b/src/index/quadtree/Key.cpp
index fedfa61..25c830a 100644
--- a/src/index/quadtree/Key.cpp
+++ b/src/index/quadtree/Key.cpp
@@ -62,10 +62,6 @@ Key::Key(const Envelope& itemEnv)
     computeKey(itemEnv);
 }
 
-Key::~Key()
-{
-}
-
 const Coordinate&
 Key::getPoint() const
 {
diff --git a/src/index/strtree/AbstractNode.cpp b/src/index/strtree/AbstractNode.cpp
index 5d6848b..fea79db 100644
--- a/src/index/strtree/AbstractNode.cpp
+++ b/src/index/strtree/AbstractNode.cpp
@@ -37,10 +37,6 @@ AbstractNode::AbstractNode(int newLevel, size_t capacity)
     level = newLevel;
 }
 
-AbstractNode::~AbstractNode()
-{
-}
-
 const void*
 AbstractNode::getBounds() const
 {
diff --git a/src/index/strtree/STRtree.cpp b/src/index/strtree/STRtree.cpp
index c03247e..8e9868e 100644
--- a/src/index/strtree/STRtree.cpp
+++ b/src/index/strtree/STRtree.cpp
@@ -95,11 +95,6 @@ STRtree::STRtree(size_t p_nodeCapacity): AbstractSTRtree(p_nodeCapacity)
 {
 }
 
-/*public*/
-STRtree::~STRtree()
-{
-}
-
 bool
 STRtree::STRIntersectsOp::intersects(const void* aBounds, const void* bBounds)
 {
diff --git a/src/io/WKBWriter.cpp b/src/io/WKBWriter.cpp
index a72c479..7876383 100644
--- a/src/io/WKBWriter.cpp
+++ b/src/io/WKBWriter.cpp
@@ -65,10 +65,6 @@ WKBWriter::setOutputDimension(int dims)
     defaultOutputDimension = dims;
 }
 
-WKBWriter::~WKBWriter()
-{
-}
-
 void
 WKBWriter::writeHEX(const Geometry& g, ostream& os)
 {
diff --git a/src/io/WKTWriter.cpp b/src/io/WKTWriter.cpp
index 7a67bb6..7c842a1 100644
--- a/src/io/WKTWriter.cpp
+++ b/src/io/WKTWriter.cpp
@@ -69,8 +69,6 @@ WKTWriter::setOutputDimension(int dims)
     defaultOutputDimension = dims;
 }
 
-WKTWriter::~WKTWriter() {}
-
 /*static*/
 string
 WKTWriter::toLineString(const CoordinateSequence& seq)
diff --git a/src/io/Writer.cpp b/src/io/Writer.cpp
index 363e09f..77e1452 100644
--- a/src/io/Writer.cpp
+++ b/src/io/Writer.cpp
@@ -20,8 +20,6 @@
 #include <geos/io/Writer.h>
 #include <string>
 
-using namespace std;
-
 namespace geos {
 namespace io { // geos.io
 
@@ -35,10 +33,6 @@ Writer::reserve(std::size_t capacity)
     str.reserve(capacity);
 }
 
-Writer::~Writer()
-{
-}
-
 void
 Writer::write(const std::string& txt)
 {
diff --git a/src/operation/linemerge/EdgeString.cpp b/src/operation/linemerge/EdgeString.cpp
index c76af8a..8c7ad8b 100644
--- a/src/operation/linemerge/EdgeString.cpp
+++ b/src/operation/linemerge/EdgeString.cpp
@@ -48,10 +48,6 @@ EdgeString::EdgeString(const GeometryFactory* newFactory):
 {
 }
 
-EdgeString::~EdgeString()
-{
-}
-
 /**
  * Adds a directed edge which is known to form part of this line.
  */
diff --git a/src/operation/overlay/ElevationMatrix.cpp b/src/operation/overlay/ElevationMatrix.cpp
index 6fcfd4a..74fc7b5 100644
--- a/src/operation/overlay/ElevationMatrix.cpp
+++ b/src/operation/overlay/ElevationMatrix.cpp
@@ -49,9 +49,6 @@ ElevationMatrixFilter::ElevationMatrixFilter(ElevationMatrix& newEm):
     em(newEm)
 { }
 
-ElevationMatrixFilter::~ElevationMatrixFilter()
-{ }
-
 void
 ElevationMatrixFilter::filter_rw(Coordinate* c) const
 {
@@ -111,10 +108,6 @@ ElevationMatrix::ElevationMatrix(const Envelope& newEnv,
     }
 }
 
-ElevationMatrix::~ElevationMatrix()
-{
-}
-
 void
 ElevationMatrix::add(const Geometry* geom)
 {
diff --git a/src/operation/overlay/ElevationMatrixCell.cpp b/src/operation/overlay/ElevationMatrixCell.cpp
index 112bc7e..a574a63 100644
--- a/src/operation/overlay/ElevationMatrixCell.cpp
+++ b/src/operation/overlay/ElevationMatrixCell.cpp
@@ -36,10 +36,6 @@ ElevationMatrixCell::ElevationMatrixCell(): ztot(0)
 {
 }
 
-ElevationMatrixCell::~ElevationMatrixCell()
-{
-}
-
 void
 ElevationMatrixCell::add(const Coordinate& c)
 {
diff --git a/src/operation/overlay/LineBuilder.cpp b/src/operation/overlay/LineBuilder.cpp
index d89f3a7..487577b 100644
--- a/src/operation/overlay/LineBuilder.cpp
+++ b/src/operation/overlay/LineBuilder.cpp
@@ -56,10 +56,6 @@ LineBuilder::LineBuilder(OverlayOp* newOp,
 {
 }
 
-LineBuilder::~LineBuilder()
-{
-}
-
 /*
  * @return a list of the LineStrings in the result of the
  *         specified overlay operation
diff --git a/src/operation/overlay/MaximalEdgeRing.cpp b/src/operation/overlay/MaximalEdgeRing.cpp
index 2f4c1f2..f8f73f8 100644
--- a/src/operation/overlay/MaximalEdgeRing.cpp
+++ b/src/operation/overlay/MaximalEdgeRing.cpp
@@ -59,14 +59,6 @@ MaximalEdgeRing::MaximalEdgeRing(DirectedEdge* start,
 }
 
 /*public*/
-MaximalEdgeRing::~MaximalEdgeRing()
-{
-#if GEOS_DEBUG
-    cerr << "MaximalEdgeRing[" << this << "] dtor" << endl;
-#endif
-}
-
-/*public*/
 DirectedEdge*
 MaximalEdgeRing::getNext(DirectedEdge* de)
 {
diff --git a/src/operation/relate/RelateComputer.cpp b/src/operation/relate/RelateComputer.cpp
index 27b6313..2b860a6 100644
--- a/src/operation/relate/RelateComputer.cpp
+++ b/src/operation/relate/RelateComputer.cpp
@@ -65,10 +65,6 @@ RelateComputer::RelateComputer(std::vector<GeometryGraph*>* newArg):
 {
 }
 
-RelateComputer::~RelateComputer()
-{
-}
-
 std::unique_ptr<IntersectionMatrix>
 RelateComputer::computeIM()
 {
diff --git a/src/operation/relate/RelateNode.cpp b/src/operation/relate/RelateNode.cpp
index 6e8d2bd..5ea1b85 100644
--- a/src/operation/relate/RelateNode.cpp
+++ b/src/operation/relate/RelateNode.cpp
@@ -36,10 +36,6 @@ RelateNode::RelateNode(const Coordinate& p_coord, EdgeEndStar* p_edges):
     Node(p_coord, p_edges)
 {}
 
-RelateNode::~RelateNode()
-{
-}
-
 /**
  * Update the IM with the contribution for this component.
  * A component only contributes if it has a labelling for both parent geometries
diff --git a/src/operation/relate/RelateOp.cpp b/src/operation/relate/RelateOp.cpp
index d5dc261..719cddb 100644
--- a/src/operation/relate/RelateOp.cpp
+++ b/src/operation/relate/RelateOp.cpp
@@ -64,10 +64,6 @@ RelateOp::RelateOp(const Geometry* g0, const Geometry* g1,
 {
 }
 
-RelateOp::~RelateOp()
-{
-}
-
 std::unique_ptr<IntersectionMatrix>
 RelateOp::getIntersectionMatrix()
 {
diff --git a/src/operation/valid/ConnectedInteriorTester.cpp b/src/operation/valid/ConnectedInteriorTester.cpp
index f977874..527622e 100644
--- a/src/operation/valid/ConnectedInteriorTester.cpp
+++ b/src/operation/valid/ConnectedInteriorTester.cpp
@@ -74,10 +74,6 @@ ConnectedInteriorTester::ConnectedInteriorTester(GeometryGraph& newGeomGraph):
 {
 }
 
-ConnectedInteriorTester::~ConnectedInteriorTester()
-{
-}
-
 Coordinate&
 ConnectedInteriorTester::getCoordinate()
 {
diff --git a/src/operation/valid/ConsistentAreaTester.cpp b/src/operation/valid/ConsistentAreaTester.cpp
index c3f3cda..0b7280a 100644
--- a/src/operation/valid/ConsistentAreaTester.cpp
+++ b/src/operation/valid/ConsistentAreaTester.cpp
@@ -50,10 +50,6 @@ ConsistentAreaTester::ConsistentAreaTester(GeometryGraph* newGeomGraph)
 {
 }
 
-ConsistentAreaTester::~ConsistentAreaTester()
-{
-}
-
 Coordinate&
 ConsistentAreaTester::getInvalidPoint()
 {
diff --git a/src/planargraph/NodeMap.cpp b/src/planargraph/NodeMap.cpp
index 0cfaf2e..a416527 100644
--- a/src/planargraph/NodeMap.cpp
+++ b/src/planargraph/NodeMap.cpp
@@ -30,10 +30,6 @@ NodeMap::NodeMap()
 {
 }
 
-NodeMap::~NodeMap()
-{
-}
-
 NodeMap::container&
 NodeMap::getNodeMap()
 {
diff --git a/src/triangulate/VoronoiDiagramBuilder.cpp b/src/triangulate/VoronoiDiagramBuilder.cpp
index 319bffa..46aa9f0 100644
--- a/src/triangulate/VoronoiDiagramBuilder.cpp
+++ b/src/triangulate/VoronoiDiagramBuilder.cpp
@@ -46,10 +46,6 @@ VoronoiDiagramBuilder::VoronoiDiagramBuilder() :
 {
 }
 
-VoronoiDiagramBuilder::~VoronoiDiagramBuilder()
-{
-}
-
 void
 VoronoiDiagramBuilder::setSites(const geom::Geometry& geom)
 {
diff --git a/src/triangulate/quadedge/Makefile.am b/src/triangulate/quadedge/Makefile.am
index 1ff015e..c58199f 100644
--- a/src/triangulate/quadedge/Makefile.am
+++ b/src/triangulate/quadedge/Makefile.am
@@ -1,20 +1,18 @@
 #
-# This file is part of project GEOS (http://trac.osgeo.org/geos/) 
+# This file is part of project GEOS (http://trac.osgeo.org/geos/)
 #
-SUBDIRS = 
+SUBDIRS =
 
 noinst_LTLIBRARIES = libquadedge.la
 
-AM_CPPFLAGS = -I$(top_srcdir)/include 
+AM_CPPFLAGS = -I$(top_srcdir)/include
 
 libquadedge_la_SOURCES = \
 	QuadEdge.cpp \
 	Vertex.cpp \
 	TrianglePredicate.cpp \
 	QuadEdgeSubdivision.cpp \
-	QuadEdgeLocator.cpp  \
 	LastFoundQuadEdgeLocator.cpp \
-	LocateFailureException.cpp \
-	TriangleVisitor.cpp
+	LocateFailureException.cpp
 
-libquadedge_la_LIBADD = 
+libquadedge_la_LIBADD =
diff --git a/src/triangulate/quadedge/QuadEdgeLocator.cpp b/src/triangulate/quadedge/QuadEdgeLocator.cpp
deleted file mode 100644
index ba41a26..0000000
--- a/src/triangulate/quadedge/QuadEdgeLocator.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-/**********************************************************************
- *
- * GEOS - Geometry Engine Open Source
- * http://geos.osgeo.org
- *
- * Copyright (C) 2012 Excensus LLC.
- *
- * This is free software; you can redistribute and/or modify it under
- * the terms of the GNU Lesser General Licence as published
- * by the Free Software Foundation.
- * See the COPYING file for more information.
- *
- **********************************************************************
- *
- * Last port: triangulate/quadedge/QuadEdgeLocator.java r524
- *
- **********************************************************************/
-
-#include <geos/triangulate/quadedge/QuadEdgeLocator.h>
-
-namespace geos {
-namespace triangulate { //geos.triangulate
-namespace quadedge { //geos.triangulate.quadedge
-
-QuadEdgeLocator::~QuadEdgeLocator() {}
-
-} //namespace geos.triangulate.quadedge
-} //namespace geos.triangulate
-} //namespace goes
-
diff --git a/src/triangulate/quadedge/TriangleVisitor.cpp b/src/triangulate/quadedge/TriangleVisitor.cpp
deleted file mode 100644
index 00ab45f..0000000
--- a/src/triangulate/quadedge/TriangleVisitor.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-/**********************************************************************
- *
- * GEOS - Geometry Engine Open Source
- * http://geos.osgeo.org
- *
- * Copyright (C) 2012 Excensus LLC.
- *
- * This is free software; you can redistribute and/or modify it under
- * the terms of the GNU Lesser General Licence as published
- * by the Free Software Foundation.
- * See the COPYING file for more information.
- *
- **********************************************************************
- *
- * Last port: triangulate/quadedge/TriangleVisitor.java r524
- *
- **********************************************************************/
-
-#include <geos/triangulate/quadedge/TriangleVisitor.h>
-
-namespace geos {
-namespace triangulate { //geos.triangulate
-namespace quadedge { //geos.triangulate.quadedge
-
-TriangleVisitor::~TriangleVisitor() {}
-
-} //namespace geos.triangulate.quadedge
-} //namespace geos.triangulate
-} //namespace goes
-

commit 73524c36f1bbe3547615d4d29929cb4f03c41b68
Author: Daniel Baston <dbaston at gmail.com>
Date:   Fri Sep 20 22:20:22 2019 -0400

    Inline most methods of TopologyLocation and Label
    
    Improves intersection perf test by 3-5%.

diff --git a/src/geomgraph/Label.cpp b/include/geos/geomgraph/Label.inl
similarity index 67%
copy from src/geomgraph/Label.cpp
copy to include/geos/geomgraph/Label.inl
index d0a05cb..65f40a4 100644
--- a/src/geomgraph/Label.cpp
+++ b/include/geos/geomgraph/Label.inl
@@ -22,23 +22,16 @@
 #include <geos/geomgraph/Position.h>
 #include <geos/geom/Location.h>
 
-#include <string>
-#include <sstream>
-#include <iostream>
 #include <cassert>
 
-
-using namespace std;
-using namespace geos::geom;
-
 namespace geos {
 namespace geomgraph { // geos.geomgraph
 
 /*public static*/
-Label
+INLINE Label
 Label::toLineLabel(const Label& label)
 {
-    Label lineLabel(Location::UNDEF);
+    Label lineLabel(geom::Location::UNDEF);
     for(int i = 0; i < 2; i++) {
         lineLabel.setLocation(i, label.getLocation(i));
     }
@@ -46,44 +39,44 @@ Label::toLineLabel(const Label& label)
 }
 
 /*public*/
-Label::Label(Location onLoc)
+INLINE
+Label::Label(geom::Location onLoc) :
+    elt{TopologyLocation(onLoc), TopologyLocation(onLoc)}
 {
-    elt[0] = TopologyLocation(onLoc);
-    elt[1] = TopologyLocation(onLoc);
 }
 
 /*public*/
-Label::Label(int geomIndex, Location onLoc)
+INLINE
+Label::Label(int geomIndex, geom::Location onLoc) :
+    elt{TopologyLocation(geom::Location::UNDEF), TopologyLocation(geom::Location::UNDEF)}
 {
     assert(geomIndex >= 0 && geomIndex < 2);
-    elt[0] = TopologyLocation(Location::UNDEF);
-    elt[1] = TopologyLocation(Location::UNDEF);
     elt[geomIndex].setLocation(onLoc);
 }
 
 /*public*/
-Label::Label(Location onLoc, Location leftLoc, Location rightLoc)
+INLINE
+Label::Label(geom::Location onLoc, geom::Location leftLoc, geom::Location rightLoc)
+    : elt {TopologyLocation(onLoc, leftLoc, rightLoc), TopologyLocation(onLoc, leftLoc, rightLoc)}
 {
-    elt[0] = TopologyLocation(onLoc, leftLoc, rightLoc);
-    elt[1] = TopologyLocation(onLoc, leftLoc, rightLoc);
 }
 
 /*public*/
+INLINE
 Label::Label()
+    : elt{TopologyLocation(geom::Location::UNDEF), TopologyLocation(geom::Location::UNDEF)}
 {
-    elt[0] = TopologyLocation(Location::UNDEF);
-    elt[1] = TopologyLocation(Location::UNDEF);
 }
 
 /*public*/
-Label::Label(const Label& l)
+INLINE
+Label::Label(const Label& l) :
+    elt{TopologyLocation(l.elt[0]), TopologyLocation(l.elt[1])}
 {
-    elt[0] = TopologyLocation(l.elt[0]);
-    elt[1] = TopologyLocation(l.elt[1]);
 }
 
 /*public*/
-Label&
+INLINE Label&
 Label::operator=(const Label& l)
 {
     elt[0] = TopologyLocation(l.elt[0]);
@@ -92,15 +85,16 @@ Label::operator=(const Label& l)
 }
 
 /*public*/
-Label::Label(int geomIndex, Location onLoc, Location leftLoc, Location rightLoc)
+INLINE
+Label::Label(int geomIndex, geom::Location onLoc, geom::Location leftLoc, geom::Location rightLoc)
 {
-    elt[0] = TopologyLocation(Location::UNDEF, Location::UNDEF, Location::UNDEF);
-    elt[1] = TopologyLocation(Location::UNDEF, Location::UNDEF, Location::UNDEF);
+    elt[0] = TopologyLocation(geom::Location::UNDEF, geom::Location::UNDEF, geom::Location::UNDEF);
+    elt[1] = TopologyLocation(geom::Location::UNDEF, geom::Location::UNDEF, geom::Location::UNDEF);
     elt[geomIndex].setLocations(onLoc, leftLoc, rightLoc);
 }
 
 /*public*/
-void
+INLINE void
 Label::flip()
 {
     elt[0].flip();
@@ -108,7 +102,7 @@ Label::flip()
 }
 
 /*public*/
-Location
+INLINE geom::Location
 Label::getLocation(int geomIndex, int posIndex) const
 {
     assert(geomIndex >= 0 && geomIndex < 2);
@@ -116,7 +110,7 @@ Label::getLocation(int geomIndex, int posIndex) const
 }
 
 /*public*/
-Location
+INLINE geom::Location
 Label::getLocation(int geomIndex) const
 {
     assert(geomIndex >= 0 && geomIndex < 2);
@@ -124,47 +118,47 @@ Label::getLocation(int geomIndex) const
 }
 
 /*public*/
-void
-Label::setLocation(int geomIndex, int posIndex, Location location)
+INLINE void
+Label::setLocation(int geomIndex, int posIndex, geom::Location location)
 {
     assert(geomIndex >= 0 && geomIndex < 2);
     elt[geomIndex].setLocation(posIndex, location);
 }
 
 /*public*/
-void
-Label::setLocation(int geomIndex, Location location)
+INLINE void
+Label::setLocation(int geomIndex, geom::Location location)
 {
     assert(geomIndex >= 0 && geomIndex < 2);
     elt[geomIndex].setLocation(Position::ON, location);
 }
 
 /*public*/
-void
-Label::setAllLocations(int geomIndex, Location location)
+INLINE void
+Label::setAllLocations(int geomIndex, geom::Location location)
 {
     assert(geomIndex >= 0 && geomIndex < 2);
     elt[geomIndex].setAllLocations(location);
 }
 
 /*public*/
-void
-Label::setAllLocationsIfNull(int geomIndex, Location location)
+INLINE void
+Label::setAllLocationsIfNull(int geomIndex, geom::Location location)
 {
     assert(geomIndex >= 0 && geomIndex < 2);
     elt[geomIndex].setAllLocationsIfNull(location);
 }
 
 /*public*/
-void
-Label::setAllLocationsIfNull(Location location)
+INLINE void
+Label::setAllLocationsIfNull(geom::Location location)
 {
     setAllLocationsIfNull(0, location);
     setAllLocationsIfNull(1, location);
 }
 
 /*public*/
-void
+INLINE void
 Label::merge(const Label& lbl)
 {
     for(int i = 0; i < 2; i++) {
@@ -173,7 +167,7 @@ Label::merge(const Label& lbl)
 }
 
 /*public*/
-int
+INLINE int
 Label::getGeometryCount() const
 {
     int count = 0;
@@ -187,7 +181,7 @@ Label::getGeometryCount() const
 }
 
 /*public*/
-bool
+INLINE bool
 Label::isNull(int geomIndex) const
 {
     assert(geomIndex >= 0 && geomIndex < 2);
@@ -195,14 +189,14 @@ Label::isNull(int geomIndex) const
 }
 
 /*public*/
-bool
+INLINE bool
 Label::isNull() const
 {
     return elt[0].isNull() && elt[1].isNull();
 }
 
 /*public*/
-bool
+INLINE bool
 Label::isAnyNull(int geomIndex) const
 {
     assert(geomIndex >= 0 && geomIndex < 2);
@@ -210,14 +204,14 @@ Label::isAnyNull(int geomIndex) const
 }
 
 /*public*/
-bool
+INLINE bool
 Label::isArea() const
 {
     return elt[0].isArea() || elt[1].isArea();
 }
 
 /*public*/
-bool
+INLINE bool
 Label::isArea(int geomIndex) const
 {
     assert(geomIndex >= 0 && geomIndex < 2);
@@ -225,7 +219,7 @@ Label::isArea(int geomIndex) const
 }
 
 /*public*/
-bool
+INLINE bool
 Label::isLine(int geomIndex) const
 {
     assert(geomIndex >= 0 && geomIndex < 2);
@@ -233,24 +227,23 @@ Label::isLine(int geomIndex) const
 }
 
 /*public*/
-bool
+INLINE bool
 Label::isEqualOnSide(const Label& lbl, int side) const
 {
-    return
-        elt[0].isEqualOnSide(lbl.elt[0], side)
-        && elt[1].isEqualOnSide(lbl.elt[1], side);
+    return elt[0].isEqualOnSide(lbl.elt[0], side)
+            && elt[1].isEqualOnSide(lbl.elt[1], side);
 }
 
 /*public*/
-bool
-Label::allPositionsEqual(int geomIndex, Location loc) const
+INLINE bool
+Label::allPositionsEqual(int geomIndex, geom::Location loc) const
 {
     assert(geomIndex >= 0 && geomIndex < 2);
     return elt[geomIndex].allPositionsEqual(loc);
 }
 
 /*public*/
-void
+INLINE void
 Label::toLine(int geomIndex)
 {
     assert(geomIndex >= 0 && geomIndex < 2);
@@ -259,23 +252,5 @@ Label::toLine(int geomIndex)
     }
 }
 
-string
-Label::toString() const
-{
-    stringstream ss;
-    ss << *this;
-    return ss.str();
-}
-
-std::ostream&
-operator<< (std::ostream& os, const Label& l)
-{
-    os << "A:"
-       << l.elt[0]
-       << " B:"
-       << l.elt[1];
-    return os;
-}
-
 } // namespace geos.geomgraph
 } // namespace geos
diff --git a/include/geos/geomgraph/Makefile.am b/include/geos/geomgraph/Makefile.am
index 758e734..50dcf8a 100644
--- a/include/geos/geomgraph/Makefile.am
+++ b/include/geos/geomgraph/Makefile.am
@@ -24,10 +24,12 @@ geos_HEADERS = \
     GeometryGraph.inl \
     GraphComponent.h \
     Label.h \
+    Label.inl \
     NodeFactory.h \
     Node.h \
     NodeMap.h \
     PlanarGraph.h \
     Position.h \
     Quadrant.h \
-    TopologyLocation.h
+    TopologyLocation.h \
+    TopologyLocation.inl
diff --git a/src/geomgraph/TopologyLocation.cpp b/include/geos/geomgraph/TopologyLocation.inl
similarity index 71%
copy from src/geomgraph/TopologyLocation.cpp
copy to include/geos/geomgraph/TopologyLocation.inl
index e3e337a..1ea8ada 100644
--- a/src/geomgraph/TopologyLocation.cpp
+++ b/include/geos/geomgraph/TopologyLocation.inl
@@ -17,33 +17,23 @@
  *
  **********************************************************************/
 
-#include <geos/geomgraph/TopologyLocation.h>
+#ifndef GEOS_GEOMGRAPH_TOPOLOGYLOCATION_INL
+#define GEOS_GEOMGRAPH_TOPOLOGYLOCATION_INL
+
 #include <geos/geomgraph/Position.h>
 #include <geos/geom/Location.h>
 
-#include <vector>
-#include <sstream>
-#include <iostream>
 #include <cassert>
 
-using namespace geos::geom;
-
 namespace geos {
 namespace geomgraph { // geos.geomgraph
 
-/*public*/
-TopologyLocation::TopologyLocation()
-{
-}
-
-/*public*/
-TopologyLocation::~TopologyLocation()
-{
-}
+using geos::geom::Location;
 
 /*public*/
+INLINE
 TopologyLocation::TopologyLocation(Location on, Location left, Location right):
-    locationSize(3)
+        locationSize(3)
 {
     location[Position::ON] = on;
     location[Position::LEFT] = left;
@@ -51,23 +41,25 @@ TopologyLocation::TopologyLocation(Location on, Location left, Location right):
 }
 
 /*public*/
+INLINE
 TopologyLocation::TopologyLocation(Location on):
-    locationSize(1)
+        locationSize(1)
 {
     location.fill(Location::UNDEF);
     location[Position::ON] = on;
 }
 
 /*public*/
+INLINE
 TopologyLocation::TopologyLocation(const TopologyLocation& gl)
-    :
-    location(gl.location),
-    locationSize(gl.locationSize)
+        :
+        location(gl.location),
+        locationSize(gl.locationSize)
 {
 }
 
 /*public*/
-TopologyLocation&
+INLINE TopologyLocation&
 TopologyLocation::operator= (const TopologyLocation& gl)
 {
     location = gl.location;
@@ -76,7 +68,7 @@ TopologyLocation::operator= (const TopologyLocation& gl)
 }
 
 /*public*/
-Location
+INLINE Location
 TopologyLocation::get(size_t posIndex) const
 {
     // should be an assert() instead ?
@@ -87,7 +79,7 @@ TopologyLocation::get(size_t posIndex) const
 }
 
 /*public*/
-bool
+INLINE bool
 TopologyLocation::isNull() const
 {
     for(size_t i = 0; i < locationSize; ++i) {
@@ -99,7 +91,7 @@ TopologyLocation::isNull() const
 }
 
 /*public*/
-bool
+INLINE bool
 TopologyLocation::isAnyNull() const
 {
     for(size_t i = 0; i < locationSize; ++i) {
@@ -111,28 +103,28 @@ TopologyLocation::isAnyNull() const
 }
 
 /*public*/
-bool
+INLINE bool
 TopologyLocation::isEqualOnSide(const TopologyLocation& le, int locIndex) const
 {
     return location[locIndex] == le.location[locIndex];
 }
 
 /*public*/
-bool
+INLINE bool
 TopologyLocation::isArea() const
 {
     return locationSize > 1;
 }
 
 /*public*/
-bool
+INLINE bool
 TopologyLocation::isLine() const
 {
     return locationSize == 1;
 }
 
 /*public*/
-void
+INLINE void
 TopologyLocation::flip()
 {
     if(locationSize <= 1) {
@@ -142,14 +134,14 @@ TopologyLocation::flip()
 }
 
 /*public*/
-void
+INLINE void
 TopologyLocation::setAllLocations(Location locValue)
 {
     location.fill(locValue);
 }
 
 /*public*/
-void
+INLINE void
 TopologyLocation::setAllLocationsIfNull(Location locValue)
 {
     for(size_t i = 0; i < locationSize; ++i) {
@@ -160,28 +152,28 @@ TopologyLocation::setAllLocationsIfNull(Location locValue)
 }
 
 /*public*/
-void
+INLINE void
 TopologyLocation::setLocation(size_t locIndex, Location locValue)
 {
     location[locIndex] = locValue;
 }
 
 /*public*/
-void
+INLINE void
 TopologyLocation::setLocation(Location locValue)
 {
     setLocation(Position::ON, locValue);
 }
 
 /*public*/
-const std::array<Location, 3>&
+INLINE const std::array<Location, 3>&
 TopologyLocation::getLocations() const
 {
     return location;
 }
 
 /*public*/
-void
+INLINE void
 TopologyLocation::setLocations(Location on, Location left, Location right)
 {
     assert(locationSize >= 3);
@@ -191,7 +183,7 @@ TopologyLocation::setLocations(Location on, Location left, Location right)
 }
 
 /*public*/
-bool
+INLINE bool
 TopologyLocation::allPositionsEqual(Location loc) const
 {
     for(size_t i = 0; i < locationSize; ++i) {
@@ -202,47 +194,7 @@ TopologyLocation::allPositionsEqual(Location loc) const
     return true;
 }
 
-/*public*/
-void
-TopologyLocation::merge(const TopologyLocation& gl)
-{
-    // if the src is an Area label & and the dest is not, increase the dest to be an Area
-    size_t sz = locationSize;
-    size_t glsz = gl.locationSize;
-    if(glsz > sz) {
-        locationSize = 3;
-        location[Position::LEFT] = Location::UNDEF;
-        location[Position::RIGHT] = Location::UNDEF;
-    }
-    for(size_t i = 0; i < locationSize; ++i) {
-        if(location[i] == Location::UNDEF && i < glsz) {
-            location[i] = gl.location[i];
-        }
-    }
-}
-
-std::string
-TopologyLocation::toString() const
-{
-    std::stringstream ss;
-    ss << *this;
-    return ss.str();
-}
-
-std::ostream&
-operator<< (std::ostream& os, const TopologyLocation& tl)
-{
-    if(tl.locationSize > 1) {
-        os << tl.location[Position::LEFT];
-    }
-    os << tl.location[Position::ON];
-    if(tl.locationSize > 1) {
-        os << tl.location[Position::RIGHT];
-    }
-    return os;
-}
-
 } // namespace geos.geomgraph
 } // namespace geos
 
-
+#endif
diff --git a/src/geomgraph/Label.cpp b/src/geomgraph/Label.cpp
index d0a05cb..7f0bfab 100644
--- a/src/geomgraph/Label.cpp
+++ b/src/geomgraph/Label.cpp
@@ -18,251 +18,21 @@
  **********************************************************************/
 
 #include <geos/geomgraph/Label.h>
-#include <geos/geomgraph/TopologyLocation.h>
-#include <geos/geomgraph/Position.h>
-#include <geos/geom/Location.h>
 
 #include <string>
 #include <sstream>
 #include <iostream>
-#include <cassert>
 
 
-using namespace std;
 using namespace geos::geom;
 
 namespace geos {
 namespace geomgraph { // geos.geomgraph
 
-/*public static*/
-Label
-Label::toLineLabel(const Label& label)
-{
-    Label lineLabel(Location::UNDEF);
-    for(int i = 0; i < 2; i++) {
-        lineLabel.setLocation(i, label.getLocation(i));
-    }
-    return lineLabel;
-}
-
-/*public*/
-Label::Label(Location onLoc)
-{
-    elt[0] = TopologyLocation(onLoc);
-    elt[1] = TopologyLocation(onLoc);
-}
-
-/*public*/
-Label::Label(int geomIndex, Location onLoc)
-{
-    assert(geomIndex >= 0 && geomIndex < 2);
-    elt[0] = TopologyLocation(Location::UNDEF);
-    elt[1] = TopologyLocation(Location::UNDEF);
-    elt[geomIndex].setLocation(onLoc);
-}
-
-/*public*/
-Label::Label(Location onLoc, Location leftLoc, Location rightLoc)
-{
-    elt[0] = TopologyLocation(onLoc, leftLoc, rightLoc);
-    elt[1] = TopologyLocation(onLoc, leftLoc, rightLoc);
-}
-
-/*public*/
-Label::Label()
-{
-    elt[0] = TopologyLocation(Location::UNDEF);
-    elt[1] = TopologyLocation(Location::UNDEF);
-}
-
-/*public*/
-Label::Label(const Label& l)
-{
-    elt[0] = TopologyLocation(l.elt[0]);
-    elt[1] = TopologyLocation(l.elt[1]);
-}
-
-/*public*/
-Label&
-Label::operator=(const Label& l)
-{
-    elt[0] = TopologyLocation(l.elt[0]);
-    elt[1] = TopologyLocation(l.elt[1]);
-    return *this;
-}
-
-/*public*/
-Label::Label(int geomIndex, Location onLoc, Location leftLoc, Location rightLoc)
-{
-    elt[0] = TopologyLocation(Location::UNDEF, Location::UNDEF, Location::UNDEF);
-    elt[1] = TopologyLocation(Location::UNDEF, Location::UNDEF, Location::UNDEF);
-    elt[geomIndex].setLocations(onLoc, leftLoc, rightLoc);
-}
-
-/*public*/
-void
-Label::flip()
-{
-    elt[0].flip();
-    elt[1].flip();
-}
-
-/*public*/
-Location
-Label::getLocation(int geomIndex, int posIndex) const
-{
-    assert(geomIndex >= 0 && geomIndex < 2);
-    return elt[geomIndex].get(posIndex);
-}
-
-/*public*/
-Location
-Label::getLocation(int geomIndex) const
-{
-    assert(geomIndex >= 0 && geomIndex < 2);
-    return elt[geomIndex].get(Position::ON);
-}
-
-/*public*/
-void
-Label::setLocation(int geomIndex, int posIndex, Location location)
-{
-    assert(geomIndex >= 0 && geomIndex < 2);
-    elt[geomIndex].setLocation(posIndex, location);
-}
-
-/*public*/
-void
-Label::setLocation(int geomIndex, Location location)
-{
-    assert(geomIndex >= 0 && geomIndex < 2);
-    elt[geomIndex].setLocation(Position::ON, location);
-}
-
-/*public*/
-void
-Label::setAllLocations(int geomIndex, Location location)
-{
-    assert(geomIndex >= 0 && geomIndex < 2);
-    elt[geomIndex].setAllLocations(location);
-}
-
-/*public*/
-void
-Label::setAllLocationsIfNull(int geomIndex, Location location)
-{
-    assert(geomIndex >= 0 && geomIndex < 2);
-    elt[geomIndex].setAllLocationsIfNull(location);
-}
-
-/*public*/
-void
-Label::setAllLocationsIfNull(Location location)
-{
-    setAllLocationsIfNull(0, location);
-    setAllLocationsIfNull(1, location);
-}
-
-/*public*/
-void
-Label::merge(const Label& lbl)
-{
-    for(int i = 0; i < 2; i++) {
-        elt[i].merge(lbl.elt[i]);
-    }
-}
-
-/*public*/
-int
-Label::getGeometryCount() const
-{
-    int count = 0;
-    if(!elt[0].isNull()) {
-        count++;
-    }
-    if(!elt[1].isNull()) {
-        count++;
-    }
-    return count;
-}
-
-/*public*/
-bool
-Label::isNull(int geomIndex) const
-{
-    assert(geomIndex >= 0 && geomIndex < 2);
-    return elt[geomIndex].isNull();
-}
-
-/*public*/
-bool
-Label::isNull() const
-{
-    return elt[0].isNull() && elt[1].isNull();
-}
-
-/*public*/
-bool
-Label::isAnyNull(int geomIndex) const
-{
-    assert(geomIndex >= 0 && geomIndex < 2);
-    return elt[geomIndex].isAnyNull();
-}
-
-/*public*/
-bool
-Label::isArea() const
-{
-    return elt[0].isArea() || elt[1].isArea();
-}
-
-/*public*/
-bool
-Label::isArea(int geomIndex) const
-{
-    assert(geomIndex >= 0 && geomIndex < 2);
-    return elt[geomIndex].isArea();
-}
-
-/*public*/
-bool
-Label::isLine(int geomIndex) const
-{
-    assert(geomIndex >= 0 && geomIndex < 2);
-    return elt[geomIndex].isLine();
-}
-
-/*public*/
-bool
-Label::isEqualOnSide(const Label& lbl, int side) const
-{
-    return
-        elt[0].isEqualOnSide(lbl.elt[0], side)
-        && elt[1].isEqualOnSide(lbl.elt[1], side);
-}
-
-/*public*/
-bool
-Label::allPositionsEqual(int geomIndex, Location loc) const
-{
-    assert(geomIndex >= 0 && geomIndex < 2);
-    return elt[geomIndex].allPositionsEqual(loc);
-}
-
-/*public*/
-void
-Label::toLine(int geomIndex)
-{
-    assert(geomIndex >= 0 && geomIndex < 2);
-    if(elt[geomIndex].isArea()) {
-        elt[geomIndex] = TopologyLocation(elt[geomIndex].getLocations()[0]);
-    }
-}
-
-string
+std::string
 Label::toString() const
 {
-    stringstream ss;
+    std::stringstream ss;
     ss << *this;
     return ss.str();
 }
diff --git a/src/geomgraph/TopologyLocation.cpp b/src/geomgraph/TopologyLocation.cpp
index e3e337a..ab744ee 100644
--- a/src/geomgraph/TopologyLocation.cpp
+++ b/src/geomgraph/TopologyLocation.cpp
@@ -32,177 +32,6 @@ namespace geos {
 namespace geomgraph { // geos.geomgraph
 
 /*public*/
-TopologyLocation::TopologyLocation()
-{
-}
-
-/*public*/
-TopologyLocation::~TopologyLocation()
-{
-}
-
-/*public*/
-TopologyLocation::TopologyLocation(Location on, Location left, Location right):
-    locationSize(3)
-{
-    location[Position::ON] = on;
-    location[Position::LEFT] = left;
-    location[Position::RIGHT] = right;
-}
-
-/*public*/
-TopologyLocation::TopologyLocation(Location on):
-    locationSize(1)
-{
-    location.fill(Location::UNDEF);
-    location[Position::ON] = on;
-}
-
-/*public*/
-TopologyLocation::TopologyLocation(const TopologyLocation& gl)
-    :
-    location(gl.location),
-    locationSize(gl.locationSize)
-{
-}
-
-/*public*/
-TopologyLocation&
-TopologyLocation::operator= (const TopologyLocation& gl)
-{
-    location = gl.location;
-    locationSize = gl.locationSize;
-    return *this;
-}
-
-/*public*/
-Location
-TopologyLocation::get(size_t posIndex) const
-{
-    // should be an assert() instead ?
-    if(posIndex < locationSize) {
-        return location[posIndex];
-    }
-    return Location::UNDEF;
-}
-
-/*public*/
-bool
-TopologyLocation::isNull() const
-{
-    for(size_t i = 0; i < locationSize; ++i) {
-        if(location[i] != Location::UNDEF) {
-            return false;
-        }
-    }
-    return true;
-}
-
-/*public*/
-bool
-TopologyLocation::isAnyNull() const
-{
-    for(size_t i = 0; i < locationSize; ++i) {
-        if(location[i] == Location::UNDEF) {
-            return true;
-        }
-    }
-    return false;
-}
-
-/*public*/
-bool
-TopologyLocation::isEqualOnSide(const TopologyLocation& le, int locIndex) const
-{
-    return location[locIndex] == le.location[locIndex];
-}
-
-/*public*/
-bool
-TopologyLocation::isArea() const
-{
-    return locationSize > 1;
-}
-
-/*public*/
-bool
-TopologyLocation::isLine() const
-{
-    return locationSize == 1;
-}
-
-/*public*/
-void
-TopologyLocation::flip()
-{
-    if(locationSize <= 1) {
-        return;
-    }
-    std::swap(location[Position::LEFT], location[Position::RIGHT]);
-}
-
-/*public*/
-void
-TopologyLocation::setAllLocations(Location locValue)
-{
-    location.fill(locValue);
-}
-
-/*public*/
-void
-TopologyLocation::setAllLocationsIfNull(Location locValue)
-{
-    for(size_t i = 0; i < locationSize; ++i) {
-        if(location[i] == Location::UNDEF) {
-            location[i] = locValue;
-        }
-    }
-}
-
-/*public*/
-void
-TopologyLocation::setLocation(size_t locIndex, Location locValue)
-{
-    location[locIndex] = locValue;
-}
-
-/*public*/
-void
-TopologyLocation::setLocation(Location locValue)
-{
-    setLocation(Position::ON, locValue);
-}
-
-/*public*/
-const std::array<Location, 3>&
-TopologyLocation::getLocations() const
-{
-    return location;
-}
-
-/*public*/
-void
-TopologyLocation::setLocations(Location on, Location left, Location right)
-{
-    assert(locationSize >= 3);
-    location[Position::ON] = on;
-    location[Position::LEFT] = left;
-    location[Position::RIGHT] = right;
-}
-
-/*public*/
-bool
-TopologyLocation::allPositionsEqual(Location loc) const
-{
-    for(size_t i = 0; i < locationSize; ++i) {
-        if(location[i] != loc) {
-            return false;
-        }
-    }
-    return true;
-}
-
-/*public*/
 void
 TopologyLocation::merge(const TopologyLocation& gl)
 {
diff --git a/src/inlines.cpp b/src/inlines.cpp
index a14ef22..514f7f6 100644
--- a/src/inlines.cpp
+++ b/src/inlines.cpp
@@ -56,6 +56,8 @@
 #include <geos/geom/MultiLineString.inl>
 #include <geos/geom/MultiPolygon.inl>
 #include <geos/geom/CoordinateArraySequenceFactory.inl>
+#include <geos/geomgraph/Label.inl>
+#include <geos/geomgraph/TopologyLocation.inl>
 #include <geos/noding/snapround/HotPixel.inl>
 #include <geos/noding/MCIndexNoder.inl>
 

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

Summary of changes:
 benchmarks/ClassSizes.cpp                          |   3 +
 include/geos/algorithm/InteriorPointArea.h         |   2 -
 include/geos/algorithm/InteriorPointLine.h         |   3 -
 include/geos/algorithm/SimplePointInRing.h         |   2 +-
 include/geos/geom/Coordinate.h                     |  10 +-
 include/geos/geom/Coordinate.inl                   |  26 +--
 include/geos/geom/CoordinateArraySequence.h        |   2 +-
 include/geos/geom/CoordinateSequence.h             |   2 +
 include/geos/geom/CoordinateSequenceFactory.h      |   2 +-
 include/geos/geom/Envelope.h                       |   6 +-
 include/geos/geom/Envelope.inl                     | 157 ++++++++++++++
 include/geos/geom/GeometryCollection.h             |   2 +-
 include/geos/geom/LineString.h                     |   2 +-
 include/geos/geom/LinearRing.h                     |   2 +-
 include/geos/geom/MultiLineString.h                |   2 +-
 include/geos/geom/MultiPoint.h                     |   2 +-
 include/geos/geom/Point.h                          |   2 +-
 include/geos/geom/Polygon.h                        |   2 +-
 include/geos/geom/prep/BasicPreparedGeometry.h     |   2 +-
 include/geos/geom/util/GeometryTransformer.h       |   2 +-
 include/geos/geomgraph/Depth.h                     |   6 +-
 include/geos/geomgraph/Depth.inl                   | 119 +++++++++++
 include/geos/geomgraph/DirectedEdgeStar.h          |  18 +-
 include/geos/geomgraph/Edge.h                      |  18 +-
 include/geos/geomgraph/EdgeEnd.h                   |   4 +-
 include/geos/geomgraph/EdgeIntersection.h          |  14 ++
 include/geos/geomgraph/EdgeIntersectionList.h      |  41 ++--
 include/geos/geomgraph/EdgeList.h                  |  17 +-
 include/geos/geomgraph/EdgeRing.h                  |   6 +-
 include/geos/geomgraph/GraphComponent.h            |   3 +-
 include/geos/geomgraph/Label.h                     |   6 +-
 .../Label.cpp => include/geos/geomgraph/Label.inl  | 121 +++++------
 include/geos/geomgraph/Makefile.am                 |   6 +-
 include/geos/geomgraph/Quadrant.h                  |   4 +
 .../geos/geomgraph/Quadrant.inl                    |  68 ++----
 include/geos/geomgraph/TopologyLocation.h          |  10 +-
 .../geos/geomgraph/TopologyLocation.inl            | 104 +++------
 include/geos/geomgraph/index/Makefile.am           |   1 +
 include/geos/geomgraph/index/MonotoneChainEdge.h   |   2 +-
 include/geos/geomgraph/index/SegmentIntersector.h  |  11 +-
 .../geos/geomgraph/index/SegmentIntersector.inl    | 101 +++++++++
 .../geomgraph/index/SimpleMCSweepLineIntersector.h |  20 +-
 include/geos/geomgraph/index/SweepLineEvent.h      |  14 +-
 include/geos/geomgraph/index/SweepLineSegment.h    |   2 +-
 include/geos/index/bintree/Interval.h              |   2 -
 include/geos/index/chain/MonotoneChain.h           |   7 +-
 include/geos/index/quadtree/Key.h                  |   2 +-
 include/geos/index/strtree/AbstractNode.h          |  42 +++-
 include/geos/index/strtree/AbstractSTRtree.h       |  11 -
 include/geos/index/strtree/Boundable.h             |   2 +
 include/geos/index/strtree/ItemBoundable.h         |  15 +-
 include/geos/index/strtree/STRtree.h               |   2 +-
 include/geos/io/WKBWriter.h                        |   2 +-
 include/geos/io/WKTWriter.h                        |   2 +-
 include/geos/io/Writer.h                           |   2 +-
 include/geos/noding/BasicSegmentString.h           |  10 +-
 .../geos/noding/BasicSegmentString.inl             |  45 ++--
 include/geos/noding/Makefile.am                    |   1 +
 include/geos/noding/OrientedCoordinateArray.h      |  10 +-
 include/geos/operation/linemerge/EdgeString.h      |   2 +-
 include/geos/operation/overlay/ElevationMatrix.h   |   4 +-
 .../geos/operation/overlay/ElevationMatrixCell.h   |   2 +-
 include/geos/operation/overlay/LineBuilder.h       |   2 +-
 include/geos/operation/overlay/MaximalEdgeRing.h   |   2 +-
 include/geos/operation/relate/EdgeEndBuilder.h     |   8 +-
 include/geos/operation/relate/EdgeEndBundle.h      |   4 +-
 include/geos/operation/relate/RelateComputer.h     |   2 +-
 include/geos/operation/relate/RelateNode.h         |   2 +-
 include/geos/operation/relate/RelateOp.h           |   2 +-
 .../geos/operation/valid/ConnectedInteriorTester.h |   2 +-
 .../geos/operation/valid/ConsistentAreaTester.h    |   2 +-
 include/geos/planargraph/NodeMap.h                 |   2 +-
 include/geos/triangulate/VoronoiDiagramBuilder.h   |   2 +-
 .../geos/triangulate/quadedge/QuadEdgeLocator.h    |   2 +-
 .../geos/triangulate/quadedge/TriangleVisitor.h    |   2 +-
 src/algorithm/InteriorPointArea.cpp                |   4 -
 src/algorithm/InteriorPointLine.cpp                |   4 -
 src/algorithm/SimplePointInRing.cpp                |   4 -
 src/geom/CoordinateArraySequence.cpp               |   2 -
 src/geom/CoordinateSequence.cpp                    |   7 +
 src/geom/CoordinateSequenceFactory.cpp             |  28 ---
 src/geom/Envelope.cpp                              | 173 +--------------
 src/geom/GeometryCollection.cpp                    |   2 -
 src/geom/LineString.cpp                            |  22 +-
 src/geom/LinearRing.cpp                            |   7 -
 src/geom/Makefile.am                               |   1 -
 src/geom/MultiLineString.cpp                       |   2 -
 src/geom/MultiPoint.cpp                            |   2 -
 src/geom/Point.cpp                                 |   5 -
 src/geom/Polygon.cpp                               |   2 -
 src/geom/prep/BasicPreparedGeometry.cpp            |   5 -
 src/geom/util/GeometryTransformer.cpp              |   4 -
 src/geomgraph/Depth.cpp                            |  94 +--------
 src/geomgraph/DirectedEdgeStar.cpp                 |  19 +-
 src/geomgraph/Edge.cpp                             |  23 +-
 src/geomgraph/EdgeEnd.cpp                          |   7 -
 src/geomgraph/EdgeIntersectionList.cpp             |  83 ++++----
 src/geomgraph/EdgeList.cpp                         |  22 +-
 src/geomgraph/EdgeRing.cpp                         |   8 -
 src/geomgraph/GeometryGraph.cpp                    |   7 +-
 src/geomgraph/GraphComponent.cpp                   |   4 -
 src/geomgraph/Label.cpp                            | 234 +--------------------
 src/geomgraph/Quadrant.cpp                         |  81 -------
 src/geomgraph/TopologyLocation.cpp                 | 171 ---------------
 src/geomgraph/index/MonotoneChainEdge.cpp          |   4 -
 src/geomgraph/index/MonotoneChainIndexer.cpp       |   3 +-
 src/geomgraph/index/SegmentIntersector.cpp         |  84 +-------
 .../index/SimpleMCSweepLineIntersector.cpp         |  41 ++--
 src/geomgraph/index/SweepLineEvent.cpp             |  22 +-
 src/geomgraph/index/SweepLineSegment.cpp           |   4 -
 src/index/bintree/Interval.cpp                     |   4 -
 src/index/chain/MonotoneChain.cpp                  |  11 +-
 src/index/chain/MonotoneChainBuilder.cpp           |  11 +-
 src/index/quadtree/Key.cpp                         |   4 -
 src/index/strtree/AbstractNode.cpp                 |  76 -------
 src/index/strtree/AbstractSTRtree.cpp              |  90 +++-----
 src/index/strtree/ItemBoundable.cpp                |  42 ----
 src/index/strtree/Makefile.am                      |   2 -
 src/index/strtree/STRtree.cpp                      |   5 -
 src/inlines.cpp                                    |   6 +
 src/io/WKBWriter.cpp                               |   4 -
 src/io/WKTWriter.cpp                               |   2 -
 src/io/Writer.cpp                                  |   6 -
 src/noding/BasicSegmentString.cpp                  |  37 ----
 src/noding/MCIndexNoder.cpp                        |  17 +-
 src/noding/OrientedCoordinateArray.cpp             |  51 ++++-
 src/operation/IsSimpleOp.cpp                       |   8 +-
 src/operation/linemerge/EdgeString.cpp             |   4 -
 src/operation/overlay/ElevationMatrix.cpp          |   7 -
 src/operation/overlay/ElevationMatrixCell.cpp      |   4 -
 src/operation/overlay/LineBuilder.cpp              |   4 -
 src/operation/overlay/MaximalEdgeRing.cpp          |   8 -
 src/operation/relate/EdgeEndBuilder.cpp            |  14 +-
 src/operation/relate/EdgeEndBundle.cpp             |  19 +-
 src/operation/relate/RelateComputer.cpp            |  20 +-
 src/operation/relate/RelateNode.cpp                |   4 -
 src/operation/relate/RelateNodeGraph.cpp           |   7 +-
 src/operation/relate/RelateOp.cpp                  |   4 -
 src/operation/valid/ConnectedInteriorTester.cpp    |   4 -
 src/operation/valid/ConsistentAreaTester.cpp       |   6 +-
 src/operation/valid/IsValidOp.cpp                  |  11 +-
 src/planargraph/NodeMap.cpp                        |   4 -
 src/triangulate/VoronoiDiagramBuilder.cpp          |   4 -
 src/triangulate/quadedge/Makefile.am               |  12 +-
 src/triangulate/quadedge/QuadEdgeLocator.cpp       |  30 ---
 src/triangulate/quadedge/TriangleVisitor.cpp       |  30 ---
 146 files changed, 959 insertions(+), 1944 deletions(-)
 create mode 100644 include/geos/geomgraph/Depth.inl
 copy src/geomgraph/Label.cpp => include/geos/geomgraph/Label.inl (67%)
 copy src/geomgraph/Quadrant.cpp => include/geos/geomgraph/Quadrant.inl (62%)
 copy src/geomgraph/TopologyLocation.cpp => include/geos/geomgraph/TopologyLocation.inl (71%)
 create mode 100644 include/geos/geomgraph/index/SegmentIntersector.inl
 copy src/noding/BasicSegmentString.cpp => include/geos/noding/BasicSegmentString.inl (65%)
 delete mode 100644 src/geom/CoordinateSequenceFactory.cpp
 delete mode 100644 src/index/strtree/AbstractNode.cpp
 delete mode 100644 src/index/strtree/ItemBoundable.cpp
 delete mode 100644 src/triangulate/quadedge/QuadEdgeLocator.cpp
 delete mode 100644 src/triangulate/quadedge/TriangleVisitor.cpp


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list