Skip to content

Commit

Permalink
OGRGeometry classes: implement move constructor and move assignment o…
Browse files Browse the repository at this point in the history
…perator

as suggested by performance warnings of Coverity Scan
  • Loading branch information
rouault committed Nov 2, 2024
1 parent 3e8bf03 commit 062bbee
Show file tree
Hide file tree
Showing 7 changed files with 347 additions and 3 deletions.
54 changes: 54 additions & 0 deletions autotest/cpp/test_ogr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,60 @@ TEST_F(test_ogr, OGRCurvePolygon_copy_constructor_illegal_use)
EXPECT_TRUE(poly.IsEmpty());
}

template <class T> void testMove()
{
auto poSRS = new OGRSpatialReference();
{
auto poOrigin = std::unique_ptr<T>(make<T>());
ASSERT_TRUE(nullptr != poOrigin);
poOrigin->assignSpatialReference(poSRS);

T valueCopy(*poOrigin);
const int refCountBefore = poSRS->GetReferenceCount();
T fromMoved(std::move(*poOrigin));
EXPECT_EQ(poSRS->GetReferenceCount(), refCountBefore);

ASSERT_TRUE(CPL_TO_BOOL(fromMoved.Equals(&valueCopy)))
<< valueCopy.getGeometryName()
<< ": move constructor changed a value";
EXPECT_EQ(fromMoved.getSpatialReference(), poSRS);

T valueCopy2(valueCopy);
EXPECT_EQ(valueCopy.getSpatialReference(), poSRS);
T value3;
const int refCountBefore2 = poSRS->GetReferenceCount();
value3 = std::move(valueCopy);
EXPECT_EQ(poSRS->GetReferenceCount(), refCountBefore2);

ASSERT_TRUE(CPL_TO_BOOL(value3.Equals(&valueCopy2)))
<< valueCopy2.getGeometryName()
<< ": move assignment operator changed a value";
EXPECT_EQ(value3.getSpatialReference(), poSRS);
}
EXPECT_EQ(poSRS->GetReferenceCount(), 1);
poSRS->Release();
}

TEST_F(test_ogr, geometry_move)
{
testMove<OGRPoint>();
testMove<OGRLineString>();
testMove<OGRLinearRing>();
testMove<OGRCircularString>();
testMove<OGRCompoundCurve>();
testMove<OGRCurvePolygon>();
testMove<OGRPolygon>();
testMove<OGRGeometryCollection>();
testMove<OGRMultiSurface>();
testMove<OGRMultiPolygon>();
testMove<OGRMultiPoint>();
testMove<OGRMultiCurve>();
testMove<OGRMultiLineString>();
testMove<OGRTriangle>();
testMove<OGRPolyhedralSurface>();
testMove<OGRTriangulatedSurface>();
}

TEST_F(test_ogr, geometry_get_point)
{
{
Expand Down
75 changes: 73 additions & 2 deletions ogr/ogr_geometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -407,9 +407,11 @@ class CPL_DLL OGRGeometry

OGRGeometry();
OGRGeometry(const OGRGeometry &other);
OGRGeometry(OGRGeometry &&other);
virtual ~OGRGeometry();

OGRGeometry &operator=(const OGRGeometry &other);
OGRGeometry &operator=(OGRGeometry &&other);

/** Returns if two geometries are equal. */
bool operator==(const OGRGeometry &other) const
Expand Down Expand Up @@ -1144,9 +1146,13 @@ class CPL_DLL OGRPoint : public OGRGeometry
OGRPoint(double x, double y, double z);
OGRPoint(double x, double y, double z, double m);
OGRPoint(const OGRPoint &other);
/** Move constructor */
OGRPoint(OGRPoint &&other) = default;
static OGRPoint *createXYM(double x, double y, double m);

OGRPoint &operator=(const OGRPoint &other);
/** Move assignment operator */
OGRPoint &operator=(OGRPoint &&other) = default;

// IWks Interface
size_t WkbSize() const override;
Expand Down Expand Up @@ -1317,6 +1323,7 @@ class CPL_DLL OGRCurve : public OGRGeometry
//! @cond Doxygen_Suppress
OGRCurve() = default;
OGRCurve(const OGRCurve &other) = default;
OGRCurve(OGRCurve &&other) = default;

virtual OGRCurveCasterToLineString GetCasterToLineString() const = 0;
virtual OGRCurveCasterToLinearRing GetCasterToLinearRing() const = 0;
Expand Down Expand Up @@ -1350,6 +1357,7 @@ class CPL_DLL OGRCurve : public OGRGeometry
public:
//! @cond Doxygen_Suppress
OGRCurve &operator=(const OGRCurve &other);
OGRCurve &operator=(OGRCurve &&other) = default;
//! @endcond

/** Type of child elements. */
Expand Down Expand Up @@ -1532,6 +1540,8 @@ class CPL_DLL OGRSimpleCurve : public OGRCurve

OGRSimpleCurve(const OGRSimpleCurve &other);

OGRSimpleCurve(OGRSimpleCurve &&other);

private:
class CPL_DLL Iterator
{
Expand Down Expand Up @@ -1576,6 +1586,8 @@ class CPL_DLL OGRSimpleCurve : public OGRCurve

OGRSimpleCurve &operator=(const OGRSimpleCurve &other);

OGRSimpleCurve &operator=(OGRSimpleCurve &&other);

/** Type of child elements. */
typedef OGRPoint ChildType;

Expand Down Expand Up @@ -1776,8 +1788,10 @@ class CPL_DLL OGRLineString : public OGRSimpleCurve
/** Create an empty line string. */
OGRLineString() = default;
OGRLineString(const OGRLineString &other);
OGRLineString(OGRLineString &&other);

OGRLineString &operator=(const OGRLineString &other);
OGRLineString &operator=(OGRLineString &&other);

virtual OGRLineString *clone() const override;
virtual OGRLineString *
Expand Down Expand Up @@ -1882,9 +1896,13 @@ class CPL_DLL OGRLinearRing : public OGRLineString
/** Constructor */
OGRLinearRing() = default;
OGRLinearRing(const OGRLinearRing &other);
/** Move constructor*/
OGRLinearRing(OGRLinearRing &&other) = default;
explicit OGRLinearRing(const OGRLinearRing *);

OGRLinearRing &operator=(const OGRLinearRing &other);
/** Move assignment operator */
OGRLinearRing &operator=(OGRLinearRing &&other) = default;

// Non standard.
virtual const char *getGeometryName() const override;
Expand Down Expand Up @@ -1965,8 +1983,12 @@ class CPL_DLL OGRCircularString : public OGRSimpleCurve
OGRCircularString() = default;

OGRCircularString(const OGRCircularString &other);
/** Move constructor */
OGRCircularString(OGRCircularString &&other) = default;

OGRCircularString &operator=(const OGRCircularString &other);
/** Move assignment operator */
OGRCircularString &operator=(OGRCircularString &&other) = default;

// IWks Interface.
virtual OGRErr importFromWkb(const unsigned char *, size_t, OGRwkbVariant,
Expand Down Expand Up @@ -2074,9 +2096,11 @@ class CPL_DLL OGRCurveCollection
public:
OGRCurveCollection() = default;
OGRCurveCollection(const OGRCurveCollection &other);
OGRCurveCollection(OGRCurveCollection &&other);
~OGRCurveCollection();

OGRCurveCollection &operator=(const OGRCurveCollection &other);
OGRCurveCollection &operator=(OGRCurveCollection &&other);

/** Type of child elements. */
typedef OGRCurve ChildType;
Expand Down Expand Up @@ -2207,8 +2231,12 @@ class CPL_DLL OGRCompoundCurve : public OGRCurve
OGRCompoundCurve() = default;

OGRCompoundCurve(const OGRCompoundCurve &other);
/** Move constructor */
OGRCompoundCurve(OGRCompoundCurve &&other) = default;

OGRCompoundCurve &operator=(const OGRCompoundCurve &other);
/** Move assignment operator */
OGRCompoundCurve &operator=(OGRCompoundCurve &&other) = default;

/** Type of child elements. */
typedef OGRCurve ChildType;
Expand Down Expand Up @@ -2476,8 +2504,12 @@ class CPL_DLL OGRCurvePolygon : public OGRSurface
OGRCurvePolygon() = default;

OGRCurvePolygon(const OGRCurvePolygon &);
/** Move constructor */
OGRCurvePolygon(OGRCurvePolygon &&) = default;

OGRCurvePolygon &operator=(const OGRCurvePolygon &other);
/** Move assignment operator */
OGRCurvePolygon &operator=(OGRCurvePolygon &&other) = default;

/** Type of child elements. */
typedef OGRCurve ChildType;
Expand Down Expand Up @@ -2685,8 +2717,12 @@ class CPL_DLL OGRPolygon : public OGRCurvePolygon
OGRPolygon() = default;

OGRPolygon(const OGRPolygon &other);
/** Move constructor */
OGRPolygon(OGRPolygon &&other) = default;

OGRPolygon &operator=(const OGRPolygon &other);
/** Move assignment operator */
OGRPolygon &operator=(OGRPolygon &&other) = default;

/** Type of child elements. */
typedef OGRLinearRing ChildType;
Expand Down Expand Up @@ -2856,8 +2892,12 @@ class CPL_DLL OGRTriangle : public OGRPolygon
OGRTriangle() = default;
OGRTriangle(const OGRPoint &p, const OGRPoint &q, const OGRPoint &r);
OGRTriangle(const OGRTriangle &other);
/** Move constructor */
OGRTriangle(OGRTriangle &&other) = default;
OGRTriangle(const OGRPolygon &other, OGRErr &eErr);
OGRTriangle &operator=(const OGRTriangle &other);
/** Move assignment operator */
OGRTriangle &operator=(OGRTriangle &&other) = default;

virtual const char *getGeometryName() const override;
virtual OGRwkbGeometryType getGeometryType() const override;
Expand Down Expand Up @@ -2938,9 +2978,11 @@ class CPL_DLL OGRGeometryCollection : public OGRGeometry
OGRGeometryCollection() = default;

OGRGeometryCollection(const OGRGeometryCollection &other);
OGRGeometryCollection(OGRGeometryCollection &&other);
~OGRGeometryCollection() override;

OGRGeometryCollection &operator=(const OGRGeometryCollection &other);
OGRGeometryCollection &operator=(OGRGeometryCollection &&other);

/** Type of child elements. */
typedef OGRGeometry ChildType;
Expand Down Expand Up @@ -3122,8 +3164,12 @@ class CPL_DLL OGRMultiSurface : public OGRGeometryCollection
OGRMultiSurface() = default;

OGRMultiSurface(const OGRMultiSurface &other);
/** Move constructor */
OGRMultiSurface(OGRMultiSurface &&other) = default;

OGRMultiSurface &operator=(const OGRMultiSurface &other);
/** Move assignment operator */
OGRMultiSurface &operator=(OGRMultiSurface &&other) = default;

/** Type of child elements. */
typedef OGRSurface ChildType;
Expand Down Expand Up @@ -3290,8 +3336,12 @@ class CPL_DLL OGRMultiPolygon : public OGRMultiSurface
OGRMultiPolygon() = default;

OGRMultiPolygon(const OGRMultiPolygon &other);
/** Move constructor */
OGRMultiPolygon(OGRMultiPolygon &&other) = default;

OGRMultiPolygon &operator=(const OGRMultiPolygon &other);
/** Move assignment operator */
OGRMultiPolygon &operator=(OGRMultiPolygon &&other) = default;

/** Type of child elements. */
typedef OGRPolygon ChildType;
Expand Down Expand Up @@ -3452,9 +3502,13 @@ class CPL_DLL OGRPolyhedralSurface : public OGRSurface
/** Create an empty PolyhedralSurface */
OGRPolyhedralSurface() = default;

OGRPolyhedralSurface(const OGRPolyhedralSurface &poGeom);
OGRPolyhedralSurface(const OGRPolyhedralSurface &other);
/** Move constructor */
OGRPolyhedralSurface(OGRPolyhedralSurface &&other) = default;

OGRPolyhedralSurface &operator=(const OGRPolyhedralSurface &other);
/** Move assignment operator */
OGRPolyhedralSurface &operator=(OGRPolyhedralSurface &&other) = default;

/** Type of child elements. */
typedef OGRPolygon ChildType;
Expand Down Expand Up @@ -3629,6 +3683,12 @@ class CPL_DLL OGRTriangulatedSurface : public OGRPolyhedralSurface
OGRTriangulatedSurface() = default;

OGRTriangulatedSurface(const OGRTriangulatedSurface &other);
/** Move constructor */
OGRTriangulatedSurface(OGRTriangulatedSurface &&other) = default;

OGRTriangulatedSurface &operator=(const OGRTriangulatedSurface &other);
/** Move assignment operator */
OGRTriangulatedSurface &operator=(OGRTriangulatedSurface &&other) = default;

/** Type of child elements. */
typedef OGRTriangle ChildType;
Expand Down Expand Up @@ -3661,7 +3721,6 @@ class CPL_DLL OGRTriangulatedSurface : public OGRPolyhedralSurface
return reinterpret_cast<const ChildType *const *>(oMP.end());
}

OGRTriangulatedSurface &operator=(const OGRTriangulatedSurface &other);
virtual const char *getGeometryName() const override;
virtual OGRwkbGeometryType getGeometryType() const override;
virtual OGRTriangulatedSurface *clone() const override;
Expand Down Expand Up @@ -3764,8 +3823,12 @@ class CPL_DLL OGRMultiPoint : public OGRGeometryCollection
OGRMultiPoint() = default;

OGRMultiPoint(const OGRMultiPoint &other);
/** Move constructor */
OGRMultiPoint(OGRMultiPoint &&other) = default;

OGRMultiPoint &operator=(const OGRMultiPoint &other);
/** Move assignment operator */
OGRMultiPoint &operator=(OGRMultiPoint &&other) = default;

/** Type of child elements. */
typedef OGRPoint ChildType;
Expand Down Expand Up @@ -3922,8 +3985,12 @@ class CPL_DLL OGRMultiCurve : public OGRGeometryCollection
OGRMultiCurve() = default;

OGRMultiCurve(const OGRMultiCurve &other);
/** Move constructor */
OGRMultiCurve(OGRMultiCurve &&other) = default;

OGRMultiCurve &operator=(const OGRMultiCurve &other);
/** Move assignment operator */
OGRMultiCurve &operator=(OGRMultiCurve &&other) = default;

/** Type of child elements. */
typedef OGRCurve ChildType;
Expand Down Expand Up @@ -4075,8 +4142,12 @@ class CPL_DLL OGRMultiLineString : public OGRMultiCurve
OGRMultiLineString() = default;

OGRMultiLineString(const OGRMultiLineString &other);
/** Move constructor */
OGRMultiLineString(OGRMultiLineString &&other) = default;

OGRMultiLineString &operator=(const OGRMultiLineString &other);
/** Move assignment operator */
OGRMultiLineString &operator=(OGRMultiLineString &&other) = default;

/** Type of child elements. */
typedef OGRLineString ChildType;
Expand Down
38 changes: 38 additions & 0 deletions ogr/ogrcurvecollection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,23 @@ OGRCurveCollection::OGRCurveCollection(const OGRCurveCollection &other)
}
}

/************************************************************************/
/* OGRCurveCollection( OGRCurveCollection&& ) */
/************************************************************************/

/**
* \brief Move constructor.
*
* @since GDAL 3.11
*/

OGRCurveCollection::OGRCurveCollection(OGRCurveCollection &&other)
: nCurveCount(other.nCurveCount), papoCurves(other.papoCurves)
{
other.nCurveCount = 0;
other.papoCurves = nullptr;
}

/************************************************************************/
/* ~OGRCurveCollection() */
/************************************************************************/
Expand Down Expand Up @@ -107,6 +124,27 @@ OGRCurveCollection::operator=(const OGRCurveCollection &other)
return *this;
}

/************************************************************************/
/* operator=( OGRCurveCollection&& ) */
/************************************************************************/

/**
* \brief Move assignment operator.
*
* @since GDAL 3.11
*/

OGRCurveCollection &OGRCurveCollection::operator=(OGRCurveCollection &&other)
{
if (this != &other)
{
empty(nullptr);
std::swap(nCurveCount, other.nCurveCount);
std::swap(papoCurves, other.papoCurves);
}
return *this;
}

/************************************************************************/
/* WkbSize() */
/************************************************************************/
Expand Down
Loading

0 comments on commit 062bbee

Please sign in to comment.